~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to scripts/mod/modpost.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
420
420
                return 0;
421
421
        }
422
422
 
423
 
        if (hdr->e_shnum == 0) {
 
423
        if (hdr->e_shnum == SHN_UNDEF) {
424
424
                /*
425
425
                 * There are more than 64k sections,
426
426
                 * read count from .sh_size.
427
 
                 * note: it doesn't need shndx2secindex()
428
427
                 */
429
428
                info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
430
429
        }
432
431
                info->num_sections = hdr->e_shnum;
433
432
        }
434
433
        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);
437
435
        }
438
436
        else {
439
437
                info->secindex_strings = hdr->e_shstrndx;
481
479
                        info->export_unused_gpl_sec = i;
482
480
                else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
483
481
                        info->export_gpl_future_sec = i;
484
 
                else if (strcmp(secname, "__markers_strings") == 0)
485
 
                        info->markers_strings_sec = i;
486
482
 
487
483
                if (sechdrs[i].sh_type == SHT_SYMTAB) {
488
484
                        unsigned int sh_link_idx;
491
487
                            sechdrs[i].sh_offset;
492
488
                        info->symtab_stop  = (void *)hdr +
493
489
                            sechdrs[i].sh_offset + sechdrs[i].sh_size;
494
 
                        sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
 
490
                        sh_link_idx = sechdrs[i].sh_link;
495
491
                        info->strtab       = (void *)hdr +
496
492
                            sechdrs[sh_link_idx].sh_offset;
497
493
                }
518
514
 
519
515
        if (symtab_shndx_idx != ~0U) {
520
516
                Elf32_Word *p;
521
 
                if (symtab_idx !=
522
 
                    shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
 
517
                if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
523
518
                        fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
524
 
                              filename,
525
 
                              shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
 
519
                              filename, sechdrs[symtab_shndx_idx].sh_link,
526
520
                              symtab_idx);
527
521
                /* Fix endianness */
528
522
                for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
800
794
        ".note*",
801
795
        ".got*",
802
796
        ".toc*",
803
 
        "__discard",
804
797
        NULL
805
798
};
806
799
 
1251
1244
                return -1;
1252
1245
}
1253
1246
 
 
1247
static void print_section_list(const char * const list[20])
 
1248
{
 
1249
        const char *const *s = list;
 
1250
 
 
1251
        while (*s) {
 
1252
                fprintf(stderr, "%s", *s);
 
1253
                s++;
 
1254
                if (*s)
 
1255
                        fprintf(stderr, ", ");
 
1256
        }
 
1257
        fprintf(stderr, "\n");
 
1258
}
 
1259
 
1254
1260
/*
1255
1261
 * Print a warning about a section mismatch.
1256
1262
 * Try to find symbols near it so user can find it.
1307
1313
                break;
1308
1314
        case DATA_TO_ANY_INIT: {
1309
1315
                prl_to = sec2annotation(tosec);
1310
 
                const char *const *s = mismatch->symbol_white_list;
1311
1316
                fprintf(stderr,
1312
1317
                "The variable %s references\n"
1313
1318
                "the %s %s%s%s\n"
1315
1320
                "variable with __init* or __refdata (see linux/init.h) "
1316
1321
                "or name the variable:\n",
1317
1322
                fromsym, to, prl_to, tosym, to_p);
1318
 
                while (*s)
1319
 
                        fprintf(stderr, "%s, ", *s++);
1320
 
                fprintf(stderr, "\n");
 
1323
                print_section_list(mismatch->symbol_white_list);
1321
1324
                free(prl_to);
1322
1325
                break;
1323
1326
        }
1332
1335
                break;
1333
1336
        case DATA_TO_ANY_EXIT: {
1334
1337
                prl_to = sec2annotation(tosec);
1335
 
                const char *const *s = mismatch->symbol_white_list;
1336
1338
                fprintf(stderr,
1337
1339
                "The variable %s references\n"
1338
1340
                "the %s %s%s%s\n"
1340
1342
                "variable with __exit* (see linux/init.h) or "
1341
1343
                "name the variable:\n",
1342
1344
                fromsym, to, prl_to, tosym, to_p);
1343
 
                while (*s)
1344
 
                        fprintf(stderr, "%s, ", *s++);
1345
 
                fprintf(stderr, "\n");
 
1345
                print_section_list(mismatch->symbol_white_list);
1346
1346
                free(prl_to);
1347
1347
                break;
1348
1348
        }
1442
1442
                                    Elf_Shdr *sechdr, Elf_Rela *r)
1443
1443
{
1444
1444
        Elf_Shdr *sechdrs = elf->sechdrs;
1445
 
        int section = shndx2secindex(sechdr->sh_info);
 
1445
        int section = sechdr->sh_info;
1446
1446
 
1447
1447
        return (void *)elf->hdr + sechdrs[section].sh_offset +
1448
1448
                r->r_offset;
1643
1643
        }
1644
1644
}
1645
1645
 
1646
 
static void get_markers(struct elf_info *info, struct module *mod)
1647
 
{
1648
 
        const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
1649
 
        const char *strings = (const char *) info->hdr + sh->sh_offset;
1650
 
        const Elf_Sym *sym, *first_sym, *last_sym;
1651
 
        size_t n;
1652
 
 
1653
 
        if (!info->markers_strings_sec)
1654
 
                return;
1655
 
 
1656
 
        /*
1657
 
         * First count the strings.  We look for all the symbols defined
1658
 
         * in the __markers_strings section named __mstrtab_*.  For
1659
 
         * these local names, the compiler puts a random .NNN suffix on,
1660
 
         * so the names don't correspond exactly.
1661
 
         */
