rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <bio.h> |
| 4 | #include <mach.h> |
| 5 | #include "elf.h" |
| 6 | #include "stabs.h" |
| 7 | |
| 8 | void |
| 9 | usage(void) |
| 10 | { |
| 11 | fprint(2, "usage: elf file list\n"); |
| 12 | fprint(2, " elf file syms\n"); |
| 13 | fprint(2, " elf file prog n\n"); |
| 14 | fprint(2, " elf file sect n\n"); |
| 15 | exits("usage"); |
| 16 | } |
| 17 | |
| 18 | void |
| 19 | main(int argc, char **argv) |
| 20 | { |
| 21 | int i, n, nn; |
| 22 | char buf[512]; |
| 23 | ulong off, len; |
| 24 | Elf *elf; |
| 25 | ElfProg *p; |
| 26 | ElfSect *s; |
| 27 | |
| 28 | ARGBEGIN{ |
| 29 | default: |
| 30 | usage(); |
| 31 | }ARGEND |
| 32 | |
| 33 | if(argc < 2) |
| 34 | usage(); |
| 35 | |
| 36 | if((elf = elfopen(argv[0])) == nil) |
| 37 | sysfatal("elfopen %s: %r", argv[0]); |
| 38 | |
| 39 | if(strcmp(argv[1], "syms") == 0){ |
| 40 | ElfSym sym; |
| 41 | for(i=0; elfsym(elf, i, &sym) >= 0; i++){ |
| 42 | print("%s 0x%lux +%lud bind %d type %d other %d shndx 0x%ux\n", |
| 43 | sym.name, (ulong)sym.value, (ulong)sym.size, |
| 44 | sym.bind, sym.type, sym.other, (uint)sym.shndx); |
| 45 | } |
| 46 | } |
| 47 | else if(strcmp(argv[1], "stabs") == 0){ |
| 48 | ElfSect *s1, *s2; |
| 49 | Stab stabs; |
| 50 | StabSym sym; |
| 51 | |
| 52 | if((s1 = elfsection(elf, ".stab")) == nil) |
| 53 | sysfatal("no stabs"); |
| 54 | if(s1->link==0 || s1->link >= elf->nsect) |
| 55 | sysfatal("bad stabstr %d", s1->link); |
| 56 | s2 = &elf->sect[s1->link]; |
| 57 | if(elfmap(elf, s1) < 0 || elfmap(elf, s2) < 0) |
| 58 | sysfatal("elfmap"); |
| 59 | stabs.stabbase = s1->base; |
| 60 | stabs.stabsize = s1->size; |
| 61 | stabs.strbase = s2->base; |
| 62 | stabs.strsize = s2->size; |
| 63 | stabs.e2 = elf->hdr.e2; |
| 64 | stabs.e4 = elf->hdr.e4; |
| 65 | print("%ud %ud\n", stabs.stabsize, stabs.strsize); |
| 66 | for(i=0; stabsym(&stabs, i, &sym) >= 0; i++) |
| 67 | print("%s type 0x%x other %d desc %d value 0x%lux\n", |
| 68 | sym.name, sym.type, sym.other, (int)sym.desc, (ulong)sym.value); |
| 69 | fprint(2, "err at %d: %r\n", i); |
| 70 | } |
| 71 | else if(strcmp(argv[1], "list") == 0){ |
| 72 | if(argc != 2) |
| 73 | usage(); |
| 74 | print("elf %s %s v%d entry 0x%08lux phoff 0x%lux shoff 0x%lux flags 0x%lux\n", |
| 75 | elftype(elf->hdr.type), elfmachine(elf->hdr.machine), |
| 76 | elf->hdr.version, elf->hdr.entry, elf->hdr.phoff, elf->hdr.shoff, |
| 77 | elf->hdr.flags); |
| 78 | print("\tehsize %d phentsize %d phnum %d shentsize %d shnum %d shstrndx %d\n", |
| 79 | elf->hdr.ehsize, elf->hdr.phentsize, elf->hdr.phnum, elf->hdr.shentsize, |
| 80 | elf->hdr.shnum, elf->hdr.shstrndx); |
| 81 | for(i=0; i<elf->nprog; i++){ |
| 82 | p = &elf->prog[i]; |
| 83 | print("prog %d type %d offset 0x%08lux vaddr 0x%08lux paddr 0x%08lux filesz 0x%08lux memsz 0x%08lux flags 0x%08lux align 0x%08lux\n", |
| 84 | i, p->type, p->offset, p->vaddr, p->paddr, |
| 85 | p->filesz, p->memsz, p->flags, p->align); |
| 86 | } |
| 87 | for(i=0; i<elf->nsect; i++){ |
| 88 | s = &elf->sect[i]; |
| 89 | print("sect %d %s type %d flags 0x%lux addr 0x%08lux offset 0x%08lux size 0x%08lux link 0x%lux info 0x%lux align 0x%lux entsize 0x%lux\n", |
| 90 | i, s->name, s->type, s->flags, s->addr, s->offset, s->size, s->link, s->info, |
| 91 | s->align, s->entsize); |
| 92 | } |
| 93 | } |
| 94 | else if(strcmp(argv[1], "prog") == 0){ |
| 95 | if(argc != 3) |
| 96 | usage(); |
| 97 | i = atoi(argv[2]); |
| 98 | if(i < 0 || i >= elf->nprog) |
| 99 | sysfatal("bad prog number"); |
| 100 | off = elf->prog[i].offset; |
| 101 | len = elf->prog[i].filesz; |
| 102 | fprint(2, "prog %d offset 0x%lux size 0x%lux\n", i, off, len); |
| 103 | copy: |
| 104 | seek(elf->fd, off, 0); |
| 105 | for(n=0; n<len; n+=nn){ |
| 106 | nn = sizeof buf; |
| 107 | if(nn > len-n) |
| 108 | nn = len-n; |
| 109 | nn = read(elf->fd, buf, nn); |
| 110 | if(nn == 0) |
| 111 | break; |
| 112 | if(nn < 0) |
| 113 | sysfatal("read error"); |
| 114 | write(1, buf, nn); |
| 115 | } |
| 116 | if(n < len) |
| 117 | fprint(2, "early eof\n"); |
| 118 | } |
| 119 | else if(strcmp(argv[1], "sect") == 0){ |
| 120 | if(argc != 3) |
| 121 | usage(); |
| 122 | i = atoi(argv[2]); |
| 123 | if(i < 0 || i >= elf->nsect) |
| 124 | sysfatal("bad section number"); |
| 125 | off = elf->sect[i].offset; |
| 126 | len = elf->sect[i].size; |
| 127 | fprint(2, "section %d offset 0x%lux size 0x%lux\n", i, off, len); |
| 128 | goto copy; |
| 129 | } |
| 130 | else |
| 131 | usage(); |
| 132 | exits(0); |
| 133 | } |