main.c (6103B)
1 2 #include <errno.h> 3 #include <limits.h> 4 #include <stdint.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 9 #include "../inc/arg.h" 10 #include "../inc/scc.h" 11 #include "../inc/myro.h" 12 13 char *argv0; 14 static char *strings; 15 static size_t strsiz; 16 17 struct obj_info { 18 char *fname; 19 FILE *fp; 20 struct myrohdr hdr; 21 fpos_t strpos; 22 fpos_t secpos; 23 fpos_t sympos; 24 fpos_t relpos; 25 fpos_t datapos; 26 }; 27 28 static char * 29 getstring(unsigned long off) 30 { 31 size_t n; 32 33 if ((int32_t) off == -1) 34 return ""; 35 if (off < SIZE_MAX) { 36 for (n = off; n < strsiz && strings[n]; ++n) 37 ; 38 if (n < strsiz) 39 return &strings[off]; 40 } 41 fprintf(stderr, "objdump: wrong string offset %lu\n", off); 42 return ""; 43 } 44 45 static int 46 printhdr(struct obj_info *obj) 47 { 48 struct myrohdr *hdr = &obj->hdr; 49 50 printf("header:\n" 51 " magic: %02x %02x %02x %02x \"%4.4s\"\n" 52 " format: %lu (\"%s\")\n" 53 " entry: %llu\n" 54 " string table size: %llu\n" 55 " section table size: %llu\n" 56 " symbol table size: %llu\n" 57 " relocation table size: %llu\n", 58 hdr->magic[0], hdr->magic[1], 59 hdr->magic[2], hdr->magic[3], 60 hdr->magic, 61 hdr->format, getstring(hdr->format), 62 hdr->entry, 63 hdr->strsize, 64 hdr->secsize, 65 hdr->symsize, 66 hdr->relsize); 67 return 0; 68 } 69 70 static int 71 printstrings(struct obj_info *obj) 72 { 73 size_t off, begin;; 74 char *s = NULL; 75 76 puts("strings:"); 77 for (off = 0; off < strsiz; off++) { 78 if (s == NULL) { 79 s = &strings[off]; 80 begin = off; 81 } 82 if (strings[off] == '\0') { 83 printf(" [%zd] \"%s\"\n", begin, s); 84 s = NULL; 85 } 86 } 87 return 0; 88 } 89 90 static char * 91 sectflags(struct myrosect *sec) 92 { 93 static char flags[10]; 94 char *s = flags + sizeof(flags); 95 96 if (sec->flags & MYROSEC_READ) 97 *--s = 'R'; 98 if (sec->flags & MYROSEC_WRITE) 99 *--s = 'W'; 100 if (sec->flags & MYROSEC_EXEC) 101 *--s = 'X'; 102 if (sec->flags & MYROSEC_LOAD) 103 *--s = 'L'; 104 if (sec->flags & MYROSEC_FILE) 105 *--s = 'F'; 106 if (sec->flags & MYROSEC_ABS) 107 *--s = 'A'; 108 return s; 109 } 110 111 static int 112 printsections(struct obj_info *obj) 113 { 114 unsigned long long n, i; 115 struct myrosect sect; 116 struct myrohdr *hdr = &obj->hdr; 117 118 printf("sections:\n" 119 " [Nr]\t%s\t%-16s\t%-16s\t%s\t%s\t%s\n", 120 "Name", 121 "Offset", 122 "Size", 123 "Fill", 124 "Align", 125 "Flags"); 126 127 n = hdr->secsize / MYROSECT_SIZ; 128 for (i = 0; i < n; ++i) { 129 if (rdmyrosec(obj->fp, §) < 0) 130 return -1; 131 printf(" [%2llu]\t%s\t%016llX\t%016llX\t%02X\t%u\t%s\n", 132 i, 133 getstring(sect.name), 134 sect.offset, 135 sect.len, 136 sect.fill, 137 sect.aligment, 138 sectflags(§)); 139 } 140 return 0; 141 } 142 143 static char * 144 symflags(struct myrosym *sym) 145 { 146 static char flags[10]; 147 char *s = flags + sizeof(flags); 148 149 if (sym->flags & MYROSYM_DEDUP) 150 *--s = 'D'; 151 if (sym->flags & MYROSYM_COMMON) 152 *--s = 'C'; 153 if (sym->flags & MYROSYM_EXTERN) 154 *--s = 'G'; 155 if (sym->flags & MYROSYM_UNDEF) 156 *s-- = 'U'; 157 return s; 158 } 159 160 static int 161 printsymbols(struct obj_info *obj) 162 { 163 unsigned long long n, i; 164 struct myrosym sym; 165 struct myrohdr *hdr = &obj->hdr; 166 167 printf("symbols:\n" 168 " [Nr]\t%s\t%-16s\t%s\t%s\t%s\n", 169 "Name", 170 "Value", 171 "Section", 172 "Flags", 173 "Type"); 174 n = hdr->symsize / MYROSYM_SIZ; 175 for (i = 0; i < n; ++i) { 176 if (rdmyrosym(obj->fp, &sym) < 0) 177 return -1; 178 printf(" [%2llu]\t%s\t%016llX\t%u\t%s\t%s\n", 179 i, 180 getstring(sym.name), 181 sym.offset, 182 sym.section, 183 symflags(&sym), 184 getstring(sym.type)); 185 } 186 return 0; 187 } 188 189 static int 190 printrelocs(struct obj_info *obj) 191 { 192 unsigned long long n, i; 193 struct myrorel rel; 194 struct myrohdr *hdr = &obj->hdr; 195 196 printf("relocs:\n" 197 " [Nr]\t%-16s\tType\tId\tSize\tNbits\tShift\n", 198 "Offset"); 199 n = hdr->relsize / MYROREL_SIZ; 200 for (i = 0; i < n; ++i) { 201 if (rdmyrorel(obj->fp, &rel) < 0) 202 return -1; 203 printf(" [%2llu]\t%016llX\t%s\t%lu\t%u\t%u\t%u\n", 204 i, 205 rel.offset, 206 (rel.id & 1<<31) ? "section" : "symbol", 207 rel.id & ~(1<<31), 208 rel.size, 209 rel.nbits, 210 rel.shift); 211 } 212 return 0; 213 } 214 215 static int 216 printdata(struct obj_info *obj) 217 { 218 unsigned long long off; 219 int c, i, j; 220 221 puts("data:"); 222 for (off = 0; ; off += 32) { 223 printf(" %016llX:", off); 224 for (i = 0; i < 2; i++) { 225 for (j = 0; j < 16; j++) { 226 if ((c = getc(obj->fp)) == EOF) 227 goto exit_loop; 228 printf(" %02X", c); 229 } 230 putchar('\t'); 231 } 232 putchar('\n'); 233 } 234 235 exit_loop: 236 putchar('\n'); 237 return (ferror(obj->fp)) ? -1 : 0; 238 } 239 240 void 241 dump(char *fname, FILE *fp) 242 { 243 struct obj_info obj; 244 struct myrohdr *hdr; 245 246 obj.fname = fname; 247 obj.fp = fp; 248 hdr = &obj.hdr; 249 250 if (rdmyrohdr(obj.fp, hdr) < 0) 251 goto wrong_file; 252 if (strncmp(hdr->magic, MYROMAGIC, MYROMAGIC_SIZ)) { 253 fprintf(stderr, 254 "objdump: %s: File format not recognized\n", 255 fname); 256 return; 257 } 258 puts(fname); 259 if (hdr->strsize > SIZE_MAX) { 260 fprintf(stderr, 261 "objdump: %s: overflow in header\n", 262 fname); 263 return; 264 } 265 strsiz = hdr->strsize; 266 267 if (strsiz > 0) { 268 strings = xmalloc(strsiz); 269 fread(strings, strsiz, 1, fp); 270 if (feof(fp)) 271 goto wrong_file; 272 } 273 274 if (printhdr(&obj) < 0) 275 goto wrong_file; 276 if (printstrings(&obj) < 0) 277 goto wrong_file; 278 if (printsections(&obj) < 0) 279 goto wrong_file; 280 if (printsymbols(&obj) < 0) 281 goto wrong_file; 282 if (printrelocs(&obj) < 0) 283 goto wrong_file; 284 if (printdata(&obj) < 0) 285 goto wrong_file; 286 return; 287 288 wrong_file: 289 fprintf(stderr, 290 "objdump: %s: %s\n", 291 fname, strerror(errno)); 292 } 293 294 void 295 doit(char *fname) 296 { 297 FILE *fp; 298 299 if ((fp = fopen(fname, "rb")) == NULL) { 300 fprintf(stderr, "objdump: %s: %s\n", fname, strerror(errno)); 301 return; 302 } 303 dump(fname, fp); 304 fclose(fp); 305 } 306 307 void 308 usage(void) 309 { 310 fputs("usage: objdump file ...\n", stderr); 311 exit(1); 312 } 313 314 int 315 main(int argc, char *argv[]) 316 { 317 ARGBEGIN { 318 default: 319 usage(); 320 } ARGEND 321 322 if (argc == 0) 323 doit("a.out"); 324 else while (*argv) { 325 free(strings); 326 strings = NULL; 327 doit(*argv++); 328 } 329 330 if (fclose(stdout) == EOF) 331 die("objdump: stdout: %s", strerror(errno)); 332 333 return 0; 334 }