Date: Friday, November 29, 2013 @ 08:59:03
  Author: tpowa
Revision: 200581

upgpkg: syslinux 6.02-8

fix efi ovmf issue

Added:
  syslinux/trunk/syslinux-6.02-fix-efi-ovmf.patch
Modified:
  syslinux/trunk/PKGBUILD

----------------------------------+
 PKGBUILD                         |   15 
 syslinux-6.02-fix-efi-ovmf.patch |  621 +++++++++++++++++++++++++++++++++++++
 2 files changed, 631 insertions(+), 5 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD    2013-11-29 07:17:13 UTC (rev 200580)
+++ PKGBUILD    2013-11-29 07:59:03 UTC (rev 200581)
@@ -4,7 +4,7 @@
 
 pkgname="syslinux"
 pkgver="6.02"
-pkgrel="7"
+pkgrel="8"
 arch=('x86_64' 'i686')
 pkgdesc="Collection of boot loaders that boot from FAT, ext2/3/4 and btrfs 
filesystems, from CDs and via PXE"
 url="http://syslinux.zytor.com/";
@@ -25,14 +25,14 @@
         'syslinux.cfg'
         'syslinux-install_update'
         'syslinux-6.02-fix-chainloading.patch'
-        'syslinux-6.02-fix-bios-isolinux.patch')
+        'syslinux-6.02-fix-bios-isolinux.patch'
+        'syslinux-6.02-fix-efi-ovmf.patch')
 md5sums=('6f275813a1b08cf852e55c0a3f8fbc78'
          '46ca150f53322ff8f1597d9a342f7e40'
          '9376f18fa3e42fc36cffa4cff0a84c09'
          '9dbede6b71a4de9e46aac4aad65334d7'
-         'adf71eceb4fccecd9a7efe1ab3d54918')
-
-
+         'adf71eceb4fccecd9a7efe1ab3d54918'
+         '62d22b101ef2ef53e25b4f86d9f41cb5')
 prepare() {
     
     cd "${srcdir}/${pkgname}-${pkgver}/"
@@ -56,6 +56,10 @@
     # fix bios booting from isohybrid
     # http://www.syslinux.org/archives/2013-November/021189.html
     patch -Np1 -i "${srcdir}/syslinux-6.02-fix-bios-isolinux.patch"
+
+    # fix efi booting in qemu/ovmf
+    # http://bugzilla.syslinux.org/show_bug.cgi?id=23
+    patch -Np1 -i  "${srcdir}/syslinux-6.02-fix-efi-ovmf.patch"
     
 }
 
@@ -186,3 +190,4 @@
     _package_syslinux_bios
     
 }
+

Added: syslinux-6.02-fix-efi-ovmf.patch
===================================================================
--- syslinux-6.02-fix-efi-ovmf.patch                            (rev 0)
+++ syslinux-6.02-fix-efi-ovmf.patch    2013-11-29 07:59:03 UTC (rev 200581)
@@ -0,0 +1,621 @@
+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 : {

Reply via email to