diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-02-18 21:08:56 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-02-18 21:08:56 -0800 |
commit | 8f5084835e9a9358e3c7f4495ee1fe7fe0221cdd (patch) | |
tree | a88983782fe1240bda599560132628bccb36e2b3 | |
parent | c1992328089420c817c070c27172939393cadc9c (diff) | |
download | syslinux-elf-8f5084835e9a9358e3c7f4495ee1fe7fe0221cdd.tar.gz syslinux-elf-8f5084835e9a9358e3c7f4495ee1fe7fe0221cdd.tar.xz syslinux-elf-8f5084835e9a9358e3c7f4495ee1fe7fe0221cdd.zip |
Constructed data objects can't be common; hack derivative_info
- Constructed data objects can't be common. Earlier version of
gcc didn't if the objects were explicitly listed extern, but
newer ones need an explicit __attribute__((nocommon)) or
-fno-common.
- Make syslinux_derivative_info() save the entire reply.
-rw-r--r-- | com32/include/klibc/compiler.h | 4 | ||||
-rw-r--r-- | com32/include/syslinux/config.h | 82 | ||||
-rw-r--r-- | com32/lib/syslinux/dsinfo.c | 12 |
3 files changed, 64 insertions, 34 deletions
diff --git a/com32/include/klibc/compiler.h b/com32/include/klibc/compiler.h index 2b8e0f6e..5ac21185 100644 --- a/com32/include/klibc/compiler.h +++ b/com32/include/klibc/compiler.h @@ -122,4 +122,8 @@ #define __aligned(x) __attribute__((aligned(x))) #define __alignas(x) __attribute__((aligned(__alignof__(x)))) +/* Handling of common (affect constructors/destructors) */ +#define __common __attribute__((common)) +#define __nocommon __attribute__((nocommon)) + #endif diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h index 6983f8aa..b5ed04c3 100644 --- a/com32/include/syslinux/config.h +++ b/com32/include/syslinux/config.h @@ -35,6 +35,7 @@ #define _SYSLINUX_CONFIG_H #include <stdint.h> +#include <com32.h> enum syslinux_filesystem { SYSLINUX_FS_UNKNOWN = 0x30, @@ -52,7 +53,7 @@ struct syslinux_version { const char *copyright_string; }; -extern struct syslinux_version __syslinux_version; +extern __nocommon struct syslinux_version __syslinux_version; static inline const struct syslinux_version * syslinux_version(void) { @@ -61,52 +62,77 @@ syslinux_version(void) union syslinux_derivative_info { struct { + com32sys_t r; + const void *esbx; + const void *fssi; + const void *gsdi; + } rr; /* real raw */ + struct { + uint16_t _pad1[4]; + uint32_t _pad2[7]; uint8_t filesystem; uint8_t ah; + uint16_t axh; } c; /* common */ struct { - uint16_t ax; - uint16_t cx; - uint16_t dx; - uint16_t _pad; + uint16_t gs; + uint16_t fs; + uint16_t es; + uint16_t ds; + uint16_t di, dih; + uint16_t si, sih; + uint16_t bp, bph; + uint16_t sp, sph; + uint16_t bx, bxh; + uint16_t dx, dxh; + uint16_t cx, cxh; + uint16_t ax, axh; + uint32_t eflags; const void *esbx; const void *fssi; const void *gsdi; } r; /* raw */ struct { - uint8_t filesystem; - uint8_t ah; - uint8_t sector_shift; - uint8_t ch; - uint8_t drive_number; - uint8_t dh; - uint16_t _pad; + uint16_t _gs, _fs, _es, _ds; + uint32_t _edi, _esi, _ebp, _esp, _ebx; + uint8_t drive_number, dh; + uint16_t _dxh; + uint8_t sector_shift, ch; + uint16_t _cxh; + uint8_t filesystem, ah; + uint16_t _axh; + uint32_t _eflags; const void *ptab_ptr; const uint32_t *esdi_ptr; } disk; /* syslinux/extlinux */ struct { - uint8_t filesystem; - uint8_t ah; - uint16_t cx; + uint16_t _gs, _fs, _es, _ds; + uint32_t _edi, _esi, _ebp, _esp, _ebx; uint16_t apiver; - uint16_t _pad; + uint16_t _dxh; + uint32_t _ecx; + uint8_t filesystem, ah; + uint16_t _axh; + uint32_t _eflags; const void *pxenvptr; const void *stack; } pxe; /* pxelinux */ struct { - uint8_t filesystem; - uint8_t ah; - uint8_t sector_shift; - uint8_t cd_mode; - uint8_t drive_number; - uint8_t dh; - uint16_t _pad; + uint16_t _gs, _fs, _es, _ds; + uint32_t _edi, _esi, _ebp, _esp, _ebx; + uint8_t drive_number, dh; + uint16_t _dxh; + uint8_t sector_shift, cd_mode; + uint16_t _cxh; + uint8_t filesystem, ah; + uint16_t _axh; + uint32_t _eflags; const void *spec_packet; const uint32_t *esdi_ptr; } iso; /* isolinux */ }; -union syslinux_derivative_info __syslinux_derivative_info; +extern __nocommon union syslinux_derivative_info __syslinux_derivative_info; static inline const union syslinux_derivative_info * syslinux_derivative_info(void) { @@ -119,14 +145,15 @@ struct syslinux_serial_console_info { uint16_t flowctl; }; -extern struct syslinux_serial_console_info __syslinux_serial_console_info; +extern __nocommon struct syslinux_serial_console_info + __syslinux_serial_console_info; static inline const struct syslinux_serial_console_info * syslinux_serial_console_info(void) { return &__syslinux_serial_console_info; } -extern const char *__syslinux_config_file; +extern __nocommon const char *__syslinux_config_file; static inline const char *syslinux_config_file(void) { return __syslinux_config_file; @@ -136,7 +163,8 @@ struct syslinux_ipappend_strings { int count; const char * const *ptr; }; -extern struct syslinux_ipappend_strings __syslinux_ipappend_strings; +extern __nocommon struct syslinux_ipappend_strings + __syslinux_ipappend_strings; static inline const struct syslinux_ipappend_strings * syslinux_ipappend_strings(void) { diff --git a/com32/lib/syslinux/dsinfo.c b/com32/lib/syslinux/dsinfo.c index 6d77a0de..eebbbd3a 100644 --- a/com32/lib/syslinux/dsinfo.c +++ b/com32/lib/syslinux/dsinfo.c @@ -34,14 +34,12 @@ union syslinux_derivative_info __syslinux_derivative_info; void __constructor __syslinux_get_derivative_info(void) { static com32sys_t reg; + com32sys_t * const r = &__syslinux_derivative_info.rr.r; reg.eax.w[0] = 0x000A; - __intcall(0x22, ®, ®); + __intcall(0x22, ®, r); - __syslinux_derivative_info.r.ax = reg.eax.w[0]; - __syslinux_derivative_info.r.cx = reg.ecx.w[0]; - __syslinux_derivative_info.r.dx = reg.edx.w[0]; - __syslinux_derivative_info.r.esbx = MK_PTR(reg.es, reg.ebx.w[0]); - __syslinux_derivative_info.r.fssi = MK_PTR(reg.fs, reg.esi.w[0]); - __syslinux_derivative_info.r.gsdi = MK_PTR(reg.gs, reg.edi.w[0]); + __syslinux_derivative_info.r.esbx = MK_PTR(r->es, r->ebx.w[0]); + __syslinux_derivative_info.r.fssi = MK_PTR(r->fs, r->esi.w[0]); + __syslinux_derivative_info.r.gsdi = MK_PTR(r->gs, r->edi.w[0]); } |