123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622 |
- The value of the field rva_and_sizes_nr is used by OVMF to check the
- consistency of the PE file with respect to the field optional_hdr_sz. It
- now have the right value.
- Signed-off-by: Celelibi <celelibi at gmail.com>
- ---
- efi/wrapper.c | 6 +++---
- efi/wrapper.h | 28 ++++++++++++++++------------
- 2 files changed, 19 insertions(+), 15 deletions(-)
- diff --git a/efi/wrapper.c b/efi/wrapper.c
- index 04c895f..ec77271 100644
- --- a/efi/wrapper.c
- +++ b/efi/wrapper.c
- @@ -102,7 +102,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- e_hdr.image_sz = total_sz;
- e_hdr.headers_sz = 512;
- e_hdr.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- - e_hdr.rva_and_sizes_nr = 1;
- + e_hdr.rva_and_sizes_nr = sizeof(e_hdr.data_directory) / sizeof(__uint64_t);
- fwrite(&e_hdr, sizeof(e_hdr), 1, f);
- }
- else if (class == ELFCLASS64) {
- @@ -130,7 +130,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- e_hdr_pe32p.image_sz = total_sz;
- e_hdr_pe32p.headers_sz = 512;
- e_hdr_pe32p.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- - e_hdr_pe32p.rva_and_sizes_nr = 1;
- + e_hdr_pe32p.rva_and_sizes_nr = sizeof(e_hdr_pe32p.data_directory) / sizeof(__uint64_t);
- fwrite(&e_hdr_pe32p, sizeof(e_hdr_pe32p), 1, f);
- }
-
- @@ -237,7 +237,7 @@ int main(int argc, char **argv)
- fprintf(stderr, "Unsupported architecture\n");
- exit(EXIT_FAILURE);
- }
- -
- +
- if (id[EI_MAG0] != ELFMAG0 ||
- id[EI_MAG1] != ELFMAG1 ||
- id[EI_MAG2] != ELFMAG2 ||
- diff --git a/efi/wrapper.h b/efi/wrapper.h
- index 4f76991..0e6b38e 100644
- --- a/efi/wrapper.h
- +++ b/efi/wrapper.h
- @@ -102,12 +102,14 @@ struct extra_hdr {
- __uint32_t heap_commit_sz;
- __uint32_t loader_flags;
- __uint32_t rva_and_sizes_nr;
- - __uint64_t export_table;
- - __uint64_t import_table;
- - __uint64_t resource_table;
- - __uint64_t exception_table;
- - __uint64_t certification_table;
- - __uint64_t base_relocation_table;
- + struct {
- + __uint64_t export_table;
- + __uint64_t import_table;
- + __uint64_t resource_table;
- + __uint64_t exception_table;
- + __uint64_t certification_table;
- + __uint64_t base_relocation_table;
- + } data_directory;
- } __packed;
-
- /* Extra header for PE32+ format
- @@ -136,12 +138,14 @@ struct extra_hdr_pe32p {
- __uint64_t heap_commit_sz;
- __uint32_t loader_flags;
- __uint32_t rva_and_sizes_nr;
- - __uint64_t export_table;
- - __uint64_t import_table;
- - __uint64_t resource_table;
- - __uint64_t exception_table;
- - __uint64_t certification_table;
- - __uint64_t base_relocation_table;
- + struct {
- + __uint64_t export_table;
- + __uint64_t import_table;
- + __uint64_t resource_table;
- + __uint64_t exception_table;
- + __uint64_t certification_table;
- + __uint64_t base_relocation_table;
- + } data_directory;
- } __packed;
-
- struct section {
- In the generated PE file, the section header for the .text section used
- to address more than the whole file. Starting at offset 0 (before the
- end of the headers) is illegal and is rejected by OVMF. Giving a size
- greater than the actual file size is also illegal and rejected.
- Moreover, the actual data inside the PE file have to be aligned to at
- least 512 bytes. Hence, .text need to be aligned as well.
- Signed-off-by: Celelibi <celelibi at gmail.com>
- ---
- efi/wrapper.c | 44 +++++++++++++++++++++++++-------------------
- 1 file changed, 25 insertions(+), 19 deletions(-)
- diff --git a/efi/wrapper.c b/efi/wrapper.c
- index ec77271..bd2c175 100644
- --- a/efi/wrapper.c
- +++ b/efi/wrapper.c
- @@ -54,11 +54,15 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- struct coff_hdr c_hdr;
- struct header hdr;
- struct coff_reloc c_rel;
- - __uint32_t total_sz = so_size;
- + __uint32_t total_sz = data_size;
- __uint32_t dummy = 0;
- __uint32_t hdr_sz;
- __uint32_t reloc_start, reloc_end;
-
- + hdr_sz = 512;
- + total_sz += hdr_sz;
- + entry += hdr_sz;
- +
- memset(&hdr, 0, sizeof(hdr));
- hdr.msdos_signature = MSDOS_SIGNATURE;
-
- @@ -77,11 +81,6 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- c_hdr.nr_sections = 2;
- c_hdr.nr_syms = 1;
- if (class == ELFCLASS32) {
- - hdr_sz = sizeof(o_hdr) + sizeof(t_sec) + sizeof(e_hdr) +
- - sizeof(r_sec) + sizeof(c_hdr) + sizeof(hdr) + sizeof(c_rel)
- - + sizeof(dummy);
- - total_sz += hdr_sz;
- - entry += hdr_sz;
- c_hdr.arch = IMAGE_FILE_MACHINE_I386;
- c_hdr.characteristics = IMAGE_FILE_32BIT_MACHINE |
- IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
- @@ -92,25 +91,20 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- o_hdr.format = PE32_FORMAT;
- o_hdr.major_linker_version = 0x02;
- o_hdr.minor_linker_version = 0x14;
- - o_hdr.code_sz = total_sz;
- + o_hdr.code_sz = data_size;
- o_hdr.entry_point = entry;
- o_hdr.initialized_data_sz = data_size;
- fwrite(&o_hdr, sizeof(o_hdr), 1, f);
- memset(&e_hdr, 0, sizeof(e_hdr));
- e_hdr.section_align = 4096;
- e_hdr.file_align = 512;
- - e_hdr.image_sz = total_sz;
- - e_hdr.headers_sz = 512;
- + e_hdr.image_sz = hdr_sz + so_size;
- + e_hdr.headers_sz = hdr_sz;
- e_hdr.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- e_hdr.rva_and_sizes_nr = sizeof(e_hdr.data_directory) / sizeof(__uint64_t);
- fwrite(&e_hdr, sizeof(e_hdr), 1, f);
- }
- else if (class == ELFCLASS64) {
- - hdr_sz = sizeof(o_hdr_pe32p) + sizeof(t_sec) + sizeof(e_hdr_pe32p) +
- - sizeof(r_sec) + sizeof(c_hdr) + sizeof(hdr) + sizeof(c_rel)
- - + sizeof(dummy);
- - total_sz += hdr_sz;
- - entry += hdr_sz;
- c_hdr.arch = IMAGE_FILE_MACHINE_X86_64;
- c_hdr.characteristics = IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
- IMAGE_FILE_LINE_NUMBERS_STRIPPED;
- @@ -120,15 +114,15 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- o_hdr_pe32p.format = PE32P_FORMAT;
- o_hdr_pe32p.major_linker_version = 0x02;
- o_hdr_pe32p.minor_linker_version = 0x14;
- - o_hdr_pe32p.code_sz = total_sz;
- + o_hdr_pe32p.code_sz = data_size;
- o_hdr_pe32p.entry_point = entry;
- o_hdr.initialized_data_sz = data_size;
- fwrite(&o_hdr_pe32p, sizeof(o_hdr_pe32p), 1, f);
- memset(&e_hdr_pe32p, 0, sizeof(e_hdr));
- e_hdr_pe32p.section_align = 4096;
- e_hdr_pe32p.file_align = 512;
- - e_hdr_pe32p.image_sz = total_sz;
- - e_hdr_pe32p.headers_sz = 512;
- + e_hdr_pe32p.image_sz = hdr_sz + so_size;
- + e_hdr_pe32p.headers_sz = hdr_sz;
- e_hdr_pe32p.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- e_hdr_pe32p.rva_and_sizes_nr = sizeof(e_hdr_pe32p.data_directory) / sizeof(__uint64_t);
- fwrite(&e_hdr_pe32p, sizeof(e_hdr_pe32p), 1, f);
- @@ -136,8 +130,10 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
-
- memset(&t_sec, 0, sizeof(t_sec));
- strcpy((char *)t_sec.name, ".text");
- - t_sec.virtual_sz = total_sz;
- - t_sec.raw_data_sz = total_sz;
- + t_sec.virtual_sz = data_size;
- + t_sec.virtual_address = hdr_sz;
- + t_sec.raw_data_sz = t_sec.virtual_sz;
- + t_sec.raw_data = t_sec.virtual_address;
- t_sec.characteristics = IMAGE_SCN_CNT_CODE |
- IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
- IMAGE_SCN_MEM_READ;
- @@ -163,6 +159,16 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- fwrite(&c_rel, sizeof(c_rel), 1, f);
- fwrite(&dummy, sizeof(dummy), 1, f);
-
- + /*
- + * Add some padding to align the ELF as needed
- + */
- + if (ftell(f) > t_sec.virtual_address) {
- + // A fseek that rewind would be a bug hard to track
- + fprintf(stderr, "PE+ headers are too large.\n");
- + exit(EXIT_FAILURE);
- + }
- +
- + fseek(f, t_sec.virtual_address, SEEK_SET);
- }
-
- static void usage(char *progname)
- There is no need to have a relocation section that nothing points at.
- The image is still seen as relocatable as long as the Characteristics of
- the FileHeader do not say otherwise.
- Moreover, the field base_relocation_table wasn't initialized properly
- leading to unpredictable bugs.
- Signed-off-by: Celelibi <celelibi at gmail.com>
- ---
- I'm not 100% positive about the uselessness of the relocation section. However:
- 1) it works on my real hardware;
- 2) OVMF doesn't check the section headers at all;
- 3) all the docs I could find say that the section names are arbitrary;
- 4) the only way to make the relocation actually happen is by setting the
- base_relocation_table field of the extra headers to point to this section;
- 5) The right way to indicate the image is not relocatable would be by setting
- the characteristics IMAGE_FILE_RELOCS_STRIPPED in the coff header.
- Moreover, the relocation entry cannot be inserted before the end of the headers
- (512 bytes), this mean we would have to push everything a few bytes further.
- And I think it's better if it can be avoided. :)
- efi/wrapper.c | 28 +++-------------------------
- 1 file changed, 3 insertions(+), 25 deletions(-)
- diff --git a/efi/wrapper.c b/efi/wrapper.c
- index bd2c175..9652368 100644
- --- a/efi/wrapper.c
- +++ b/efi/wrapper.c
- @@ -48,14 +48,12 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- {
- struct optional_hdr o_hdr;
- struct optional_hdr_pe32p o_hdr_pe32p;
- - struct section t_sec, r_sec;
- + struct section t_sec;
- struct extra_hdr e_hdr;
- struct extra_hdr_pe32p e_hdr_pe32p;
- struct coff_hdr c_hdr;
- struct header hdr;
- - struct coff_reloc c_rel;
- __uint32_t total_sz = data_size;
- - __uint32_t dummy = 0;
- __uint32_t hdr_sz;
- __uint32_t reloc_start, reloc_end;
-
- @@ -78,7 +76,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- fwrite(&hdr, sizeof(hdr), 1, f);
-
- memset(&c_hdr, 0, sizeof(c_hdr));
- - c_hdr.nr_sections = 2;
- + c_hdr.nr_sections = 1;
- c_hdr.nr_syms = 1;
- if (class == ELFCLASS32) {
- c_hdr.arch = IMAGE_FILE_MACHINE_I386;
- @@ -118,7 +116,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- o_hdr_pe32p.entry_point = entry;
- o_hdr.initialized_data_sz = data_size;
- fwrite(&o_hdr_pe32p, sizeof(o_hdr_pe32p), 1, f);
- - memset(&e_hdr_pe32p, 0, sizeof(e_hdr));
- + memset(&e_hdr_pe32p, 0, sizeof(e_hdr_pe32p));
- e_hdr_pe32p.section_align = 4096;
- e_hdr_pe32p.file_align = 512;
- e_hdr_pe32p.image_sz = hdr_sz + so_size;
- @@ -140,26 +138,6 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- fwrite(&t_sec, sizeof(t_sec), 1, f);
-
- /*
- - * Write our dummy relocation and reloc section.
- - */
- - memset(&r_sec, 0, sizeof(r_sec));
- - strcpy((char *)r_sec.name, ".reloc");
- - r_sec.virtual_sz = sizeof(c_rel);
- - r_sec.virtual_address = ftell(f) + sizeof(r_sec);
- - r_sec.raw_data_sz = r_sec.virtual_sz;
- - r_sec.raw_data = r_sec.virtual_address;
- - r_sec.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
- - IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_MEM_DISCARDABLE |
- - IMAGE_SCN_MEM_READ;
- - fwrite(&r_sec, sizeof(r_sec), 1, f);
- -
- - memset(&c_rel, 0, sizeof(c_rel));
- - c_rel.virtual_address = ftell(f) + sizeof(c_rel);
- - c_rel.symtab_index = 10;
- - fwrite(&c_rel, sizeof(c_rel), 1, f);
- - fwrite(&dummy, sizeof(dummy), 1, f);
- -
- - /*
- * Add some padding to align the ELF as needed
- */
- if (ftell(f) > t_sec.virtual_address) {
- PE headers code_sz and image_sz indicate more or less, the size of the
- file and the size of the in-memory image. They are now given the right
- value.
- In the ELF format, only the program headers are reliable to determine
- the actually needed part of the file and the in-memory size.
- The .bss section should always be marked as NOLOAD for ld since its
- content shouldn't be included into the binary file.
- Signed-off-by: Celelibi <celelibi at gmail.com>
- ---
- Again, I'm not 100% positive about the semantics of NOLOAD in a linker script.
- However I found this make things work better.
- Actually the file core/fs/fs.o have a .bss16 section that is not empty. If I
- understood correctly, only .bss can be empty in a .o. Thus ld generates the
- zeros that belong to that section in the .o. Then, when merging the section
- .bss16 into the .bss of syslinux.so, ld is forced to generate ALL the zeros
- that belong to the .bss section. Marking this section as NOLOAD make ld to
- ignore its content but still produce a PT_LOAD program header with the right
- memory size, as needed for the bss.
- efi/i386/syslinux.ld | 4 +-
- efi/wrapper.c | 138 +++++++++++++++----------------------------------
- efi/x86_64/syslinux.ld | 4 +-
- 3 files changed, 45 insertions(+), 101 deletions(-)
- diff --git a/efi/i386/syslinux.ld b/efi/i386/syslinux.ld
- index 523a9b9..bab3fc7 100644
- --- a/efi/i386/syslinux.ld
- +++ b/efi/i386/syslinux.ld
- @@ -136,7 +136,7 @@ SECTIONS
- *(.strtab)
- }
-
- - .bss : {
- + .bss (NOLOAD) : {
- /* the EFI loader doesn't seem to like a .bss section,
- so we stick it all into .data: */
- __bss_start = .;
- @@ -153,7 +153,7 @@ SECTIONS
- __bss_dwords = (__bss_len + 3) >> 2;
-
- . = ALIGN(128);
- -
- +
- /* Very large objects which don't need to be zeroed */
-
- .hugebss : {
- diff --git a/efi/wrapper.c b/efi/wrapper.c
- index 9652368..a5247ae 100644
- --- a/efi/wrapper.c
- +++ b/efi/wrapper.c
- @@ -35,7 +35,7 @@ typedef Elf64_Addr Elf_Addr;
- #endif
-
- /*
- - * 'so_size' is the file size of the ELF shared object.
- + * 'so_memsz' is the size of the ELF shared object once loaded.
- * 'data_size' is the size of initialised data in the shared object.
- * 'class' dictates how the header is written
- * For 32bit machines (class == ELFCLASS32), the optional
- @@ -44,7 +44,7 @@ typedef Elf64_Addr Elf_Addr;
- * header includes PE32+header fields
- */
- static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- - __uint32_t so_size, __uint8_t class)
- + __uint32_t so_memsz, __uint8_t class)
- {
- struct optional_hdr o_hdr;
- struct optional_hdr_pe32p o_hdr_pe32p;
- @@ -96,7 +96,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- memset(&e_hdr, 0, sizeof(e_hdr));
- e_hdr.section_align = 4096;
- e_hdr.file_align = 512;
- - e_hdr.image_sz = hdr_sz + so_size;
- + e_hdr.image_sz = hdr_sz + so_memsz;
- e_hdr.headers_sz = hdr_sz;
- e_hdr.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- e_hdr.rva_and_sizes_nr = sizeof(e_hdr.data_directory) / sizeof(__uint64_t);
- @@ -119,7 +119,7 @@ static void write_header(FILE *f, __uint32_t entry, size_t data_size,
- memset(&e_hdr_pe32p, 0, sizeof(e_hdr_pe32p));
- e_hdr_pe32p.section_align = 4096;
- e_hdr_pe32p.file_align = 512;
- - e_hdr_pe32p.image_sz = hdr_sz + so_size;
- + e_hdr_pe32p.image_sz = hdr_sz + so_memsz;
- e_hdr_pe32p.headers_sz = hdr_sz;
- e_hdr_pe32p.subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
- e_hdr_pe32p.rva_and_sizes_nr = sizeof(e_hdr_pe32p.data_directory) / sizeof(__uint64_t);
- @@ -157,17 +157,16 @@ static void usage(char *progname)
-
- int main(int argc, char **argv)
- {
- - struct stat st;
- Elf32_Ehdr e32_hdr;
- Elf64_Ehdr e64_hdr;
- __uint32_t entry;
- __uint8_t class;
- - __uint64_t shoff;
- - __uint16_t shnum, shentsize, shstrndx;
- + __uint64_t phoff = 0;
- + __uint16_t phnum = 0, phentsize = 0;
- unsigned char *id;
- FILE *f_in, *f_out;
- void *buf;
- - size_t datasz, rv;
- + size_t datasz, memsz, rv;
-
- if (argc < 3) {
- usage(argv[0]);
- @@ -180,11 +179,6 @@ int main(int argc, char **argv)
- exit(EXIT_FAILURE);
- }
-
- - if (stat(argv[1], &st) != 0) {
- - perror("stat");
- - exit(EXIT_FAILURE);
- - }
- -
- f_out = fopen(argv[2], "w");
- if (!f_out) {
- perror("fopen");
- @@ -194,15 +188,14 @@ int main(int argc, char **argv)
- /*
- * Parse the ELF header and find the entry point.
- */
- - fread((void *)&e32_hdr, sizeof(e32_hdr), 1, f_in);
- + fread((void *)&e32_hdr, sizeof(e32_hdr), 1, f_in);
- if (e32_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
- id = e32_hdr.e_ident;
- class = ELFCLASS32;
- entry = e32_hdr.e_entry;
- - shoff = e32_hdr.e_shoff;
- - shnum = e32_hdr.e_shnum;
- - shstrndx = e32_hdr.e_shstrndx;
- - shentsize = e32_hdr.e_shentsize;
- + phoff = e32_hdr.e_phoff;
- + phnum = e32_hdr.e_phnum;
- + phentsize = e32_hdr.e_phentsize;
- }
- else if (e32_hdr.e_ident[EI_CLASS] == ELFCLASS64) {
- /* read the header again for x86_64
- @@ -213,10 +206,9 @@ int main(int argc, char **argv)
- fread((void *)&e64_hdr, sizeof(e64_hdr), 1, f_in);
- id = e64_hdr.e_ident;
- entry = e64_hdr.e_entry;
- - shoff = e64_hdr.e_shoff;
- - shnum = e64_hdr.e_shnum;
- - shstrndx = e64_hdr.e_shstrndx;
- - shentsize = e64_hdr.e_shentsize;
- + phoff = e64_hdr.e_phoff;
- + phnum = e64_hdr.e_phnum;
- + phentsize = e64_hdr.e_phentsize;
- } else {
- fprintf(stderr, "Unsupported architecture\n");
- exit(EXIT_FAILURE);
- @@ -230,98 +222,47 @@ int main(int argc, char **argv)
- exit(EXIT_FAILURE);
- }
-
- - if (!shoff || !shnum || (shstrndx == SHN_UNDEF)) {
- - fprintf(stderr, "Cannot find section table\n");
- + if (!phoff || !phnum) {
- + fprintf(stderr, "Cannot find segment table\n");
- exit(EXIT_FAILURE);
- }
-
- /*
- - * Find the beginning of the .bss section. Everything preceding
- - * it is copied verbatim to the output file.
- + * Find the LOAD program header. Everything in this segment
- + * is copied verbatim to the output file.
- + * Although there may be several LOAD program headers, only
- + * one is currently copied.
- */
- if (e32_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
- - const char *shstrtab, *name;
- - Elf32_Shdr shdr;
- + Elf32_Phdr phdr;
- int i;
- - void *strtab;
- -
- - fseek(f_in, shoff, SEEK_SET);
- -
- - /* First find the strtab section */
- - fseek(f_in, shstrndx * shentsize, SEEK_CUR);
- - fread(&shdr, sizeof(shdr), 1, f_in);
-
- - strtab = malloc(shdr.sh_size);
- - if (!strtab) {
- - fprintf(stderr, "Failed to malloc strtab\n");
- - exit(EXIT_FAILURE);
- - }
- -
- - fseek(f_in, shdr.sh_offset, SEEK_SET);
- - fread(strtab, shdr.sh_size, 1, f_in);
- -
- - /* Now search for the .bss section */
- - fseek(f_in, shoff, SEEK_SET);
- - for (i = 0; i < shnum; i++) {
- - rv = fread(&shdr, sizeof(shdr), 1, f_in);
- - if (!rv) {
- - fprintf(stderr, "Failed to read section table\n");
- - exit(EXIT_FAILURE);
- - }
- + /* Find the first LOAD program header */
- + for (i = 0; i < phnum; i++) {
- + fseek(f_in, phoff + i * phentsize, SEEK_SET);
- + fread(&phdr, sizeof(phdr), 1, f_in);
-
- - name = strtab + shdr.sh_name;
- - if (!strcmp(name, ".bss"))
- + if (phdr.p_type == PT_LOAD)
- break;
- }
-
- - if (i == shnum) {
- - fprintf(stderr, "Failed to find .bss section\n");
- - exit(EXIT_FAILURE);
- - }
- -
- - datasz = shdr.sh_offset;
- - }
- - else if (e32_hdr.e_ident[EI_CLASS] == ELFCLASS64) {
- - const char *shstrtab, *name;
- - Elf64_Shdr shdr;
- + datasz = phdr.p_filesz;
- + memsz = phdr.p_memsz;
- + } else if (e32_hdr.e_ident[EI_CLASS] == ELFCLASS64) {
- + Elf64_Phdr phdr;
- int i;
- - void *strtab;
- -
- - fseek(f_in, shoff, SEEK_SET);
-
- - /* First find the strtab section */
- - fseek(f_in, shstrndx * shentsize, SEEK_CUR);
- - fread(&shdr, sizeof(shdr), 1, f_in);
- -
- - strtab = malloc(shdr.sh_size);
- - if (!strtab) {
- - fprintf(stderr, "Failed to malloc strtab\n");
- - exit(EXIT_FAILURE);
- - }
- + /* Find the first LOAD program header */
- + for (i = 0; i < phnum; i++) {
- + fseek(f_in, phoff + i * phentsize, SEEK_SET);
- + fread(&phdr, sizeof(phdr), 1, f_in);
-
- - fseek(f_in, shdr.sh_offset, SEEK_SET);
- - fread(strtab, shdr.sh_size, 1, f_in);
- -
- - /* Now search for the .bss section */
- - fseek(f_in, shoff, SEEK_SET);
- - for (i = 0; i < shnum; i++) {
- - rv = fread(&shdr, sizeof(shdr), 1, f_in);
- - if (!rv) {
- - fprintf(stderr, "Failed to read section table\n");
- - exit(EXIT_FAILURE);
- - }
- -
- - name = strtab + shdr.sh_name;
- - if (!strcmp(name, ".bss"))
- + if (phdr.p_type == PT_LOAD)
- break;
- }
-
- - if (i == shnum) {
- - fprintf(stderr, "Failed to find .bss section\n");
- - exit(EXIT_FAILURE);
- - }
- -
- - datasz = shdr.sh_offset;
- + datasz = phdr.p_filesz;
- + memsz = phdr.p_memsz;
- }
-
- buf = malloc(datasz);
- @@ -330,7 +271,7 @@ int main(int argc, char **argv)
- exit(EXIT_FAILURE);
- }
-
- - write_header(f_out, entry, datasz, st.st_size, class);
- + write_header(f_out, entry, datasz, memsz, class);
-
- /* Write out the entire ELF shared object */
- rewind(f_in);
- @@ -341,5 +282,8 @@ int main(int argc, char **argv)
- }
-
- fwrite(buf, datasz, rv, f_out);
- + free(buf);
- + fclose(f_out);
- + fclose(f_in);
- return 0;
- }
- diff --git a/efi/x86_64/syslinux.ld b/efi/x86_64/syslinux.ld
- index 95160bd..450641c 100644
- --- a/efi/x86_64/syslinux.ld
- +++ b/efi/x86_64/syslinux.ld
- @@ -136,7 +136,7 @@ SECTIONS
- *(.strtab)
- }
-
- - .bss : {
- + .bss (NOLOAD) : {
- /* the EFI loader doesn't seem to like a .bss section,
- so we stick it all into .data: */
- __bss_start = .;
- @@ -153,7 +153,7 @@ SECTIONS
- __bss_dwords = (__bss_len + 3) >> 2;
-
- . = ALIGN(128);
- -
- +
- /* Very large objects which don't need to be zeroed */
-
- .hugebss : {
|