1662
 
        first_sym = last_sym = NULL;
1663
 
        n = 0;
1664
 
        for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
1665
 
                if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1666
 
                    sym->st_shndx == info->markers_strings_sec &&
1667
 
                    !strncmp(info->strtab + sym->st_name,
1668
 
                             "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1669
 
                        if (first_sym == NULL)
1670
 
                                first_sym = sym;
1671
 
                        last_sym = sym;
1672
 
                        ++n;
1673
 
                }
1674
 
 
1675
 
        if (n == 0)
1676
 
                return;
1677
 
 
1678
 
        /*
1679
 
         * Now collect each name and format into a line for the output.
1680
 
         * Lines look like:
1681
 
         *      marker_name     vmlinux marker %s format %d
1682
 
         * The format string after the second \t can use whitespace.
1683
 
         */
1684
 
        mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
1685
 
        mod->nmarkers = n;
1686
 
 
1687
 
        n = 0;
1688
 
        for (sym = first_sym; sym <= last_sym; sym++)
1689
 
                if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1690
 
                    sym->st_shndx == info->markers_strings_sec &&
1691
 
                    !strncmp(info->strtab + sym->st_name,
1692
 
                             "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1693
 
                        const char *name = strings + sym->st_value;
1694
 
                        const char *fmt = strchr(name, '\0') + 1;
1695
 
                        char *line = NULL;
1696
 
                        asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1697
 
                        NOFAIL(line);
1698
 
                        mod->markers[n++] = line;
1699
 
                }
