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 --- |