Deleted Added
full compact
readelf.c (285841) readelf.c (285845)
1/*-
2 * Copyright (c) 2009-2015 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/param.h>
28#include <sys/queue.h>
29#include <ar.h>
1/*-
2 * Copyright (c) 2009-2015 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/param.h>
28#include <sys/queue.h>
29#include <ar.h>
30#include <assert.h>
30#include <ctype.h>
31#include <dwarf.h>
32#include <err.h>
33#include <fcntl.h>
34#include <gelf.h>
35#include <getopt.h>
36#include <libdwarf.h>
37#include <libelftc.h>

--- 271 unchanged lines hidden (view full) ---

309static void dump_ver(struct readelf *re);
310static void dump_verdef(struct readelf *re, int dump);
311static void dump_verneed(struct readelf *re, int dump);
312static void dump_versym(struct readelf *re);
313static const char *dwarf_reg(unsigned int mach, unsigned int reg);
314static const char *dwarf_regname(struct readelf *re, unsigned int num);
315static struct dumpop *find_dumpop(struct readelf *re, size_t si,
316 const char *sn, int op, int t);
31#include <ctype.h>
32#include <dwarf.h>
33#include <err.h>
34#include <fcntl.h>
35#include <gelf.h>
36#include <getopt.h>
37#include <libdwarf.h>
38#include <libelftc.h>

--- 271 unchanged lines hidden (view full) ---

310static void dump_ver(struct readelf *re);
311static void dump_verdef(struct readelf *re, int dump);
312static void dump_verneed(struct readelf *re, int dump);
313static void dump_versym(struct readelf *re);
314static const char *dwarf_reg(unsigned int mach, unsigned int reg);
315static const char *dwarf_regname(struct readelf *re, unsigned int num);
316static struct dumpop *find_dumpop(struct readelf *re, size_t si,
317 const char *sn, int op, int t);
318static int get_ent_count(struct section *s, int *ent_count);
317static char *get_regoff_str(struct readelf *re, Dwarf_Half reg,
318 Dwarf_Addr off);
319static const char *get_string(struct readelf *re, int strtab, size_t off);
320static const char *get_symbol_name(struct readelf *re, int symtab, int i);
321static uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
322static void load_sections(struct readelf *re);
323static const char *mips_abi_fp(uint64_t fp);
324static const char *note_type(const char *note_name, unsigned int et,

--- 2571 unchanged lines hidden (view full) ---

2896#undef S_HDRL
2897#undef ST_HDR
2898#undef ST_HDRL
2899#undef S_CT
2900#undef ST_CT
2901#undef ST_CTL
2902}
2903
319static char *get_regoff_str(struct readelf *re, Dwarf_Half reg,
320 Dwarf_Addr off);
321static const char *get_string(struct readelf *re, int strtab, size_t off);
322static const char *get_symbol_name(struct readelf *re, int symtab, int i);
323static uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
324static void load_sections(struct readelf *re);
325static const char *mips_abi_fp(uint64_t fp);
326static const char *note_type(const char *note_name, unsigned int et,

--- 2571 unchanged lines hidden (view full) ---

2898#undef S_HDRL
2899#undef ST_HDR
2900#undef ST_HDRL
2901#undef S_CT
2902#undef ST_CT
2903#undef ST_CTL
2904}
2905
2906/*
2907 * Return number of entries in the given section. We'd prefer ent_count be a
2908 * size_t *, but libelf APIs already use int for section indices.
2909 */
2910static int
2911get_ent_count(struct section *s, int *ent_count)
2912{
2913 if (s->entsize == 0) {
2914 warnx("section %s has entry size 0", s->name);
2915 return (0);
2916 } else if (s->sz / s->entsize > INT_MAX) {
2917 warnx("section %s has invalid section count", s->name);
2918 return (0);
2919 }
2920 *ent_count = (int)(s->sz / s->entsize);
2921 return (1);
2922}
2923
2904static void
2905dump_dynamic(struct readelf *re)
2906{
2907 GElf_Dyn dyn;
2908 Elf_Data *d;
2909 struct section *s;
2910 int elferr, i, is_dynamic, j, jmax, nentries;
2911

--- 12 unchanged lines hidden (view full) ---

2924 }
2925 if (d->d_size <= 0)
2926 continue;
2927
2928 is_dynamic = 1;
2929
2930 /* Determine the actual number of table entries. */
2931 nentries = 0;
2924static void
2925dump_dynamic(struct readelf *re)
2926{
2927 GElf_Dyn dyn;
2928 Elf_Data *d;
2929 struct section *s;
2930 int elferr, i, is_dynamic, j, jmax, nentries;
2931

--- 12 unchanged lines hidden (view full) ---

2944 }
2945 if (d->d_size <= 0)
2946 continue;
2947
2948 is_dynamic = 1;
2949
2950 /* Determine the actual number of table entries. */
2951 nentries = 0;
2932 jmax = (int) (s->sz / s->entsize);
2933
2952 if (!get_ent_count(s, &jmax))
2953 continue;
2934 for (j = 0; j < jmax; j++) {
2935 if (gelf_getdyn(d, j, &dyn) != &dyn) {
2936 warnx("gelf_getdyn failed: %s",
2937 elf_errmsg(-1));
2938 continue;
2939 }
2940 nentries ++;
2941 if (dyn.d_tag == DT_NULL)

--- 229 unchanged lines hidden (view full) ---

3171 if (re->ec == ELFCLASS32)
3172 printf("%-8s %-8s %-19s %-8s %s\n", REL_HDR);
3173 else {
3174 if (re->options & RE_WW)
3175 printf("%-16s %-16s %-24s %-16s %s\n", REL_HDR);
3176 else
3177 printf("%-12s %-12s %-19s %-16s %s\n", REL_HDR);
3178 }
2954 for (j = 0; j < jmax; j++) {
2955 if (gelf_getdyn(d, j, &dyn) != &dyn) {
2956 warnx("gelf_getdyn failed: %s",
2957 elf_errmsg(-1));
2958 continue;
2959 }
2960 nentries ++;
2961 if (dyn.d_tag == DT_NULL)

--- 229 unchanged lines hidden (view full) ---

3191 if (re->ec == ELFCLASS32)
3192 printf("%-8s %-8s %-19s %-8s %s\n", REL_HDR);
3193 else {
3194 if (re->options & RE_WW)
3195 printf("%-16s %-16s %-24s %-16s %s\n", REL_HDR);
3196 else
3197 printf("%-12s %-12s %-19s %-16s %s\n", REL_HDR);
3198 }
3179 len = d->d_size / s->entsize;
3199 assert(d->d_size == s->sz);
3200 if (!get_ent_count(s, &len))
3201 return;
3180 for (i = 0; i < len; i++) {
3181 if (gelf_getrel(d, i, &r) != &r) {
3182 warnx("gelf_getrel failed: %s", elf_errmsg(-1));
3183 continue;
3184 }
3185 if (s->link >= re->shnum) {
3186 warnx("invalid section link index %u", s->link);
3187 continue;

--- 39 unchanged lines hidden (view full) ---

3227 if (re->ec == ELFCLASS32)
3228 printf("%-8s %-8s %-19s %-8s %s\n", RELA_HDR);
3229 else {
3230 if (re->options & RE_WW)
3231 printf("%-16s %-16s %-24s %-16s %s\n", RELA_HDR);
3232 else
3233 printf("%-12s %-12s %-19s %-16s %s\n", RELA_HDR);
3234 }
3202 for (i = 0; i < len; i++) {
3203 if (gelf_getrel(d, i, &r) != &r) {
3204 warnx("gelf_getrel failed: %s", elf_errmsg(-1));
3205 continue;
3206 }
3207 if (s->link >= re->shnum) {
3208 warnx("invalid section link index %u", s->link);
3209 continue;

--- 39 unchanged lines hidden (view full) ---

3249 if (re->ec == ELFCLASS32)
3250 printf("%-8s %-8s %-19s %-8s %s\n", RELA_HDR);
3251 else {
3252 if (re->options & RE_WW)
3253 printf("%-16s %-16s %-24s %-16s %s\n", RELA_HDR);
3254 else
3255 printf("%-12s %-12s %-19s %-16s %s\n", RELA_HDR);
3256 }
3235 len = d->d_size / s->entsize;
3257 assert(d->d_size == s->sz);
3258 if (!get_ent_count(s, &len))
3259 return;
3236 for (i = 0; i < len; i++) {
3237 if (gelf_getrela(d, i, &r) != &r) {
3238 warnx("gelf_getrel failed: %s", elf_errmsg(-1));
3239 continue;
3240 }
3241 if (s->link >= re->shnum) {
3242 warnx("invalid section link index %u", s->link);
3243 continue;

--- 48 unchanged lines hidden (view full) ---

3292
3293static void
3294dump_symtab(struct readelf *re, int i)
3295{
3296 struct section *s;
3297 Elf_Data *d;
3298 GElf_Sym sym;
3299 const char *name;
3260 for (i = 0; i < len; i++) {
3261 if (gelf_getrela(d, i, &r) != &r) {
3262 warnx("gelf_getrel failed: %s", elf_errmsg(-1));
3263 continue;
3264 }
3265 if (s->link >= re->shnum) {
3266 warnx("invalid section link index %u", s->link);
3267 continue;

--- 48 unchanged lines hidden (view full) ---

3316
3317static void
3318dump_symtab(struct readelf *re, int i)
3319{
3320 struct section *s;
3321 Elf_Data *d;
3322 GElf_Sym sym;
3323 const char *name;
3300 int elferr, stab, j;
3324 int elferr, stab, j, len;
3301
3302 s = &re->sl[i];
3303 stab = s->link;
3304 (void) elf_errno();
3305 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
3306 elferr = elf_errno();
3307 if (elferr != 0)
3308 warnx("elf_getdata failed: %s", elf_errmsg(elferr));
3309 return;
3310 }
3311 if (d->d_size <= 0)
3312 return;
3325
3326 s = &re->sl[i];
3327 stab = s->link;
3328 (void) elf_errno();
3329 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
3330 elferr = elf_errno();
3331 if (elferr != 0)
3332 warnx("elf_getdata failed: %s", elf_errmsg(elferr));
3333 return;
3334 }
3335 if (d->d_size <= 0)
3336 return;
3337 if (!get_ent_count(s, &len))
3338 return;
3313 printf("Symbol table (%s)", s->name);
3339 printf("Symbol table (%s)", s->name);
3314 printf(" contains %ju entries:\n", s->sz / s->entsize);
3340 printf(" contains %d entries:\n", len);
3315 printf("%7s%9s%14s%5s%8s%6s%9s%5s\n", "Num:", "Value", "Size", "Type",
3316 "Bind", "Vis", "Ndx", "Name");
3317
3341 printf("%7s%9s%14s%5s%8s%6s%9s%5s\n", "Num:", "Value", "Size", "Type",
3342 "Bind", "Vis", "Ndx", "Name");
3343
3318 for (j = 0; (uint64_t)j < s->sz / s->entsize; j++) {
3344 for (j = 0; j < len; j++) {
3319 if (gelf_getsym(d, j, &sym) != &sym) {
3320 warnx("gelf_getsym failed: %s", elf_errmsg(-1));
3321 continue;
3322 }
3323 printf("%6d:", j);
3324 printf(" %16.16jx", (uintmax_t)sym.st_value);
3325 printf(" %5ju", sym.st_size);
3326 printf(" %-7s", st_type(GELF_ST_TYPE(sym.st_info)));

--- 21 unchanged lines hidden (view full) ---

3348
3349static void
3350dump_symtabs(struct readelf *re)
3351{
3352 GElf_Dyn dyn;
3353 Elf_Data *d;
3354 struct section *s;
3355 uint64_t dyn_off;
3345 if (gelf_getsym(d, j, &sym) != &sym) {
3346 warnx("gelf_getsym failed: %s", elf_errmsg(-1));
3347 continue;
3348 }
3349 printf("%6d:", j);
3350 printf(" %16.16jx", (uintmax_t)sym.st_value);
3351 printf(" %5ju", sym.st_size);
3352 printf(" %-7s", st_type(GELF_ST_TYPE(sym.st_info)));

--- 21 unchanged lines hidden (view full) ---

3374
3375static void
3376dump_symtabs(struct readelf *re)
3377{
3378 GElf_Dyn dyn;
3379 Elf_Data *d;
3380 struct section *s;
3381 uint64_t dyn_off;
3356 int elferr, i;
3382 int elferr, i, len;
3357
3358 /*
3359 * If -D is specified, only dump the symbol table specified by
3360 * the DT_SYMTAB entry in the .dynamic section.
3361 */
3362 dyn_off = 0;
3363 if (re->options & RE_DD) {
3364 s = NULL;

--- 8 unchanged lines hidden (view full) ---

3373 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
3374 elferr = elf_errno();
3375 if (elferr != 0)
3376 warnx("elf_getdata failed: %s", elf_errmsg(-1));
3377 return;
3378 }
3379 if (d->d_size <= 0)
3380 return;
3383
3384 /*
3385 * If -D is specified, only dump the symbol table specified by
3386 * the DT_SYMTAB entry in the .dynamic section.
3387 */
3388 dyn_off = 0;
3389 if (re->options & RE_DD) {
3390 s = NULL;

--- 8 unchanged lines hidden (view full) ---

3399 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
3400 elferr = elf_errno();
3401 if (elferr != 0)
3402 warnx("elf_getdata failed: %s", elf_errmsg(-1));
3403 return;
3404 }
3405 if (d->d_size <= 0)
3406 return;
3407 if (!get_ent_count(s, &len))
3408 return;
3381
3409
3382 for (i = 0; (uint64_t)i < s->sz / s->entsize; i++) {
3410 for (i = 0; i < len; i++) {
3383 if (gelf_getdyn(d, i, &dyn) != &dyn) {
3384 warnx("gelf_getdyn failed: %s", elf_errmsg(-1));
3385 continue;
3386 }
3387 if (dyn.d_tag == DT_SYMTAB) {
3388 dyn_off = dyn.d_un.d_val;
3389 break;
3390 }

--- 171 unchanged lines hidden (view full) ---

3562 return;
3563 }
3564 buf = d->d_buf;
3565 nbucket = buf[0];
3566 symndx = buf[1];
3567 maskwords = buf[2];
3568 buf += 4;
3569 ds = &re->sl[s->link];
3411 if (gelf_getdyn(d, i, &dyn) != &dyn) {
3412 warnx("gelf_getdyn failed: %s", elf_errmsg(-1));
3413 continue;
3414 }
3415 if (dyn.d_tag == DT_SYMTAB) {
3416 dyn_off = dyn.d_un.d_val;
3417 break;
3418 }

--- 171 unchanged lines hidden (view full) ---

3590 return;
3591 }
3592 buf = d->d_buf;
3593 nbucket = buf[0];
3594 symndx = buf[1];
3595 maskwords = buf[2];
3596 buf += 4;
3597 ds = &re->sl[s->link];
3570 dynsymcount = ds->sz / ds->entsize;
3598 if (!get_ent_count(ds, &dynsymcount))
3599 return;
3571 nchain = dynsymcount - symndx;
3572 if (d->d_size != 4 * sizeof(uint32_t) + maskwords *
3573 (re->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) +
3574 (nbucket + nchain) * sizeof(uint32_t)) {
3575 warnx("Malformed .gnu.hash section");
3576 return;
3577 }
3578 bucket = buf + (re->ec == ELFCLASS32 ? maskwords : maskwords * 2);

--- 412 unchanged lines hidden (view full) ---

3991dump_liblist(struct readelf *re)
3992{
3993 struct section *s;
3994 struct tm *t;
3995 time_t ti;
3996 char tbuf[20];
3997 Elf_Data *d;
3998 Elf_Lib *lib;
3600 nchain = dynsymcount - symndx;
3601 if (d->d_size != 4 * sizeof(uint32_t) + maskwords *
3602 (re->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) +
3603 (nbucket + nchain) * sizeof(uint32_t)) {
3604 warnx("Malformed .gnu.hash section");
3605 return;
3606 }
3607 bucket = buf + (re->ec == ELFCLASS32 ? maskwords : maskwords * 2);

--- 412 unchanged lines hidden (view full) ---

4020dump_liblist(struct readelf *re)
4021{
4022 struct section *s;
4023 struct tm *t;
4024 time_t ti;
4025 char tbuf[20];
4026 Elf_Data *d;
4027 Elf_Lib *lib;
3999 int i, j, k, elferr, first;
4028 int i, j, k, elferr, first, len;
4000
4001 for (i = 0; (size_t) i < re->shnum; i++) {
4002 s = &re->sl[i];
4003 if (s->type != SHT_GNU_LIBLIST)
4004 continue;
4005 (void) elf_errno();
4006 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
4007 elferr = elf_errno();
4008 if (elferr != 0)
4009 warnx("elf_getdata failed: %s",
4010 elf_errmsg(elferr));
4011 continue;
4012 }
4013 if (d->d_size <= 0)
4014 continue;
4015 lib = d->d_buf;
4029
4030 for (i = 0; (size_t) i < re->shnum; i++) {
4031 s = &re->sl[i];
4032 if (s->type != SHT_GNU_LIBLIST)
4033 continue;
4034 (void) elf_errno();
4035 if ((d = elf_getdata(s->scn, NULL)) == NULL) {
4036 elferr = elf_errno();
4037 if (elferr != 0)
4038 warnx("elf_getdata failed: %s",
4039 elf_errmsg(elferr));
4040 continue;
4041 }
4042 if (d->d_size <= 0)
4043 continue;
4044 lib = d->d_buf;
4045 if (!get_ent_count(s, &len))
4046 continue;
4016 printf("\nLibrary list section '%s' ", s->name);
4047 printf("\nLibrary list section '%s' ", s->name);
4017 printf("contains %ju entries:\n", s->sz / s->entsize);
4048 printf("contains %d entries:\n", len);
4018 printf("%12s%24s%18s%10s%6s\n", "Library", "Time Stamp",
4019 "Checksum", "Version", "Flags");
4020 for (j = 0; (uint64_t) j < s->sz / s->entsize; j++) {
4021 printf("%3d: ", j);
4022 printf("%-20.20s ",
4023 get_string(re, s->link, lib->l_name));
4024 ti = lib->l_time_stamp;
4025 t = gmtime(&ti);

--- 368 unchanged lines hidden (view full) ---

4394 }
4395 }
4396}
4397
4398static void
4399dump_mips_reginfo(struct readelf *re, struct section *s)
4400{
4401 Elf_Data *d;
4049 printf("%12s%24s%18s%10s%6s\n", "Library", "Time Stamp",
4050 "Checksum", "Version", "Flags");
4051 for (j = 0; (uint64_t) j < s->sz / s->entsize; j++) {
4052 printf("%3d: ", j);
4053 printf("%-20.20s ",
4054 get_string(re, s->link, lib->l_name));
4055 ti = lib->l_time_stamp;
4056 t = gmtime(&ti);

--- 368 unchanged lines hidden (view full) ---

4425 }
4426 }
4427}
4428
4429static void
4430dump_mips_reginfo(struct readelf *re, struct section *s)
4431{
4432 Elf_Data *d;
4402 int elferr;
4433 int elferr, len;
4403
4404 (void) elf_errno();
4405 if ((d = elf_rawdata(s->scn, NULL)) == NULL) {
4406 elferr = elf_errno();
4407 if (elferr != 0)
4408 warnx("elf_rawdata failed: %s",
4409 elf_errmsg(elferr));
4410 return;
4411 }
4412 if (d->d_size <= 0)
4413 return;
4434
4435 (void) elf_errno();
4436 if ((d = elf_rawdata(s->scn, NULL)) == NULL) {
4437 elferr = elf_errno();
4438 if (elferr != 0)
4439 warnx("elf_rawdata failed: %s",
4440 elf_errmsg(elferr));
4441 return;
4442 }
4443 if (d->d_size <= 0)
4444 return;
4445 if (!get_ent_count(s, &len))
4446 return;
4414
4447
4415 printf("\nSection '%s' contains %ju entries:\n", s->name,
4416 s->sz / s->entsize);
4448 printf("\nSection '%s' contains %d entries:\n", s->name, len);
4417 dump_mips_odk_reginfo(re, d->d_buf, d->d_size);
4418}
4419
4420static void
4421dump_mips_options(struct readelf *re, struct section *s)
4422{
4423 Elf_Data *d;
4424 uint32_t info;

--- 3118 unchanged lines hidden ---
4449 dump_mips_odk_reginfo(re, d->d_buf, d->d_size);
4450}
4451
4452static void
4453dump_mips_options(struct readelf *re, struct section *s)
4454{
4455 Elf_Data *d;
4456 uint32_t info;

--- 3118 unchanged lines hidden ---