diff options
| author | Sam Ravnborg <sam@mars.ravnborg.org> | 2006-02-19 05:53:35 -0500 |
|---|---|---|
| committer | Sam Ravnborg <sam@mars.ravnborg.org> | 2006-02-19 05:53:35 -0500 |
| commit | 93684d3b8062d1cebdeaed398ec6d1f354cb41a9 (patch) | |
| tree | 65a87d5e53f8458d7574325e05f6a3cd9997e392 /scripts/mod | |
| parent | 8ea80ca4f583e377c902811d42626ccfce16913f (diff) | |
kbuild: include symbol names in section mismatch warnings
Try to look up the symbol that is referenced. Include the symbol
name in the warning message.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/modpost.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index eeaf57476820..844f84b0818a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -451,6 +451,29 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | |||
| 451 | return NULL; | 451 | return NULL; |
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | /** | ||
| 455 | * Find symbol based on relocation record info. | ||
| 456 | * In some cases the symbol supplied is a valid symbol so | ||
| 457 | * return refsym. If st_name != 0 we assume this is a valid symbol. | ||
| 458 | * In other cases the symbol needs to be looked up in the symbol table | ||
| 459 | * based on section and address. | ||
| 460 | * **/ | ||
| 461 | static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, | ||
| 462 | Elf_Sym *relsym) | ||
| 463 | { | ||
| 464 | Elf_Sym *sym; | ||
| 465 | |||
| 466 | if (relsym->st_name != 0) | ||
| 467 | return relsym; | ||
| 468 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | ||
| 469 | if (sym->st_shndx != relsym->st_shndx) | ||
| 470 | continue; | ||
| 471 | if (sym->st_value == addr) | ||
| 472 | return sym; | ||
| 473 | } | ||
| 474 | return NULL; | ||
| 475 | } | ||
| 476 | |||
| 454 | /* | 477 | /* |
| 455 | * Find symbols before or equal addr and after addr - in the section sec | 478 | * Find symbols before or equal addr and after addr - in the section sec |
| 456 | **/ | 479 | **/ |
| @@ -499,8 +522,9 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, | |||
| 499 | static void warn_sec_mismatch(const char *modname, const char *fromsec, | 522 | static void warn_sec_mismatch(const char *modname, const char *fromsec, |
| 500 | struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) | 523 | struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) |
| 501 | { | 524 | { |
| 502 | Elf_Sym *before; | 525 | const char *refsymname = ""; |
| 503 | Elf_Sym *after; | 526 | Elf_Sym *before, *after; |
| 527 | Elf_Sym *refsym; | ||
| 504 | Elf_Ehdr *hdr = elf->hdr; | 528 | Elf_Ehdr *hdr = elf->hdr; |
| 505 | Elf_Shdr *sechdrs = elf->sechdrs; | 529 | Elf_Shdr *sechdrs = elf->sechdrs; |
| 506 | const char *secstrings = (void *)hdr + | 530 | const char *secstrings = (void *)hdr + |
| @@ -509,29 +533,34 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
| 509 | 533 | ||
| 510 | find_symbols_between(elf, r.r_offset, fromsec, &before, &after); | 534 | find_symbols_between(elf, r.r_offset, fromsec, &before, &after); |
| 511 | 535 | ||
| 536 | refsym = find_elf_symbol(elf, r.r_addend, sym); | ||
| 537 | if (refsym && strlen(elf->strtab + refsym->st_name)) | ||
| 538 | refsymname = elf->strtab + refsym->st_name; | ||
| 539 | |||
| 512 | if (before && after) { | 540 | if (before && after) { |
| 513 | warn("%s - Section mismatch: reference to %s from %s " | 541 | warn("%s - Section mismatch: reference to %s:%s from %s " |
| 514 | "between '%s' (at offset 0x%lx) and '%s'\n", | 542 | "between '%s' (at offset 0x%llx) and '%s'\n", |
| 515 | modname, secname, fromsec, | 543 | modname, secname, refsymname, fromsec, |
| 516 | elf->strtab + before->st_name, | 544 | elf->strtab + before->st_name, |
| 517 | (long)(r.r_offset - before->st_value), | 545 | (long long)r.r_offset, |
| 518 | elf->strtab + after->st_name); | 546 | elf->strtab + after->st_name); |
| 519 | } else if (before) { | 547 | } else if (before) { |
| 520 | warn("%s - Section mismatch: reference to %s from %s " | 548 | warn("%s - Section mismatch: reference to %s:%s from %s " |
| 521 | "after '%s' (at offset 0x%lx)\n", | 549 | "after '%s' (at offset 0x%llx)\n", |
| 522 | modname, secname, fromsec, | 550 | modname, secname, refsymname, fromsec, |
| 523 | elf->strtab + before->st_name, | 551 | elf->strtab + before->st_name, |
| 524 | (long)(r.r_offset - before->st_value)); | 552 | (long long)r.r_offset); |
| 525 | } else if (after) { | 553 | } else if (after) { |
| 526 | warn("%s - Section mismatch: reference to %s from %s " | 554 | warn("%s - Section mismatch: reference to %s:%s from %s " |
| 527 | "before '%s' (at offset -0x%lx)\n", | 555 | "before '%s' (at offset -0x%llx)\n", |
| 528 | modname, secname, fromsec, | 556 | modname, secname, refsymname, fromsec, |
| 529 | elf->strtab + before->st_name, | 557 | elf->strtab + before->st_name, |
| 530 | (long)(before->st_value - r.r_offset)); | 558 | (long long)r.r_offset); |
| 531 | } else { | 559 | } else { |
| 532 | warn("%s - Section mismatch: reference to %s from %s " | 560 | warn("%s - Section mismatch: reference to %s:%s from %s " |
| 533 | "(offset 0x%lx)\n", | 561 | "(offset 0x%llx)\n", |
| 534 | modname, secname, fromsec, (long)r.r_offset); | 562 | modname, secname, fromsec, refsymname, |
| 563 | (long long)r.r_offset); | ||
| 535 | } | 564 | } |
| 536 | } | 565 | } |
| 537 | 566 | ||
| @@ -575,6 +604,7 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 575 | const char *secname; | 604 | const char *secname; |
| 576 | r.r_offset = TO_NATIVE(rela->r_offset); | 605 | r.r_offset = TO_NATIVE(rela->r_offset); |
| 577 | r.r_info = TO_NATIVE(rela->r_info); | 606 | r.r_info = TO_NATIVE(rela->r_info); |
| 607 | r.r_addend = TO_NATIVE(rela->r_addend); | ||
| 578 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); | 608 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); |
| 579 | /* Skip special sections */ | 609 | /* Skip special sections */ |
| 580 | if (sym->st_shndx >= SHN_LORESERVE) | 610 | if (sym->st_shndx >= SHN_LORESERVE) |
