aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2011-12-15 18:01:25 +0000
committerMatt Fleming <matt.fleming@intel.com>2011-12-16 16:38:08 +0000
commitc2ac88873a32b198cff0b3ac6e07957f8d2a4f4f (patch)
treea420801aa7b6780da5535305b07dab76f494db42
parent400e21c5f4af4c688907dd8ceb8a1df321ab7f78 (diff)
downloadsyslinux-c2ac88873a32b198cff0b3ac6e07957f8d2a4f4f.tar.gz
syslinux-c2ac88873a32b198cff0b3ac6e07957f8d2a4f4f.tar.xz
syslinux-c2ac88873a32b198cff0b3ac6e07957f8d2a4f4f.zip
elflink: Don't statically initialise core_module.base_addr
The EFI firmware loader might place syslinux.efi anywhere in RAM, we can't assume that base addr of core_module is 0x0 to initialise it at runtime with the correct value. Also, using __dynsym_len doesn't seem to work properly with syslinux.efi so calculate the length at runtime. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--core/elflink/load_env32.c13
-rw-r--r--core/syslinux.ld1
-rw-r--r--efi/syslinux.ld5
3 files changed, 12 insertions, 7 deletions
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 7ffe185b..c2e0767e 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -28,11 +28,12 @@ typedef void (*constructor_t) (void);
constructor_t __ctors_start[], __ctors_end[];
extern char __dynstr_start[];
-extern char __dynstr_len[], __dynsym_len[];
+extern char __dynstr_end[], __dynsym_end[];
extern char __dynsym_start[];
extern char __got_start[];
extern Elf32_Dyn __dynamic_start[];
extern Elf32_Word __gnu_hash_start[];
+extern char __module_start[];
struct elf_module core_module = {
.name = "(core)",
@@ -41,15 +42,12 @@ struct elf_module core_module = {
.dependants = LIST_HEAD_INIT((core_module.dependants)),
.list = LIST_HEAD_INIT((core_module.list)),
.module_addr = (void *)0x0,
- .base_addr = (Elf32_Addr) 0x0,
.ghash_table = __gnu_hash_start,
.str_table = __dynstr_start,
.sym_table = __dynsym_start,
.got = __got_start,
.dyn_table = __dynamic_start,
- .strtable_size = (size_t) __dynstr_len,
.syment_size = sizeof(Elf32_Sym),
- .symtable_size = (size_t) __dynsym_len
};
/*
@@ -77,6 +75,7 @@ void load_env32(com32sys_t * regs)
struct file_info *fp;
int fd;
char *argv[] = { LDLINUX, NULL };
+ size_t size;
static const char *search_directories[] = {
"/boot/isolinux",
@@ -95,6 +94,12 @@ void load_env32(com32sys_t * regs)
dprintf("Starting 32 bit elf module subsystem...\n");
call_constr();
+ size = (size_t)__dynstr_end - (size_t)__dynstr_start;
+ core_module.strtable_size = size;
+ size = (size_t)__dynsym_end - (size_t)__dynsym_start;
+ core_module.symtable_size = size;
+ core_module.base_addr = (Elf32_Addr)__module_start;
+
init_module_subsystem(&core_module);
spawn_load(LDLINUX, 1, argv);
diff --git a/core/syslinux.ld b/core/syslinux.ld
index 43fc1531..7b4e012c 100644
--- a/core/syslinux.ld
+++ b/core/syslinux.ld
@@ -26,6 +26,7 @@ SECTIONS
{
/* Prefix structure for the compression program */
. = 0;
+ __module_start = .;
.prefix : {
*(.prefix)
}
diff --git a/efi/syslinux.ld b/efi/syslinux.ld
index 5f8aa051..e0270537 100644
--- a/efi/syslinux.ld
+++ b/efi/syslinux.ld
@@ -22,7 +22,8 @@ ENTRY(_start)
SECTIONS
{
. = 0;
- ImageBase = .;
+ ImageBase = .; /* For gnu-efi's crt0 */
+ __module_start = .;
. = SEGMENT_START("text-segment", 0) + SIZEOF_HEADERS;
.text : {
FILL(0x90909090)
@@ -79,7 +80,6 @@ SECTIONS
*(.dynsym)
__dynsym_end = .;
}
- __dynsym_len = __dynsym_end - __dynsym_start;
. = ALIGN(4);
@@ -88,7 +88,6 @@ SECTIONS
*(.dynstr)
__dynstr_end = .;
}
- __dynstr_len = __dynstr_end - __dynstr_start;
. = ALIGN(4);