qemu/include/user/thunk.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

214 lines
5.7 KiB
C
Raw Normal View History

/*
* Generic thunking code to convert data between host and target CPU
*
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef USER_THUNK_H
#define USER_THUNK_H
#ifndef CONFIG_USER_ONLY
#error Cannot include this header from system emulation
#endif
#include "cpu.h"
#include "user/abitypes.h"
/* types enums definitions */
typedef enum argtype {
TYPE_NULL,
TYPE_CHAR,
TYPE_SHORT,
TYPE_INT,
TYPE_LONG,
TYPE_ULONG,
TYPE_PTRVOID, /* pointer on unknown data */
TYPE_LONGLONG,
TYPE_ULONGLONG,
TYPE_PTR,
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_OLDDEVT,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
#define MK_ARRAY(type, size) TYPE_ARRAY, (int)(size), type
#define MK_STRUCT(id) TYPE_STRUCT, id
#define THUNK_TARGET 0
#define THUNK_HOST 1
typedef struct {
/* standard struct handling */
const argtype *field_types;
int nb_fields;
int *field_offsets[2];
/* special handling */
void (*convert[2])(void *dst, const void *src);
linux-user: Add strace support for printing arguments for ioctls used for terminals and serial lines Functions "print_ioctl()" and "print_syscall_ret_ioctl()" are used to print arguments of "ioctl()" with "-strace". These functions use "thunk_print()", which is defined in "thunk.c", to print the contents of ioctl's third arguments that are not basic types. However, this function doesn't handle ioctls of group ioctl_tty which are used for terminals and serial lines. These ioctls use a type "struct termios" which thunk type is defined in a non standard way using "STRUCT_SPECIAL()". This means that this type is not decoded regularly using "thunk_convert()" and uses special converting functions "target_to_host_termios()" and "host_to_target_termios()", which are defined in "syscall.c" to decode it's values. For simillar reasons, this type is also not printed regularly using "thunk_print()". That is the reason why a separate printing function "print_termios()" is defined in file "strace.c". This function decodes and prints flag values of the "termios" structure. Implementation notes: Function "print_termios()" was implemented in "strace.c" using an existing function "print_flags()" to print flag values of "struct termios" fields. Also, recently implemented function "print_enums()" was also used to print enumareted values which are contained in the fields of 'struct termios'. These flag values were defined using an existing macro "FLAG_TARGET()" that generates aproppriate target flag values and string representations of these flags. Also, the recently defined macro "ENUM_TARGET()" was used to generate aproppriate enumarated values and their respective string representations. Function "print_termios()" was declared in "qemu.h" so that it can be accessed in "syscall.c". Type "StructEntry" defined in "exec/user/thunk.h" contains information that is used to decode structure values. Field "void print(void *arg)" was added in this structure as a special print function. Also, function "thunk_print()" was changed a little so that it uses this special print function in case it is defined. This printing function was instantiated with the defined "print_termios()" in "syscall.c" in "struct_termios_def". Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20200723210233.349690-4-Filip.Bozuta@syrmia.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2020-07-24 00:02:33 +03:00
void (*print)(void *arg);
int size[2];
int align[2];
const char *name;
} StructEntry;
/* Translation table for bitmasks... */
typedef struct bitmask_transtbl {
unsigned int target_mask;
unsigned int target_bits;
unsigned int host_mask;
unsigned int host_bits;
} bitmask_transtbl;
void thunk_register_struct(int id, const char *name, const argtype *types);
void thunk_register_struct_direct(int id, const char *name,
const StructEntry *se1);
const argtype *thunk_convert(void *dst, const void *src,
const argtype *type_ptr, int to_host);
linux-user: Add strace support for printing arguments of ioctl() This patch implements functionality for strace argument printing for ioctls. When running ioctls through qemu with "-strace", they get printed in format: "ioctl(fd_num,0x*,0x*) = ret_value" where the request code an the ioctl's third argument get printed in a hexadicemal format. This patch changes that by enabling strace to print both the request code name and the contents of the third argument. For example, when running ioctl RTC_SET_TIME with "-strace", with changes from this patch, it gets printed in this way: "ioctl(3,RTC_SET_TIME,{12,13,15,20,10,119,0,0,0}) = 0" In case of IOC_R type ioctls, the contents of the third argument get printed after the return value, and the argument inside the ioctl call gets printed as pointer in hexadecimal format. For example, when running RTC_RD_TIME with "-strace", with changes from this patch, it gets printed in this way: "ioctl(3,RTC_RD_TIME,0x40800374) = 0 ({22,9,13,11,5,120,0,0,0})" In case of IOC_RW type ioctls, the contents of the third argument get printed both inside the ioctl call and after the return value. Implementation notes: Functions "print_ioctl()" and "print_syscall_ret_ioctl()", that are defined in "strace.c", are listed in file "strace.list" as "call" and "result" value for ioctl. Structure definition "IOCTLEntry" as well as predefined values for IOC_R, IOC_W and IOC_RW were cut and pasted from file "syscall.c" to file "qemu.h" so that they can be used by these functions to print the contents of the third ioctl argument. Also, the "static" identifier for array "ioctl_entries[]" was removed and this array was declared as "extern" in "qemu.h" so that it can also be used by these functions. To decode the structure type of the ioctl third argument, function "thunk_print()" was defined in file "thunk.c" and its definition is somewhat simillar to that of function "thunk_convert()". Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20200619124727.18080-3-filip.bozuta@syrmia.com> [lv: fix close-bracket] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2020-06-19 15:47:27 +03:00
const argtype *thunk_print(void *arg, const argtype *type_ptr);
extern StructEntry *struct_entries;
int thunk_type_size_array(const argtype *type_ptr, int is_host);
int thunk_type_align_array(const argtype *type_ptr, int is_host);
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
{
int type, size;
const StructEntry *se;
type = *type_ptr;
switch(type) {
case TYPE_CHAR:
return 1;
case TYPE_SHORT:
return 2;
case TYPE_INT:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
return 8;
case TYPE_LONG:
case TYPE_ULONG:
case TYPE_PTRVOID:
case TYPE_PTR:
if (is_host) {
return sizeof(void *);
} else {
return TARGET_ABI_BITS / 8;
}
break;
case TYPE_OLDDEVT:
if (is_host) {
#if defined(HOST_X86_64)
return 8;
#elif defined(HOST_MIPS) || defined(HOST_SPARC64)
return 4;
#elif defined(HOST_PPC)
return sizeof(void *);
#else
return 2;
#endif
} else {
#if defined(TARGET_X86_64)
return 8;
#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
defined(TARGET_PARISC) || defined(TARGET_SPARC64)
return 4;
#elif defined(TARGET_PPC)
return TARGET_ABI_BITS / 8;
#else
return 2;
#endif
}
break;
case TYPE_ARRAY:
size = type_ptr[1];
return size * thunk_type_size_array(type_ptr + 2, is_host);
case TYPE_STRUCT:
se = struct_entries + type_ptr[1];
return se->size[is_host];
default:
g_assert_not_reached();
}
}
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
{
int type;
const StructEntry *se;
type = *type_ptr;
switch(type) {
case TYPE_CHAR:
return 1;
case TYPE_SHORT:
linux-user: correctly align types in thunking code This is a follow up of patch: commit c2e3dee6e03527baf8698698cce76b1a3174969a Author: Laurent Vivier <laurent@vivier.eu> Date: Sun Feb 13 23:37:34 2011 +0100 linux-user: Define target alignment size In my case m68k aligns "int" on 2 not 4. You can check this with the following program: int main(void) { struct rtentry rt; printf("rt_pad1 %ld %zd\n", offsetof(struct rtentry, rt_pad1), sizeof(rt.rt_pad1)); printf("rt_dst %ld %zd\n", offsetof(struct rtentry, rt_dst), sizeof(rt.rt_dst)); printf("rt_gateway %ld %zd\n", offsetof(struct rtentry, rt_gateway), sizeof(rt.rt_gateway)); printf("rt_genmask %ld %zd\n", offsetof(struct rtentry, rt_genmask), sizeof(rt.rt_genmask)); printf("rt_flags %ld %zd\n", offsetof(struct rtentry, rt_flags), sizeof(rt.rt_flags)); printf("rt_pad2 %ld %zd\n", offsetof(struct rtentry, rt_pad2), sizeof(rt.rt_pad2)); printf("rt_pad3 %ld %zd\n", offsetof(struct rtentry, rt_pad3), sizeof(rt.rt_pad3)); printf("rt_pad4 %ld %zd\n", offsetof(struct rtentry, rt_pad4), sizeof(rt.rt_pad4)); printf("rt_metric %ld %zd\n", offsetof(struct rtentry, rt_metric), sizeof(rt.rt_metric)); printf("rt_dev %ld %zd\n", offsetof(struct rtentry, rt_dev), sizeof(rt.rt_dev)); printf("rt_mtu %ld %zd\n", offsetof(struct rtentry, rt_mtu), sizeof(rt.rt_mtu)); printf("rt_window %ld %zd\n", offsetof(struct rtentry, rt_window), sizeof(rt.rt_window)); printf("rt_irtt %ld %zd\n", offsetof(struct rtentry, rt_irtt), sizeof(rt.rt_irtt)); } And result is : i386 rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 68 4 rt_mtu 72 4 rt_window 76 4 rt_irtt 80 2 m68k rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 66 4 rt_mtu 70 4 rt_window 74 4 rt_irtt 78 2 This affects the "route" command : WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 67108866 32768 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 WITH this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 1024 2 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20180510205949.26455-1-laurent@vivier.eu>
2018-05-10 23:59:49 +03:00
if (is_host) {
return __alignof__(short);
} else {
return ABI_SHORT_ALIGNMENT;
}
case TYPE_INT:
linux-user: correctly align types in thunking code This is a follow up of patch: commit c2e3dee6e03527baf8698698cce76b1a3174969a Author: Laurent Vivier <laurent@vivier.eu> Date: Sun Feb 13 23:37:34 2011 +0100 linux-user: Define target alignment size In my case m68k aligns "int" on 2 not 4. You can check this with the following program: int main(void) { struct rtentry rt; printf("rt_pad1 %ld %zd\n", offsetof(struct rtentry, rt_pad1), sizeof(rt.rt_pad1)); printf("rt_dst %ld %zd\n", offsetof(struct rtentry, rt_dst), sizeof(rt.rt_dst)); printf("rt_gateway %ld %zd\n", offsetof(struct rtentry, rt_gateway), sizeof(rt.rt_gateway)); printf("rt_genmask %ld %zd\n", offsetof(struct rtentry, rt_genmask), sizeof(rt.rt_genmask)); printf("rt_flags %ld %zd\n", offsetof(struct rtentry, rt_flags), sizeof(rt.rt_flags)); printf("rt_pad2 %ld %zd\n", offsetof(struct rtentry, rt_pad2), sizeof(rt.rt_pad2)); printf("rt_pad3 %ld %zd\n", offsetof(struct rtentry, rt_pad3), sizeof(rt.rt_pad3)); printf("rt_pad4 %ld %zd\n", offsetof(struct rtentry, rt_pad4), sizeof(rt.rt_pad4)); printf("rt_metric %ld %zd\n", offsetof(struct rtentry, rt_metric), sizeof(rt.rt_metric)); printf("rt_dev %ld %zd\n", offsetof(struct rtentry, rt_dev), sizeof(rt.rt_dev)); printf("rt_mtu %ld %zd\n", offsetof(struct rtentry, rt_mtu), sizeof(rt.rt_mtu)); printf("rt_window %ld %zd\n", offsetof(struct rtentry, rt_window), sizeof(rt.rt_window)); printf("rt_irtt %ld %zd\n", offsetof(struct rtentry, rt_irtt), sizeof(rt.rt_irtt)); } And result is : i386 rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 68 4 rt_mtu 72 4 rt_window 76 4 rt_irtt 80 2 m68k rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 66 4 rt_mtu 70 4 rt_window 74 4 rt_irtt 78 2 This affects the "route" command : WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 67108866 32768 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 WITH this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 1024 2 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20180510205949.26455-1-laurent@vivier.eu>
2018-05-10 23:59:49 +03:00
if (is_host) {
return __alignof__(int);
} else {
return ABI_INT_ALIGNMENT;
}
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
linux-user: correctly align types in thunking code This is a follow up of patch: commit c2e3dee6e03527baf8698698cce76b1a3174969a Author: Laurent Vivier <laurent@vivier.eu> Date: Sun Feb 13 23:37:34 2011 +0100 linux-user: Define target alignment size In my case m68k aligns "int" on 2 not 4. You can check this with the following program: int main(void) { struct rtentry rt; printf("rt_pad1 %ld %zd\n", offsetof(struct rtentry, rt_pad1), sizeof(rt.rt_pad1)); printf("rt_dst %ld %zd\n", offsetof(struct rtentry, rt_dst), sizeof(rt.rt_dst)); printf("rt_gateway %ld %zd\n", offsetof(struct rtentry, rt_gateway), sizeof(rt.rt_gateway)); printf("rt_genmask %ld %zd\n", offsetof(struct rtentry, rt_genmask), sizeof(rt.rt_genmask)); printf("rt_flags %ld %zd\n", offsetof(struct rtentry, rt_flags), sizeof(rt.rt_flags)); printf("rt_pad2 %ld %zd\n", offsetof(struct rtentry, rt_pad2), sizeof(rt.rt_pad2)); printf("rt_pad3 %ld %zd\n", offsetof(struct rtentry, rt_pad3), sizeof(rt.rt_pad3)); printf("rt_pad4 %ld %zd\n", offsetof(struct rtentry, rt_pad4), sizeof(rt.rt_pad4)); printf("rt_metric %ld %zd\n", offsetof(struct rtentry, rt_metric), sizeof(rt.rt_metric)); printf("rt_dev %ld %zd\n", offsetof(struct rtentry, rt_dev), sizeof(rt.rt_dev)); printf("rt_mtu %ld %zd\n", offsetof(struct rtentry, rt_mtu), sizeof(rt.rt_mtu)); printf("rt_window %ld %zd\n", offsetof(struct rtentry, rt_window), sizeof(rt.rt_window)); printf("rt_irtt %ld %zd\n", offsetof(struct rtentry, rt_irtt), sizeof(rt.rt_irtt)); } And result is : i386 rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 68 4 rt_mtu 72 4 rt_window 76 4 rt_irtt 80 2 m68k rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 66 4 rt_mtu 70 4 rt_window 74 4 rt_irtt 78 2 This affects the "route" command : WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 67108866 32768 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 WITH this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 1024 2 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20180510205949.26455-1-laurent@vivier.eu>
2018-05-10 23:59:49 +03:00
if (is_host) {
return __alignof__(long long);
} else {
return ABI_LLONG_ALIGNMENT;
}
case TYPE_LONG:
case TYPE_ULONG:
case TYPE_PTRVOID:
case TYPE_PTR:
if (is_host) {
linux-user: correctly align types in thunking code This is a follow up of patch: commit c2e3dee6e03527baf8698698cce76b1a3174969a Author: Laurent Vivier <laurent@vivier.eu> Date: Sun Feb 13 23:37:34 2011 +0100 linux-user: Define target alignment size In my case m68k aligns "int" on 2 not 4. You can check this with the following program: int main(void) { struct rtentry rt; printf("rt_pad1 %ld %zd\n", offsetof(struct rtentry, rt_pad1), sizeof(rt.rt_pad1)); printf("rt_dst %ld %zd\n", offsetof(struct rtentry, rt_dst), sizeof(rt.rt_dst)); printf("rt_gateway %ld %zd\n", offsetof(struct rtentry, rt_gateway), sizeof(rt.rt_gateway)); printf("rt_genmask %ld %zd\n", offsetof(struct rtentry, rt_genmask), sizeof(rt.rt_genmask)); printf("rt_flags %ld %zd\n", offsetof(struct rtentry, rt_flags), sizeof(rt.rt_flags)); printf("rt_pad2 %ld %zd\n", offsetof(struct rtentry, rt_pad2), sizeof(rt.rt_pad2)); printf("rt_pad3 %ld %zd\n", offsetof(struct rtentry, rt_pad3), sizeof(rt.rt_pad3)); printf("rt_pad4 %ld %zd\n", offsetof(struct rtentry, rt_pad4), sizeof(rt.rt_pad4)); printf("rt_metric %ld %zd\n", offsetof(struct rtentry, rt_metric), sizeof(rt.rt_metric)); printf("rt_dev %ld %zd\n", offsetof(struct rtentry, rt_dev), sizeof(rt.rt_dev)); printf("rt_mtu %ld %zd\n", offsetof(struct rtentry, rt_mtu), sizeof(rt.rt_mtu)); printf("rt_window %ld %zd\n", offsetof(struct rtentry, rt_window), sizeof(rt.rt_window)); printf("rt_irtt %ld %zd\n", offsetof(struct rtentry, rt_irtt), sizeof(rt.rt_irtt)); } And result is : i386 rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 68 4 rt_mtu 72 4 rt_window 76 4 rt_irtt 80 2 m68k rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 66 4 rt_mtu 70 4 rt_window 74 4 rt_irtt 78 2 This affects the "route" command : WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 67108866 32768 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 WITH this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 1024 2 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20180510205949.26455-1-laurent@vivier.eu>
2018-05-10 23:59:49 +03:00
return __alignof__(long);
} else {
linux-user: correctly align types in thunking code This is a follow up of patch: commit c2e3dee6e03527baf8698698cce76b1a3174969a Author: Laurent Vivier <laurent@vivier.eu> Date: Sun Feb 13 23:37:34 2011 +0100 linux-user: Define target alignment size In my case m68k aligns "int" on 2 not 4. You can check this with the following program: int main(void) { struct rtentry rt; printf("rt_pad1 %ld %zd\n", offsetof(struct rtentry, rt_pad1), sizeof(rt.rt_pad1)); printf("rt_dst %ld %zd\n", offsetof(struct rtentry, rt_dst), sizeof(rt.rt_dst)); printf("rt_gateway %ld %zd\n", offsetof(struct rtentry, rt_gateway), sizeof(rt.rt_gateway)); printf("rt_genmask %ld %zd\n", offsetof(struct rtentry, rt_genmask), sizeof(rt.rt_genmask)); printf("rt_flags %ld %zd\n", offsetof(struct rtentry, rt_flags), sizeof(rt.rt_flags)); printf("rt_pad2 %ld %zd\n", offsetof(struct rtentry, rt_pad2), sizeof(rt.rt_pad2)); printf("rt_pad3 %ld %zd\n", offsetof(struct rtentry, rt_pad3), sizeof(rt.rt_pad3)); printf("rt_pad4 %ld %zd\n", offsetof(struct rtentry, rt_pad4), sizeof(rt.rt_pad4)); printf("rt_metric %ld %zd\n", offsetof(struct rtentry, rt_metric), sizeof(rt.rt_metric)); printf("rt_dev %ld %zd\n", offsetof(struct rtentry, rt_dev), sizeof(rt.rt_dev)); printf("rt_mtu %ld %zd\n", offsetof(struct rtentry, rt_mtu), sizeof(rt.rt_mtu)); printf("rt_window %ld %zd\n", offsetof(struct rtentry, rt_window), sizeof(rt.rt_window)); printf("rt_irtt %ld %zd\n", offsetof(struct rtentry, rt_irtt), sizeof(rt.rt_irtt)); } And result is : i386 rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 68 4 rt_mtu 72 4 rt_window 76 4 rt_irtt 80 2 m68k rt_pad1 0 4 rt_dst 4 16 rt_gateway 20 16 rt_genmask 36 16 rt_flags 52 2 rt_pad2 54 2 rt_pad3 56 4 rt_pad4 62 2 rt_metric 64 2 rt_dev 66 4 rt_mtu 70 4 rt_window 74 4 rt_irtt 78 2 This affects the "route" command : WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 67108866 32768 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 WITH this patch: $ sudo route add -net default gw 10.0.3.1 window 1024 irtt 2 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 1024 2 eth0 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20180510205949.26455-1-laurent@vivier.eu>
2018-05-10 23:59:49 +03:00
return ABI_LONG_ALIGNMENT;
}
break;
case TYPE_OLDDEVT:
return thunk_type_size(type_ptr, is_host);
case TYPE_ARRAY:
return thunk_type_align_array(type_ptr + 2, is_host);
case TYPE_STRUCT:
se = struct_entries + type_ptr[1];
return se->align[is_host];
default:
g_assert_not_reached();
}
}
unsigned int target_to_host_bitmask_len(unsigned int target_mask,
const bitmask_transtbl *trans_tbl,
size_t trans_len);
unsigned int host_to_target_bitmask_len(unsigned int host_mask,
const bitmask_transtbl * trans_tbl,
size_t trans_len);
#define target_to_host_bitmask(M, T) \
target_to_host_bitmask_len(M, T, ARRAY_SIZE(T))
#define host_to_target_bitmask(M, T) \
host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
void thunk_init(unsigned int max_structs);
#endif