aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.build37
-rw-r--r--scripts/Makefile.modpost9
-rw-r--r--scripts/mod/file2alias.c6
-rw-r--r--scripts/mod/modpost.c102
-rw-r--r--scripts/mod/modpost.h43
5 files changed, 147 insertions, 50 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index e4deb73e9a8..a1a5cf95a68 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -115,7 +115,10 @@ endif
115# --------------------------------------------------------------------------- 115# ---------------------------------------------------------------------------
116 116
117# Default is built-in, unless we know otherwise 117# Default is built-in, unless we know otherwise
118modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL)) 118modkern_cflags = \
119 $(if $(part-of-module), \
120 $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
121 $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
119quiet_modtag := $(empty) $(empty) 122quiet_modtag := $(empty) $(empty)
120 123
121$(real-objs-m) : part-of-module := y 124$(real-objs-m) : part-of-module := y
@@ -156,14 +159,14 @@ $(obj)/%.i: $(src)/%.c FORCE
156 159
157cmd_gensymtypes = \ 160cmd_gensymtypes = \
158 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ 161 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
159 $(GENKSYMS) -T $@ -a $(ARCH) \ 162 $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \
160 $(if $(KBUILD_PRESERVE),-p) \ 163 $(if $(KBUILD_PRESERVE),-p) \
161 $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) 164 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
162 165
163quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ 166quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
164cmd_cc_symtypes_c = \ 167cmd_cc_symtypes_c = \
165 set -e; \ 168 set -e; \
166 $(call cmd_gensymtypes, true) >/dev/null; \ 169 $(call cmd_gensymtypes,true,$@) >/dev/null; \
167 test -s $@ || rm -f $@ 170 test -s $@ || rm -f $@
168 171
169$(obj)/%.symtypes : $(src)/%.c FORCE 172$(obj)/%.symtypes : $(src)/%.c FORCE
@@ -192,16 +195,16 @@ else
192# the actual value of the checksum generated by genksyms 195# the actual value of the checksum generated by genksyms
193 196
194cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< 197cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
195cmd_modversions = \ 198cmd_modversions = \
196 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ 199 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
197 $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \ 200 $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
198 > $(@D)/.tmp_$(@F:.o=.ver); \ 201 > $(@D)/.tmp_$(@F:.o=.ver); \
199 \ 202 \
200 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ 203 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
201 -T $(@D)/.tmp_$(@F:.o=.ver); \ 204 -T $(@D)/.tmp_$(@F:.o=.ver); \
202 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ 205 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
203 else \ 206 else \
204 mv -f $(@D)/.tmp_$(@F) $@; \ 207 mv -f $(@D)/.tmp_$(@F) $@; \
205 fi; 208 fi;
206endif 209endif
207 210
@@ -248,10 +251,10 @@ $(obj)/%.lst: $(src)/%.c FORCE
248# Compile assembler sources (.S) 251# Compile assembler sources (.S)
249# --------------------------------------------------------------------------- 252# ---------------------------------------------------------------------------
250 253
251modkern_aflags := $(AFLAGS_KERNEL) 254modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
252 255
253$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE) 256$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
254$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE) 257$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
255 258
256quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ 259quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
257cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< 260cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 8f14c81abbc..7d22056582c 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -30,7 +30,7 @@
30# - See include/linux/module.h for more details 30# - See include/linux/module.h for more details
31 31
32# Step 4 is solely used to allow module versioning in external modules, 32# Step 4 is solely used to allow module versioning in external modules,
33# where the CRC of each module is retrieved from the Module.symers file. 33# where the CRC of each module is retrieved from the Module.symvers file.
34 34
35# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined 35# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
36# symbols in the final module linking stage 36# symbols in the final module linking stage
@@ -107,7 +107,7 @@ $(modules:.ko=.mod.c): __modpost ;
107modname = $(notdir $(@:.mod.o=)) 107modname = $(notdir $(@:.mod.o=))
108 108
109quiet_cmd_cc_o_c = CC $@ 109quiet_cmd_cc_o_c = CC $@
110 cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ 110 cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \
111 -c -o $@ $< 111 -c -o $@ $<
112 112
113$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE 113$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
@@ -117,8 +117,9 @@ targets += $(modules:.ko=.mod.o)
117 117
118# Step 6), final link of the modules 118# Step 6), final link of the modules
119quiet_cmd_ld_ko_o = LD [M] $@ 119quiet_cmd_ld_ko_o = LD [M] $@
120 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ 120 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
121 $(filter-out FORCE,$^) 121 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
122 -o $@ $(filter-out FORCE,$^)
122 123
123$(modules): %.ko :%.o %.mod.o FORCE 124$(modules): %.ko :%.o %.mod.o FORCE
124 $(call if_changed,ld_ko_o) 125 $(call if_changed,ld_ko_o)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 5758aab0d8b..88f3f07205f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -884,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
884 char *zeros = NULL; 884 char *zeros = NULL;
885 885
886 /* We're looking for a section relative symbol */ 886 /* We're looking for a section relative symbol */
887 if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum) 887 if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
888 return; 888 return;
889 889
890 /* Handle all-NULL symbols allocated into .bss */ 890 /* Handle all-NULL symbols allocated into .bss */
891 if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) { 891 if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
892 zeros = calloc(1, sym->st_size); 892 zeros = calloc(1, sym->st_size);
893 symval = zeros; 893 symval = zeros;
894 } else { 894 } else {
895 symval = (void *)info->hdr 895 symval = (void *)info->hdr
896 + info->sechdrs[sym->st_shndx].sh_offset 896 + info->sechdrs[get_secindex(info, sym)].sh_offset
897 + sym->st_value; 897 + sym->st_value;
898 } 898 }
899 899
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index f6127b9f5ac..c827309c29c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -253,7 +253,7 @@ static enum export export_no(const char *s)
253 return export_unknown; 253 return export_unknown;
254} 254}
255 255
256static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) 256static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
257{ 257{
258 if (sec == elf->export_sec) 258 if (sec == elf->export_sec)
259 return export_plain; 259 return export_plain;
@@ -373,6 +373,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
373 Elf_Ehdr *hdr; 373 Elf_Ehdr *hdr;
374 Elf_Shdr *sechdrs; 374 Elf_Shdr *sechdrs;
375 Elf_Sym *sym; 375 Elf_Sym *sym;
376 const char *secstrings;
377 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
376 378
377 hdr = grab_file(filename, &info->size); 379 hdr = grab_file(filename, &info->size);
378 if (!hdr) { 380 if (!hdr) {
@@ -417,8 +419,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
417 return 0; 419 return 0;
418 } 420 }
419 421
422 if (hdr->e_shnum == 0) {
423 /*
424 * There are more than 64k sections,
425 * read count from .sh_size.
426 * note: it doesn't need shndx2secindex()
427 */
428 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
429 }
430 else {
431 info->num_sections = hdr->e_shnum;
432 }
433 if (hdr->e_shstrndx == SHN_XINDEX) {
434 info->secindex_strings =
435 shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
436 }
437 else {
438 info->secindex_strings = hdr->e_shstrndx;
439 }
440
420 /* Fix endianness in section headers */ 441 /* Fix endianness in section headers */
421 for (i = 0; i < hdr->e_shnum; i++) { 442 for (i = 0; i < info->num_sections; i++) {
422 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); 443 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
423 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); 444 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
424 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); 445 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
@@ -431,9 +452,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
431 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); 452 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
432 } 453 }
433 /* Find symbol table. */ 454 /* Find symbol table. */
434 for (i = 1; i < hdr->e_shnum; i++) { 455 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
435 const char *secstrings 456 for (i = 1; i < info->num_sections; i++) {
436 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
437 const char *secname; 457 const char *secname;
438 int nobits = sechdrs[i].sh_type == SHT_NOBITS; 458 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
439 459
@@ -461,14 +481,26 @@ static int parse_elf(struct elf_info *info, const char *filename)
461 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 481 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
462 info->export_gpl_future_sec = i; 482 info->export_gpl_future_sec = i;
463 483
464 if (sechdrs[i].sh_type != SHT_SYMTAB) 484 if (sechdrs[i].sh_type == SHT_SYMTAB) {
465 continue; 485 unsigned int sh_link_idx;
486 symtab_idx = i;
487 info->symtab_start = (void *)hdr +
488 sechdrs[i].sh_offset;
489 info->symtab_stop = (void *)hdr +
490 sechdrs[i].sh_offset + sechdrs[i].sh_size;
491 sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
492 info->strtab = (void *)hdr +
493 sechdrs[sh_link_idx].sh_offset;
494 }
466 495
467 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; 496 /* 32bit section no. table? ("more than 64k sections") */
468 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset 497 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
469 + sechdrs[i].sh_size; 498 symtab_shndx_idx = i;
470 info->strtab = (void *)hdr + 499 info->symtab_shndx_start = (void *)hdr +
471 sechdrs[sechdrs[i].sh_link].sh_offset; 500 sechdrs[i].sh_offset;
501 info->symtab_shndx_stop = (void *)hdr +
502 sechdrs[i].sh_offset + sechdrs[i].sh_size;
503 }
472 } 504 }
473 if (!info->symtab_start) 505 if (!info->symtab_start)
474 fatal("%s has no symtab?\n", filename); 506 fatal("%s has no symtab?\n", filename);
@@ -480,6 +512,21 @@ static int parse_elf(struct elf_info *info, const char *filename)
480 sym->st_value = TO_NATIVE(sym->st_value); 512 sym->st_value = TO_NATIVE(sym->st_value);
481 sym->st_size = TO_NATIVE(sym->st_size); 513 sym->st_size = TO_NATIVE(sym->st_size);
482 } 514 }
515
516 if (symtab_shndx_idx != ~0U) {
517 Elf32_Word *p;
518 if (symtab_idx !=
519 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
520 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
521 filename,
522 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
523 symtab_idx);
524 /* Fix endianness */
525 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
526 p++)
527 *p = TO_NATIVE(*p);
528 }
529
483 return 1; 530 return 1;
484} 531}
485 532
@@ -519,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
519 Elf_Sym *sym, const char *symname) 566 Elf_Sym *sym, const char *symname)
520{ 567{
521 unsigned int crc; 568 unsigned int crc;
522 enum export export = export_from_sec(info, sym->st_shndx); 569 enum export export = export_from_sec(info, get_secindex(info, sym));
523 570
524 switch (sym->st_shndx) { 571 switch (sym->st_shndx) {
525 case SHN_COMMON: 572 case SHN_COMMON:
@@ -661,19 +708,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
661 return "(unknown)"; 708 return "(unknown)";
662} 709}
663 710
664static const char *sec_name(struct elf_info *elf, int shndx) 711static const char *sec_name(struct elf_info *elf, int secindex)
665{ 712{
666 Elf_Shdr *sechdrs = elf->sechdrs; 713 Elf_Shdr *sechdrs = elf->sechdrs;
667 return (void *)elf->hdr + 714 return (void *)elf->hdr +
668 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 715 elf->sechdrs[elf->secindex_strings].sh_offset +
669 sechdrs[shndx].sh_name; 716 sechdrs[secindex].sh_name;
670} 717}
671 718
672static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) 719static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
673{ 720{
674 return (void *)elf->hdr + 721 return (void *)elf->hdr +
675 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 722 elf->sechdrs[elf->secindex_strings].sh_offset +
676 sechdr->sh_name; 723 sechdr->sh_name;
677} 724}
678 725
679/* if sym is empty or point to a string 726/* if sym is empty or point to a string
@@ -1052,11 +1099,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
1052 Elf_Sym *near = NULL; 1099 Elf_Sym *near = NULL;
1053 Elf64_Sword distance = 20; 1100 Elf64_Sword distance = 20;
1054 Elf64_Sword d; 1101 Elf64_Sword d;
1102 unsigned int relsym_secindex;
1055 1103
1056 if (relsym->st_name != 0) 1104 if (relsym->st_name != 0)
1057 return relsym; 1105 return relsym;
1106
1107 relsym_secindex = get_secindex(elf, relsym);
1058 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1108 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1059 if (sym->st_shndx != relsym->st_shndx) 1109 if (get_secindex(elf, sym) != relsym_secindex)
1060 continue; 1110 continue;
1061 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) 1111 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1062 continue; 1112 continue;
@@ -1118,9 +1168,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1118 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1168 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1119 const char *symsec; 1169 const char *symsec;
1120 1170
1121 if (sym->st_shndx >= SHN_LORESERVE) 1171 if (is_shndx_special(sym->st_shndx))
1122 continue; 1172 continue;
1123 symsec = sec_name(elf, sym->st_shndx); 1173 symsec = sec_name(elf, get_secindex(elf, sym));
1124 if (strcmp(symsec, sec) != 0) 1174 if (strcmp(symsec, sec) != 0)
1125 continue; 1175 continue;
1126 if (!is_valid_name(elf, sym)) 1176 if (!is_valid_name(elf, sym))
@@ -1316,7 +1366,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1316 const char *tosec; 1366 const char *tosec;
1317 const struct sectioncheck *mismatch; 1367 const struct sectioncheck *mismatch;
1318 1368
1319 tosec = sec_name(elf, sym->st_shndx); 1369 tosec = sec_name(elf, get_secindex(elf, sym));
1320 mismatch = section_mismatch(fromsec, tosec); 1370 mismatch = section_mismatch(fromsec, tosec);
1321 if (mismatch) { 1371 if (mismatch) {
1322 Elf_Sym *to; 1372 Elf_Sym *to;
@@ -1344,7 +1394,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
1344 Elf_Shdr *sechdr, Elf_Rela *r) 1394 Elf_Shdr *sechdr, Elf_Rela *r)
1345{ 1395{
1346 Elf_Shdr *sechdrs = elf->sechdrs; 1396 Elf_Shdr *sechdrs = elf->sechdrs;
1347 int section = sechdr->sh_info; 1397 int section = shndx2secindex(sechdr->sh_info);
1348 1398
1349 return (void *)elf->hdr + sechdrs[section].sh_offset + 1399 return (void *)elf->hdr + sechdrs[section].sh_offset +
1350 r->r_offset - sechdrs[section].sh_addr; 1400 r->r_offset - sechdrs[section].sh_addr;
@@ -1452,7 +1502,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
1452 r.r_addend = TO_NATIVE(rela->r_addend); 1502 r.r_addend = TO_NATIVE(rela->r_addend);
1453 sym = elf->symtab_start + r_sym; 1503 sym = elf->symtab_start + r_sym;
1454 /* Skip special sections */ 1504 /* Skip special sections */
1455 if (sym->st_shndx >= SHN_LORESERVE) 1505 if (is_shndx_special(sym->st_shndx))
1456 continue; 1506 continue;
1457 check_section_mismatch(modname, elf, &r, sym, fromsec); 1507 check_section_mismatch(modname, elf, &r, sym, fromsec);
1458 } 1508 }
@@ -1510,7 +1560,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
1510 } 1560 }
1511 sym = elf->symtab_start + r_sym; 1561 sym = elf->symtab_start + r_sym;
1512 /* Skip special sections */ 1562 /* Skip special sections */
1513 if (sym->st_shndx >= SHN_LORESERVE) 1563 if (is_shndx_special(sym->st_shndx))
1514 continue; 1564 continue;
1515 check_section_mismatch(modname, elf, &r, sym, fromsec); 1565 check_section_mismatch(modname, elf, &r, sym, fromsec);
1516 } 1566 }
@@ -1535,7 +1585,7 @@ static void check_sec_ref(struct module *mod, const char *modname,
1535 Elf_Shdr *sechdrs = elf->sechdrs; 1585 Elf_Shdr *sechdrs = elf->sechdrs;
1536 1586
1537 /* Walk through all sections */ 1587 /* Walk through all sections */
1538 for (i = 0; i < elf->hdr->e_shnum; i++) { 1588 for (i = 0; i < elf->num_sections; i++) {
1539 check_section(modname, elf, &elf->sechdrs[i]); 1589 check_section(modname, elf, &elf->sechdrs[i]);
1540 /* We want to process only relocation sections and not .init */ 1590 /* We want to process only relocation sections and not .init */
1541 if (sechdrs[i].sh_type == SHT_RELA) 1591 if (sechdrs[i].sh_type == SHT_RELA)
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index be987a44f25..0388cfccac8 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -129,8 +129,51 @@ struct elf_info {
129 const char *strtab; 129 const char *strtab;
130 char *modinfo; 130 char *modinfo;
131 unsigned int modinfo_len; 131 unsigned int modinfo_len;
132
133 /* support for 32bit section numbers */
134
135 unsigned int num_sections; /* max_secindex + 1 */
136 unsigned int secindex_strings;
137 /* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
138 * take shndx from symtab_shndx_start[N] instead */
139 Elf32_Word *symtab_shndx_start;
140 Elf32_Word *symtab_shndx_stop;
132}; 141};
133 142
143static inline int is_shndx_special(unsigned int i)
144{
145 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
146}
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)
159 */
160static 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}
166
167/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168static inline unsigned int get_secindex(const struct elf_info *info,
169 const Elf_Sym *sym)
170{
171 if (sym->st_shndx != SHN_XINDEX)
172 return sym->st_shndx;
173 return shndx2secindex(info->symtab_shndx_start[sym -
174 info->symtab_start]);
175}
176
134/* file2alias.c */ 177/* file2alias.c */
135extern unsigned int cross_build; 178extern unsigned int cross_build;
136void handle_moddevtable(struct module *mod, struct elf_info *info, 179void handle_moddevtable(struct module *mod, struct elf_info *info,