According to the System V Application Binary Interface specification [1]
the sections holding a symbol table, SHT_SYMTAB and SHT_DYNSYM, have to
have sh_info set to "One greater than the symbol table index of the last
local symbol (binding STB_LOCAL)". Current code converting PE images to
ELF files does not do that and readelf complains in following way:

  ...

  Section Headers:
    [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf 
Al
    [ 0]                   NULL            00000000 000000 000000 00      0   0 
 0
    [ 1] .text             PROGBITS        00000000 000034 0014d4 00  AX  0   0 
 4
    [ 2] .data             PROGBITS        00000000 001508 000040 00  WA  0   0 
32
    [ 3] .rdata            PROGBITS        00000000 001548 0006b8 00   A  0   0 
 4
    [ 4] .module_license   PROGBITS        00000000 001c00 000010 00      0   0 
 4
    [ 5] .bss              NOBITS          00000000 000000 000008 00  WA  0   0 
 4
    [ 6] .moddeps          PROGBITS        00000000 001c10 000010 00      0   0 
 4
    [ 7] .modname          PROGBITS        00000000 001c20 000008 00      0   0 
 4
    [ 8] .rel.text         REL             00000000 001c28 0008c8 08     11   1 
 4
    [ 9] .rel.data         REL             00000000 0024f0 000040 08     11   2 
 4
    [10] .rel.rdata        REL             00000000 002530 000070 08     11   3 
 4
    [11] .symtab           SYMTAB          00000000 0025a0 0001d0 10     12   0 
 4
    [12] .strtab           STRTAB          00000000 002770 000237 00      0   0 
 1

  ...

  Symbol table '.symtab' contains 29 entries:
     Num:    Value  Size Type    Bind   Vis      Ndx Name
       0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
  readelf: Warning: local symbol 0 found at index >= .symtab's sh_info value of 0
       1: 0000144a     0 FUNC    LOCAL  DEFAULT    1 grub_mod_init
  readelf: Warning: local symbol 1 found at index >= .symtab's sh_info value of 0
       2: 000014aa     0 FUNC    LOCAL  DEFAULT    1 grub_mod_fini
  readelf: Warning: local symbol 2 found at index >= .symtab's sh_info value of 0
       3: 00000000     0 SECTION LOCAL  DEFAULT    1 .text
  readelf: Warning: local symbol 3 found at index >= .symtab's sh_info value of 0
       4: 00000000     0 SECTION LOCAL  DEFAULT    2 .data
  readelf: Warning: local symbol 4 found at index >= .symtab's sh_info value of 0
       5: 00000000     0 SECTION LOCAL  DEFAULT    5 .bss
  readelf: Warning: local symbol 5 found at index >= .symtab's sh_info value of 0
       6: 00000000     0 SECTION LOCAL  DEFAULT    3 .rdata
  readelf: Warning: local symbol 6 found at index >= .symtab's sh_info value of 0
       7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND grub_dma_get_phys
       8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND grub_cs5536_write_msr
       9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND grub_dma_free

  ...

Let's fix it...

[1] https://www.sco.com/developers/gabi/2012-12-31/contents.html

Signed-off-by: Daniel Kiper <[email protected]>
---
 util/grub-pe2elf.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c
index 5d8d9c1de..7a3c5a06e 100644
--- a/util/grub-pe2elf.c
+++ b/util/grub-pe2elf.c
@@ -360,7 +360,7 @@ write_symbol_table (FILE* fp, const char *name, char *image,
   struct grub_pe32_symbol *pe_symtab;
   char *pe_strtab;
   Elf_Sym *symtab;
-  int *symtab_map, num_syms;
+  int *symtab_map, num_syms, last_stb_local = 0;
   int i;
 
   pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset);
@@ -391,7 +391,10 @@ write_symbol_table (FILE* fp, const char *name, char 
*image,
       if (pe_symtab->storage_class == GRUB_PE32_SYM_CLASS_EXTERNAL)
         bind = STB_GLOBAL;
       else
-        bind = STB_LOCAL;
+       {
+         bind = STB_LOCAL;
+         last_stb_local = num_syms;
+       }
 
       if ((pe_symtab->type != GRUB_PE32_DT_FUNCTION) && (pe_symtab->num_aux))
         {
@@ -441,6 +444,7 @@ write_symbol_table (FILE* fp, const char *name, char *image,
   shdr[symtab_section].sh_size = num_syms * sizeof (Elf_Sym);
   shdr[symtab_section].sh_entsize = sizeof (Elf_Sym);
   shdr[symtab_section].sh_link = strtab_section;
+  shdr[symtab_section].sh_info = ++last_stb_local;
   shdr[symtab_section].sh_addralign = 4;
 
   grub_util_write_image_at (symtab, shdr[symtab_section].sh_size,
-- 
2.11.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to