1700
 
}
1701
 
 
1702
1646
static void read_symbols(char *modname)
1703
1647
{
1704
1648
        const char *symname;
1754
1698
                get_src_version(modname, mod->srcversion,
1755
1699
                                sizeof(mod->srcversion)-1);
1756
1700
 
1757
 
        get_markers(&info, mod);
1758
 
 
1759
1701
        parse_elf_finish(&info);
1760
1702
 
1761
1703
        /* Our trick to get versioning for module struct etc. - it's
2110
2052
        write_if_changed(&buf, fname);
2111
2053
}
2112
2054
 
2113
 
static void add_marker(struct module *mod, const char *name, const char *fmt)
2114
 
{
2115
 
        char *line = NULL;
2116
 
        asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
2117
 
        NOFAIL(line);
2118
 
 
2119
 
        mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
2120
 
                                                     sizeof mod->markers[0])));
2121
 
        mod->markers[mod->nmarkers++] = line;
2122
 
}
2123
 
 
2124
 
static void read_markers(const char *fname)
2125
 
{
2126
 
        unsigned long size, pos = 0;
2127
 
        void *file = grab_file(fname, &size);
2128
 
        char *line;
2129
 
 
2130
 
        if (!file)              /* No old markers, silently ignore */
2131
 
                return;
2132
 
 
2133
 
        while ((line = get_next_line(&pos, file, size))) {
2134
 
                char *marker, *modname, *fmt;
2135
 
                struct module *mod;
2136
 
 
2137
 
                marker = line;
2138
 
                modname = strchr(marker, '\t');
2139
 
                if (!modname)
2140
 
                        goto fail;
2141
 
                *modname++ = '\0';
2142
 
                fmt = strchr(modname, '\t');
2143
 
                if (!fmt)
2144
 
                        goto fail;
2145
 
                *fmt++ = '\0';
2146
 
                if (*marker == '\0' || *modname == '\0')
2147
 
                        goto fail;
2148
 
 
2149
 
                mod = find_module(modname);
2150
 
                if (!mod) {
2151
 
                        mod = new_module(modname);
2152
 
                        mod->skip = 1;
2153
 
                }
2154
 
                if (is_vmlinux(modname)) {
2155
 
                        have_vmlinux = 1;
2156
 
                        mod->skip = 0;
2157
 
                }
2158
 
 
2159
 
                if (!mod->skip)
2160
 
                        add_marker(mod, marker, fmt);
2161
 
        }
2162
 
        release_file(file, size);
2163
 
        return;
2164
 
fail:
2165
 
        fatal("parse error in markers list file\n");
2166
 
}
2167
 
 
2168
 
static int compare_strings(const void *a, const void *b)
2169
 
{
2170
 
        return strcmp(*(const char **) a, *(const char **) b);
2171
 
}
2172
 
 
2173
 
static void write_markers(const char *fname)
2174
 
{
2175
 
        struct buffer buf = { };
2176
 
        struct module *mod;
2177
 
        size_t i;
2178
 
 
2179
 
        for (mod = modules; mod; mod = mod->next)
2180
 
                if ((!external_module || !mod->skip) && mod->markers != NULL) {
2181
 
                        /*
2182
 
                         * Sort the strings so we can skip duplicates when
2183
 
                         * we write them out.
2184
 
                         */
2185
 
                        qsort(mod->markers, mod->nmarkers,
2186
 
                              sizeof mod->markers[0], &compare_strings);
2187
 
                        for (i = 0; i < mod->nmarkers; ++i) {
2188
 
                                char *line = mod->markers[i];
2189
 
                                buf_write(&buf, line, strlen(line));
2190
 
                                while (i + 1 < mod->nmarkers &&
2191
 
                                       !strcmp(mod->markers[i],
2192
 
                                               mod->markers[i + 1]))
2193
 
                                        free(mod->markers[i++]);
2194
 
                                free(mod->markers[i]);
2195
 
                        }
2196
 
                        free(mod->markers);
2197
 
                        mod->markers = NULL;
2198
 
                }
2199
 
 
2200
 
        write_if_changed(&buf, fname);
2201
 
}
2202
 
 
2203
2055
struct ext_sym_list {
2204
2056
        struct ext_sym_list *next;
2205
2057
        const char *file;
2211
2063
        struct buffer buf = { };
2212
2064
        char *kernel_read = NULL, *module_read = NULL;
2213
2065
        char *dump_write = NULL;
2214
 
        char *markers_read = NULL;
2215
 
        char *markers_write = NULL;
2216
2066
        int opt;
2217
2067
        int err;
2218
2068
        struct ext_sym_list *extsym_iter;
2256
2106
                case 'w':
2257
2107
                        warn_unresolved = 1;
2258
2108
                        break;
2259
 
                        case 'M':
2260
 
                                markers_write = optarg;
2261
 
                                break;
2262
 
                        case 'K':
2263
 
                                markers_read = optarg;
2264
 
                                break;
2265
2109
                default:
2266
2110
                        exit(1);
2267
2111
                }
2316
2160
                     "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
2317
2161
                     sec_mismatch_count);
2318
2162
 
2319
 
        if (markers_read)
2320
 
                read_markers(markers_read);
2321
 
 
2322
 
        if (markers_write)
2323
 
                write_markers(markers_write);
2324
 
 
2325
2163
        return err;
2326
2164
}