elflink: Don't statically initialise core_module.base_addr
authorMatt Fleming <matt.fleming@intel.com>
Thu, 15 Dec 2011 18:01:25 +0000 (18:01 +0000)
committerMatt Fleming <matt.fleming@intel.com>
Fri, 16 Dec 2011 16:38:08 +0000 (16:38 +0000)
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>
core/elflink/load_env32.c
core/syslinux.ld
efi/syslinux.ld

index 7ffe185..c2e0767 100644 (file)
@@ -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);
index 43fc153..7b4e012 100644 (file)
@@ -26,6 +26,7 @@ SECTIONS
 {
        /* Prefix structure for the compression program */
        . = 0;
+       __module_start = .;
        .prefix : {
                *(.prefix)
        }
index 5f8aa05..e027053 100644 (file)
@@ -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);