modpost: use more reliable way to get fromsec in section_rel(a)()
[linux-2.6-microblaze.git] / scripts / mod / modpost.c
index 29d5a84..c6a055c 100644 (file)
@@ -321,13 +321,10 @@ static void *sym_get_data_by_offset(const struct elf_info *info,
 {
        Elf_Shdr *sechdr = &info->sechdrs[secindex];
 
-       if (info->hdr->e_type != ET_REL)
-               offset -= sechdr->sh_addr;
-
        return (void *)info->hdr + sechdr->sh_offset + offset;
 }
 
-static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
+void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
 {
        return sym_get_data_by_offset(info, get_secindex(info, sym),
                                      sym->st_value);
@@ -339,8 +336,16 @@ static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
                                      sechdr->sh_name);
 }
 
-static const char *sec_name(const struct elf_info *info, int secindex)
+static const char *sec_name(const struct elf_info *info, unsigned int secindex)
 {
+       /*
+        * If sym->st_shndx is a special section index, there is no
+        * corresponding section header.
+        * Return "" if the index is out of range of info->sechdrs[] array.
+        */
+       if (secindex >= info->num_sections)
+               return "";
+
        return sech_name(info, &info->sechdrs[secindex]);
 }
 
@@ -466,6 +471,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
        sechdrs = (void *)hdr + hdr->e_shoff;
        info->sechdrs = sechdrs;
 
+       /* modpost only works for relocatable objects */
+       if (hdr->e_type != ET_REL)
+               fatal("%s: not relocatable object.", filename);
+
        /* Check if file offset is correct */
        if (hdr->e_shoff > info->size) {
                fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
@@ -742,7 +751,6 @@ static const char *const section_white_list[] =
 {
        ".comment*",
        ".debug*",
-       ".cranges",             /* sh64 */
        ".zdebug*",             /* Compressed debug sections. */
        ".GCC.command.line",    /* record-gcc-switches */
        ".mdebug*",        /* alpha, score, mips etc. */
@@ -980,7 +988,7 @@ static const struct sectioncheck sectioncheck[] = {
 },
 /* Do not export init/exit functions or data */
 {
-       .fromsec = { "__ksymtab*", NULL },
+       .fromsec = { "___ksymtab*", NULL },
        .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
        .mismatch = EXPORT_TO_INIT_EXIT,
        .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
@@ -1623,9 +1631,6 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
                break;
        case R_386_PC32:
                r->r_addend = TO_NATIVE(*location) + 4;
-               /* For CONFIG_RELOCATABLE=y */
-               if (elf->hdr->e_type == ET_EXEC)
-                       r->r_addend += r->r_offset;
                break;
        }
        return 0;
@@ -1718,8 +1723,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
        Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
        Elf_Rela *stop  = (void *)start + sechdr->sh_size;
 
-       fromsec = sech_name(elf, sechdr);
-       fromsec += strlen(".rela");
+       fromsec = sec_name(elf, sechdr->sh_info);
        /* if from section (name) is know good then skip it */
        if (match(fromsec, section_white_list))
                return;
@@ -1771,8 +1775,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
        Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
        Elf_Rel *stop  = (void *)start + sechdr->sh_size;
 
-       fromsec = sech_name(elf, sechdr);
-       fromsec += strlen(".rel");
+       fromsec = sec_name(elf, sechdr->sh_info);
        /* if from section (name) is know good then skip it */
        if (match(fromsec, section_white_list))
                return;