Skip to content

Commit 6845756

Browse files
anderskrustyrussell
authored andcommitted
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 <[email protected]> Signed-off-by: Rusty Russell <[email protected]>
1 parent 9d63487 commit 6845756

File tree

2 files changed

+14
-29
lines changed

2 files changed

+14
-29
lines changed

scripts/mod/modpost.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -420,20 +420,18 @@ static int parse_elf(struct elf_info *info, const char *filename)
420420
return 0;
421421
}
422422

423-
if (hdr->e_shnum == 0) {
423+
if (hdr->e_shnum == SHN_UNDEF) {
424424
/*
425425
* There are more than 64k sections,
426426
* read count from .sh_size.
427-
* note: it doesn't need shndx2secindex()
428427
*/
429428
info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
430429
}
431430
else {
432431
info->num_sections = hdr->e_shnum;
433432
}
434433
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);
437435
}
438436
else {
439437
info->secindex_strings = hdr->e_shstrndx;
@@ -489,7 +487,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
489487
sechdrs[i].sh_offset;
490488
info->symtab_stop = (void *)hdr +
491489
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;
493491
info->strtab = (void *)hdr +
494492
sechdrs[sh_link_idx].sh_offset;
495493
}
@@ -516,11 +514,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
516514

517515
if (symtab_shndx_idx != ~0U) {
518516
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)
521518
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,
524520
symtab_idx);
525521
/* Fix endianness */
526522
for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
@@ -1446,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
14461442
Elf_Shdr *sechdr, Elf_Rela *r)
14471443
{
14481444
Elf_Shdr *sechdrs = elf->sechdrs;
1449-
int section = shndx2secindex(sechdr->sh_info);
1445+
int section = sechdr->sh_info;
14501446

14511447
return (void *)elf->hdr + sechdrs[section].sh_offset +
14521448
r->r_offset;

scripts/mod/modpost.h

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -145,33 +145,22 @@ static inline int is_shndx_special(unsigned int i)
145145
return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
146146
}
147147

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.
159152
*/
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))
166154

167155
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168156
static inline unsigned int get_secindex(const struct elf_info *info,
169157
const Elf_Sym *sym)
170158
{
159+
if (is_shndx_special(sym->st_shndx))
160+
return SPECIAL(sym->st_shndx);
171161
if (sym->st_shndx != SHN_XINDEX)
172162
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];
175164
}
176165

177166
/* file2alias.c */

0 commit comments

Comments
 (0)