From 36dd3b2d27ac7a89754dbdbed6b81f3662e4dafb Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sat, 15 May 2021 13:56:19 -0500 Subject: Cleanup readelf. --- toys/pending/readelf.c | 193 ++++++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 108 deletions(-) diff --git a/toys/pending/readelf.c b/toys/pending/readelf.c index e6e1623f..75726ecb 100644 --- a/toys/pending/readelf.c +++ b/toys/pending/readelf.c @@ -54,8 +54,12 @@ struct ph { static long long elf_get(char **p, int len) { - long long result = ((TT.endian == 2) ? peek_be : peek_le)(*p, len); + long long result; + if (*p+len-TT.elf>TT.size) + perror_exit("Access off end: %ld[%d] of %lld\n", *p-TT.elf, len, TT.size); + + result = ((TT.endian == 2) ? peek_be : peek_le)(*p, len); *p += len; return result; } @@ -118,17 +122,15 @@ static int get_sh(unsigned i, struct sh *s) static int find_section(char *spec, struct sh *s) { char *end; - int i; + unsigned i; // Valid section number? - errno = 0; - i = strtoul(spec, &end, 0); - if (!errno && !*end && i < TT.shnum) return get_sh(i, s); + i = estrtol(spec, &end, 0); + if (!errno && !*end && iname, spec)) return 1; - } error_msg("%s: no section '%s", TT.f, spec); return 0; @@ -243,17 +245,16 @@ static void show_symbols(struct sh *table, struct sh *strtab) char *symtab = TT.elf+table->offset, *ndx; int numsym = table->size/(TT.bits ? 24 : 16), i; - if (numsym == 0) return; + if (!numsym) return; xputc('\n'); printf("Symbol table '%s' contains %d entries:\n" " Num: %*s Size Type Bind Vis Ndx Name\n", table->name, numsym, 5+8*TT.bits, "Value"); for (i=0; ioffset + st_name; if (name >= TT.elf+TT.size) name = "???"; if (!st_shndx) ndx = "UND"; else if (st_shndx==0xfff1) ndx = "ABS"; - else sprintf(ndx = toybuf, "%d", st_shndx); + else sprintf(ndx = buf, "%d", st_shndx); // TODO: look up and show any symbol versions with @ or @@. @@ -285,10 +287,11 @@ static void show_symbols(struct sh *table, struct sh *strtab) } } -static int notematch(int namesz, char **p, char *expected, int len) +static int notematch(int namesz, char **p, char *expected) { - if (namesz != len || memcmp(*p, expected, namesz)) return 0; + if (namesz!=strlen(expected)+1 || strcmp(*p, expected)) return 0; *p += namesz; + return 1; } @@ -298,44 +301,46 @@ static void show_notes(unsigned long offset, unsigned long size) if (size > TT.size || offset > TT.size-size) { printf("Bad note bounds %lu/%lu\n", offset, size); + return; } - printf(" %-20s %10s\tDescription\n", "Owner", "Data size"); + printf(" %-20s%11s\tDescription\n", "Owner", "Data size"); while (note < TT.elf+offset+size) { char *p = note, *desc; unsigned namesz=elf_int(&p), descsz=elf_int(&p), type=elf_int(&p), j=0; - if (namesz > size || descsz > size) { - error_msg("%s: bad note @%lu", TT.f, offset); - return; - } + if (namesz > size || descsz > size) + return error_msg("%s: bad note @%lu", TT.f, offset); printf(" %-20.*s 0x%08x\t", namesz, p, descsz); - if (notematch(namesz, &p, "GNU", 4)) { + if (notematch(namesz, &p, "GNU")) { if (type == 1) { printf("NT_GNU_ABI_TAG\tOS: %s, ABI: %u.%u.%u", !elf_int(&p)?"Linux":"?", elf_int(&p), elf_int(&p), elf_int(&p)), j=1; } else if (type == 3) { +// TODO should this set j=1? printf("NT_GNU_BUILD_ID\t"); for (;j=132) printf(", NDK %.64s (%.64s)", p, p+64); } else p -= 8; - } else if (notematch(namesz, &p, "CORE", 5)) { + } else if (notematch(namesz, &p, "CORE")) { if (*(desc = nt_type_core(type)) != '0') printf("%s", desc), j=1; - } else if (notematch(namesz, &p, "LINUX", 6)) { +// TODO else p -= 5? + } else if (notematch(namesz, &p, "LINUX")) { if (*(desc = nt_type_linux(type)) != '0') printf("%s", desc), j=1; +// TODO else p -= 6? } // If we didn't do custom output above, show a hex dump. if (!j) { printf("0x%x\t", type); - for (;j1 || TT.endian<1 || TT.endian>2 || hdr[6]!=1) { - error_msg("%s: bad ELF", TT.f); - return; - } + if (TT.bits<0 || TT.bits>1 || TT.endian<1 || TT.endian>2 || hdr[6]!=1) + return error_msg("%s: bad ELF", TT.f); hdr += 16; // EI_NIDENT type = elf_short(&hdr); @@ -382,7 +383,7 @@ static void scan_elf() if (FLAG(h)) { printf("ELF Header:\n"); printf(" Magic: "); - for (i=0; i<16; i++) printf("%02x%c", TT.elf[i], i==15?'\n':' '); + for (i=0; i<16; i++) printf("%02x%c", TT.elf[i], (i==15) ? '\n' : ' '); printf(" Class: ELF%d\n", TT.bits?64:32); printf(" Data: 2's complement, %s endian\n", (TT.endian==2)?"big":"little"); @@ -405,24 +406,16 @@ static void scan_elf() printf(" Number of section headers: %d\n", TT.shnum); printf(" Section header string table index: %d\n", shstrndx); } - if (TT.phoff > TT.size) { - error_msg("%s: bad phoff", TT.f); - return; - } - if (TT.shoff > TT.size) { - error_msg("%s: bad shoff", TT.f); - return; - } + if (TT.phoff > TT.size) return error_msg("%s: bad phoff", TT.f); + if (TT.shoff > TT.size) return error_msg("%s: bad shoff", TT.f); // Set up the section header string table so we can use section header names. // Core files have shstrndx == 0. TT.shstrtab = 0; TT.shstrtabsz = 0; - if (shstrndx != 0) { - if (!get_sh(shstrndx, &shstr) || shstr.type != 3 /*SHT_STRTAB*/) { - error_msg("%s: bad shstrndx", TT.f); - return; - } + if (shstrndx) { + if (!get_sh(shstrndx, &shstr) || shstr.type != 3 /*SHT_STRTAB*/) + return error_msg("%s: bad shstrndx", TT.f); TT.shstrtab = TT.elf+shstr.offset; TT.shstrtabsz = shstr.size; } @@ -431,12 +424,10 @@ static void scan_elf() if (FLAG(S)) { if (!TT.shnum) printf("\nThere are no sections in this file.\n"); else { - if (!FLAG(h)) { + if (!FLAG(h)) printf("There are %d section headers, starting at offset %#llx:\n", TT.shnum, TT.shoff); - } - printf("\n" - "Section Headers:\n" + printf("\nSection Headers:\n" " [Nr] %-17s %-15s %-*s %-6s %-6s ES Flg Lk Inf Al\n", "Name", "Type", w, "Address", "Off", "Size"); } @@ -456,48 +447,42 @@ static void scan_elf() if (FLAG(S)) { char sh_flags[12] = {}, *p = sh_flags; - for (j=0; j<12; j++) if (s.flags&(1<=' ' && *p<='~' ? *p : '.'); - xputc('\n'); - } - printf("\n"); + printf(" 0x%08lx ", offset); + for (i=0; i<16 && offset < s.size; offset++) + space -= printf("%02x%s", *p++, " "+!!(++i%4)); + printf("%*s", space, ""); + for (p -= i; i; i--, p++) putchar((*p>=' ' && *p<='~') ? *p : '.'); + xputc('\n'); } + xputc('\n'); } - if (FLAG(p)) { - if (find_section(TT.p, &s)) { - char *begin = TT.elf+s.offset, *end = begin + s.size, *p = begin; - int any = 0; + if (FLAG(p) && find_section(TT.p, &s)) { + char *begin = TT.elf+s.offset, *end = begin + s.size, *p = begin; + int any = 0; - printf("\nString dump of section '%s':\n", s.name); - for (; p < end; p++) { - if (isprint(*p)) { - printf(" [%6tx] ", p-begin); - while (p < end && isprint(*p)) putchar(*p++); - xputc('\n'); - any=1; - } + printf("\nString dump of section '%s':\n", s.name); + for (; p < end; p++) { + if (isprint(*p)) { + printf(" [%6tx] ", p-begin); + while (p < end && isprint(*p)) putchar(*p++); + xputc('\n'); + any=1; } - if (!any) printf(" No strings found in this section.\n"); - printf("\n"); } + if (!any) printf(" No strings found in this section.\n"); + xputc('\n'); } } @@ -653,7 +630,7 @@ void readelf_main(void) else if (!sb.st_size) error_msg("%s: empty", TT.f); else if (!S_ISREG(sb.st_mode)) error_msg("%s: not a regular file",TT.f); else { - TT.elf = xmmap(NULL, TT.size=sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + TT.elf = xmmap(0, TT.size=sb.st_size, PROT_READ, MAP_SHARED, fd, 0); scan_elf(); munmap(TT.elf, TT.size); } -- cgit v1.2.3