aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
authorAnders Kaseorg <andersk@ksplice.com>2011-05-19 18:55:27 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-05-19 03:25:28 -0400
commit6845756b29e4c4e7db41e2d75cafa9d091bc1c07 (patch)
treecceb66e295b238d2ab62a9ca77c9b6adce867935 /scripts/mod
parent9d63487f86115b1d3ef69670043bcf2b83c4d227 (diff)
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>
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c16
-rw-r--r--scripts/mod/modpost.h27
2 files changed, 14 insertions, 29 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index cd104afcc5f2..413c53693e62 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -420,11 +420,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
420 return 0; 420 return 0;
421 } 421 }
422 422
423 if (hdr->e_shnum == 0) { 423 if (hdr->e_shnum == SHN_UNDEF) {
424 /* 424 /*
425 * There are more than 64k sections, 425 * There are more than 64k sections,
426 * read count from .sh_size. 426 * read count from .sh_size.
427 * note: it doesn't need shndx2secindex()
428 */ 427 */
429 info->num_sections = TO_NATIVE(sechdrs[0].sh_size); 428 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
430 } 429 }
@@ -432,8 +431,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
432 info->num_sections = hdr->e_shnum; 431 info->num_sections = hdr->e_shnum;
433 } 432 }
434 if (hdr->e_shstrndx == SHN_XINDEX) { 433 if (hdr->e_shstrndx == SHN_XINDEX) {
435 info->secindex_strings = 434 info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
436 shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
437 } 435 }
438 else { 436 else {
439 info->secindex_strings = hdr->e_shstrndx; 437 info->secindex_strings = hdr->e_shstrndx;
@@ -489,7 +487,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
489 sechdrs[i].sh_offset; 487 sechdrs[i].sh_offset;
490 info->symtab_stop = (void *)hdr + 488 info->symtab_stop = (void *)hdr +
491 sechdrs[i].sh_offset + sechdrs[i].sh_size; 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 info->strtab = (void *)hdr + 491 info->strtab = (void *)hdr +
494 sechdrs[sh_link_idx].sh_offset; 492 sechdrs[sh_link_idx].sh_offset;
495 } 493 }
@@ -516,11 +514,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
516 514
517 if (symtab_shndx_idx != ~0U) { 515 if (symtab_shndx_idx != ~0U) {
518 Elf32_Word *p; 516 Elf32_Word *p;
519 if (symtab_idx != 517 if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
520 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
521 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", 518 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
522 filename, 519 filename, sechdrs[symtab_shndx_idx].sh_link,
523 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
524 symtab_idx); 520 symtab_idx);
525 /* Fix endianness */ 521 /* Fix endianness */
526 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; 522 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
@@ -1446,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
1446 Elf_Shdr *sechdr, Elf_Rela *r) 1442 Elf_Shdr *sechdr, Elf_Rela *r)
1447{ 1443{
1448 Elf_Shdr *sechdrs = elf->sechdrs; 1444 Elf_Shdr *sechdrs = elf->sechdrs;
1449 int section = shndx2secindex(sechdr->sh_info); 1445 int section = sechdr->sh_info;
1450 1446
1451 return (void *)elf->hdr + sechdrs[section].sh_offset + 1447 return (void *)elf->hdr + sechdrs[section].sh_offset +
1452 r->r_offset; 1448 r->r_offset;
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 0388cfccac8d..2031119080dc 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -145,33 +145,22 @@ static inline int is_shndx_special(unsigned int i)
145 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; 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: 148/*
149 * shndx == 0 <=> sechdrs[0] 149 * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
150 * ...... 150 * the way to -256..-1, to avoid conflicting with real section
151 * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1] 151 * indices.
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)
159 */ 152 */
160static inline unsigned int shndx2secindex(unsigned int i) 153#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
161{
162 if (i <= SHN_HIRESERVE)
163 return i;
164 return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
165}
166 154
167/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ 155/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168static inline unsigned int get_secindex(const struct elf_info *info, 156static inline unsigned int get_secindex(const struct elf_info *info,
169 const Elf_Sym *sym) 157 const Elf_Sym *sym)
170{ 158{
159 if (is_shndx_special(sym->st_shndx))
160 return SPECIAL(sym->st_shndx);
171 if (sym->st_shndx != SHN_XINDEX) 161 if (sym->st_shndx != SHN_XINDEX)
172 return sym->st_shndx; 162 return sym->st_shndx;
173 return shndx2secindex(info->symtab_shndx_start[sym - 163 return info->symtab_shndx_start[sym - info->symtab_start];
174 info->symtab_start]);
175} 164}
176 165
177/* file2alias.c */ 166/* file2alias.c */