Commit 6845756b29e4c4e7db41e2d75cafa9d091bc1c07

Authored by Anders Kaseorg
Committed by Rusty Russell
1 parent 9d63487f86

modpost: Update 64k section support for binutils 2.18.50

Binutils 2.18.50 made a backwards-incompatible change in the way it
writes ELF objects with over 65280 sections, to improve conformance
with the ELF specification and interoperability with other ELF tools.
Specifically, it no longer adds 256 to section indices SHN_LORESERVE
and higher to skip over the reserved range SHN_LORESERVE through
SHN_HIRESERVE; those values are only considered special in the
st_shndx field, and not in other places where section indices are
stored.  See:

http://sourceware.org/bugzilla/show_bug.cgi?id=5900
http://groups.google.com/group/generic-abi/browse_thread/thread/e8bb63714b072e67/6c63738f12cc8a17

Signed-off-by: Anders Kaseorg <andersk@ksplice.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 14 additions and 29 deletions Side-by-side Diff

scripts/mod/modpost.c
... ... @@ -420,11 +420,10 @@
420 420 return 0;
421 421 }
422 422  
423   - if (hdr->e_shnum == 0) {
  423 + if (hdr->e_shnum == SHN_UNDEF) {
424 424 /*
425 425 * There are more than 64k sections,
426 426 * read count from .sh_size.
427   - * note: it doesn't need shndx2secindex()
428 427 */
429 428 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
430 429 }
... ... @@ -432,8 +431,7 @@
432 431 info->num_sections = hdr->e_shnum;
433 432 }
434 433 if (hdr->e_shstrndx == SHN_XINDEX) {
435   - info->secindex_strings =
436   - shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
  434 + info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
437 435 }
438 436 else {
439 437 info->secindex_strings = hdr->e_shstrndx;
... ... @@ -489,7 +487,7 @@
489 487 sechdrs[i].sh_offset;
490 488 info->symtab_stop = (void *)hdr +
491 489 sechdrs[i].sh_offset + sechdrs[i].sh_size;
492   - sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
  490 + sh_link_idx = sechdrs[i].sh_link;
493 491 info->strtab = (void *)hdr +
494 492 sechdrs[sh_link_idx].sh_offset;
495 493 }
496 494  
... ... @@ -516,11 +514,9 @@
516 514  
517 515 if (symtab_shndx_idx != ~0U) {
518 516 Elf32_Word *p;
519   - if (symtab_idx !=
520   - shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
  517 + if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
521 518 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
522   - filename,
523   - shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
  519 + filename, sechdrs[symtab_shndx_idx].sh_link,
524 520 symtab_idx);
525 521 /* Fix endianness */
526 522 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
... ... @@ -1446,7 +1442,7 @@
1446 1442 Elf_Shdr *sechdr, Elf_Rela *r)
1447 1443 {
1448 1444 Elf_Shdr *sechdrs = elf->sechdrs;
1449   - int section = shndx2secindex(sechdr->sh_info);
  1445 + int section = sechdr->sh_info;
1450 1446  
1451 1447 return (void *)elf->hdr + sechdrs[section].sh_offset +
1452 1448 r->r_offset;
scripts/mod/modpost.h
... ... @@ -145,33 +145,22 @@
145 145 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
146 146 }
147 147  
148   -/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
149   - * shndx == 0 <=> sechdrs[0]
150   - * ......
151   - * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
152   - * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
153   - * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
154   - * ......
155   - * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
156   - * so basically we map 0000..feff -> 0000..feff
157   - * ff00..ffff -> (you are a bad boy, dont do it)
158   - * 10000..xxxx -> ff00..(xxxx-0x100)
  148 +/*
  149 + * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
  150 + * the way to -256..-1, to avoid conflicting with real section
  151 + * indices.
159 152 */
160   -static inline unsigned int shndx2secindex(unsigned int i)
161   -{
162   - if (i <= SHN_HIRESERVE)
163   - return i;
164   - return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
165   -}
  153 +#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
166 154  
167 155 /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168 156 static inline unsigned int get_secindex(const struct elf_info *info,
169 157 const Elf_Sym *sym)
170 158 {
  159 + if (is_shndx_special(sym->st_shndx))
  160 + return SPECIAL(sym->st_shndx);
171 161 if (sym->st_shndx != SHN_XINDEX)
172 162 return sym->st_shndx;
173   - return shndx2secindex(info->symtab_shndx_start[sym -
174   - info->symtab_start]);
  163 + return info->symtab_shndx_start[sym - info->symtab_start];
175 164 }
176 165  
177 166 /* file2alias.c */