From: Sunil N. <su...@su...> - 2012-04-12 10:54:25
|
Here is an attempt to implement solution for this ticket. Tested with limited knowledge about elf. Index: readelf.c =================================================================== --- readelf.c (revision 2487) +++ readelf.c (working copy) @@ -118,6 +118,7 @@ size_t sn; /* section index */ #define HEX_DUMP 0x0001 #define STR_DUMP 0x0002 + const char *sname; /* section name */ int op; /* dump op type */ STAILQ_ENTRY(dumpop) dumpop_list; }; @@ -196,6 +197,7 @@ }; static void add_dumpop(struct readelf *re, size_t sn, int op); +static void addstr_dumpop(struct readelf *re, const char *sname, int op); static const char *aeabi_adv_simd_arch(uint64_t simd); static const char *aeabi_align_needed(uint64_t an); static const char *aeabi_align_preserved(uint64_t ap); @@ -270,6 +272,7 @@ static void dump_verneed(struct readelf *re, int dump); static void dump_versym(struct readelf *re); static struct dumpop *find_dumpop(struct readelf *re, size_t sn, int op); +static struct dumpop *findstr_dumpop(struct readelf *re, const char *sname, int op); static const char *get_string(struct readelf *re, int strtab, size_t off); static const char *get_symbol_name(struct readelf *re, int symtab, int i); static uint64_t get_symbol_value(struct readelf *re, int symtab, int i); @@ -5961,7 +5964,8 @@ int i, j, elferr, found; for (i = 1; (size_t) i < re->shnum; i++) { - if (find_dumpop(re, (size_t) i, STR_DUMP) == NULL) + if ((find_dumpop(re, (size_t) i, STR_DUMP) == NULL) && + (findstr_dumpop(re, re->sl[i].name, STR_DUMP) == NULL)) continue; s = &re->sl[i]; (void) elf_errno(); @@ -6314,12 +6318,28 @@ if ((d = malloc(sizeof(*d))) == NULL) err(EXIT_FAILURE, "malloc failed"); d->sn = sn; + d->sname = NULL; d->op = op; STAILQ_INSERT_TAIL(&re->v_dumpop, d, dumpop_list); } else d->op |= op; } +static void +addstr_dumpop(struct readelf *re, const char *sname, int op) +{ + struct dumpop *d; + + if ((d = findstr_dumpop(re, sname, 0)) == NULL) { + if ((d = malloc(sizeof(*d))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + d->sname = sname; + d->op = op; + STAILQ_INSERT_TAIL(&re->v_dumpop, d, dumpop_list); + } else + d->op |= op; +} + static struct dumpop * find_dumpop(struct readelf *re, size_t sn, int op) { @@ -6333,6 +6353,19 @@ return (NULL); } +static struct dumpop * +findstr_dumpop(struct readelf *re, const char *sname, int op) +{ + struct dumpop *d; + + STAILQ_FOREACH(d, &re->v_dumpop, dumpop_list) { + if ( d->sname && (strcmp(d->sname, sname) == 0) && + (op == 0 || op & d->op)) + return (d); + } + + return (NULL); +} static struct { const char *ln; char sn; @@ -6626,6 +6659,7 @@ struct readelf *re, re_storage; unsigned long sn; int opt, i; + char *ep; re = &re_storage; memset(re, 0, sizeof(*re)); @@ -6682,7 +6716,11 @@ break; case 'p': re->options |= RE_P; - sn = strtoul(optarg, NULL, 10); + sn = strtoul(optarg, &ep, 10); + if (optarg[0] == '\0' || *ep != '\0') { + addstr_dumpop(re, optarg, STR_DUMP); + break; + } add_dumpop(re, (size_t) sn, STR_DUMP); break; case 'r': |