view src/gba/elf.cpp @ 19:5e8e5083da94

brought in common and gba, fixed problems with outdated Makefile.am files in both of these packages
author Robert McIntyre <rlm@mit.edu>
date Sun, 04 Mar 2012 14:33:52 -0600
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
5 #include "../Port.h"
6 #include "../NLS.h"
7 #include "../common/System.h" // systemMessage
8 #include "GBAGlobals.h"
9 #include "elf.h"
11 #define elfReadMemory(addr) \
12 READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
14 #define DW_TAG_array_type 0x01
15 #define DW_TAG_enumeration_type 0x04
16 #define DW_TAG_formal_parameter 0x05
17 #define DW_TAG_label 0x0a
18 #define DW_TAG_lexical_block 0x0b
19 #define DW_TAG_member 0x0d
20 #define DW_TAG_pointer_type 0x0f
21 #define DW_TAG_reference_type 0x10
22 #define DW_TAG_compile_unit 0x11
23 #define DW_TAG_structure_type 0x13
24 #define DW_TAG_subroutine_type 0x15
25 #define DW_TAG_typedef 0x16
26 #define DW_TAG_union_type 0x17
27 #define DW_TAG_unspecified_parameters 0x18
28 #define DW_TAG_inheritance 0x1c
29 #define DW_TAG_inlined_subroutine 0x1d
30 #define DW_TAG_subrange_type 0x21
31 #define DW_TAG_base_type 0x24
32 #define DW_TAG_const_type 0x26
33 #define DW_TAG_enumerator 0x28
34 #define DW_TAG_subprogram 0x2e
35 #define DW_TAG_variable 0x34
36 #define DW_TAG_volatile_type 0x35
38 #define DW_AT_sibling 0x01
39 #define DW_AT_location 0x02
40 #define DW_AT_name 0x03
41 #define DW_AT_byte_size 0x0b
42 #define DW_AT_bit_offset 0x0c
43 #define DW_AT_bit_size 0x0d
44 #define DW_AT_stmt_list 0x10
45 #define DW_AT_low_pc 0x11
46 #define DW_AT_high_pc 0x12
47 #define DW_AT_language 0x13
48 #define DW_AT_compdir 0x1b
49 #define DW_AT_const_value 0x1c
50 #define DW_AT_containing_type 0x1d
51 #define DW_AT_inline 0x20
52 #define DW_AT_producer 0x25
53 #define DW_AT_prototyped 0x27
54 #define DW_AT_upper_bound 0x2f
55 #define DW_AT_abstract_origin 0x31
56 #define DW_AT_accessibility 0x32
57 #define DW_AT_artificial 0x34
58 #define DW_AT_data_member_location 0x38
59 #define DW_AT_decl_file 0x3a
60 #define DW_AT_decl_line 0x3b
61 #define DW_AT_declaration 0x3c
62 #define DW_AT_encoding 0x3e
63 #define DW_AT_external 0x3f
64 #define DW_AT_frame_base 0x40
65 #define DW_AT_macro_info 0x43
66 #define DW_AT_specification 0x47
67 #define DW_AT_type 0x49
68 #define DW_AT_virtuality 0x4c
69 #define DW_AT_vtable_elem_location 0x4d
70 // DWARF 2.1/3.0 extensions
71 #define DW_AT_entry_pc 0x52
72 #define DW_AT_ranges 0x55
73 // ARM Compiler extensions
74 #define DW_AT_proc_body 0x2000
75 #define DW_AT_save_offset 0x2001
76 #define DW_AT_user_2002 0x2002
77 // MIPS extensions
78 #define DW_AT_MIPS_linkage_name 0x2007
80 #define DW_FORM_addr 0x01
81 #define DW_FORM_data2 0x05
82 #define DW_FORM_data4 0x06
83 #define DW_FORM_string 0x08
84 #define DW_FORM_block 0x09
85 #define DW_FORM_block1 0x0a
86 #define DW_FORM_data1 0x0b
87 #define DW_FORM_flag 0x0c
88 #define DW_FORM_sdata 0x0d
89 #define DW_FORM_strp 0x0e
90 #define DW_FORM_udata 0x0f
91 #define DW_FORM_ref_addr 0x10
92 #define DW_FORM_ref4 0x13
93 #define DW_FORM_ref_udata 0x15
94 #define DW_FORM_indirect 0x16
96 #define DW_OP_addr 0x03
97 #define DW_OP_plus_uconst 0x23
98 #define DW_OP_reg0 0x50
99 #define DW_OP_reg1 0x51
100 #define DW_OP_reg2 0x52
101 #define DW_OP_reg3 0x53
102 #define DW_OP_reg4 0x54
103 #define DW_OP_reg5 0x55
104 #define DW_OP_reg6 0x56
105 #define DW_OP_reg7 0x57
106 #define DW_OP_reg8 0x58
107 #define DW_OP_reg9 0x59
108 #define DW_OP_reg10 0x5a
109 #define DW_OP_reg11 0x5b
110 #define DW_OP_reg12 0x5c
111 #define DW_OP_reg13 0x5d
112 #define DW_OP_reg14 0x5e
113 #define DW_OP_reg15 0x5f
114 #define DW_OP_fbreg 0x91
116 #define DW_LNS_extended_op 0x00
117 #define DW_LNS_copy 0x01
118 #define DW_LNS_advance_pc 0x02
119 #define DW_LNS_advance_line 0x03
120 #define DW_LNS_set_file 0x04
121 #define DW_LNS_set_column 0x05
122 #define DW_LNS_negate_stmt 0x06
123 #define DW_LNS_set_basic_block 0x07
124 #define DW_LNS_const_add_pc 0x08
125 #define DW_LNS_fixed_advance_pc 0x09
127 #define DW_LNE_end_sequence 0x01
128 #define DW_LNE_set_address 0x02
129 #define DW_LNE_define_file 0x03
131 #define DW_CFA_advance_loc 0x01
132 #define DW_CFA_offset 0x02
133 #define DW_CFA_restore 0x03
134 #define DW_CFA_set_loc 0x01
135 #define DW_CFA_advance_loc1 0x02
136 #define DW_CFA_advance_loc2 0x03
137 #define DW_CFA_advance_loc4 0x04
138 #define DW_CFA_offset_extended 0x05
139 #define DW_CFA_restore_extended 0x06
140 #define DW_CFA_undefined 0x07
141 #define DW_CFA_same_value 0x08
142 #define DW_CFA_register 0x09
143 #define DW_CFA_remember_state 0x0a
144 #define DW_CFA_restore_state 0x0b
145 #define DW_CFA_def_cfa 0x0c
146 #define DW_CFA_def_cfa_register 0x0d
147 #define DW_CFA_def_cfa_offset 0x0e
148 #define DW_CFA_nop 0x00
150 #define CASE_TYPE_TAG \
151 case DW_TAG_const_type: \
152 case DW_TAG_volatile_type: \
153 case DW_TAG_pointer_type: \
154 case DW_TAG_base_type: \
155 case DW_TAG_array_type: \
156 case DW_TAG_structure_type: \
157 case DW_TAG_union_type: \
158 case DW_TAG_typedef: \
159 case DW_TAG_subroutine_type: \
160 case DW_TAG_enumeration_type: \
161 case DW_TAG_enumerator: \
162 case DW_TAG_reference_type
164 struct ELFcie
165 {
166 ELFcie *next;
167 u32 offset;
168 u8 * augmentation;
169 u32 codeAlign;
170 s32 dataAlign;
171 int returnAddress;
172 u8 * data;
173 u32 dataLen;
174 };
176 struct ELFfde
177 {
178 ELFcie *cie;
179 u32 address;
180 u32 end;
181 u8 * data;
182 u32 dataLen;
183 };
185 enum ELFRegMode
186 {
187 REG_NOT_SET,
188 REG_OFFSET,
189 REG_REGISTER
190 };
192 struct ELFFrameStateRegister
193 {
194 ELFRegMode mode;
195 int reg;
196 s32 offset;
197 };
199 struct ELFFrameStateRegisters
200 {
201 ELFFrameStateRegister regs[16];
202 ELFFrameStateRegisters *previous;
203 };
205 enum ELFCfaMode
206 {
207 CFA_NOT_SET,
208 CFA_REG_OFFSET
209 };
211 struct ELFFrameState
212 {
213 ELFFrameStateRegisters registers;
215 ELFCfaMode cfaMode;
216 int cfaRegister;
217 s32 cfaOffset;
219 u32 pc;
221 int dataAlign;
222 int codeAlign;
223 int returnAddress;
224 };
226 extern bool8 cpuIsMultiBoot;
228 Symbol *elfSymbols = NULL;
229 char * elfSymbolsStrTab = NULL;
230 int elfSymbolsCount = 0;
232 ELFSectionHeader **elfSectionHeaders = NULL;
233 char *elfSectionHeadersStringTable = NULL;
234 int elfSectionHeadersCount = 0;
235 u8 * elfFileData = NULL;
237 CompileUnit *elfCompileUnits = NULL;
238 DebugInfo * elfDebugInfo = NULL;
239 char * elfDebugStrings = NULL;
241 ELFcie * elfCies = NULL;
242 ELFfde **elfFdes = NULL;
243 int elfFdeCount = 0;
245 CompileUnit *elfCurrentUnit = NULL;
247 u32 elfRead4Bytes(u8 *);
248 u16 elfRead2Bytes(u8 *);
250 CompileUnit *elfGetCompileUnit(u32 addr)
251 {
252 if (elfCompileUnits)
253 {
254 CompileUnit *unit = elfCompileUnits;
255 while (unit)
256 {
257 if (unit->lowPC)
258 {
259 if (addr >= unit->lowPC && addr < unit->highPC)
260 return unit;
261 }
262 else
263 {
264 ARanges *r = unit->ranges;
265 if (r)
266 {
267 int count = r->count;
268 for (int j = 0; j < count; j++)
269 {
270 if (addr >= r->ranges[j].lowPC && addr < r->ranges[j].highPC)
271 return unit;
272 }
273 }
274 }
275 unit = unit->next;
276 }
277 }
278 return NULL;
279 }
281 char *elfGetAddressSymbol(u32 addr)
282 {
283 static char buffer[256];
285 CompileUnit *unit = elfGetCompileUnit(addr);
286 // found unit, need to find function
287 if (unit)
288 {
289 Function *func = unit->functions;
290 while (func)
291 {
292 if (addr >= func->lowPC && addr < func->highPC)
293 {
294 int offset = addr - func->lowPC;
295 char *name = func->name;
296 if (!name)
297 name = "";
298 if (offset)
299 sprintf(buffer, "%s+%d", name, offset);
300 else
301 strcpy(buffer, name);
302 return buffer;
303 }
304 func = func->next;
305 }
306 }
308 if (elfSymbolsCount)
309 {
310 for (int i = 0; i < elfSymbolsCount; i++)
311 {
312 Symbol *s = &elfSymbols[i];
313 if ((addr >= s->value) && addr < (s->value+s->size))
314 {
315 int offset = addr-s->value;
316 char *name = s->name;
317 if (name == NULL)
318 name = "";
319 if (offset)
320 sprintf(buffer, "%s+%d", name, addr-s->value);
321 else
322 strcpy(buffer, name);
323 return buffer;
324 }
325 else if (addr == s->value)
326 {
327 if (s->name)
328 strcpy(buffer, s->name);
329 else
330 strcpy(buffer, "");
331 return buffer;
332 }
333 }
334 }
336 return "";
337 }
339 bool elfFindLineInModule(u32 *addr, char *name, int line)
340 {
341 CompileUnit *unit = elfCompileUnits;
343 while (unit)
344 {
345 if (unit->lineInfoTable)
346 {
347 int i;
348 int count = unit->lineInfoTable->fileCount;
349 char *found = NULL;
350 for (i = 0; i < count; i++)
351 {
352 if (strcmp(name, unit->lineInfoTable->files[i]) == 0)
353 {
354 found = unit->lineInfoTable->files[i];
355 break;
356 }
357 }
358 // found a matching filename... try to find line now
359 if (found)
360 {
361 LineInfoItem *table = unit->lineInfoTable->lines;
362 count = unit->lineInfoTable->number;
363 for (i = 0; i < count; i++)
364 {
365 if (table[i].file == found && table[i].line == line)
366 {
367 *addr = table[i].address;
368 return true;
369 }
370 }
371 // we can only find a single match
372 return false;
373 }
374 }
375 unit = unit->next;
376 }
377 return false;
378 }
380 int elfFindLine(CompileUnit *unit, Function * /* func */, u32 addr, char **f)
381 {
382 int currentLine = -1;
383 if (unit->hasLineInfo)
384 {
385 int count = unit->lineInfoTable->number;
386 LineInfoItem *table = unit->lineInfoTable->lines;
387 int i;
388 for (i = 0; i < count; i++)
389 {
390 if (addr <= table[i].address)
391 break;
392 }
393 if (i == count)
394 i--;
395 *f = table[i].file;
396 currentLine = table[i].line;
397 }
398 return currentLine;
399 }
401 bool elfFindLineInUnit(u32 *addr, CompileUnit *unit, int line)
402 {
403 if (unit->hasLineInfo)
404 {
405 int count = unit->lineInfoTable->number;
406 LineInfoItem *table = unit->lineInfoTable->lines;
407 int i;
408 for (i = 0; i < count; i++)
409 {
410 if (line == table[i].line)
411 {
412 *addr = table[i].address;
413 return true;
414 }
415 }
416 }
417 return false;
418 }
420 bool elfGetCurrentFunction(u32 addr, Function **f, CompileUnit **u)
421 {
422 CompileUnit *unit = elfGetCompileUnit(addr);
423 // found unit, need to find function
424 if (unit)
425 {
426 Function *func = unit->functions;
427 while (func)
428 {
429 if (addr >= func->lowPC && addr < func->highPC)
430 {
431 *f = func;
432 *u = unit;
433 return true;
434 }
435 func = func->next;
436 }
437 }
438 return false;
439 }
441 bool elfGetObject(char *name, Function *f, CompileUnit *u, Object **o)
442 {
443 if (f && u)
444 {
445 Object *v = f->variables;
447 while (v)
448 {
449 if (strcmp(name, v->name) == 0)
450 {
451 *o = v;
452 return true;
453 }
454 v = v->next;
455 }
456 v = f->parameters;
457 while (v)
458 {
459 if (strcmp(name, v->name) == 0)
460 {
461 *o = v;
462 return true;
463 }
464 v = v->next;
465 }
466 v = u->variables;
467 while (v)
468 {
469 if (strcmp(name, v->name) == 0)
470 {
471 *o = v;
472 return true;
473 }
474 v = v->next;
475 }
476 }
478 CompileUnit *c = elfCompileUnits;
480 while (c)
481 {
482 if (c != u)
483 {
484 Object *v = c->variables;
485 while (v)
486 {
487 if (strcmp(name, v->name) == 0)
488 {
489 *o = v;
490 return true;
491 }
492 v = v->next;
493 }
494 }
495 c = c->next;
496 }
498 return false;
499 }
501 char *elfGetSymbol(int i, u32 *value, u32 *size, int *type)
502 {
503 if (i < elfSymbolsCount)
504 {
505 Symbol *s = &elfSymbols[i];
506 *value = s->value;
507 *size = s->size;
508 *type = s->type;
509 return s->name;
510 }
511 return NULL;
512 }
514 bool elfGetSymbolAddress(char *sym, u32 *addr, u32 *size, int *type)
515 {
516 if (elfSymbolsCount)
517 {
518 for (int i = 0; i < elfSymbolsCount; i++)
519 {
520 Symbol *s = &elfSymbols[i];
521 if (strcmp(sym, s->name) == 0)
522 {
523 *addr = s->value;
524 *size = s->size;
525 *type = s->type;
526 return true;
527 }
528 }
529 }
530 return false;
531 }
533 ELFfde *elfGetFde(u32 address)
534 {
535 if (elfFdes)
536 {
537 int i;
538 for (i = 0; i < elfFdeCount; i++)
539 {
540 if (address >= elfFdes[i]->address &&
541 address < elfFdes[i]->end)
542 {
543 return elfFdes[i];
544 }
545 }
546 }
548 return NULL;
549 }
551 void elfExecuteCFAInstructions(ELFFrameState *state, u8 *data, u32 len,
552 u32 pc)
553 {
554 u8 *end = data + len;
555 int bytes;
556 int reg;
557 ELFFrameStateRegisters *fs;
559 while (data < end && state->pc < pc)
560 {
561 u8 op = *data++;
563 switch (op >> 6)
564 {
565 case DW_CFA_advance_loc:
566 state->pc += (op & 0x3f) * state->codeAlign;
567 break;
568 case DW_CFA_offset:
569 reg = op & 0x3f;
570 state->registers.regs[reg].mode = REG_OFFSET;
571 state->registers.regs[reg].offset = state->dataAlign *
572 (s32)elfReadLEB128(data, &bytes);
573 data += bytes;
574 break;
575 case DW_CFA_restore:
576 // we don't care much about the other possible settings,
577 // so just setting to unset is enough for now
578 state->registers.regs[op & 0x3f].mode = REG_NOT_SET;
579 break;
580 case 0:
581 switch (op & 0x3f)
582 {
583 case DW_CFA_nop:
584 break;
585 case DW_CFA_advance_loc1:
586 state->pc += state->codeAlign * (*data++);
587 break;
588 case DW_CFA_advance_loc2:
589 state->pc += state->codeAlign * elfRead2Bytes(data);
590 data += 2;
591 break;
592 case DW_CFA_advance_loc4:
593 state->pc += state->codeAlign * elfRead4Bytes(data);
594 data += 4;
595 break;
596 case DW_CFA_offset_extended:
597 reg = elfReadLEB128(data, &bytes);
598 data += bytes;
599 state->registers.regs[reg].mode = REG_OFFSET;
600 state->registers.regs[reg].offset = state->dataAlign *
601 (s32)elfReadLEB128(data, &bytes);
602 data += bytes;
603 break;
604 case DW_CFA_restore_extended:
605 case DW_CFA_undefined:
606 case DW_CFA_same_value:
607 reg = elfReadLEB128(data, &bytes);
608 data += bytes;
609 state->registers.regs[reg].mode = REG_NOT_SET;
610 break;
611 case DW_CFA_register:
612 reg = elfReadLEB128(data, &bytes);
613 data += bytes;
614 state->registers.regs[reg].mode = REG_REGISTER;
615 state->registers.regs[reg].reg = elfReadLEB128(data, &bytes);
616 data += bytes;
617 break;
618 case DW_CFA_remember_state:
619 fs = (ELFFrameStateRegisters *)calloc(1,
620 sizeof(ELFFrameStateRegisters));
621 memcpy(fs, &state->registers, sizeof(ELFFrameStateRegisters));
622 state->registers.previous = fs;
623 break;
624 case DW_CFA_restore_state:
625 if (state->registers.previous == NULL)
626 {
627 printf("Error: previous frame state is NULL.\n");
628 return;
629 }
630 fs = state->registers.previous;
631 memcpy(&state->registers, fs, sizeof(ELFFrameStateRegisters));
632 free(fs);
633 break;
634 case DW_CFA_def_cfa:
635 state->cfaRegister = elfReadLEB128(data, &bytes);
636 data += bytes;
637 state->cfaOffset = (s32)elfReadLEB128(data, &bytes);
638 data += bytes;
639 state->cfaMode = CFA_REG_OFFSET;
640 break;
641 case DW_CFA_def_cfa_register:
642 state->cfaRegister = elfReadLEB128(data, &bytes);
643 data += bytes;
644 state->cfaMode = CFA_REG_OFFSET;
645 break;
646 case DW_CFA_def_cfa_offset:
647 state->cfaOffset = (s32)elfReadLEB128(data, &bytes);
648 data += bytes;
649 state->cfaMode = CFA_REG_OFFSET;
650 break;
651 default:
652 printf("Unknown CFA opcode %08x\n", op);
653 return;
654 }
655 break;
656 default:
657 printf("Unknown CFA opcode %08x\n", op);
658 return;
659 }
660 }
661 }
663 ELFFrameState *elfGetFrameState(ELFfde *fde, u32 address)
664 {
665 ELFFrameState *state = (ELFFrameState *)calloc(1, sizeof(ELFFrameState));
666 state->pc = fde->address;
667 state->dataAlign = fde->cie->dataAlign;
668 state->codeAlign = fde->cie->codeAlign;
669 state->returnAddress = fde->cie->returnAddress;
671 elfExecuteCFAInstructions(state,
672 fde->cie->data,
673 fde->cie->dataLen,
674 0xffffffff);
675 elfExecuteCFAInstructions(state,
676 fde->data,
677 fde->dataLen,
678 address);
680 return state;
681 }
683 void elfPrintCallChain(u32 address)
684 {
685 int count = 1;
687 reg_pair regs[15];
688 reg_pair newRegs[15];
690 memcpy(&regs[0], &reg[0], sizeof(reg_pair) * 15);
692 while (count < 20)
693 {
694 char *addr = elfGetAddressSymbol(address);
695 if (*addr == 0)
696 addr = "???";
698 printf("%08x %s\n", address, addr);
700 ELFfde *fde = elfGetFde(address);
702 if (fde == NULL)
703 {
704 break;
705 }
707 ELFFrameState *state = elfGetFrameState(fde, address);
709 if (!state)
710 {
711 break;
712 }
714 if (state->cfaMode == CFA_REG_OFFSET)
715 {
716 memcpy(&newRegs[0], &regs[0], sizeof(reg_pair) * 15);
717 u32 addr = 0;
718 for (int i = 0; i < 15; i++)
719 {
720 ELFFrameStateRegister *r = &state->registers.
721 regs[i];
723 switch (r->mode)
724 {
725 case REG_NOT_SET:
726 newRegs[i].I = regs[i].I;
727 break;
728 case REG_OFFSET:
729 newRegs[i].I = elfReadMemory(regs[state->cfaRegister].I +
730 state->cfaOffset +
731 r->offset);
732 break;
733 case REG_REGISTER:
734 newRegs[i].I = regs[r->reg].I;
735 break;
736 default:
737 printf("Unknown register mode: %d\n", r->mode);
738 break;
739 }
740 }
741 memcpy(regs, newRegs, sizeof(reg_pair)*15);
742 addr = newRegs[14].I;
743 addr &= 0xfffffffe;
744 address = addr;
745 count++;
746 }
747 else
748 {
749 printf("CFA not set\n");
750 break;
751 }
752 if (state->registers.previous)
753 {
754 ELFFrameStateRegisters *prev = state->registers.previous;
756 while (prev)
757 {
758 ELFFrameStateRegisters *p = prev->previous;
759 free(prev);
760 prev = p;
761 }
762 }
763 free(state);
764 }
765 }
767 u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type, u32 base)
768 {
769 u32 framebase = 0;
770 if (f && f->frameBase)
771 {
772 ELFBlock *b = f->frameBase;
773 switch (*b->data)
774 {
775 case DW_OP_reg0:
776 case DW_OP_reg1:
777 case DW_OP_reg2:
778 case DW_OP_reg3:
779 case DW_OP_reg4:
780 case DW_OP_reg5:
781 case DW_OP_reg6:
782 case DW_OP_reg7:
783 case DW_OP_reg8:
784 case DW_OP_reg9:
785 case DW_OP_reg10:
786 case DW_OP_reg11:
787 case DW_OP_reg12:
788 case DW_OP_reg13:
789 case DW_OP_reg14:
790 case DW_OP_reg15:
791 framebase = reg[*b->data-0x50].I;
792 break;
793 default:
794 fprintf(stderr, "Unknown frameBase %02x\n", *b->data);
795 break;
796 }
797 }
799 ELFBlock *loc = o;
800 u32 location = 0;
801 int bytes = 0;
802 if (loc)
803 {
804 switch (*loc->data)
805 {
806 case DW_OP_addr:
807 location = elfRead4Bytes(loc->data+1);
808 *type = LOCATION_memory;
809 break;
810 case DW_OP_plus_uconst:
811 location = base + elfReadLEB128(loc->data+1, &bytes);
812 *type = LOCATION_memory;
813 break;
814 case DW_OP_reg0:
815 case DW_OP_reg1:
816 case DW_OP_reg2:
817 case DW_OP_reg3:
818 case DW_OP_reg4:
819 case DW_OP_reg5:
820 case DW_OP_reg6:
821 case DW_OP_reg7:
822 case DW_OP_reg8:
823 case DW_OP_reg9:
824 case DW_OP_reg10:
825 case DW_OP_reg11:
826 case DW_OP_reg12:
827 case DW_OP_reg13:
828 case DW_OP_reg14:
829 case DW_OP_reg15:
830 location = *loc->data - 0x50;
831 *type = LOCATION_register;
832 break;
833 case DW_OP_fbreg:
834 {
835 int bytes;
836 s32 off = elfReadSignedLEB128(loc->data+1, &bytes);
837 location = framebase + off;
838 *type = LOCATION_memory;
839 break;
840 }
841 default:
842 fprintf(stderr, "Unknown location %02x\n", *loc->data);
843 break;
844 }
845 }
846 return location;
847 }
849 u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type)
850 {
851 return elfDecodeLocation(f, o, type, 0);
852 }
854 // reading function
856 u32 elfRead4Bytes(u8 *data)
857 {
858 u32 value = *data++;
859 value |= (*data++ << 8);
860 value |= (*data++ << 16);
861 value |= (*data << 24);
862 return value;
863 }
865 u16 elfRead2Bytes(u8 *data)
866 {
867 u16 value = *data++;
868 value |= (*data << 8);
869 return value;
870 }
872 char *elfReadString(u8 *data, int *bytesRead)
873 {
874 if (*data == 0)
875 {
876 *bytesRead = 1;
877 return NULL;
878 }
879 *bytesRead = strlen((char *)data) + 1;
880 return (char *)data;
881 }
883 s32 elfReadSignedLEB128(u8 *data, int *bytesRead)
884 {
885 s32 result = 0;
886 int shift = 0;
887 int count = 0;
889 u8 byte;
890 do
891 {
892 byte = *data++;
893 count++;
894 result |= (byte & 0x7f) << shift;
895 shift += 7;
896 }
897 while (byte & 0x80);
898 if ((shift < 32) && (byte & 0x40))
899 result |= -(1 << shift);
900 *bytesRead = count;
901 return result;
902 }
904 u32 elfReadLEB128(u8 *data, int *bytesRead)
905 {
906 u32 result = 0;
907 int shift = 0;
908 int count = 0;
909 u8 byte;
910 do
911 {
912 byte = *data++;
913 count++;
914 result |= (byte & 0x7f) << shift;
915 shift += 7;
916 }
917 while (byte & 0x80);
918 *bytesRead = count;
919 return result;
920 }
922 u8 *elfReadSection(u8 *data, ELFSectionHeader *sh)
923 {
924 return data + READ32LE(&sh->offset);
925 }
927 ELFSectionHeader *elfGetSectionByName(char *name)
928 {
929 for (int i = 0; i < elfSectionHeadersCount; i++)
930 {
931 if (strcmp(name,
932 &elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]->
933 name)]) == 0)
934 {
935 return elfSectionHeaders[i];
936 }
937 }
938 return NULL;
939 }
941 ELFSectionHeader *elfGetSectionByNumber(int number)
942 {
943 if (number < elfSectionHeadersCount)
944 {
945 return elfSectionHeaders[number];
946 }
947 return NULL;
948 }
950 CompileUnit *elfGetCompileUnitForData(u8 *data)
951 {
952 u8 *end = elfCurrentUnit->top + 4 + elfCurrentUnit->length;
954 if (data >= elfCurrentUnit->top && data < end)
955 return elfCurrentUnit;
957 CompileUnit *unit = elfCompileUnits;
959 while (unit)
960 {
961 end = unit->top + 4 + unit->length;
963 if (data >= unit->top && data < end)
964 return unit;
966 unit = unit->next;
967 }
969 printf("Error: cannot find reference to compile unit at offset %08x\n",
970 (int)(data - elfDebugInfo->infodata));
971 exit(-1);
972 }
974 u8 *elfReadAttribute(u8 *data, ELFAttr *attr)
975 {
976 int bytes;
977 int form = attr->form;
978 start:
979 switch (form)
980 {
981 case DW_FORM_addr:
982 attr->value = elfRead4Bytes(data);
983 data += 4;
984 break;
985 case DW_FORM_data2:
986 attr->value = elfRead2Bytes(data);
987 data += 2;
988 break;
989 case DW_FORM_data4:
990 attr->value = elfRead4Bytes(data);
991 data += 4;
992 break;
993 case DW_FORM_string:
994 attr->string = (char *)data;
995 data += strlen(attr->string)+1;
996 break;
997 case DW_FORM_strp:
998 attr->string = elfDebugStrings + elfRead4Bytes(data);
999 data += 4;
1000 break;
1001 case DW_FORM_block:
1002 attr->block = (ELFBlock *)malloc(sizeof(ELFBlock));
1003 attr->block->length = elfReadLEB128(data, &bytes);
1004 data += bytes;
1005 attr->block->data = data;
1006 data += attr->block->length;
1007 break;
1008 case DW_FORM_block1:
1009 attr->block = (ELFBlock *)malloc(sizeof(ELFBlock));
1010 attr->block->length = *data++;
1011 attr->block->data = data;
1012 data += attr->block->length;
1013 break;
1014 case DW_FORM_data1:
1015 attr->value = *data++;
1016 break;
1017 case DW_FORM_flag:
1018 attr->flag = (*data++) ? true : false;
1019 break;
1020 case DW_FORM_sdata:
1021 attr->value = elfReadSignedLEB128(data, &bytes);
1022 data += bytes;
1023 break;
1024 case DW_FORM_udata:
1025 attr->value = elfReadLEB128(data, &bytes);
1026 data += bytes;
1027 break;
1028 case DW_FORM_ref_addr:
1029 attr->value = (elfDebugInfo->infodata + elfRead4Bytes(data)) -
1030 elfGetCompileUnitForData(data)->top;
1031 data += 4;
1032 break;
1033 case DW_FORM_ref4:
1034 attr->value = elfRead4Bytes(data);
1035 data += 4;
1036 break;
1037 case DW_FORM_ref_udata:
1038 attr->value = (elfDebugInfo->infodata +
1039 (elfGetCompileUnitForData(data)->top -
1040 elfDebugInfo->infodata) +
1041 elfReadLEB128(data, &bytes)) -
1042 elfCurrentUnit->top;
1043 data += bytes;
1044 break;
1045 case DW_FORM_indirect:
1046 form = elfReadLEB128(data, &bytes);
1047 data += bytes;
1048 goto start;
1049 default:
1050 fprintf(stderr, "Unsupported FORM %02x\n", form);
1051 exit(-1);
1053 return data;
1056 ELFAbbrev *elfGetAbbrev(ELFAbbrev **table, u32 number)
1058 int hash = number % 121;
1060 ELFAbbrev *abbrev = table[hash];
1062 while (abbrev)
1064 if (abbrev->number == number)
1065 return abbrev;
1066 abbrev = abbrev->next;
1068 return NULL;
1071 ELFAbbrev * *elfReadAbbrevs(u8 *data, u32 offset)
1073 data += offset;
1074 ELFAbbrev **abbrevs = (ELFAbbrev * *)calloc(sizeof(ELFAbbrev *)*121, 1);
1075 int bytes = 0;
1076 u32 number = elfReadLEB128(data, &bytes);
1077 data += bytes;
1078 while (number)
1080 ELFAbbrev *abbrev = (ELFAbbrev *)calloc(sizeof(ELFAbbrev), 1);
1082 // read tag information
1083 abbrev->number = number;
1084 abbrev->tag = elfReadLEB128(data, &bytes);
1085 data += bytes;
1086 abbrev->hasChildren = *data++ ? true : false;
1088 // read attributes
1089 int name = elfReadLEB128(data, &bytes);
1090 data += bytes;
1091 int form = elfReadLEB128(data, &bytes);
1092 data += bytes;
1094 while (name)
1096 if ((abbrev->numAttrs % 4) == 0)
1098 abbrev->attrs = (ELFAttr *)realloc(abbrev->attrs,
1099 (abbrev->numAttrs + 4) *
1100 sizeof(ELFAttr));
1102 abbrev->attrs[abbrev->numAttrs].name = name;
1103 abbrev->attrs[abbrev->numAttrs++].form = form;
1105 name = elfReadLEB128(data, &bytes);
1106 data += bytes;
1107 form = elfReadLEB128(data, &bytes);
1108 data += bytes;
1111 int hash = number % 121;
1112 abbrev->next = abbrevs[hash];
1113 abbrevs[hash] = abbrev;
1115 number = elfReadLEB128(data, &bytes);
1116 data += bytes;
1118 if (elfGetAbbrev(abbrevs, number) != NULL)
1119 break;
1122 return abbrevs;
1125 void elfParseCFA(u8 *top)
1127 ELFSectionHeader *h = elfGetSectionByName(".debug_frame");
1129 if (h == NULL)
1131 return;
1134 u8 *data = elfReadSection(top, h);
1136 u8 *topOffset = data;
1138 u8 *end = data + READ32LE(&h->size);
1140 ELFcie *cies = NULL;
1142 while (data < end)
1144 u32 offset = data - topOffset;
1145 u32 len = elfRead4Bytes(data);
1146 data += 4;
1148 u8 *dataEnd = data + len;
1150 u32 id = elfRead4Bytes(data);
1151 data += 4;
1153 if (id == 0xffffffff)
1155 // skip version
1156 *data++;
1158 ELFcie *cie = (ELFcie *)calloc(1, sizeof(ELFcie));
1160 cie->next = cies;
1161 cies = cie;
1163 cie->offset = offset;
1165 cie->augmentation = data;
1166 while (*data)
1167 data++;
1168 data++;
1170 if (*cie->augmentation)
1172 fprintf(stderr, "Error: augmentation not supported\n");
1173 exit(-1);
1176 int bytes;
1177 cie->codeAlign = elfReadLEB128(data, &bytes);
1178 data += bytes;
1180 cie->dataAlign = elfReadSignedLEB128(data, &bytes);
1181 data += bytes;
1183 cie->returnAddress = *data++;
1185 cie->data = data;
1186 cie->dataLen = dataEnd - data;
1188 else
1190 ELFfde *fde = (ELFfde *)calloc(1, sizeof(ELFfde));
1192 ELFcie *cie = cies;
1194 while (cie != NULL)
1196 if (cie->offset == id)
1197 break;
1198 cie = cie->next;
1201 if (!cie)
1203 fprintf(stderr, "Cannot find CIE %08x\n", id);
1204 exit(-1);
1207 fde->cie = cie;
1209 fde->address = elfRead4Bytes(data);
1210 data += 4;
1212 fde->end = fde->address + elfRead4Bytes(data);
1213 data += 4;
1215 fde->data = data;
1216 fde->dataLen = dataEnd - data;
1218 if ((elfFdeCount %10) == 0)
1220 elfFdes = (ELFfde * *)realloc(elfFdes, (elfFdeCount+10) *
1221 sizeof(ELFfde *));
1223 elfFdes[elfFdeCount++] = fde;
1225 data = dataEnd;
1228 elfCies = cies;
1231 void elfAddLine(LineInfo *l, u32 a, int file, int line, int *max)
1233 if (l->number == *max)
1235 *max += 1000;
1236 l->lines = (LineInfoItem *)realloc(l->lines, *max*sizeof(LineInfoItem));
1238 LineInfoItem *li = &l->lines[l->number];
1239 li->file = l->files[file-1];
1240 li->address = a;
1241 li->line = line;
1242 l->number++;
1245 void elfParseLineInfo(CompileUnit *unit, u8 *top)
1247 ELFSectionHeader *h = elfGetSectionByName(".debug_line");
1248 if (h == NULL)
1250 fprintf(stderr, "No line information found\n");
1251 return;
1253 LineInfo *l = unit->lineInfoTable = (LineInfo *)calloc(1, sizeof(LineInfo));
1254 l->number = 0;
1255 int max = 1000;
1256 l->lines = (LineInfoItem *)malloc(1000*sizeof(LineInfoItem));
1258 u8 *data = elfReadSection(top, h);
1259 data += unit->lineInfo;
1260 u32 totalLen = elfRead4Bytes(data);
1261 data += 4;
1262 u8 *end = data + totalLen;
1263 // u16 version = elfRead2Bytes(data);
1264 data += 2;
1265 // u32 offset = elfRead4Bytes(data);
1266 data += 4;
1267 int minInstrSize = *data++;
1268 int defaultIsStmt = *data++;
1269 int lineBase = (s8)*data++;
1270 int lineRange = *data++;
1271 int opcodeBase = *data++;
1272 u8 *stdOpLen = (u8 *)malloc(opcodeBase * sizeof(u8));
1273 stdOpLen[0] = 1;
1274 int i;
1275 for (i = 1; i < opcodeBase; i++)
1276 stdOpLen[i] = *data++;
1278 free(stdOpLen); // todo
1279 int bytes = 0;
1281 char *s;
1282 while ((s = elfReadString(data, &bytes)) != NULL)
1284 data += bytes;
1285 // fprintf(stderr, "Directory is %s\n", s);
1287 data += bytes;
1288 int count = 4;
1289 int index = 0;
1290 l->files = (char * *)malloc(sizeof(char *)*count);
1292 while ((s = elfReadString(data, &bytes)) != NULL)
1294 l->files[index++] = s;
1296 data += bytes;
1297 // directory
1298 elfReadLEB128(data, &bytes);
1299 data += bytes;
1300 // time
1301 elfReadLEB128(data, &bytes);
1302 data += bytes;
1303 // size
1304 elfReadLEB128(data, &bytes);
1305 data += bytes;
1306 // fprintf(stderr, "File is %s\n", s);
1307 if (index == count)
1309 count += 4;
1310 l->files = (char * *)realloc(l->files, sizeof(char *)*count);
1313 l->fileCount = index;
1314 data += bytes;
1316 while (data < end)
1318 u32 address = 0;
1319 int file = 1;
1320 int line = 1;
1321 int col = 0;
1322 int isStmt = defaultIsStmt;
1323 int basicBlock = 0;
1324 int endSeq = 0;
1326 while (!endSeq)
1328 int op = *data++;
1329 switch (op)
1331 case DW_LNS_extended_op:
1333 data++;
1334 op = *data++;
1335 switch (op)
1337 case DW_LNE_end_sequence:
1338 endSeq = 1;
1339 break;
1340 case DW_LNE_set_address:
1341 address = elfRead4Bytes(data);
1342 data += 4;
1343 break;
1344 default:
1345 fprintf(stderr, "Unknown extended LINE opcode %02x\n", op);
1346 exit(-1);
1348 break;
1350 case DW_LNS_copy:
1351 // fprintf(stderr, "Address %08x line %d (%d)\n", address, line, file);
1352 elfAddLine(l, address, file, line, &max);
1353 basicBlock = 0;
1354 break;
1355 case DW_LNS_advance_pc:
1356 address += minInstrSize * elfReadLEB128(data, &bytes);
1357 data += bytes;
1358 break;
1359 case DW_LNS_advance_line:
1360 line += elfReadSignedLEB128(data, &bytes);
1361 data += bytes;
1362 break;
1363 case DW_LNS_set_file:
1364 file = elfReadLEB128(data, &bytes);
1365 data += bytes;
1366 break;
1367 case DW_LNS_set_column:
1368 col = elfReadLEB128(data, &bytes);
1369 data += bytes;
1370 break;
1371 case DW_LNS_negate_stmt:
1372 isStmt = !isStmt;
1373 break;
1374 case DW_LNS_set_basic_block:
1375 basicBlock = 1;
1376 break;
1377 case DW_LNS_const_add_pc:
1378 address += (minInstrSize *((255 - opcodeBase)/lineRange));
1379 break;
1380 case DW_LNS_fixed_advance_pc:
1381 address += elfRead2Bytes(data);
1382 data += 2;
1383 break;
1384 default:
1385 op = op - opcodeBase;
1386 address += (op / lineRange) * minInstrSize;
1387 line += lineBase + (op % lineRange);
1388 elfAddLine(l, address, file, line, &max);
1389 // fprintf(stderr, "Address %08x line %d (%d)\n", address, line,file);
1390 basicBlock = 1;
1391 break;
1395 l->lines = (LineInfoItem *)realloc(l->lines, l->number*sizeof(LineInfoItem));
1398 u8 *elfSkipData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs)
1400 int i;
1401 int bytes;
1403 for (i = 0; i < abbrev->numAttrs; i++)
1405 data = elfReadAttribute(data, &abbrev->attrs[i]);
1406 if (abbrev->attrs[i].form == DW_FORM_block1)
1407 free(abbrev->attrs[i].block);
1410 if (abbrev->hasChildren)
1412 int nesting = 1;
1413 while (nesting)
1415 u32 abbrevNum = elfReadLEB128(data, &bytes);
1416 data += bytes;
1418 if (!abbrevNum)
1420 nesting--;
1421 continue;
1424 abbrev = elfGetAbbrev(abbrevs, abbrevNum);
1426 for (i = 0; i < abbrev->numAttrs; i++)
1428 data = elfReadAttribute(data, &abbrev->attrs[i]);
1429 if (abbrev->attrs[i].form == DW_FORM_block1)
1430 free(abbrev->attrs[i].block);
1433 if (abbrev->hasChildren)
1435 nesting++;
1439 return data;
1442 Type *elfParseType(CompileUnit *unit, u32);
1443 u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit,
1444 Object **object);
1445 u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit,
1446 Function **function);
1447 void elfCleanUp(Function *);
1449 void elfAddType(Type *type, CompileUnit *unit, u32 offset)
1451 if (type->next == NULL)
1453 if (unit->types != type && type->offset == 0)
1455 type->offset = offset;
1456 type->next = unit->types;
1457 unit->types = type;
1462 void elfParseType(u8 *data, u32 offset, ELFAbbrev *abbrev, CompileUnit *unit,
1463 Type **type)
1465 switch (abbrev->tag)
1467 case DW_TAG_typedef:
1469 u32 typeref = 0;
1470 char *name = NULL;
1471 for (int i = 0; i < abbrev->numAttrs; i++)
1473 ELFAttr *attr = &abbrev->attrs[i];
1474 data = elfReadAttribute(data, attr);
1475 switch (attr->name)
1477 case DW_AT_name:
1478 name = attr->string;
1479 break;
1480 case DW_AT_type:
1481 typeref = attr->value;
1482 break;
1483 case DW_AT_decl_file:
1484 case DW_AT_decl_line:
1485 break;
1486 default:
1487 fprintf(stderr, "Unknown attribute for typedef %02x\n", attr->name);
1488 break;
1491 if (abbrev->hasChildren)
1492 fprintf(stderr, "Unexpected children for typedef\n");
1493 *type = elfParseType(unit, typeref);
1494 if (name)
1495 (*type)->name = name;
1496 return;
1497 break;
1499 case DW_TAG_union_type:
1500 case DW_TAG_structure_type:
1502 Type *t = (Type *)calloc(sizeof(Type), 1);
1503 if (abbrev->tag == DW_TAG_structure_type)
1504 t->type = TYPE_struct;
1505 else
1506 t->type = TYPE_union;
1508 Struct *s = (Struct *)calloc(sizeof(Struct), 1);
1509 t->structure = s;
1510 elfAddType(t, unit, offset);
1512 for (int i = 0; i < abbrev->numAttrs; i++)
1514 ELFAttr *attr = &abbrev->attrs[i];
1515 data = elfReadAttribute(data, attr);
1516 switch (attr->name)
1518 case DW_AT_name:
1519 t->name = attr->string;
1520 break;
1521 case DW_AT_byte_size:
1522 t->size = attr->value;
1523 break;
1524 case DW_AT_decl_file:
1525 case DW_AT_decl_line:
1526 case DW_AT_sibling:
1527 case DW_AT_containing_type: // todo?
1528 case DW_AT_declaration:
1529 case DW_AT_specification: // TODO:
1530 break;
1531 default:
1532 fprintf(stderr, "Unknown attribute for struct %02x\n", attr->name);
1533 break;
1536 if (abbrev->hasChildren)
1538 int bytes;
1539 u32 num = elfReadLEB128(data, &bytes);
1540 data += bytes;
1541 int index = 0;
1542 while (num)
1544 ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num);
1546 switch (abbr->tag)
1548 case DW_TAG_member:
1550 if ((index % 4) == 0)
1551 s->members = (Member *)realloc(s->members,
1552 sizeof(Member)*(index+4));
1553 Member *m = &s->members[index];
1554 m->location = NULL;
1555 m->bitOffset = 0;
1556 m->bitSize = 0;
1557 m->byteSize = 0;
1558 for (int i = 0; i < abbr->numAttrs; i++)
1560 ELFAttr *attr = &abbr->attrs[i];
1561 data = elfReadAttribute(data, attr);
1562 switch (attr->name)
1564 case DW_AT_name:
1565 m->name = attr->string;
1566 break;
1567 case DW_AT_type:
1568 m->type = elfParseType(unit, attr->value);
1569 break;
1570 case DW_AT_data_member_location:
1571 m->location = attr->block;
1572 break;
1573 case DW_AT_byte_size:
1574 m->byteSize = attr->value;
1575 break;
1576 case DW_AT_bit_offset:
1577 m->bitOffset = attr->value;
1578 break;
1579 case DW_AT_bit_size:
1580 m->bitSize = attr->value;
1581 break;
1582 case DW_AT_decl_file:
1583 case DW_AT_decl_line:
1584 case DW_AT_accessibility:
1585 case DW_AT_artificial: // todo?
1586 break;
1587 default:
1588 fprintf(stderr, "Unknown member attribute %02x\n",
1589 attr->name);
1592 index++;
1593 break;
1595 case DW_TAG_subprogram:
1597 Function *fnc = NULL;
1598 data = elfParseFunction(data, abbr, unit, &fnc);
1599 if (fnc != NULL)
1601 if (unit->lastFunction)
1602 unit->lastFunction->next = fnc;
1603 else
1604 unit->functions = fnc;
1605 unit->lastFunction = fnc;
1607 break;
1609 case DW_TAG_inheritance:
1610 // TODO: add support
1611 data = elfSkipData(data, abbr, unit->abbrevs);
1612 break;
1613 CASE_TYPE_TAG:
1614 // skip types... parsed only when used
1615 data = elfSkipData(data, abbr, unit->abbrevs);
1616 break;
1617 case DW_TAG_variable:
1618 data = elfSkipData(data, abbr, unit->abbrevs);
1619 break;
1620 default:
1621 fprintf(stderr, "Unknown struct tag %02x %s\n", abbr->tag, t->name);
1622 data = elfSkipData(data, abbr, unit->abbrevs);
1623 break;
1625 num = elfReadLEB128(data, &bytes);
1626 data += bytes;
1628 s->memberCount = index;
1630 *type = t;
1631 return;
1632 break;
1634 case DW_TAG_base_type:
1636 Type *t = (Type *)calloc(sizeof(Type), 1);
1638 t->type = TYPE_base;
1639 elfAddType(t, unit, offset);
1640 for (int i = 0; i < abbrev->numAttrs; i++)
1642 ELFAttr *attr = &abbrev->attrs[i];
1643 data = elfReadAttribute(data, attr);
1644 switch (attr->name)
1646 case DW_AT_name:
1647 t->name = attr->string;
1648 break;
1649 case DW_AT_encoding:
1650 t->encoding = attr->value;
1651 break;
1652 case DW_AT_byte_size:
1653 t->size = attr->value;
1654 break;
1655 case DW_AT_bit_size:
1656 t->bitSize = attr->value;
1657 break;
1658 default:
1659 fprintf(stderr, "Unknown attribute for base type %02x\n",
1660 attr->name);
1661 break;
1664 if (abbrev->hasChildren)
1665 fprintf(stderr, "Unexpected children for base type\n");
1666 *type = t;
1667 return;
1668 break;
1670 case DW_TAG_pointer_type:
1672 Type *t = (Type *)calloc(sizeof(Type), 1);
1674 t->type = TYPE_pointer;
1676 elfAddType(t, unit, offset);
1678 for (int i = 0; i < abbrev->numAttrs; i++)
1680 ELFAttr *attr = &abbrev->attrs[i];
1681 data = elfReadAttribute(data, attr);
1682 switch (attr->name)
1684 case DW_AT_type:
1685 t->pointer = elfParseType(unit, attr->value);
1686 break;
1687 case DW_AT_byte_size:
1688 t->size = attr->value;
1689 break;
1690 default:
1691 fprintf(stderr, "Unknown pointer type attribute %02x\n", attr->name);
1692 break;
1695 if (abbrev->hasChildren)
1696 fprintf(stderr, "Unexpected children for pointer type\n");
1697 *type = t;
1698 return;
1699 break;
1701 case DW_TAG_reference_type:
1703 Type *t = (Type *)calloc(sizeof(Type), 1);
1705 t->type = TYPE_reference;
1707 elfAddType(t, unit, offset);
1709 for (int i = 0; i < abbrev->numAttrs; i++)
1711 ELFAttr *attr = &abbrev->attrs[i];
1712 data = elfReadAttribute(data, attr);
1713 switch (attr->name)
1715 case DW_AT_type:
1716 t->pointer = elfParseType(unit, attr->value);
1717 break;
1718 case DW_AT_byte_size:
1719 t->size = attr->value;
1720 break;
1721 default:
1722 fprintf(stderr, "Unknown ref type attribute %02x\n", attr->name);
1723 break;
1726 if (abbrev->hasChildren)
1727 fprintf(stderr, "Unexpected children for ref type\n");
1728 *type = t;
1729 return;
1730 break;
1732 case DW_TAG_volatile_type:
1734 u32 typeref = 0;
1736 for (int i = 0; i < abbrev->numAttrs; i++)
1738 ELFAttr *attr = &abbrev->attrs[i];
1739 data = elfReadAttribute(data, attr);
1740 switch (attr->name)
1742 case DW_AT_type:
1743 typeref = attr->value;
1744 break;
1745 default:
1746 fprintf(stderr, "Unknown volatile attribute for type %02x\n",
1747 attr->name);
1748 break;
1751 if (abbrev->hasChildren)
1752 fprintf(stderr, "Unexpected children for volatile type\n");
1753 *type = elfParseType(unit, typeref);
1754 return;
1755 break;
1757 case DW_TAG_const_type:
1759 u32 typeref = 0;
1761 for (int i = 0; i < abbrev->numAttrs; i++)
1763 ELFAttr *attr = &abbrev->attrs[i];
1764 data = elfReadAttribute(data, attr);
1765 switch (attr->name)
1767 case DW_AT_type:
1768 typeref = attr->value;
1769 break;
1770 default:
1771 fprintf(stderr, "Unknown const attribute for type %02x\n",
1772 attr->name);
1773 break;
1776 if (abbrev->hasChildren)
1777 fprintf(stderr, "Unexpected children for const type\n");
1778 *type = elfParseType(unit, typeref);
1779 return;
1780 break;
1782 case DW_TAG_enumeration_type:
1784 Type *t = (Type *)calloc(sizeof(Type), 1);
1785 t->type = TYPE_enum;
1786 Enum *e = (Enum *)calloc(sizeof(Enum), 1);
1787 t->enumeration = e;
1788 elfAddType(t, unit, offset);
1789 int count = 0;
1790 for (int i = 0; i < abbrev->numAttrs; i++)
1792 ELFAttr *attr = &abbrev->attrs[i];
1793 data = elfReadAttribute(data, attr);
1794 switch (attr->name)
1796 case DW_AT_name:
1797 t->name = attr->string;
1798 break;
1799 case DW_AT_byte_size:
1800 t->size = attr->value;
1801 break;
1802 case DW_AT_sibling:
1803 case DW_AT_decl_file:
1804 case DW_AT_decl_line:
1805 break;
1806 default:
1807 fprintf(stderr, "Unknown enum attribute %02x\n", attr->name);
1810 if (abbrev->hasChildren)
1812 int bytes;
1813 u32 num = elfReadLEB128(data, &bytes);
1814 data += bytes;
1815 while (num)
1817 ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num);
1819 switch (abbr->tag)
1821 case DW_TAG_enumerator:
1823 count++;
1824 e->members = (EnumMember *)realloc(e->members,
1825 count*sizeof(EnumMember));
1826 EnumMember *m = &e->members[count-1];
1827 for (int i = 0; i < abbr->numAttrs; i++)
1829 ELFAttr *attr = &abbr->attrs[i];
1830 data = elfReadAttribute(data, attr);
1831 switch (attr->name)
1833 case DW_AT_name:
1834 m->name = attr->string;
1835 break;
1836 case DW_AT_const_value:
1837 m->value = attr->value;
1838 break;
1839 default:
1840 fprintf(stderr, "Unknown sub param attribute %02x\n",
1841 attr->name);
1844 break;
1846 default:
1847 fprintf(stderr, "Unknown enum tag %02x\n", abbr->tag);
1848 data = elfSkipData(data, abbr, unit->abbrevs);
1849 break;
1851 num = elfReadLEB128(data, &bytes);
1852 data += bytes;
1855 e->count = count;
1856 *type = t;
1857 return;
1858 break;
1860 case DW_TAG_subroutine_type:
1862 Type *t = (Type *)calloc(sizeof(Type), 1);
1863 t->type = TYPE_function;
1864 FunctionType *f = (FunctionType *)calloc(sizeof(FunctionType), 1);
1865 t->function = f;
1866 elfAddType(t, unit, offset);
1867 for (int i = 0; i < abbrev->numAttrs; i++)
1869 ELFAttr *attr = &abbrev->attrs[i];
1870 data = elfReadAttribute(data, attr);
1871 switch (attr->name)
1873 case DW_AT_prototyped:
1874 case DW_AT_sibling:
1875 break;
1876 case DW_AT_type:
1877 f->returnType = elfParseType(unit, attr->value);
1878 break;
1879 default:
1880 fprintf(stderr, "Unknown subroutine attribute %02x\n", attr->name);
1883 if (abbrev->hasChildren)
1885 int bytes;
1886 u32 num = elfReadLEB128(data, &bytes);
1887 data += bytes;
1888 Object *lastVar = NULL;
1889 while (num)
1891 ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num);
1893 switch (abbr->tag)
1895 case DW_TAG_formal_parameter:
1897 Object *o;
1898 data = elfParseObject(data, abbr, unit, &o);
1899 if (f->args)
1900 lastVar->next = o;
1901 else
1902 f->args = o;
1903 lastVar = o;
1904 break;
1906 case DW_TAG_unspecified_parameters:
1907 // no use in the debugger yet
1908 data = elfSkipData(data, abbr, unit->abbrevs);
1909 break;
1910 CASE_TYPE_TAG:
1911 // skip types... parsed only when used
1912 data = elfSkipData(data, abbr, unit->abbrevs);
1913 break;
1914 default:
1915 fprintf(stderr, "Unknown subroutine tag %02x\n", abbr->tag);
1916 data = elfSkipData(data, abbr, unit->abbrevs);
1917 break;
1919 num = elfReadLEB128(data, &bytes);
1920 data += bytes;
1923 *type = t;
1924 return;
1925 break;
1927 case DW_TAG_array_type:
1929 u32 typeref = 0;
1930 int i;
1931 Array *array = (Array *)calloc(sizeof(Array), 1);
1932 Type * t = (Type *)calloc(sizeof(Type), 1);
1933 t->type = TYPE_array;
1934 elfAddType(t, unit, offset);
1936 for (i = 0; i < abbrev->numAttrs; i++)
1938 ELFAttr *attr = &abbrev->attrs[i];
1939 data = elfReadAttribute(data, attr);
1940 switch (attr->name)
1942 case DW_AT_sibling:
1943 break;
1944 case DW_AT_type:
1945 typeref = attr->value;
1946 array->type = elfParseType(unit, typeref);
1947 break;
1948 default:
1949 fprintf(stderr, "Unknown array attribute %02x\n", attr->name);
1952 if (abbrev->hasChildren)
1954 int bytes;
1955 u32 num = elfReadLEB128(data, &bytes);
1956 data += bytes;
1957 int index = 0;
1958 int maxBounds = 0;
1959 while (num)
1961 ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num);
1963 switch (abbr->tag)
1965 case DW_TAG_subrange_type:
1967 if (maxBounds == index)
1969 maxBounds += 4;
1970 array->bounds = (int *)realloc(array->bounds,
1971 sizeof(int)*maxBounds);
1973 for (int i = 0; i < abbr->numAttrs; i++)
1975 ELFAttr *attr = &abbr->attrs[i];
1976 data = elfReadAttribute(data, attr);
1977 switch (attr->name)
1979 case DW_AT_upper_bound:
1980 array->bounds[index] = attr->value+1;
1981 break;
1982 case DW_AT_type: // ignore
1983 break;
1984 default:
1985 fprintf(stderr, "Unknown subrange attribute %02x\n",
1986 attr->name);
1989 index++;
1990 break;
1992 default:
1993 fprintf(stderr, "Unknown array tag %02x\n", abbr->tag);
1994 data = elfSkipData(data, abbr, unit->abbrevs);
1995 break;
1997 num = elfReadLEB128(data, &bytes);
1998 data += bytes;
2000 array->maxBounds = index;
2002 t->size = array->type->size;
2003 for (i = 0; i < array->maxBounds; i++)
2004 t->size *= array->bounds[i];
2005 t->array = array;
2006 *type = t;
2007 return;
2008 break;
2010 default:
2011 fprintf(stderr, "Unknown type TAG %02x\n", abbrev->tag);
2012 exit(-1);
2016 Type *elfParseType(CompileUnit *unit, u32 offset)
2018 Type *t = unit->types;
2020 while (t)
2022 if (t->offset == offset)
2023 return t;
2024 t = t->next;
2026 if (offset == 0)
2028 Type *t = (Type *)calloc(sizeof(Type), 1);
2029 t->type = TYPE_void;
2030 t->offset = 0;
2031 elfAddType(t, unit, 0);
2032 return t;
2034 u8 *data = unit->top + offset;
2035 int bytes;
2036 int abbrevNum = elfReadLEB128(data, &bytes);
2037 data += bytes;
2038 Type *type = NULL;
2040 ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2042 elfParseType(data, offset, abbrev, unit, &type);
2043 return type;
2046 void elfGetObjectAttributes(CompileUnit *unit, u32 offset, Object *o)
2048 u8 *data = unit->top + offset;
2049 int bytes;
2050 u32 abbrevNum = elfReadLEB128(data, &bytes);
2051 data += bytes;
2053 if (!abbrevNum)
2055 return;
2058 ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2060 for (int i = 0; i < abbrev->numAttrs; i++)
2062 ELFAttr *attr = &abbrev->attrs[i];
2063 data = elfReadAttribute(data, attr);
2064 switch (attr->name)
2066 case DW_AT_location:
2067 o->location = attr->block;
2068 break;
2069 case DW_AT_name:
2070 if (o->name == NULL)
2071 o->name = attr->string;
2072 break;
2073 case DW_AT_MIPS_linkage_name:
2074 o->name = attr->string;
2075 break;
2076 case DW_AT_decl_file:
2077 o->file = attr->value;
2078 break;
2079 case DW_AT_decl_line:
2080 o->line = attr->value;
2081 break;
2082 case DW_AT_type:
2083 o->type = elfParseType(unit, attr->value);
2084 break;
2085 case DW_AT_external:
2086 o->external = attr->flag;
2087 break;
2088 case DW_AT_const_value:
2089 case DW_AT_abstract_origin:
2090 case DW_AT_declaration:
2091 case DW_AT_artificial:
2092 // todo
2093 break;
2094 case DW_AT_specification:
2095 // TODO:
2096 break;
2097 default:
2098 fprintf(stderr, "Unknown object attribute %02x\n", attr->name);
2099 break;
2104 u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit,
2105 Object **object)
2107 Object *o = (Object *)calloc(sizeof(Object), 1);
2109 o->next = NULL;
2111 for (int i = 0; i < abbrev->numAttrs; i++)
2113 ELFAttr *attr = &abbrev->attrs[i];
2114 data = elfReadAttribute(data, attr);
2115 switch (attr->name)
2117 case DW_AT_location:
2118 o->location = attr->block;
2119 break;
2120 case DW_AT_name:
2121 if (o->name == NULL)
2122 o->name = attr->string;
2123 break;
2124 case DW_AT_MIPS_linkage_name:
2125 o->name = attr->string;
2126 break;
2127 case DW_AT_decl_file:
2128 o->file = attr->value;
2129 break;
2130 case DW_AT_decl_line:
2131 o->line = attr->value;
2132 break;
2133 case DW_AT_type:
2134 o->type = elfParseType(unit, attr->value);
2135 break;
2136 case DW_AT_external:
2137 o->external = attr->flag;
2138 break;
2139 case DW_AT_abstract_origin:
2140 elfGetObjectAttributes(unit, attr->value, o);
2141 break;
2142 case DW_AT_const_value:
2143 case DW_AT_declaration:
2144 case DW_AT_artificial:
2145 break;
2146 case DW_AT_specification:
2147 // TODO:
2148 break;
2149 default:
2150 fprintf(stderr, "Unknown object attribute %02x\n", attr->name);
2151 break;
2154 *object = o;
2155 return data;
2158 u8 *elfParseBlock(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit,
2159 Function *func, Object **lastVar)
2161 int bytes;
2162 u32 start = func->lowPC;
2163 u32 end = func->highPC;
2165 for (int i = 0; i < abbrev->numAttrs; i++)
2167 ELFAttr *attr = &abbrev->attrs[i];
2168 data = elfReadAttribute(data, attr);
2169 switch (attr->name)
2171 case DW_AT_sibling:
2172 break;
2173 case DW_AT_low_pc:
2174 start = attr->value;
2175 break;
2176 case DW_AT_high_pc:
2177 end = attr->value;
2178 break;
2179 case DW_AT_ranges: // ignore for now
2180 break;
2181 default:
2182 fprintf(stderr, "Unknown block attribute %02x\n", attr->name);
2183 break;
2187 if (abbrev->hasChildren)
2189 int nesting = 1;
2191 while (nesting)
2193 u32 abbrevNum = elfReadLEB128(data, &bytes);
2194 data += bytes;
2196 if (!abbrevNum)
2198 nesting--;
2199 continue;
2202 abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2204 switch (abbrev->tag)
2206 CASE_TYPE_TAG: // types only parsed when used
2207 case DW_TAG_label: // not needed
2208 data = elfSkipData(data, abbrev, unit->abbrevs);
2209 break;
2210 case DW_TAG_lexical_block:
2211 data = elfParseBlock(data, abbrev, unit, func, lastVar);
2212 break;
2213 case DW_TAG_subprogram:
2215 Function *f = NULL;
2216 data = elfParseFunction(data, abbrev, unit, &f);
2217 if (f != NULL)
2219 if (unit->lastFunction)
2220 unit->lastFunction->next = f;
2221 else
2222 unit->functions = f;
2223 unit->lastFunction = f;
2225 break;
2227 case DW_TAG_variable:
2229 Object *o;
2230 data = elfParseObject(data, abbrev, unit, &o);
2231 if (o->startScope == 0)
2232 o->startScope = start;
2233 if (o->endScope == 0)
2234 o->endScope = 0;
2235 if (func->variables)
2236 (*lastVar)->next = o;
2237 else
2238 func->variables = o;
2239 *lastVar = o;
2240 break;
2242 case DW_TAG_inlined_subroutine:
2243 // TODO:
2244 data = elfSkipData(data, abbrev, unit->abbrevs);
2245 break;
2246 default:
2248 fprintf(stderr, "Unknown block TAG %02x\n", abbrev->tag);
2249 data = elfSkipData(data, abbrev, unit->abbrevs);
2250 break;
2255 return data;
2258 void elfGetFunctionAttributes(CompileUnit *unit, u32 offset, Function *func)
2260 u8 *data = unit->top + offset;
2261 int bytes;
2262 u32 abbrevNum = elfReadLEB128(data, &bytes);
2263 data += bytes;
2265 if (!abbrevNum)
2267 return;
2270 ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2272 for (int i = 0; i < abbrev->numAttrs; i++)
2274 ELFAttr *attr = &abbrev->attrs[i];
2275 data = elfReadAttribute(data, attr);
2277 switch (attr->name)
2279 case DW_AT_sibling:
2280 break;
2281 case DW_AT_name:
2282 if (func->name == NULL)
2283 func->name = attr->string;
2284 break;
2285 case DW_AT_MIPS_linkage_name:
2286 func->name = attr->string;
2287 break;
2288 case DW_AT_low_pc:
2289 func->lowPC = attr->value;
2290 break;
2291 case DW_AT_high_pc:
2292 func->highPC = attr->value;
2293 break;
2294 case DW_AT_decl_file:
2295 func->file = attr->value;
2296 break;
2297 case DW_AT_decl_line:
2298 func->line = attr->value;
2299 break;
2300 case DW_AT_external:
2301 func->external = attr->flag;
2302 break;
2303 case DW_AT_frame_base:
2304 func->frameBase = attr->block;
2305 break;
2306 case DW_AT_type:
2307 func->returnType = elfParseType(unit, attr->value);
2308 break;
2309 case DW_AT_inline:
2310 case DW_AT_specification:
2311 case DW_AT_declaration:
2312 case DW_AT_artificial:
2313 case DW_AT_prototyped:
2314 case DW_AT_proc_body:
2315 case DW_AT_save_offset:
2316 case DW_AT_user_2002:
2317 case DW_AT_virtuality:
2318 case DW_AT_containing_type:
2319 case DW_AT_accessibility:
2320 // todo;
2321 break;
2322 case DW_AT_vtable_elem_location:
2323 free(attr->block);
2324 break;
2325 default:
2326 fprintf(stderr, "Unknown function attribute %02x\n", attr->name);
2327 break;
2331 return;
2334 u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit,
2335 Function **f)
2337 Function *func = (Function *)calloc(sizeof(Function), 1);
2338 *f = func;
2340 int bytes;
2341 bool mangled = false;
2342 bool declaration = false;
2343 for (int i = 0; i < abbrev->numAttrs; i++)
2345 ELFAttr *attr = &abbrev->attrs[i];
2346 data = elfReadAttribute(data, attr);
2347 switch (attr->name)
2349 case DW_AT_sibling:
2350 break;
2351 case DW_AT_name:
2352 if (func->name == NULL)
2353 func->name = attr->string;
2354 break;
2355 case DW_AT_MIPS_linkage_name:
2356 func->name = attr->string;
2357 mangled = true;
2358 break;
2359 case DW_AT_low_pc:
2360 func->lowPC = attr->value;
2361 break;
2362 case DW_AT_high_pc:
2363 func->highPC = attr->value;
2364 break;
2365 case DW_AT_prototyped:
2366 break;
2367 case DW_AT_decl_file:
2368 func->file = attr->value;
2369 break;
2370 case DW_AT_decl_line:
2371 func->line = attr->value;
2372 break;
2373 case DW_AT_external:
2374 func->external = attr->flag;
2375 break;
2376 case DW_AT_frame_base:
2377 func->frameBase = attr->block;
2378 break;
2379 case DW_AT_type:
2380 func->returnType = elfParseType(unit, attr->value);
2381 break;
2382 case DW_AT_abstract_origin:
2383 elfGetFunctionAttributes(unit, attr->value, func);
2384 break;
2385 case DW_AT_declaration:
2386 declaration = attr->flag;
2387 break;
2388 case DW_AT_inline:
2389 case DW_AT_specification:
2390 case DW_AT_artificial:
2391 case DW_AT_proc_body:
2392 case DW_AT_save_offset:
2393 case DW_AT_user_2002:
2394 case DW_AT_virtuality:
2395 case DW_AT_containing_type:
2396 case DW_AT_accessibility:
2397 // todo;
2398 break;
2399 case DW_AT_vtable_elem_location:
2400 free(attr->block);
2401 break;
2402 default:
2403 fprintf(stderr, "Unknown function attribute %02x\n", attr->name);
2404 break;
2408 if (declaration)
2410 elfCleanUp(func);
2411 free(func);
2412 *f = NULL;
2414 while (1)
2416 u32 abbrevNum = elfReadLEB128(data, &bytes);
2417 data += bytes;
2419 if (!abbrevNum)
2421 return data;
2424 abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2426 data = elfSkipData(data, abbrev, unit->abbrevs);
2430 if (abbrev->hasChildren)
2432 int nesting = 1;
2433 Object *lastParam = NULL;
2434 Object *lastVar = NULL;
2436 while (nesting)
2438 u32 abbrevNum = elfReadLEB128(data, &bytes);
2439 data += bytes;
2441 if (!abbrevNum)
2443 nesting--;
2444 continue;
2447 abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2449 switch (abbrev->tag)
2451 CASE_TYPE_TAG: // no need to parse types. only parsed when used
2452 case DW_TAG_label: // not needed
2453 data = elfSkipData(data, abbrev, unit->abbrevs);
2454 break;
2455 case DW_TAG_subprogram:
2457 Function *fnc = NULL;
2458 data = elfParseFunction(data, abbrev, unit, &fnc);
2459 if (fnc != NULL)
2461 if (unit->lastFunction == NULL)
2462 unit->functions = fnc;
2463 else
2464 unit->lastFunction->next = fnc;
2465 unit->lastFunction = fnc;
2467 break;
2469 case DW_TAG_lexical_block:
2471 data = elfParseBlock(data, abbrev, unit, func, &lastVar);
2472 break;
2474 case DW_TAG_formal_parameter:
2476 Object *o;
2477 data = elfParseObject(data, abbrev, unit, &o);
2478 if (func->parameters)
2479 lastParam->next = o;
2480 else
2481 func->parameters = o;
2482 lastParam = o;
2483 break;
2485 case DW_TAG_variable:
2487 Object *o;
2488 data = elfParseObject(data, abbrev, unit, &o);
2489 if (func->variables)
2490 lastVar->next = o;
2491 else
2492 func->variables = o;
2493 lastVar = o;
2494 break;
2496 case DW_TAG_unspecified_parameters:
2497 case DW_TAG_inlined_subroutine:
2499 // todo
2500 for (int i = 0; i < abbrev->numAttrs; i++)
2502 data = elfReadAttribute(data, &abbrev->attrs[i]);
2503 if (abbrev->attrs[i].form == DW_FORM_block1)
2504 free(abbrev->attrs[i].block);
2507 if (abbrev->hasChildren)
2508 nesting++;
2509 break;
2511 default:
2513 fprintf(stderr, "Unknown function TAG %02x\n", abbrev->tag);
2514 data = elfSkipData(data, abbrev, unit->abbrevs);
2515 break;
2520 return data;
2523 u8 *elfParseUnknownData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs)
2525 int i;
2526 int bytes;
2527 // switch(abbrev->tag) {
2528 // default:
2529 fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag);
2531 for (i = 0; i < abbrev->numAttrs; i++)
2533 data = elfReadAttribute(data, &abbrev->attrs[i]);
2534 if (abbrev->attrs[i].form == DW_FORM_block1)
2535 free(abbrev->attrs[i].block);
2538 if (abbrev->hasChildren)
2540 int nesting = 1;
2541 while (nesting)
2543 u32 abbrevNum = elfReadLEB128(data, &bytes);
2544 data += bytes;
2546 if (!abbrevNum)
2548 nesting--;
2549 continue;
2552 abbrev = elfGetAbbrev(abbrevs, abbrevNum);
2554 fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag);
2556 for (i = 0; i < abbrev->numAttrs; i++)
2558 data = elfReadAttribute(data, &abbrev->attrs[i]);
2559 if (abbrev->attrs[i].form == DW_FORM_block1)
2560 free(abbrev->attrs[i].block);
2563 if (abbrev->hasChildren)
2565 nesting++;
2569 // }
2570 return data;
2573 u8 *elfParseCompileUnitChildren(u8 *data, CompileUnit *unit)
2575 int bytes;
2576 u32 abbrevNum = elfReadLEB128(data, &bytes);
2577 data += bytes;
2578 Object *lastObj = NULL;
2579 while (abbrevNum)
2581 ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum);
2582 switch (abbrev->tag)
2584 case DW_TAG_subprogram:
2586 Function *func = NULL;
2587 data = elfParseFunction(data, abbrev, unit, &func);
2588 if (func != NULL)
2590 if (unit->lastFunction)
2591 unit->lastFunction->next = func;
2592 else
2593 unit->functions = func;
2594 unit->lastFunction = func;
2596 break;
2598 CASE_TYPE_TAG:
2599 data = elfSkipData(data, abbrev, unit->abbrevs);
2600 break;
2601 case DW_TAG_variable:
2603 Object *var = NULL;
2604 data = elfParseObject(data, abbrev, unit, &var);
2605 if (lastObj)
2606 lastObj->next = var;
2607 else
2608 unit->variables = var;
2609 lastObj = var;
2610 break;
2612 default:
2613 data = elfParseUnknownData(data, abbrev, unit->abbrevs);
2614 break;
2617 abbrevNum = elfReadLEB128(data, &bytes);
2618 data += bytes;
2620 return data;
2623 CompileUnit *elfParseCompUnit(u8 *data, u8 *abbrevData)
2625 int bytes;
2626 u8 *top = data;
2628 u32 length = elfRead4Bytes(data);
2629 data += 4;
2631 u16 version = elfRead2Bytes(data);
2632 data += 2;
2634 u32 offset = elfRead4Bytes(data);
2635 data += 4;
2637 u8 addrSize = *data++;
2639 if (version != 2)
2641 fprintf(stderr, "Unsupported debugging information version %d\n", version);
2642 return NULL;
2645 if (addrSize != 4)
2647 fprintf(stderr, "Unsupported address size %d\n", addrSize);
2648 return NULL;
2651 ELFAbbrev **abbrevs = elfReadAbbrevs(abbrevData, offset);
2653 u32 abbrevNum = elfReadLEB128(data, &bytes);
2654 data += bytes;
2656 ELFAbbrev *abbrev = elfGetAbbrev(abbrevs, abbrevNum);
2658 CompileUnit *unit = (CompileUnit *)calloc(sizeof(CompileUnit), 1);
2659 unit->top = top;
2660 unit->length = length;
2661 unit->abbrevs = abbrevs;
2662 unit->next = NULL;
2664 elfCurrentUnit = unit;
2666 int i;
2668 for (i = 0; i < abbrev->numAttrs; i++)
2670 ELFAttr *attr = &abbrev->attrs[i];
2671 data = elfReadAttribute(data, attr);
2673 switch (attr->name)
2675 case DW_AT_name:
2676 unit->name = attr->string;
2677 break;
2678 case DW_AT_stmt_list:
2679 unit->hasLineInfo = true;
2680 unit->lineInfo = attr->value;
2681 break;
2682 case DW_AT_low_pc:
2683 unit->lowPC = attr->value;
2684 break;
2685 case DW_AT_high_pc:
2686 unit->highPC = attr->value;
2687 break;
2688 case DW_AT_compdir:
2689 unit->compdir = attr->string;
2690 break;
2691 // ignore
2692 case DW_AT_language:
2693 case DW_AT_producer:
2694 case DW_AT_macro_info:
2695 case DW_AT_entry_pc:
2696 break;
2697 default:
2698 fprintf(stderr, "Unknown attribute %02x\n", attr->name);
2699 break;
2703 if (abbrev->hasChildren)
2704 elfParseCompileUnitChildren(data, unit);
2706 return unit;
2709 void elfParseAranges(u8 *data)
2711 ELFSectionHeader *sh = elfGetSectionByName(".debug_aranges");
2712 if (sh == NULL)
2714 fprintf(stderr, "No aranges found\n");
2715 return;
2718 data = elfReadSection(data, sh);
2719 u8 *end = data + READ32LE(&sh->size);
2721 int max = 4;
2722 ARanges *ranges = (ARanges *)calloc(sizeof(ARanges), 4);
2724 int index = 0;
2726 while (data < end)
2728 u32 len = elfRead4Bytes(data);
2729 data += 4;
2730 // u16 version = elfRead2Bytes(data);
2731 data += 2;
2732 u32 offset = elfRead4Bytes(data);
2733 data += 4;
2734 // u8 addrSize = *data++;
2735 // u8 segSize = *data++;
2736 data += 2; // remove if uncommenting above
2737 data += 4;
2738 ranges[index].count = (len-20)/8;
2739 ranges[index].offset = offset;
2740 ranges[index].ranges = (ARange *)calloc(sizeof(ARange), (len-20)/8);
2741 int i = 0;
2742 while (true)
2744 u32 addr = elfRead4Bytes(data);
2745 data += 4;
2746 u32 len = elfRead4Bytes(data);
2747 data += 4;
2748 if (addr == 0 && len == 0)
2749 break;
2750 ranges[index].ranges[i].lowPC = addr;
2751 ranges[index].ranges[i].highPC = addr+len;
2752 i++;
2754 index++;
2755 if (index == max)
2757 max += 4;
2758 ranges = (ARanges *)realloc(ranges, max*sizeof(ARanges));
2761 elfDebugInfo->numRanges = index;
2762 elfDebugInfo->ranges = ranges;
2765 void elfReadSymtab(u8 *data)
2767 ELFSectionHeader *sh = elfGetSectionByName(".symtab");
2768 int table = READ32LE(&sh->link);
2770 char *strtable = (char *)elfReadSection(data, elfGetSectionByNumber(table));
2772 ELFSymbol *symtab = (ELFSymbol *)elfReadSection(data, sh);
2774 int count = READ32LE(&sh->size) / sizeof(ELFSymbol);
2775 elfSymbolsCount = 0;
2777 elfSymbols = (Symbol *)malloc(sizeof(Symbol)*count);
2779 int i;
2781 for (i = 0; i < count; i++)
2783 ELFSymbol *s = &symtab[i];
2784 int type = s->info & 15;
2785 int binding = s->info >> 4;
2787 if (binding)
2789 Symbol *sym = &elfSymbols[elfSymbolsCount];
2790 sym->name = &strtable[READ32LE(&s->name)];
2791 sym->binding = binding;
2792 sym->type = type;
2793 sym->value = READ32LE(&s->value);
2794 sym->size = READ32LE(&s->size);
2795 elfSymbolsCount++;
2798 for (i = 0; i < count; i++)
2800 ELFSymbol *s = &symtab[i];
2801 int bind = s->info>>4;
2802 int type = s->info & 15;
2804 if (!bind)
2806 Symbol *sym = &elfSymbols[elfSymbolsCount];
2807 sym->name = &strtable[READ32LE(&s->name)];
2808 sym->binding = (s->info >> 4);
2809 sym->type = type;
2810 sym->value = READ32LE(&s->value);
2811 sym->size = READ32LE(&s->size);
2812 elfSymbolsCount++;
2815 elfSymbolsStrTab = strtable;
2816 // free(symtab);
2819 bool elfReadProgram(ELFHeader *eh, u8 *data, int& size, bool parseDebug)
2821 int count = READ16LE(&eh->e_phnum);
2822 int i;
2824 if (READ32LE(&eh->e_entry) == 0x2000000)
2825 cpuIsMultiBoot = true;
2827 // read program headers... should probably move this code down
2828 u8 *p = data + READ32LE(&eh->e_phoff);
2829 size = 0;
2830 for (i = 0; i < count; i++)
2832 ELFProgramHeader *ph = (ELFProgramHeader *)p;
2833 p += sizeof(ELFProgramHeader);
2834 if (READ16LE(&eh->e_phentsize) != sizeof(ELFProgramHeader))
2836 p += READ16LE(&eh->e_phentsize) - sizeof(ELFProgramHeader);
2839 // printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n",
2840 // i, ph->type, ph->offset, ph->vaddr, ph->paddr,
2841 // ph->filesz, ph->memsz, ph->flags, ph->align);
2842 if (cpuIsMultiBoot)
2844 if (READ32LE(&ph->paddr) >= 0x2000000 &&
2845 READ32LE(&ph->paddr) <= 0x203ffff)
2847 memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff],
2848 data + READ32LE(&ph->offset),
2849 READ32LE(&ph->filesz));
2852 else
2854 if (READ32LE(&ph->paddr) >= 0x8000000 &&
2855 READ32LE(&ph->paddr) <= 0x9ffffff)
2857 memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff],
2858 data + READ32LE(&ph->offset),
2859 READ32LE(&ph->filesz));
2860 size += READ32LE(&ph->filesz);
2865 char *stringTable = NULL;
2867 // read section headers
2868 p = data + READ32LE(&eh->e_shoff);
2869 count = READ16LE(&eh->e_shnum);
2871 ELFSectionHeader **sh = (ELFSectionHeader * *)
2872 malloc(sizeof(ELFSectionHeader *) * count);
2874 for (i = 0; i < count; i++)
2876 sh[i] = (ELFSectionHeader *)p;
2877 p += sizeof(ELFSectionHeader);
2878 if (READ16LE(&eh->e_shentsize) != sizeof(ELFSectionHeader))
2879 p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader);
2882 if (READ16LE(&eh->e_shstrndx) != 0)
2884 stringTable = (char *)elfReadSection(data,
2885 sh[READ16LE(&eh->e_shstrndx)]);
2888 elfSectionHeaders = sh;
2889 elfSectionHeadersStringTable = stringTable;
2890 elfSectionHeadersCount = count;
2892 for (i = 0; i < count; i++)
2894 // printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n",
2895 // i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type,
2896 // sh[i]->flags, sh[i]->addr, sh[i]->offset, sh[i]->size,
2897 // sh[i]->link, sh[i]->info);
2898 if (READ32LE(&sh[i]->flags) & 2) // load section
2900 if (cpuIsMultiBoot)
2902 if (READ32LE(&sh[i]->addr) >= 0x2000000 &&
2903 READ32LE(&sh[i]->addr) <= 0x203ffff)
2905 memcpy(&workRAM[READ32LE(&sh[i]->addr) & 0x3ffff], data +
2906 READ32LE(&sh[i]->offset),
2907 READ32LE(&sh[i]->size));
2910 else
2912 if (READ32LE(&sh[i]->addr) >= 0x8000000 &&
2913 READ32LE(&sh[i]->addr) <= 0x9ffffff)
2915 memcpy(&rom[READ32LE(&sh[i]->addr) & 0x1ffffff],
2916 data + READ32LE(&sh[i]->offset),
2917 READ32LE(&sh[i]->size));
2918 size += READ32LE(&sh[i]->size);
2924 if (parseDebug)
2926 fprintf(stderr, "Parsing debug info\n");
2928 ELFSectionHeader *dbgHeader = elfGetSectionByName(".debug_info");
2929 if (dbgHeader == NULL)
2931 fprintf(stderr, "Cannot find debug information\n");
2932 goto end;
2935 ELFSectionHeader *h = elfGetSectionByName(".debug_abbrev");
2936 if (h == NULL)
2938 fprintf(stderr, "Cannot find abbreviation table\n");
2939 goto end;
2942 elfDebugInfo = (DebugInfo *)calloc(sizeof(DebugInfo), 1);
2943 u8 *abbrevdata = elfReadSection(data, h);
2945 h = elfGetSectionByName(".debug_str");
2947 if (h == NULL)
2948 elfDebugStrings = NULL;
2949 else
2950 elfDebugStrings = (char *)elfReadSection(data, h);
2952 u8 *debugdata = elfReadSection(data, dbgHeader);
2954 elfDebugInfo->debugdata = data;
2955 elfDebugInfo->infodata = debugdata;
2957 u32 total = READ32LE(&dbgHeader->size);
2958 u8 *end = debugdata + total;
2959 u8 *ddata = debugdata;
2961 CompileUnit *last = NULL;
2962 CompileUnit *unit = NULL;
2964 while (ddata < end)
2966 unit = elfParseCompUnit(ddata, abbrevdata);
2967 unit->offset = ddata-debugdata;
2968 elfParseLineInfo(unit, data);
2969 if (last == NULL)
2970 elfCompileUnits = unit;
2971 else
2972 last->next = unit;
2973 last = unit;
2974 ddata += 4 + unit->length;
2976 elfParseAranges(data);
2977 CompileUnit *comp = elfCompileUnits;
2978 while (comp)
2980 ARanges *r = elfDebugInfo->ranges;
2981 for (int i = 0; i < elfDebugInfo->numRanges; i++)
2982 if (r[i].offset == comp->offset)
2984 comp->ranges = &r[i];
2985 break;
2987 comp = comp->next;
2989 elfParseCFA(data);
2990 elfReadSymtab(data);
2992 end:
2993 if (sh)
2995 free(sh);
2998 elfSectionHeaders = NULL;
2999 elfSectionHeadersStringTable = NULL;
3000 elfSectionHeadersCount = 0;
3002 return true;
3005 extern bool8 parseDebug;
3007 bool elfRead(const char *name, int& siz, FILE *f)
3009 fseek(f, 0, SEEK_END);
3010 long size = ftell(f);
3011 elfFileData = (u8 *)malloc(size);
3012 fseek(f, 0, SEEK_SET);
3013 fread(elfFileData, 1, size, f);
3014 fclose(f);
3016 ELFHeader *header = (ELFHeader *)elfFileData;
3018 if (READ32LE(&header->magic) != 0x464C457F ||
3019 READ16LE(&header->e_machine) != 40 ||
3020 header->clazz != 1)
3022 systemMessage(0, N_("Not a valid ELF file %s"), name);
3023 free(elfFileData);
3024 elfFileData = NULL;
3025 return false;
3028 if (!elfReadProgram(header, elfFileData, siz, parseDebug))
3030 free(elfFileData);
3031 elfFileData = NULL;
3032 return false;
3035 return true;
3038 void elfCleanUp(Object *o)
3040 free(o->location);
3043 void elfCleanUp(Function *func)
3045 Object *o = func->parameters;
3046 while (o)
3048 elfCleanUp(o);
3049 Object *next = o->next;
3050 free(o);
3051 o = next;
3054 o = func->variables;
3055 while (o)
3057 elfCleanUp(o);
3058 Object *next = o->next;
3059 free(o);
3060 o = next;
3062 free(func->frameBase);
3065 void elfCleanUp(ELFAbbrev **abbrevs)
3067 for (int i = 0; i < 121; i++)
3069 ELFAbbrev *abbrev = abbrevs[i];
3071 while (abbrev)
3073 free(abbrev->attrs);
3074 ELFAbbrev *next = abbrev->next;
3075 free(abbrev);
3077 abbrev = next;
3082 void elfCleanUp(Type *t)
3084 switch (t->type)
3086 case TYPE_function:
3087 if (t->function)
3089 Object *o = t->function->args;
3090 while (o)
3092 elfCleanUp(o);
3093 Object *next = o->next;
3094 free(o);
3095 o = next;
3097 free(t->function);
3099 break;
3100 case TYPE_array:
3101 if (t->array)
3103 free(t->array->bounds);
3104 free(t->array);
3106 break;
3107 case TYPE_struct:
3108 case TYPE_union:
3109 if (t->structure)
3111 for (int i = 0; i < t->structure->memberCount; i++)
3113 free(t->structure->members[i].location);
3115 free(t->structure->members);
3116 free(t->structure);
3118 break;
3119 case TYPE_enum:
3120 if (t->enumeration)
3122 free(t->enumeration->members);
3123 free(t->enumeration);
3125 break;
3126 case TYPE_base:
3127 case TYPE_pointer:
3128 case TYPE_void:
3129 case TYPE_reference:
3130 break; // nothing to do
3134 void elfCleanUp(CompileUnit *comp)
3136 elfCleanUp(comp->abbrevs);
3137 free(comp->abbrevs);
3138 Function *func = comp->functions;
3139 while (func)
3141 elfCleanUp(func);
3142 Function *next = func->next;
3143 free(func);
3144 func = next;
3146 Type *t = comp->types;
3147 while (t)
3149 elfCleanUp(t);
3150 Type *next = t->next;
3151 free(t);
3152 t = next;
3154 Object *o = comp->variables;
3155 while (o)
3157 elfCleanUp(o);
3158 Object *next = o->next;
3159 free(o);
3160 o = next;
3162 if (comp->lineInfoTable)
3164 free(comp->lineInfoTable->lines);
3165 free(comp->lineInfoTable->files);
3166 free(comp->lineInfoTable);
3170 void elfCleanUp()
3172 CompileUnit *comp = elfCompileUnits;
3174 while (comp)
3176 elfCleanUp(comp);
3177 CompileUnit *next = comp->next;
3178 free(comp);
3179 comp = next;
3181 elfCompileUnits = NULL;
3182 free(elfSymbols);
3183 elfSymbols = NULL;
3184 // free(elfSymbolsStrTab);
3185 elfSymbolsStrTab = NULL;
3187 elfDebugStrings = NULL;
3188 if (elfDebugInfo)
3190 int num = elfDebugInfo->numRanges;
3191 int i;
3192 for (i = 0; i < num; i++)
3194 free(elfDebugInfo->ranges[i].ranges);
3196 free(elfDebugInfo->ranges);
3197 free(elfDebugInfo);
3198 elfDebugInfo = NULL;
3201 if (elfFdes)
3203 if (elfFdeCount)
3205 for (int i = 0; i < elfFdeCount; i++)
3206 free(elfFdes[i]);
3208 free(elfFdes);
3210 elfFdes = NULL;
3211 elfFdeCount = 0;
3214 ELFcie *cie = elfCies;
3215 while (cie)
3217 ELFcie *next = cie->next;
3218 free(cie);
3219 cie = next;
3221 elfCies = NULL;
3223 if (elfFileData)
3225 free(elfFileData);
3226 elfFileData = NULL;