aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-02-18 21:08:56 -0800
committerH. Peter Anvin <hpa@zytor.com>2009-02-18 21:08:56 -0800
commit8f5084835e9a9358e3c7f4495ee1fe7fe0221cdd (patch)
treea88983782fe1240bda599560132628bccb36e2b3
parentc1992328089420c817c070c27172939393cadc9c (diff)
downloadsyslinux-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.h4
-rw-r--r--com32/include/syslinux/config.h82
-rw-r--r--com32/lib/syslinux/dsinfo.c12
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, &reg, &reg);
+ __intcall(0x22, &reg, 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]);
}