Mercurial > vba-linux
diff src/gba/elf.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gba/elf.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,3229 @@ 1.4 +#include <cstdio> 1.5 +#include <cstdlib> 1.6 +#include <cstring> 1.7 + 1.8 +#include "../Port.h" 1.9 +#include "../NLS.h" 1.10 +#include "../common/System.h" // systemMessage 1.11 +#include "GBAGlobals.h" 1.12 +#include "elf.h" 1.13 + 1.14 +#define elfReadMemory(addr) \ 1.15 + READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 1.16 + 1.17 +#define DW_TAG_array_type 0x01 1.18 +#define DW_TAG_enumeration_type 0x04 1.19 +#define DW_TAG_formal_parameter 0x05 1.20 +#define DW_TAG_label 0x0a 1.21 +#define DW_TAG_lexical_block 0x0b 1.22 +#define DW_TAG_member 0x0d 1.23 +#define DW_TAG_pointer_type 0x0f 1.24 +#define DW_TAG_reference_type 0x10 1.25 +#define DW_TAG_compile_unit 0x11 1.26 +#define DW_TAG_structure_type 0x13 1.27 +#define DW_TAG_subroutine_type 0x15 1.28 +#define DW_TAG_typedef 0x16 1.29 +#define DW_TAG_union_type 0x17 1.30 +#define DW_TAG_unspecified_parameters 0x18 1.31 +#define DW_TAG_inheritance 0x1c 1.32 +#define DW_TAG_inlined_subroutine 0x1d 1.33 +#define DW_TAG_subrange_type 0x21 1.34 +#define DW_TAG_base_type 0x24 1.35 +#define DW_TAG_const_type 0x26 1.36 +#define DW_TAG_enumerator 0x28 1.37 +#define DW_TAG_subprogram 0x2e 1.38 +#define DW_TAG_variable 0x34 1.39 +#define DW_TAG_volatile_type 0x35 1.40 + 1.41 +#define DW_AT_sibling 0x01 1.42 +#define DW_AT_location 0x02 1.43 +#define DW_AT_name 0x03 1.44 +#define DW_AT_byte_size 0x0b 1.45 +#define DW_AT_bit_offset 0x0c 1.46 +#define DW_AT_bit_size 0x0d 1.47 +#define DW_AT_stmt_list 0x10 1.48 +#define DW_AT_low_pc 0x11 1.49 +#define DW_AT_high_pc 0x12 1.50 +#define DW_AT_language 0x13 1.51 +#define DW_AT_compdir 0x1b 1.52 +#define DW_AT_const_value 0x1c 1.53 +#define DW_AT_containing_type 0x1d 1.54 +#define DW_AT_inline 0x20 1.55 +#define DW_AT_producer 0x25 1.56 +#define DW_AT_prototyped 0x27 1.57 +#define DW_AT_upper_bound 0x2f 1.58 +#define DW_AT_abstract_origin 0x31 1.59 +#define DW_AT_accessibility 0x32 1.60 +#define DW_AT_artificial 0x34 1.61 +#define DW_AT_data_member_location 0x38 1.62 +#define DW_AT_decl_file 0x3a 1.63 +#define DW_AT_decl_line 0x3b 1.64 +#define DW_AT_declaration 0x3c 1.65 +#define DW_AT_encoding 0x3e 1.66 +#define DW_AT_external 0x3f 1.67 +#define DW_AT_frame_base 0x40 1.68 +#define DW_AT_macro_info 0x43 1.69 +#define DW_AT_specification 0x47 1.70 +#define DW_AT_type 0x49 1.71 +#define DW_AT_virtuality 0x4c 1.72 +#define DW_AT_vtable_elem_location 0x4d 1.73 +// DWARF 2.1/3.0 extensions 1.74 +#define DW_AT_entry_pc 0x52 1.75 +#define DW_AT_ranges 0x55 1.76 +// ARM Compiler extensions 1.77 +#define DW_AT_proc_body 0x2000 1.78 +#define DW_AT_save_offset 0x2001 1.79 +#define DW_AT_user_2002 0x2002 1.80 +// MIPS extensions 1.81 +#define DW_AT_MIPS_linkage_name 0x2007 1.82 + 1.83 +#define DW_FORM_addr 0x01 1.84 +#define DW_FORM_data2 0x05 1.85 +#define DW_FORM_data4 0x06 1.86 +#define DW_FORM_string 0x08 1.87 +#define DW_FORM_block 0x09 1.88 +#define DW_FORM_block1 0x0a 1.89 +#define DW_FORM_data1 0x0b 1.90 +#define DW_FORM_flag 0x0c 1.91 +#define DW_FORM_sdata 0x0d 1.92 +#define DW_FORM_strp 0x0e 1.93 +#define DW_FORM_udata 0x0f 1.94 +#define DW_FORM_ref_addr 0x10 1.95 +#define DW_FORM_ref4 0x13 1.96 +#define DW_FORM_ref_udata 0x15 1.97 +#define DW_FORM_indirect 0x16 1.98 + 1.99 +#define DW_OP_addr 0x03 1.100 +#define DW_OP_plus_uconst 0x23 1.101 +#define DW_OP_reg0 0x50 1.102 +#define DW_OP_reg1 0x51 1.103 +#define DW_OP_reg2 0x52 1.104 +#define DW_OP_reg3 0x53 1.105 +#define DW_OP_reg4 0x54 1.106 +#define DW_OP_reg5 0x55 1.107 +#define DW_OP_reg6 0x56 1.108 +#define DW_OP_reg7 0x57 1.109 +#define DW_OP_reg8 0x58 1.110 +#define DW_OP_reg9 0x59 1.111 +#define DW_OP_reg10 0x5a 1.112 +#define DW_OP_reg11 0x5b 1.113 +#define DW_OP_reg12 0x5c 1.114 +#define DW_OP_reg13 0x5d 1.115 +#define DW_OP_reg14 0x5e 1.116 +#define DW_OP_reg15 0x5f 1.117 +#define DW_OP_fbreg 0x91 1.118 + 1.119 +#define DW_LNS_extended_op 0x00 1.120 +#define DW_LNS_copy 0x01 1.121 +#define DW_LNS_advance_pc 0x02 1.122 +#define DW_LNS_advance_line 0x03 1.123 +#define DW_LNS_set_file 0x04 1.124 +#define DW_LNS_set_column 0x05 1.125 +#define DW_LNS_negate_stmt 0x06 1.126 +#define DW_LNS_set_basic_block 0x07 1.127 +#define DW_LNS_const_add_pc 0x08 1.128 +#define DW_LNS_fixed_advance_pc 0x09 1.129 + 1.130 +#define DW_LNE_end_sequence 0x01 1.131 +#define DW_LNE_set_address 0x02 1.132 +#define DW_LNE_define_file 0x03 1.133 + 1.134 +#define DW_CFA_advance_loc 0x01 1.135 +#define DW_CFA_offset 0x02 1.136 +#define DW_CFA_restore 0x03 1.137 +#define DW_CFA_set_loc 0x01 1.138 +#define DW_CFA_advance_loc1 0x02 1.139 +#define DW_CFA_advance_loc2 0x03 1.140 +#define DW_CFA_advance_loc4 0x04 1.141 +#define DW_CFA_offset_extended 0x05 1.142 +#define DW_CFA_restore_extended 0x06 1.143 +#define DW_CFA_undefined 0x07 1.144 +#define DW_CFA_same_value 0x08 1.145 +#define DW_CFA_register 0x09 1.146 +#define DW_CFA_remember_state 0x0a 1.147 +#define DW_CFA_restore_state 0x0b 1.148 +#define DW_CFA_def_cfa 0x0c 1.149 +#define DW_CFA_def_cfa_register 0x0d 1.150 +#define DW_CFA_def_cfa_offset 0x0e 1.151 +#define DW_CFA_nop 0x00 1.152 + 1.153 +#define CASE_TYPE_TAG \ 1.154 +case DW_TAG_const_type: \ 1.155 +case DW_TAG_volatile_type: \ 1.156 +case DW_TAG_pointer_type: \ 1.157 +case DW_TAG_base_type: \ 1.158 +case DW_TAG_array_type: \ 1.159 +case DW_TAG_structure_type: \ 1.160 +case DW_TAG_union_type: \ 1.161 +case DW_TAG_typedef: \ 1.162 +case DW_TAG_subroutine_type: \ 1.163 +case DW_TAG_enumeration_type: \ 1.164 +case DW_TAG_enumerator: \ 1.165 +case DW_TAG_reference_type 1.166 + 1.167 +struct ELFcie 1.168 +{ 1.169 + ELFcie *next; 1.170 + u32 offset; 1.171 + u8 * augmentation; 1.172 + u32 codeAlign; 1.173 + s32 dataAlign; 1.174 + int returnAddress; 1.175 + u8 * data; 1.176 + u32 dataLen; 1.177 +}; 1.178 + 1.179 +struct ELFfde 1.180 +{ 1.181 + ELFcie *cie; 1.182 + u32 address; 1.183 + u32 end; 1.184 + u8 * data; 1.185 + u32 dataLen; 1.186 +}; 1.187 + 1.188 +enum ELFRegMode 1.189 +{ 1.190 + REG_NOT_SET, 1.191 + REG_OFFSET, 1.192 + REG_REGISTER 1.193 +}; 1.194 + 1.195 +struct ELFFrameStateRegister 1.196 +{ 1.197 + ELFRegMode mode; 1.198 + int reg; 1.199 + s32 offset; 1.200 +}; 1.201 + 1.202 +struct ELFFrameStateRegisters 1.203 +{ 1.204 + ELFFrameStateRegister regs[16]; 1.205 + ELFFrameStateRegisters *previous; 1.206 +}; 1.207 + 1.208 +enum ELFCfaMode 1.209 +{ 1.210 + CFA_NOT_SET, 1.211 + CFA_REG_OFFSET 1.212 +}; 1.213 + 1.214 +struct ELFFrameState 1.215 +{ 1.216 + ELFFrameStateRegisters registers; 1.217 + 1.218 + ELFCfaMode cfaMode; 1.219 + int cfaRegister; 1.220 + s32 cfaOffset; 1.221 + 1.222 + u32 pc; 1.223 + 1.224 + int dataAlign; 1.225 + int codeAlign; 1.226 + int returnAddress; 1.227 +}; 1.228 + 1.229 +extern bool8 cpuIsMultiBoot; 1.230 + 1.231 +Symbol *elfSymbols = NULL; 1.232 +char * elfSymbolsStrTab = NULL; 1.233 +int elfSymbolsCount = 0; 1.234 + 1.235 +ELFSectionHeader **elfSectionHeaders = NULL; 1.236 +char *elfSectionHeadersStringTable = NULL; 1.237 +int elfSectionHeadersCount = 0; 1.238 +u8 * elfFileData = NULL; 1.239 + 1.240 +CompileUnit *elfCompileUnits = NULL; 1.241 +DebugInfo * elfDebugInfo = NULL; 1.242 +char * elfDebugStrings = NULL; 1.243 + 1.244 +ELFcie * elfCies = NULL; 1.245 +ELFfde **elfFdes = NULL; 1.246 +int elfFdeCount = 0; 1.247 + 1.248 +CompileUnit *elfCurrentUnit = NULL; 1.249 + 1.250 +u32 elfRead4Bytes(u8 *); 1.251 +u16 elfRead2Bytes(u8 *); 1.252 + 1.253 +CompileUnit *elfGetCompileUnit(u32 addr) 1.254 +{ 1.255 + if (elfCompileUnits) 1.256 + { 1.257 + CompileUnit *unit = elfCompileUnits; 1.258 + while (unit) 1.259 + { 1.260 + if (unit->lowPC) 1.261 + { 1.262 + if (addr >= unit->lowPC && addr < unit->highPC) 1.263 + return unit; 1.264 + } 1.265 + else 1.266 + { 1.267 + ARanges *r = unit->ranges; 1.268 + if (r) 1.269 + { 1.270 + int count = r->count; 1.271 + for (int j = 0; j < count; j++) 1.272 + { 1.273 + if (addr >= r->ranges[j].lowPC && addr < r->ranges[j].highPC) 1.274 + return unit; 1.275 + } 1.276 + } 1.277 + } 1.278 + unit = unit->next; 1.279 + } 1.280 + } 1.281 + return NULL; 1.282 +} 1.283 + 1.284 +char *elfGetAddressSymbol(u32 addr) 1.285 +{ 1.286 + static char buffer[256]; 1.287 + 1.288 + CompileUnit *unit = elfGetCompileUnit(addr); 1.289 + // found unit, need to find function 1.290 + if (unit) 1.291 + { 1.292 + Function *func = unit->functions; 1.293 + while (func) 1.294 + { 1.295 + if (addr >= func->lowPC && addr < func->highPC) 1.296 + { 1.297 + int offset = addr - func->lowPC; 1.298 + char *name = func->name; 1.299 + if (!name) 1.300 + name = ""; 1.301 + if (offset) 1.302 + sprintf(buffer, "%s+%d", name, offset); 1.303 + else 1.304 + strcpy(buffer, name); 1.305 + return buffer; 1.306 + } 1.307 + func = func->next; 1.308 + } 1.309 + } 1.310 + 1.311 + if (elfSymbolsCount) 1.312 + { 1.313 + for (int i = 0; i < elfSymbolsCount; i++) 1.314 + { 1.315 + Symbol *s = &elfSymbols[i]; 1.316 + if ((addr >= s->value) && addr < (s->value+s->size)) 1.317 + { 1.318 + int offset = addr-s->value; 1.319 + char *name = s->name; 1.320 + if (name == NULL) 1.321 + name = ""; 1.322 + if (offset) 1.323 + sprintf(buffer, "%s+%d", name, addr-s->value); 1.324 + else 1.325 + strcpy(buffer, name); 1.326 + return buffer; 1.327 + } 1.328 + else if (addr == s->value) 1.329 + { 1.330 + if (s->name) 1.331 + strcpy(buffer, s->name); 1.332 + else 1.333 + strcpy(buffer, ""); 1.334 + return buffer; 1.335 + } 1.336 + } 1.337 + } 1.338 + 1.339 + return ""; 1.340 +} 1.341 + 1.342 +bool elfFindLineInModule(u32 *addr, char *name, int line) 1.343 +{ 1.344 + CompileUnit *unit = elfCompileUnits; 1.345 + 1.346 + while (unit) 1.347 + { 1.348 + if (unit->lineInfoTable) 1.349 + { 1.350 + int i; 1.351 + int count = unit->lineInfoTable->fileCount; 1.352 + char *found = NULL; 1.353 + for (i = 0; i < count; i++) 1.354 + { 1.355 + if (strcmp(name, unit->lineInfoTable->files[i]) == 0) 1.356 + { 1.357 + found = unit->lineInfoTable->files[i]; 1.358 + break; 1.359 + } 1.360 + } 1.361 + // found a matching filename... try to find line now 1.362 + if (found) 1.363 + { 1.364 + LineInfoItem *table = unit->lineInfoTable->lines; 1.365 + count = unit->lineInfoTable->number; 1.366 + for (i = 0; i < count; i++) 1.367 + { 1.368 + if (table[i].file == found && table[i].line == line) 1.369 + { 1.370 + *addr = table[i].address; 1.371 + return true; 1.372 + } 1.373 + } 1.374 + // we can only find a single match 1.375 + return false; 1.376 + } 1.377 + } 1.378 + unit = unit->next; 1.379 + } 1.380 + return false; 1.381 +} 1.382 + 1.383 +int elfFindLine(CompileUnit *unit, Function * /* func */, u32 addr, char **f) 1.384 +{ 1.385 + int currentLine = -1; 1.386 + if (unit->hasLineInfo) 1.387 + { 1.388 + int count = unit->lineInfoTable->number; 1.389 + LineInfoItem *table = unit->lineInfoTable->lines; 1.390 + int i; 1.391 + for (i = 0; i < count; i++) 1.392 + { 1.393 + if (addr <= table[i].address) 1.394 + break; 1.395 + } 1.396 + if (i == count) 1.397 + i--; 1.398 + *f = table[i].file; 1.399 + currentLine = table[i].line; 1.400 + } 1.401 + return currentLine; 1.402 +} 1.403 + 1.404 +bool elfFindLineInUnit(u32 *addr, CompileUnit *unit, int line) 1.405 +{ 1.406 + if (unit->hasLineInfo) 1.407 + { 1.408 + int count = unit->lineInfoTable->number; 1.409 + LineInfoItem *table = unit->lineInfoTable->lines; 1.410 + int i; 1.411 + for (i = 0; i < count; i++) 1.412 + { 1.413 + if (line == table[i].line) 1.414 + { 1.415 + *addr = table[i].address; 1.416 + return true; 1.417 + } 1.418 + } 1.419 + } 1.420 + return false; 1.421 +} 1.422 + 1.423 +bool elfGetCurrentFunction(u32 addr, Function **f, CompileUnit **u) 1.424 +{ 1.425 + CompileUnit *unit = elfGetCompileUnit(addr); 1.426 + // found unit, need to find function 1.427 + if (unit) 1.428 + { 1.429 + Function *func = unit->functions; 1.430 + while (func) 1.431 + { 1.432 + if (addr >= func->lowPC && addr < func->highPC) 1.433 + { 1.434 + *f = func; 1.435 + *u = unit; 1.436 + return true; 1.437 + } 1.438 + func = func->next; 1.439 + } 1.440 + } 1.441 + return false; 1.442 +} 1.443 + 1.444 +bool elfGetObject(char *name, Function *f, CompileUnit *u, Object **o) 1.445 +{ 1.446 + if (f && u) 1.447 + { 1.448 + Object *v = f->variables; 1.449 + 1.450 + while (v) 1.451 + { 1.452 + if (strcmp(name, v->name) == 0) 1.453 + { 1.454 + *o = v; 1.455 + return true; 1.456 + } 1.457 + v = v->next; 1.458 + } 1.459 + v = f->parameters; 1.460 + while (v) 1.461 + { 1.462 + if (strcmp(name, v->name) == 0) 1.463 + { 1.464 + *o = v; 1.465 + return true; 1.466 + } 1.467 + v = v->next; 1.468 + } 1.469 + v = u->variables; 1.470 + while (v) 1.471 + { 1.472 + if (strcmp(name, v->name) == 0) 1.473 + { 1.474 + *o = v; 1.475 + return true; 1.476 + } 1.477 + v = v->next; 1.478 + } 1.479 + } 1.480 + 1.481 + CompileUnit *c = elfCompileUnits; 1.482 + 1.483 + while (c) 1.484 + { 1.485 + if (c != u) 1.486 + { 1.487 + Object *v = c->variables; 1.488 + while (v) 1.489 + { 1.490 + if (strcmp(name, v->name) == 0) 1.491 + { 1.492 + *o = v; 1.493 + return true; 1.494 + } 1.495 + v = v->next; 1.496 + } 1.497 + } 1.498 + c = c->next; 1.499 + } 1.500 + 1.501 + return false; 1.502 +} 1.503 + 1.504 +char *elfGetSymbol(int i, u32 *value, u32 *size, int *type) 1.505 +{ 1.506 + if (i < elfSymbolsCount) 1.507 + { 1.508 + Symbol *s = &elfSymbols[i]; 1.509 + *value = s->value; 1.510 + *size = s->size; 1.511 + *type = s->type; 1.512 + return s->name; 1.513 + } 1.514 + return NULL; 1.515 +} 1.516 + 1.517 +bool elfGetSymbolAddress(char *sym, u32 *addr, u32 *size, int *type) 1.518 +{ 1.519 + if (elfSymbolsCount) 1.520 + { 1.521 + for (int i = 0; i < elfSymbolsCount; i++) 1.522 + { 1.523 + Symbol *s = &elfSymbols[i]; 1.524 + if (strcmp(sym, s->name) == 0) 1.525 + { 1.526 + *addr = s->value; 1.527 + *size = s->size; 1.528 + *type = s->type; 1.529 + return true; 1.530 + } 1.531 + } 1.532 + } 1.533 + return false; 1.534 +} 1.535 + 1.536 +ELFfde *elfGetFde(u32 address) 1.537 +{ 1.538 + if (elfFdes) 1.539 + { 1.540 + int i; 1.541 + for (i = 0; i < elfFdeCount; i++) 1.542 + { 1.543 + if (address >= elfFdes[i]->address && 1.544 + address < elfFdes[i]->end) 1.545 + { 1.546 + return elfFdes[i]; 1.547 + } 1.548 + } 1.549 + } 1.550 + 1.551 + return NULL; 1.552 +} 1.553 + 1.554 +void elfExecuteCFAInstructions(ELFFrameState *state, u8 *data, u32 len, 1.555 + u32 pc) 1.556 +{ 1.557 + u8 *end = data + len; 1.558 + int bytes; 1.559 + int reg; 1.560 + ELFFrameStateRegisters *fs; 1.561 + 1.562 + while (data < end && state->pc < pc) 1.563 + { 1.564 + u8 op = *data++; 1.565 + 1.566 + switch (op >> 6) 1.567 + { 1.568 + case DW_CFA_advance_loc: 1.569 + state->pc += (op & 0x3f) * state->codeAlign; 1.570 + break; 1.571 + case DW_CFA_offset: 1.572 + reg = op & 0x3f; 1.573 + state->registers.regs[reg].mode = REG_OFFSET; 1.574 + state->registers.regs[reg].offset = state->dataAlign * 1.575 + (s32)elfReadLEB128(data, &bytes); 1.576 + data += bytes; 1.577 + break; 1.578 + case DW_CFA_restore: 1.579 + // we don't care much about the other possible settings, 1.580 + // so just setting to unset is enough for now 1.581 + state->registers.regs[op & 0x3f].mode = REG_NOT_SET; 1.582 + break; 1.583 + case 0: 1.584 + switch (op & 0x3f) 1.585 + { 1.586 + case DW_CFA_nop: 1.587 + break; 1.588 + case DW_CFA_advance_loc1: 1.589 + state->pc += state->codeAlign * (*data++); 1.590 + break; 1.591 + case DW_CFA_advance_loc2: 1.592 + state->pc += state->codeAlign * elfRead2Bytes(data); 1.593 + data += 2; 1.594 + break; 1.595 + case DW_CFA_advance_loc4: 1.596 + state->pc += state->codeAlign * elfRead4Bytes(data); 1.597 + data += 4; 1.598 + break; 1.599 + case DW_CFA_offset_extended: 1.600 + reg = elfReadLEB128(data, &bytes); 1.601 + data += bytes; 1.602 + state->registers.regs[reg].mode = REG_OFFSET; 1.603 + state->registers.regs[reg].offset = state->dataAlign * 1.604 + (s32)elfReadLEB128(data, &bytes); 1.605 + data += bytes; 1.606 + break; 1.607 + case DW_CFA_restore_extended: 1.608 + case DW_CFA_undefined: 1.609 + case DW_CFA_same_value: 1.610 + reg = elfReadLEB128(data, &bytes); 1.611 + data += bytes; 1.612 + state->registers.regs[reg].mode = REG_NOT_SET; 1.613 + break; 1.614 + case DW_CFA_register: 1.615 + reg = elfReadLEB128(data, &bytes); 1.616 + data += bytes; 1.617 + state->registers.regs[reg].mode = REG_REGISTER; 1.618 + state->registers.regs[reg].reg = elfReadLEB128(data, &bytes); 1.619 + data += bytes; 1.620 + break; 1.621 + case DW_CFA_remember_state: 1.622 + fs = (ELFFrameStateRegisters *)calloc(1, 1.623 + sizeof(ELFFrameStateRegisters)); 1.624 + memcpy(fs, &state->registers, sizeof(ELFFrameStateRegisters)); 1.625 + state->registers.previous = fs; 1.626 + break; 1.627 + case DW_CFA_restore_state: 1.628 + if (state->registers.previous == NULL) 1.629 + { 1.630 + printf("Error: previous frame state is NULL.\n"); 1.631 + return; 1.632 + } 1.633 + fs = state->registers.previous; 1.634 + memcpy(&state->registers, fs, sizeof(ELFFrameStateRegisters)); 1.635 + free(fs); 1.636 + break; 1.637 + case DW_CFA_def_cfa: 1.638 + state->cfaRegister = elfReadLEB128(data, &bytes); 1.639 + data += bytes; 1.640 + state->cfaOffset = (s32)elfReadLEB128(data, &bytes); 1.641 + data += bytes; 1.642 + state->cfaMode = CFA_REG_OFFSET; 1.643 + break; 1.644 + case DW_CFA_def_cfa_register: 1.645 + state->cfaRegister = elfReadLEB128(data, &bytes); 1.646 + data += bytes; 1.647 + state->cfaMode = CFA_REG_OFFSET; 1.648 + break; 1.649 + case DW_CFA_def_cfa_offset: 1.650 + state->cfaOffset = (s32)elfReadLEB128(data, &bytes); 1.651 + data += bytes; 1.652 + state->cfaMode = CFA_REG_OFFSET; 1.653 + break; 1.654 + default: 1.655 + printf("Unknown CFA opcode %08x\n", op); 1.656 + return; 1.657 + } 1.658 + break; 1.659 + default: 1.660 + printf("Unknown CFA opcode %08x\n", op); 1.661 + return; 1.662 + } 1.663 + } 1.664 +} 1.665 + 1.666 +ELFFrameState *elfGetFrameState(ELFfde *fde, u32 address) 1.667 +{ 1.668 + ELFFrameState *state = (ELFFrameState *)calloc(1, sizeof(ELFFrameState)); 1.669 + state->pc = fde->address; 1.670 + state->dataAlign = fde->cie->dataAlign; 1.671 + state->codeAlign = fde->cie->codeAlign; 1.672 + state->returnAddress = fde->cie->returnAddress; 1.673 + 1.674 + elfExecuteCFAInstructions(state, 1.675 + fde->cie->data, 1.676 + fde->cie->dataLen, 1.677 + 0xffffffff); 1.678 + elfExecuteCFAInstructions(state, 1.679 + fde->data, 1.680 + fde->dataLen, 1.681 + address); 1.682 + 1.683 + return state; 1.684 +} 1.685 + 1.686 +void elfPrintCallChain(u32 address) 1.687 +{ 1.688 + int count = 1; 1.689 + 1.690 + reg_pair regs[15]; 1.691 + reg_pair newRegs[15]; 1.692 + 1.693 + memcpy(®s[0], ®[0], sizeof(reg_pair) * 15); 1.694 + 1.695 + while (count < 20) 1.696 + { 1.697 + char *addr = elfGetAddressSymbol(address); 1.698 + if (*addr == 0) 1.699 + addr = "???"; 1.700 + 1.701 + printf("%08x %s\n", address, addr); 1.702 + 1.703 + ELFfde *fde = elfGetFde(address); 1.704 + 1.705 + if (fde == NULL) 1.706 + { 1.707 + break; 1.708 + } 1.709 + 1.710 + ELFFrameState *state = elfGetFrameState(fde, address); 1.711 + 1.712 + if (!state) 1.713 + { 1.714 + break; 1.715 + } 1.716 + 1.717 + if (state->cfaMode == CFA_REG_OFFSET) 1.718 + { 1.719 + memcpy(&newRegs[0], ®s[0], sizeof(reg_pair) * 15); 1.720 + u32 addr = 0; 1.721 + for (int i = 0; i < 15; i++) 1.722 + { 1.723 + ELFFrameStateRegister *r = &state->registers. 1.724 + regs[i]; 1.725 + 1.726 + switch (r->mode) 1.727 + { 1.728 + case REG_NOT_SET: 1.729 + newRegs[i].I = regs[i].I; 1.730 + break; 1.731 + case REG_OFFSET: 1.732 + newRegs[i].I = elfReadMemory(regs[state->cfaRegister].I + 1.733 + state->cfaOffset + 1.734 + r->offset); 1.735 + break; 1.736 + case REG_REGISTER: 1.737 + newRegs[i].I = regs[r->reg].I; 1.738 + break; 1.739 + default: 1.740 + printf("Unknown register mode: %d\n", r->mode); 1.741 + break; 1.742 + } 1.743 + } 1.744 + memcpy(regs, newRegs, sizeof(reg_pair)*15); 1.745 + addr = newRegs[14].I; 1.746 + addr &= 0xfffffffe; 1.747 + address = addr; 1.748 + count++; 1.749 + } 1.750 + else 1.751 + { 1.752 + printf("CFA not set\n"); 1.753 + break; 1.754 + } 1.755 + if (state->registers.previous) 1.756 + { 1.757 + ELFFrameStateRegisters *prev = state->registers.previous; 1.758 + 1.759 + while (prev) 1.760 + { 1.761 + ELFFrameStateRegisters *p = prev->previous; 1.762 + free(prev); 1.763 + prev = p; 1.764 + } 1.765 + } 1.766 + free(state); 1.767 + } 1.768 +} 1.769 + 1.770 +u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type, u32 base) 1.771 +{ 1.772 + u32 framebase = 0; 1.773 + if (f && f->frameBase) 1.774 + { 1.775 + ELFBlock *b = f->frameBase; 1.776 + switch (*b->data) 1.777 + { 1.778 + case DW_OP_reg0: 1.779 + case DW_OP_reg1: 1.780 + case DW_OP_reg2: 1.781 + case DW_OP_reg3: 1.782 + case DW_OP_reg4: 1.783 + case DW_OP_reg5: 1.784 + case DW_OP_reg6: 1.785 + case DW_OP_reg7: 1.786 + case DW_OP_reg8: 1.787 + case DW_OP_reg9: 1.788 + case DW_OP_reg10: 1.789 + case DW_OP_reg11: 1.790 + case DW_OP_reg12: 1.791 + case DW_OP_reg13: 1.792 + case DW_OP_reg14: 1.793 + case DW_OP_reg15: 1.794 + framebase = reg[*b->data-0x50].I; 1.795 + break; 1.796 + default: 1.797 + fprintf(stderr, "Unknown frameBase %02x\n", *b->data); 1.798 + break; 1.799 + } 1.800 + } 1.801 + 1.802 + ELFBlock *loc = o; 1.803 + u32 location = 0; 1.804 + int bytes = 0; 1.805 + if (loc) 1.806 + { 1.807 + switch (*loc->data) 1.808 + { 1.809 + case DW_OP_addr: 1.810 + location = elfRead4Bytes(loc->data+1); 1.811 + *type = LOCATION_memory; 1.812 + break; 1.813 + case DW_OP_plus_uconst: 1.814 + location = base + elfReadLEB128(loc->data+1, &bytes); 1.815 + *type = LOCATION_memory; 1.816 + break; 1.817 + case DW_OP_reg0: 1.818 + case DW_OP_reg1: 1.819 + case DW_OP_reg2: 1.820 + case DW_OP_reg3: 1.821 + case DW_OP_reg4: 1.822 + case DW_OP_reg5: 1.823 + case DW_OP_reg6: 1.824 + case DW_OP_reg7: 1.825 + case DW_OP_reg8: 1.826 + case DW_OP_reg9: 1.827 + case DW_OP_reg10: 1.828 + case DW_OP_reg11: 1.829 + case DW_OP_reg12: 1.830 + case DW_OP_reg13: 1.831 + case DW_OP_reg14: 1.832 + case DW_OP_reg15: 1.833 + location = *loc->data - 0x50; 1.834 + *type = LOCATION_register; 1.835 + break; 1.836 + case DW_OP_fbreg: 1.837 + { 1.838 + int bytes; 1.839 + s32 off = elfReadSignedLEB128(loc->data+1, &bytes); 1.840 + location = framebase + off; 1.841 + *type = LOCATION_memory; 1.842 + break; 1.843 + } 1.844 + default: 1.845 + fprintf(stderr, "Unknown location %02x\n", *loc->data); 1.846 + break; 1.847 + } 1.848 + } 1.849 + return location; 1.850 +} 1.851 + 1.852 +u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type) 1.853 +{ 1.854 + return elfDecodeLocation(f, o, type, 0); 1.855 +} 1.856 + 1.857 +// reading function 1.858 + 1.859 +u32 elfRead4Bytes(u8 *data) 1.860 +{ 1.861 + u32 value = *data++; 1.862 + value |= (*data++ << 8); 1.863 + value |= (*data++ << 16); 1.864 + value |= (*data << 24); 1.865 + return value; 1.866 +} 1.867 + 1.868 +u16 elfRead2Bytes(u8 *data) 1.869 +{ 1.870 + u16 value = *data++; 1.871 + value |= (*data << 8); 1.872 + return value; 1.873 +} 1.874 + 1.875 +char *elfReadString(u8 *data, int *bytesRead) 1.876 +{ 1.877 + if (*data == 0) 1.878 + { 1.879 + *bytesRead = 1; 1.880 + return NULL; 1.881 + } 1.882 + *bytesRead = strlen((char *)data) + 1; 1.883 + return (char *)data; 1.884 +} 1.885 + 1.886 +s32 elfReadSignedLEB128(u8 *data, int *bytesRead) 1.887 +{ 1.888 + s32 result = 0; 1.889 + int shift = 0; 1.890 + int count = 0; 1.891 + 1.892 + u8 byte; 1.893 + do 1.894 + { 1.895 + byte = *data++; 1.896 + count++; 1.897 + result |= (byte & 0x7f) << shift; 1.898 + shift += 7; 1.899 + } 1.900 + while (byte & 0x80); 1.901 + if ((shift < 32) && (byte & 0x40)) 1.902 + result |= -(1 << shift); 1.903 + *bytesRead = count; 1.904 + return result; 1.905 +} 1.906 + 1.907 +u32 elfReadLEB128(u8 *data, int *bytesRead) 1.908 +{ 1.909 + u32 result = 0; 1.910 + int shift = 0; 1.911 + int count = 0; 1.912 + u8 byte; 1.913 + do 1.914 + { 1.915 + byte = *data++; 1.916 + count++; 1.917 + result |= (byte & 0x7f) << shift; 1.918 + shift += 7; 1.919 + } 1.920 + while (byte & 0x80); 1.921 + *bytesRead = count; 1.922 + return result; 1.923 +} 1.924 + 1.925 +u8 *elfReadSection(u8 *data, ELFSectionHeader *sh) 1.926 +{ 1.927 + return data + READ32LE(&sh->offset); 1.928 +} 1.929 + 1.930 +ELFSectionHeader *elfGetSectionByName(char *name) 1.931 +{ 1.932 + for (int i = 0; i < elfSectionHeadersCount; i++) 1.933 + { 1.934 + if (strcmp(name, 1.935 + &elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]-> 1.936 + name)]) == 0) 1.937 + { 1.938 + return elfSectionHeaders[i]; 1.939 + } 1.940 + } 1.941 + return NULL; 1.942 +} 1.943 + 1.944 +ELFSectionHeader *elfGetSectionByNumber(int number) 1.945 +{ 1.946 + if (number < elfSectionHeadersCount) 1.947 + { 1.948 + return elfSectionHeaders[number]; 1.949 + } 1.950 + return NULL; 1.951 +} 1.952 + 1.953 +CompileUnit *elfGetCompileUnitForData(u8 *data) 1.954 +{ 1.955 + u8 *end = elfCurrentUnit->top + 4 + elfCurrentUnit->length; 1.956 + 1.957 + if (data >= elfCurrentUnit->top && data < end) 1.958 + return elfCurrentUnit; 1.959 + 1.960 + CompileUnit *unit = elfCompileUnits; 1.961 + 1.962 + while (unit) 1.963 + { 1.964 + end = unit->top + 4 + unit->length; 1.965 + 1.966 + if (data >= unit->top && data < end) 1.967 + return unit; 1.968 + 1.969 + unit = unit->next; 1.970 + } 1.971 + 1.972 + printf("Error: cannot find reference to compile unit at offset %08x\n", 1.973 + (int)(data - elfDebugInfo->infodata)); 1.974 + exit(-1); 1.975 +} 1.976 + 1.977 +u8 *elfReadAttribute(u8 *data, ELFAttr *attr) 1.978 +{ 1.979 + int bytes; 1.980 + int form = attr->form; 1.981 +start: 1.982 + switch (form) 1.983 + { 1.984 + case DW_FORM_addr: 1.985 + attr->value = elfRead4Bytes(data); 1.986 + data += 4; 1.987 + break; 1.988 + case DW_FORM_data2: 1.989 + attr->value = elfRead2Bytes(data); 1.990 + data += 2; 1.991 + break; 1.992 + case DW_FORM_data4: 1.993 + attr->value = elfRead4Bytes(data); 1.994 + data += 4; 1.995 + break; 1.996 + case DW_FORM_string: 1.997 + attr->string = (char *)data; 1.998 + data += strlen(attr->string)+1; 1.999 + break; 1.1000 + case DW_FORM_strp: 1.1001 + attr->string = elfDebugStrings + elfRead4Bytes(data); 1.1002 + data += 4; 1.1003 + break; 1.1004 + case DW_FORM_block: 1.1005 + attr->block = (ELFBlock *)malloc(sizeof(ELFBlock)); 1.1006 + attr->block->length = elfReadLEB128(data, &bytes); 1.1007 + data += bytes; 1.1008 + attr->block->data = data; 1.1009 + data += attr->block->length; 1.1010 + break; 1.1011 + case DW_FORM_block1: 1.1012 + attr->block = (ELFBlock *)malloc(sizeof(ELFBlock)); 1.1013 + attr->block->length = *data++; 1.1014 + attr->block->data = data; 1.1015 + data += attr->block->length; 1.1016 + break; 1.1017 + case DW_FORM_data1: 1.1018 + attr->value = *data++; 1.1019 + break; 1.1020 + case DW_FORM_flag: 1.1021 + attr->flag = (*data++) ? true : false; 1.1022 + break; 1.1023 + case DW_FORM_sdata: 1.1024 + attr->value = elfReadSignedLEB128(data, &bytes); 1.1025 + data += bytes; 1.1026 + break; 1.1027 + case DW_FORM_udata: 1.1028 + attr->value = elfReadLEB128(data, &bytes); 1.1029 + data += bytes; 1.1030 + break; 1.1031 + case DW_FORM_ref_addr: 1.1032 + attr->value = (elfDebugInfo->infodata + elfRead4Bytes(data)) - 1.1033 + elfGetCompileUnitForData(data)->top; 1.1034 + data += 4; 1.1035 + break; 1.1036 + case DW_FORM_ref4: 1.1037 + attr->value = elfRead4Bytes(data); 1.1038 + data += 4; 1.1039 + break; 1.1040 + case DW_FORM_ref_udata: 1.1041 + attr->value = (elfDebugInfo->infodata + 1.1042 + (elfGetCompileUnitForData(data)->top - 1.1043 + elfDebugInfo->infodata) + 1.1044 + elfReadLEB128(data, &bytes)) - 1.1045 + elfCurrentUnit->top; 1.1046 + data += bytes; 1.1047 + break; 1.1048 + case DW_FORM_indirect: 1.1049 + form = elfReadLEB128(data, &bytes); 1.1050 + data += bytes; 1.1051 + goto start; 1.1052 + default: 1.1053 + fprintf(stderr, "Unsupported FORM %02x\n", form); 1.1054 + exit(-1); 1.1055 + } 1.1056 + return data; 1.1057 +} 1.1058 + 1.1059 +ELFAbbrev *elfGetAbbrev(ELFAbbrev **table, u32 number) 1.1060 +{ 1.1061 + int hash = number % 121; 1.1062 + 1.1063 + ELFAbbrev *abbrev = table[hash]; 1.1064 + 1.1065 + while (abbrev) 1.1066 + { 1.1067 + if (abbrev->number == number) 1.1068 + return abbrev; 1.1069 + abbrev = abbrev->next; 1.1070 + } 1.1071 + return NULL; 1.1072 +} 1.1073 + 1.1074 +ELFAbbrev * *elfReadAbbrevs(u8 *data, u32 offset) 1.1075 +{ 1.1076 + data += offset; 1.1077 + ELFAbbrev **abbrevs = (ELFAbbrev * *)calloc(sizeof(ELFAbbrev *)*121, 1); 1.1078 + int bytes = 0; 1.1079 + u32 number = elfReadLEB128(data, &bytes); 1.1080 + data += bytes; 1.1081 + while (number) 1.1082 + { 1.1083 + ELFAbbrev *abbrev = (ELFAbbrev *)calloc(sizeof(ELFAbbrev), 1); 1.1084 + 1.1085 + // read tag information 1.1086 + abbrev->number = number; 1.1087 + abbrev->tag = elfReadLEB128(data, &bytes); 1.1088 + data += bytes; 1.1089 + abbrev->hasChildren = *data++ ? true : false; 1.1090 + 1.1091 + // read attributes 1.1092 + int name = elfReadLEB128(data, &bytes); 1.1093 + data += bytes; 1.1094 + int form = elfReadLEB128(data, &bytes); 1.1095 + data += bytes; 1.1096 + 1.1097 + while (name) 1.1098 + { 1.1099 + if ((abbrev->numAttrs % 4) == 0) 1.1100 + { 1.1101 + abbrev->attrs = (ELFAttr *)realloc(abbrev->attrs, 1.1102 + (abbrev->numAttrs + 4) * 1.1103 + sizeof(ELFAttr)); 1.1104 + } 1.1105 + abbrev->attrs[abbrev->numAttrs].name = name; 1.1106 + abbrev->attrs[abbrev->numAttrs++].form = form; 1.1107 + 1.1108 + name = elfReadLEB128(data, &bytes); 1.1109 + data += bytes; 1.1110 + form = elfReadLEB128(data, &bytes); 1.1111 + data += bytes; 1.1112 + } 1.1113 + 1.1114 + int hash = number % 121; 1.1115 + abbrev->next = abbrevs[hash]; 1.1116 + abbrevs[hash] = abbrev; 1.1117 + 1.1118 + number = elfReadLEB128(data, &bytes); 1.1119 + data += bytes; 1.1120 + 1.1121 + if (elfGetAbbrev(abbrevs, number) != NULL) 1.1122 + break; 1.1123 + } 1.1124 + 1.1125 + return abbrevs; 1.1126 +} 1.1127 + 1.1128 +void elfParseCFA(u8 *top) 1.1129 +{ 1.1130 + ELFSectionHeader *h = elfGetSectionByName(".debug_frame"); 1.1131 + 1.1132 + if (h == NULL) 1.1133 + { 1.1134 + return; 1.1135 + } 1.1136 + 1.1137 + u8 *data = elfReadSection(top, h); 1.1138 + 1.1139 + u8 *topOffset = data; 1.1140 + 1.1141 + u8 *end = data + READ32LE(&h->size); 1.1142 + 1.1143 + ELFcie *cies = NULL; 1.1144 + 1.1145 + while (data < end) 1.1146 + { 1.1147 + u32 offset = data - topOffset; 1.1148 + u32 len = elfRead4Bytes(data); 1.1149 + data += 4; 1.1150 + 1.1151 + u8 *dataEnd = data + len; 1.1152 + 1.1153 + u32 id = elfRead4Bytes(data); 1.1154 + data += 4; 1.1155 + 1.1156 + if (id == 0xffffffff) 1.1157 + { 1.1158 + // skip version 1.1159 + *data++; 1.1160 + 1.1161 + ELFcie *cie = (ELFcie *)calloc(1, sizeof(ELFcie)); 1.1162 + 1.1163 + cie->next = cies; 1.1164 + cies = cie; 1.1165 + 1.1166 + cie->offset = offset; 1.1167 + 1.1168 + cie->augmentation = data; 1.1169 + while (*data) 1.1170 + data++; 1.1171 + data++; 1.1172 + 1.1173 + if (*cie->augmentation) 1.1174 + { 1.1175 + fprintf(stderr, "Error: augmentation not supported\n"); 1.1176 + exit(-1); 1.1177 + } 1.1178 + 1.1179 + int bytes; 1.1180 + cie->codeAlign = elfReadLEB128(data, &bytes); 1.1181 + data += bytes; 1.1182 + 1.1183 + cie->dataAlign = elfReadSignedLEB128(data, &bytes); 1.1184 + data += bytes; 1.1185 + 1.1186 + cie->returnAddress = *data++; 1.1187 + 1.1188 + cie->data = data; 1.1189 + cie->dataLen = dataEnd - data; 1.1190 + } 1.1191 + else 1.1192 + { 1.1193 + ELFfde *fde = (ELFfde *)calloc(1, sizeof(ELFfde)); 1.1194 + 1.1195 + ELFcie *cie = cies; 1.1196 + 1.1197 + while (cie != NULL) 1.1198 + { 1.1199 + if (cie->offset == id) 1.1200 + break; 1.1201 + cie = cie->next; 1.1202 + } 1.1203 + 1.1204 + if (!cie) 1.1205 + { 1.1206 + fprintf(stderr, "Cannot find CIE %08x\n", id); 1.1207 + exit(-1); 1.1208 + } 1.1209 + 1.1210 + fde->cie = cie; 1.1211 + 1.1212 + fde->address = elfRead4Bytes(data); 1.1213 + data += 4; 1.1214 + 1.1215 + fde->end = fde->address + elfRead4Bytes(data); 1.1216 + data += 4; 1.1217 + 1.1218 + fde->data = data; 1.1219 + fde->dataLen = dataEnd - data; 1.1220 + 1.1221 + if ((elfFdeCount %10) == 0) 1.1222 + { 1.1223 + elfFdes = (ELFfde * *)realloc(elfFdes, (elfFdeCount+10) * 1.1224 + sizeof(ELFfde *)); 1.1225 + } 1.1226 + elfFdes[elfFdeCount++] = fde; 1.1227 + } 1.1228 + data = dataEnd; 1.1229 + } 1.1230 + 1.1231 + elfCies = cies; 1.1232 +} 1.1233 + 1.1234 +void elfAddLine(LineInfo *l, u32 a, int file, int line, int *max) 1.1235 +{ 1.1236 + if (l->number == *max) 1.1237 + { 1.1238 + *max += 1000; 1.1239 + l->lines = (LineInfoItem *)realloc(l->lines, *max*sizeof(LineInfoItem)); 1.1240 + } 1.1241 + LineInfoItem *li = &l->lines[l->number]; 1.1242 + li->file = l->files[file-1]; 1.1243 + li->address = a; 1.1244 + li->line = line; 1.1245 + l->number++; 1.1246 +} 1.1247 + 1.1248 +void elfParseLineInfo(CompileUnit *unit, u8 *top) 1.1249 +{ 1.1250 + ELFSectionHeader *h = elfGetSectionByName(".debug_line"); 1.1251 + if (h == NULL) 1.1252 + { 1.1253 + fprintf(stderr, "No line information found\n"); 1.1254 + return; 1.1255 + } 1.1256 + LineInfo *l = unit->lineInfoTable = (LineInfo *)calloc(1, sizeof(LineInfo)); 1.1257 + l->number = 0; 1.1258 + int max = 1000; 1.1259 + l->lines = (LineInfoItem *)malloc(1000*sizeof(LineInfoItem)); 1.1260 + 1.1261 + u8 *data = elfReadSection(top, h); 1.1262 + data += unit->lineInfo; 1.1263 + u32 totalLen = elfRead4Bytes(data); 1.1264 + data += 4; 1.1265 + u8 *end = data + totalLen; 1.1266 + // u16 version = elfRead2Bytes(data); 1.1267 + data += 2; 1.1268 + // u32 offset = elfRead4Bytes(data); 1.1269 + data += 4; 1.1270 + int minInstrSize = *data++; 1.1271 + int defaultIsStmt = *data++; 1.1272 + int lineBase = (s8)*data++; 1.1273 + int lineRange = *data++; 1.1274 + int opcodeBase = *data++; 1.1275 + u8 *stdOpLen = (u8 *)malloc(opcodeBase * sizeof(u8)); 1.1276 + stdOpLen[0] = 1; 1.1277 + int i; 1.1278 + for (i = 1; i < opcodeBase; i++) 1.1279 + stdOpLen[i] = *data++; 1.1280 + 1.1281 + free(stdOpLen); // todo 1.1282 + int bytes = 0; 1.1283 + 1.1284 + char *s; 1.1285 + while ((s = elfReadString(data, &bytes)) != NULL) 1.1286 + { 1.1287 + data += bytes; 1.1288 + // fprintf(stderr, "Directory is %s\n", s); 1.1289 + } 1.1290 + data += bytes; 1.1291 + int count = 4; 1.1292 + int index = 0; 1.1293 + l->files = (char * *)malloc(sizeof(char *)*count); 1.1294 + 1.1295 + while ((s = elfReadString(data, &bytes)) != NULL) 1.1296 + { 1.1297 + l->files[index++] = s; 1.1298 + 1.1299 + data += bytes; 1.1300 + // directory 1.1301 + elfReadLEB128(data, &bytes); 1.1302 + data += bytes; 1.1303 + // time 1.1304 + elfReadLEB128(data, &bytes); 1.1305 + data += bytes; 1.1306 + // size 1.1307 + elfReadLEB128(data, &bytes); 1.1308 + data += bytes; 1.1309 + // fprintf(stderr, "File is %s\n", s); 1.1310 + if (index == count) 1.1311 + { 1.1312 + count += 4; 1.1313 + l->files = (char * *)realloc(l->files, sizeof(char *)*count); 1.1314 + } 1.1315 + } 1.1316 + l->fileCount = index; 1.1317 + data += bytes; 1.1318 + 1.1319 + while (data < end) 1.1320 + { 1.1321 + u32 address = 0; 1.1322 + int file = 1; 1.1323 + int line = 1; 1.1324 + int col = 0; 1.1325 + int isStmt = defaultIsStmt; 1.1326 + int basicBlock = 0; 1.1327 + int endSeq = 0; 1.1328 + 1.1329 + while (!endSeq) 1.1330 + { 1.1331 + int op = *data++; 1.1332 + switch (op) 1.1333 + { 1.1334 + case DW_LNS_extended_op: 1.1335 + { 1.1336 + data++; 1.1337 + op = *data++; 1.1338 + switch (op) 1.1339 + { 1.1340 + case DW_LNE_end_sequence: 1.1341 + endSeq = 1; 1.1342 + break; 1.1343 + case DW_LNE_set_address: 1.1344 + address = elfRead4Bytes(data); 1.1345 + data += 4; 1.1346 + break; 1.1347 + default: 1.1348 + fprintf(stderr, "Unknown extended LINE opcode %02x\n", op); 1.1349 + exit(-1); 1.1350 + } 1.1351 + break; 1.1352 + } 1.1353 + case DW_LNS_copy: 1.1354 + // fprintf(stderr, "Address %08x line %d (%d)\n", address, line, file); 1.1355 + elfAddLine(l, address, file, line, &max); 1.1356 + basicBlock = 0; 1.1357 + break; 1.1358 + case DW_LNS_advance_pc: 1.1359 + address += minInstrSize * elfReadLEB128(data, &bytes); 1.1360 + data += bytes; 1.1361 + break; 1.1362 + case DW_LNS_advance_line: 1.1363 + line += elfReadSignedLEB128(data, &bytes); 1.1364 + data += bytes; 1.1365 + break; 1.1366 + case DW_LNS_set_file: 1.1367 + file = elfReadLEB128(data, &bytes); 1.1368 + data += bytes; 1.1369 + break; 1.1370 + case DW_LNS_set_column: 1.1371 + col = elfReadLEB128(data, &bytes); 1.1372 + data += bytes; 1.1373 + break; 1.1374 + case DW_LNS_negate_stmt: 1.1375 + isStmt = !isStmt; 1.1376 + break; 1.1377 + case DW_LNS_set_basic_block: 1.1378 + basicBlock = 1; 1.1379 + break; 1.1380 + case DW_LNS_const_add_pc: 1.1381 + address += (minInstrSize *((255 - opcodeBase)/lineRange)); 1.1382 + break; 1.1383 + case DW_LNS_fixed_advance_pc: 1.1384 + address += elfRead2Bytes(data); 1.1385 + data += 2; 1.1386 + break; 1.1387 + default: 1.1388 + op = op - opcodeBase; 1.1389 + address += (op / lineRange) * minInstrSize; 1.1390 + line += lineBase + (op % lineRange); 1.1391 + elfAddLine(l, address, file, line, &max); 1.1392 + // fprintf(stderr, "Address %08x line %d (%d)\n", address, line,file); 1.1393 + basicBlock = 1; 1.1394 + break; 1.1395 + } 1.1396 + } 1.1397 + } 1.1398 + l->lines = (LineInfoItem *)realloc(l->lines, l->number*sizeof(LineInfoItem)); 1.1399 +} 1.1400 + 1.1401 +u8 *elfSkipData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs) 1.1402 +{ 1.1403 + int i; 1.1404 + int bytes; 1.1405 + 1.1406 + for (i = 0; i < abbrev->numAttrs; i++) 1.1407 + { 1.1408 + data = elfReadAttribute(data, &abbrev->attrs[i]); 1.1409 + if (abbrev->attrs[i].form == DW_FORM_block1) 1.1410 + free(abbrev->attrs[i].block); 1.1411 + } 1.1412 + 1.1413 + if (abbrev->hasChildren) 1.1414 + { 1.1415 + int nesting = 1; 1.1416 + while (nesting) 1.1417 + { 1.1418 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.1419 + data += bytes; 1.1420 + 1.1421 + if (!abbrevNum) 1.1422 + { 1.1423 + nesting--; 1.1424 + continue; 1.1425 + } 1.1426 + 1.1427 + abbrev = elfGetAbbrev(abbrevs, abbrevNum); 1.1428 + 1.1429 + for (i = 0; i < abbrev->numAttrs; i++) 1.1430 + { 1.1431 + data = elfReadAttribute(data, &abbrev->attrs[i]); 1.1432 + if (abbrev->attrs[i].form == DW_FORM_block1) 1.1433 + free(abbrev->attrs[i].block); 1.1434 + } 1.1435 + 1.1436 + if (abbrev->hasChildren) 1.1437 + { 1.1438 + nesting++; 1.1439 + } 1.1440 + } 1.1441 + } 1.1442 + return data; 1.1443 +} 1.1444 + 1.1445 +Type *elfParseType(CompileUnit *unit, u32); 1.1446 +u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, 1.1447 + Object **object); 1.1448 +u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, 1.1449 + Function **function); 1.1450 +void elfCleanUp(Function *); 1.1451 + 1.1452 +void elfAddType(Type *type, CompileUnit *unit, u32 offset) 1.1453 +{ 1.1454 + if (type->next == NULL) 1.1455 + { 1.1456 + if (unit->types != type && type->offset == 0) 1.1457 + { 1.1458 + type->offset = offset; 1.1459 + type->next = unit->types; 1.1460 + unit->types = type; 1.1461 + } 1.1462 + } 1.1463 +} 1.1464 + 1.1465 +void elfParseType(u8 *data, u32 offset, ELFAbbrev *abbrev, CompileUnit *unit, 1.1466 + Type **type) 1.1467 +{ 1.1468 + switch (abbrev->tag) 1.1469 + { 1.1470 + case DW_TAG_typedef: 1.1471 + { 1.1472 + u32 typeref = 0; 1.1473 + char *name = NULL; 1.1474 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1475 + { 1.1476 + ELFAttr *attr = &abbrev->attrs[i]; 1.1477 + data = elfReadAttribute(data, attr); 1.1478 + switch (attr->name) 1.1479 + { 1.1480 + case DW_AT_name: 1.1481 + name = attr->string; 1.1482 + break; 1.1483 + case DW_AT_type: 1.1484 + typeref = attr->value; 1.1485 + break; 1.1486 + case DW_AT_decl_file: 1.1487 + case DW_AT_decl_line: 1.1488 + break; 1.1489 + default: 1.1490 + fprintf(stderr, "Unknown attribute for typedef %02x\n", attr->name); 1.1491 + break; 1.1492 + } 1.1493 + } 1.1494 + if (abbrev->hasChildren) 1.1495 + fprintf(stderr, "Unexpected children for typedef\n"); 1.1496 + *type = elfParseType(unit, typeref); 1.1497 + if (name) 1.1498 + (*type)->name = name; 1.1499 + return; 1.1500 + break; 1.1501 + } 1.1502 + case DW_TAG_union_type: 1.1503 + case DW_TAG_structure_type: 1.1504 + { 1.1505 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1506 + if (abbrev->tag == DW_TAG_structure_type) 1.1507 + t->type = TYPE_struct; 1.1508 + else 1.1509 + t->type = TYPE_union; 1.1510 + 1.1511 + Struct *s = (Struct *)calloc(sizeof(Struct), 1); 1.1512 + t->structure = s; 1.1513 + elfAddType(t, unit, offset); 1.1514 + 1.1515 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1516 + { 1.1517 + ELFAttr *attr = &abbrev->attrs[i]; 1.1518 + data = elfReadAttribute(data, attr); 1.1519 + switch (attr->name) 1.1520 + { 1.1521 + case DW_AT_name: 1.1522 + t->name = attr->string; 1.1523 + break; 1.1524 + case DW_AT_byte_size: 1.1525 + t->size = attr->value; 1.1526 + break; 1.1527 + case DW_AT_decl_file: 1.1528 + case DW_AT_decl_line: 1.1529 + case DW_AT_sibling: 1.1530 + case DW_AT_containing_type: // todo? 1.1531 + case DW_AT_declaration: 1.1532 + case DW_AT_specification: // TODO: 1.1533 + break; 1.1534 + default: 1.1535 + fprintf(stderr, "Unknown attribute for struct %02x\n", attr->name); 1.1536 + break; 1.1537 + } 1.1538 + } 1.1539 + if (abbrev->hasChildren) 1.1540 + { 1.1541 + int bytes; 1.1542 + u32 num = elfReadLEB128(data, &bytes); 1.1543 + data += bytes; 1.1544 + int index = 0; 1.1545 + while (num) 1.1546 + { 1.1547 + ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); 1.1548 + 1.1549 + switch (abbr->tag) 1.1550 + { 1.1551 + case DW_TAG_member: 1.1552 + { 1.1553 + if ((index % 4) == 0) 1.1554 + s->members = (Member *)realloc(s->members, 1.1555 + sizeof(Member)*(index+4)); 1.1556 + Member *m = &s->members[index]; 1.1557 + m->location = NULL; 1.1558 + m->bitOffset = 0; 1.1559 + m->bitSize = 0; 1.1560 + m->byteSize = 0; 1.1561 + for (int i = 0; i < abbr->numAttrs; i++) 1.1562 + { 1.1563 + ELFAttr *attr = &abbr->attrs[i]; 1.1564 + data = elfReadAttribute(data, attr); 1.1565 + switch (attr->name) 1.1566 + { 1.1567 + case DW_AT_name: 1.1568 + m->name = attr->string; 1.1569 + break; 1.1570 + case DW_AT_type: 1.1571 + m->type = elfParseType(unit, attr->value); 1.1572 + break; 1.1573 + case DW_AT_data_member_location: 1.1574 + m->location = attr->block; 1.1575 + break; 1.1576 + case DW_AT_byte_size: 1.1577 + m->byteSize = attr->value; 1.1578 + break; 1.1579 + case DW_AT_bit_offset: 1.1580 + m->bitOffset = attr->value; 1.1581 + break; 1.1582 + case DW_AT_bit_size: 1.1583 + m->bitSize = attr->value; 1.1584 + break; 1.1585 + case DW_AT_decl_file: 1.1586 + case DW_AT_decl_line: 1.1587 + case DW_AT_accessibility: 1.1588 + case DW_AT_artificial: // todo? 1.1589 + break; 1.1590 + default: 1.1591 + fprintf(stderr, "Unknown member attribute %02x\n", 1.1592 + attr->name); 1.1593 + } 1.1594 + } 1.1595 + index++; 1.1596 + break; 1.1597 + } 1.1598 + case DW_TAG_subprogram: 1.1599 + { 1.1600 + Function *fnc = NULL; 1.1601 + data = elfParseFunction(data, abbr, unit, &fnc); 1.1602 + if (fnc != NULL) 1.1603 + { 1.1604 + if (unit->lastFunction) 1.1605 + unit->lastFunction->next = fnc; 1.1606 + else 1.1607 + unit->functions = fnc; 1.1608 + unit->lastFunction = fnc; 1.1609 + } 1.1610 + break; 1.1611 + } 1.1612 + case DW_TAG_inheritance: 1.1613 + // TODO: add support 1.1614 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1615 + break; 1.1616 +CASE_TYPE_TAG: 1.1617 + // skip types... parsed only when used 1.1618 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1619 + break; 1.1620 + case DW_TAG_variable: 1.1621 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1622 + break; 1.1623 + default: 1.1624 + fprintf(stderr, "Unknown struct tag %02x %s\n", abbr->tag, t->name); 1.1625 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1626 + break; 1.1627 + } 1.1628 + num = elfReadLEB128(data, &bytes); 1.1629 + data += bytes; 1.1630 + } 1.1631 + s->memberCount = index; 1.1632 + } 1.1633 + *type = t; 1.1634 + return; 1.1635 + break; 1.1636 + } 1.1637 + case DW_TAG_base_type: 1.1638 + { 1.1639 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1640 + 1.1641 + t->type = TYPE_base; 1.1642 + elfAddType(t, unit, offset); 1.1643 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1644 + { 1.1645 + ELFAttr *attr = &abbrev->attrs[i]; 1.1646 + data = elfReadAttribute(data, attr); 1.1647 + switch (attr->name) 1.1648 + { 1.1649 + case DW_AT_name: 1.1650 + t->name = attr->string; 1.1651 + break; 1.1652 + case DW_AT_encoding: 1.1653 + t->encoding = attr->value; 1.1654 + break; 1.1655 + case DW_AT_byte_size: 1.1656 + t->size = attr->value; 1.1657 + break; 1.1658 + case DW_AT_bit_size: 1.1659 + t->bitSize = attr->value; 1.1660 + break; 1.1661 + default: 1.1662 + fprintf(stderr, "Unknown attribute for base type %02x\n", 1.1663 + attr->name); 1.1664 + break; 1.1665 + } 1.1666 + } 1.1667 + if (abbrev->hasChildren) 1.1668 + fprintf(stderr, "Unexpected children for base type\n"); 1.1669 + *type = t; 1.1670 + return; 1.1671 + break; 1.1672 + } 1.1673 + case DW_TAG_pointer_type: 1.1674 + { 1.1675 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1676 + 1.1677 + t->type = TYPE_pointer; 1.1678 + 1.1679 + elfAddType(t, unit, offset); 1.1680 + 1.1681 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1682 + { 1.1683 + ELFAttr *attr = &abbrev->attrs[i]; 1.1684 + data = elfReadAttribute(data, attr); 1.1685 + switch (attr->name) 1.1686 + { 1.1687 + case DW_AT_type: 1.1688 + t->pointer = elfParseType(unit, attr->value); 1.1689 + break; 1.1690 + case DW_AT_byte_size: 1.1691 + t->size = attr->value; 1.1692 + break; 1.1693 + default: 1.1694 + fprintf(stderr, "Unknown pointer type attribute %02x\n", attr->name); 1.1695 + break; 1.1696 + } 1.1697 + } 1.1698 + if (abbrev->hasChildren) 1.1699 + fprintf(stderr, "Unexpected children for pointer type\n"); 1.1700 + *type = t; 1.1701 + return; 1.1702 + break; 1.1703 + } 1.1704 + case DW_TAG_reference_type: 1.1705 + { 1.1706 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1707 + 1.1708 + t->type = TYPE_reference; 1.1709 + 1.1710 + elfAddType(t, unit, offset); 1.1711 + 1.1712 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1713 + { 1.1714 + ELFAttr *attr = &abbrev->attrs[i]; 1.1715 + data = elfReadAttribute(data, attr); 1.1716 + switch (attr->name) 1.1717 + { 1.1718 + case DW_AT_type: 1.1719 + t->pointer = elfParseType(unit, attr->value); 1.1720 + break; 1.1721 + case DW_AT_byte_size: 1.1722 + t->size = attr->value; 1.1723 + break; 1.1724 + default: 1.1725 + fprintf(stderr, "Unknown ref type attribute %02x\n", attr->name); 1.1726 + break; 1.1727 + } 1.1728 + } 1.1729 + if (abbrev->hasChildren) 1.1730 + fprintf(stderr, "Unexpected children for ref type\n"); 1.1731 + *type = t; 1.1732 + return; 1.1733 + break; 1.1734 + } 1.1735 + case DW_TAG_volatile_type: 1.1736 + { 1.1737 + u32 typeref = 0; 1.1738 + 1.1739 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1740 + { 1.1741 + ELFAttr *attr = &abbrev->attrs[i]; 1.1742 + data = elfReadAttribute(data, attr); 1.1743 + switch (attr->name) 1.1744 + { 1.1745 + case DW_AT_type: 1.1746 + typeref = attr->value; 1.1747 + break; 1.1748 + default: 1.1749 + fprintf(stderr, "Unknown volatile attribute for type %02x\n", 1.1750 + attr->name); 1.1751 + break; 1.1752 + } 1.1753 + } 1.1754 + if (abbrev->hasChildren) 1.1755 + fprintf(stderr, "Unexpected children for volatile type\n"); 1.1756 + *type = elfParseType(unit, typeref); 1.1757 + return; 1.1758 + break; 1.1759 + } 1.1760 + case DW_TAG_const_type: 1.1761 + { 1.1762 + u32 typeref = 0; 1.1763 + 1.1764 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1765 + { 1.1766 + ELFAttr *attr = &abbrev->attrs[i]; 1.1767 + data = elfReadAttribute(data, attr); 1.1768 + switch (attr->name) 1.1769 + { 1.1770 + case DW_AT_type: 1.1771 + typeref = attr->value; 1.1772 + break; 1.1773 + default: 1.1774 + fprintf(stderr, "Unknown const attribute for type %02x\n", 1.1775 + attr->name); 1.1776 + break; 1.1777 + } 1.1778 + } 1.1779 + if (abbrev->hasChildren) 1.1780 + fprintf(stderr, "Unexpected children for const type\n"); 1.1781 + *type = elfParseType(unit, typeref); 1.1782 + return; 1.1783 + break; 1.1784 + } 1.1785 + case DW_TAG_enumeration_type: 1.1786 + { 1.1787 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1788 + t->type = TYPE_enum; 1.1789 + Enum *e = (Enum *)calloc(sizeof(Enum), 1); 1.1790 + t->enumeration = e; 1.1791 + elfAddType(t, unit, offset); 1.1792 + int count = 0; 1.1793 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1794 + { 1.1795 + ELFAttr *attr = &abbrev->attrs[i]; 1.1796 + data = elfReadAttribute(data, attr); 1.1797 + switch (attr->name) 1.1798 + { 1.1799 + case DW_AT_name: 1.1800 + t->name = attr->string; 1.1801 + break; 1.1802 + case DW_AT_byte_size: 1.1803 + t->size = attr->value; 1.1804 + break; 1.1805 + case DW_AT_sibling: 1.1806 + case DW_AT_decl_file: 1.1807 + case DW_AT_decl_line: 1.1808 + break; 1.1809 + default: 1.1810 + fprintf(stderr, "Unknown enum attribute %02x\n", attr->name); 1.1811 + } 1.1812 + } 1.1813 + if (abbrev->hasChildren) 1.1814 + { 1.1815 + int bytes; 1.1816 + u32 num = elfReadLEB128(data, &bytes); 1.1817 + data += bytes; 1.1818 + while (num) 1.1819 + { 1.1820 + ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); 1.1821 + 1.1822 + switch (abbr->tag) 1.1823 + { 1.1824 + case DW_TAG_enumerator: 1.1825 + { 1.1826 + count++; 1.1827 + e->members = (EnumMember *)realloc(e->members, 1.1828 + count*sizeof(EnumMember)); 1.1829 + EnumMember *m = &e->members[count-1]; 1.1830 + for (int i = 0; i < abbr->numAttrs; i++) 1.1831 + { 1.1832 + ELFAttr *attr = &abbr->attrs[i]; 1.1833 + data = elfReadAttribute(data, attr); 1.1834 + switch (attr->name) 1.1835 + { 1.1836 + case DW_AT_name: 1.1837 + m->name = attr->string; 1.1838 + break; 1.1839 + case DW_AT_const_value: 1.1840 + m->value = attr->value; 1.1841 + break; 1.1842 + default: 1.1843 + fprintf(stderr, "Unknown sub param attribute %02x\n", 1.1844 + attr->name); 1.1845 + } 1.1846 + } 1.1847 + break; 1.1848 + } 1.1849 + default: 1.1850 + fprintf(stderr, "Unknown enum tag %02x\n", abbr->tag); 1.1851 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1852 + break; 1.1853 + } 1.1854 + num = elfReadLEB128(data, &bytes); 1.1855 + data += bytes; 1.1856 + } 1.1857 + } 1.1858 + e->count = count; 1.1859 + *type = t; 1.1860 + return; 1.1861 + break; 1.1862 + } 1.1863 + case DW_TAG_subroutine_type: 1.1864 + { 1.1865 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.1866 + t->type = TYPE_function; 1.1867 + FunctionType *f = (FunctionType *)calloc(sizeof(FunctionType), 1); 1.1868 + t->function = f; 1.1869 + elfAddType(t, unit, offset); 1.1870 + for (int i = 0; i < abbrev->numAttrs; i++) 1.1871 + { 1.1872 + ELFAttr *attr = &abbrev->attrs[i]; 1.1873 + data = elfReadAttribute(data, attr); 1.1874 + switch (attr->name) 1.1875 + { 1.1876 + case DW_AT_prototyped: 1.1877 + case DW_AT_sibling: 1.1878 + break; 1.1879 + case DW_AT_type: 1.1880 + f->returnType = elfParseType(unit, attr->value); 1.1881 + break; 1.1882 + default: 1.1883 + fprintf(stderr, "Unknown subroutine attribute %02x\n", attr->name); 1.1884 + } 1.1885 + } 1.1886 + if (abbrev->hasChildren) 1.1887 + { 1.1888 + int bytes; 1.1889 + u32 num = elfReadLEB128(data, &bytes); 1.1890 + data += bytes; 1.1891 + Object *lastVar = NULL; 1.1892 + while (num) 1.1893 + { 1.1894 + ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); 1.1895 + 1.1896 + switch (abbr->tag) 1.1897 + { 1.1898 + case DW_TAG_formal_parameter: 1.1899 + { 1.1900 + Object *o; 1.1901 + data = elfParseObject(data, abbr, unit, &o); 1.1902 + if (f->args) 1.1903 + lastVar->next = o; 1.1904 + else 1.1905 + f->args = o; 1.1906 + lastVar = o; 1.1907 + break; 1.1908 + } 1.1909 + case DW_TAG_unspecified_parameters: 1.1910 + // no use in the debugger yet 1.1911 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1912 + break; 1.1913 +CASE_TYPE_TAG: 1.1914 + // skip types... parsed only when used 1.1915 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1916 + break; 1.1917 + default: 1.1918 + fprintf(stderr, "Unknown subroutine tag %02x\n", abbr->tag); 1.1919 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1920 + break; 1.1921 + } 1.1922 + num = elfReadLEB128(data, &bytes); 1.1923 + data += bytes; 1.1924 + } 1.1925 + } 1.1926 + *type = t; 1.1927 + return; 1.1928 + break; 1.1929 + } 1.1930 + case DW_TAG_array_type: 1.1931 + { 1.1932 + u32 typeref = 0; 1.1933 + int i; 1.1934 + Array *array = (Array *)calloc(sizeof(Array), 1); 1.1935 + Type * t = (Type *)calloc(sizeof(Type), 1); 1.1936 + t->type = TYPE_array; 1.1937 + elfAddType(t, unit, offset); 1.1938 + 1.1939 + for (i = 0; i < abbrev->numAttrs; i++) 1.1940 + { 1.1941 + ELFAttr *attr = &abbrev->attrs[i]; 1.1942 + data = elfReadAttribute(data, attr); 1.1943 + switch (attr->name) 1.1944 + { 1.1945 + case DW_AT_sibling: 1.1946 + break; 1.1947 + case DW_AT_type: 1.1948 + typeref = attr->value; 1.1949 + array->type = elfParseType(unit, typeref); 1.1950 + break; 1.1951 + default: 1.1952 + fprintf(stderr, "Unknown array attribute %02x\n", attr->name); 1.1953 + } 1.1954 + } 1.1955 + if (abbrev->hasChildren) 1.1956 + { 1.1957 + int bytes; 1.1958 + u32 num = elfReadLEB128(data, &bytes); 1.1959 + data += bytes; 1.1960 + int index = 0; 1.1961 + int maxBounds = 0; 1.1962 + while (num) 1.1963 + { 1.1964 + ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); 1.1965 + 1.1966 + switch (abbr->tag) 1.1967 + { 1.1968 + case DW_TAG_subrange_type: 1.1969 + { 1.1970 + if (maxBounds == index) 1.1971 + { 1.1972 + maxBounds += 4; 1.1973 + array->bounds = (int *)realloc(array->bounds, 1.1974 + sizeof(int)*maxBounds); 1.1975 + } 1.1976 + for (int i = 0; i < abbr->numAttrs; i++) 1.1977 + { 1.1978 + ELFAttr *attr = &abbr->attrs[i]; 1.1979 + data = elfReadAttribute(data, attr); 1.1980 + switch (attr->name) 1.1981 + { 1.1982 + case DW_AT_upper_bound: 1.1983 + array->bounds[index] = attr->value+1; 1.1984 + break; 1.1985 + case DW_AT_type: // ignore 1.1986 + break; 1.1987 + default: 1.1988 + fprintf(stderr, "Unknown subrange attribute %02x\n", 1.1989 + attr->name); 1.1990 + } 1.1991 + } 1.1992 + index++; 1.1993 + break; 1.1994 + } 1.1995 + default: 1.1996 + fprintf(stderr, "Unknown array tag %02x\n", abbr->tag); 1.1997 + data = elfSkipData(data, abbr, unit->abbrevs); 1.1998 + break; 1.1999 + } 1.2000 + num = elfReadLEB128(data, &bytes); 1.2001 + data += bytes; 1.2002 + } 1.2003 + array->maxBounds = index; 1.2004 + } 1.2005 + t->size = array->type->size; 1.2006 + for (i = 0; i < array->maxBounds; i++) 1.2007 + t->size *= array->bounds[i]; 1.2008 + t->array = array; 1.2009 + *type = t; 1.2010 + return; 1.2011 + break; 1.2012 + } 1.2013 + default: 1.2014 + fprintf(stderr, "Unknown type TAG %02x\n", abbrev->tag); 1.2015 + exit(-1); 1.2016 + } 1.2017 +} 1.2018 + 1.2019 +Type *elfParseType(CompileUnit *unit, u32 offset) 1.2020 +{ 1.2021 + Type *t = unit->types; 1.2022 + 1.2023 + while (t) 1.2024 + { 1.2025 + if (t->offset == offset) 1.2026 + return t; 1.2027 + t = t->next; 1.2028 + } 1.2029 + if (offset == 0) 1.2030 + { 1.2031 + Type *t = (Type *)calloc(sizeof(Type), 1); 1.2032 + t->type = TYPE_void; 1.2033 + t->offset = 0; 1.2034 + elfAddType(t, unit, 0); 1.2035 + return t; 1.2036 + } 1.2037 + u8 *data = unit->top + offset; 1.2038 + int bytes; 1.2039 + int abbrevNum = elfReadLEB128(data, &bytes); 1.2040 + data += bytes; 1.2041 + Type *type = NULL; 1.2042 + 1.2043 + ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2044 + 1.2045 + elfParseType(data, offset, abbrev, unit, &type); 1.2046 + return type; 1.2047 +} 1.2048 + 1.2049 +void elfGetObjectAttributes(CompileUnit *unit, u32 offset, Object *o) 1.2050 +{ 1.2051 + u8 *data = unit->top + offset; 1.2052 + int bytes; 1.2053 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2054 + data += bytes; 1.2055 + 1.2056 + if (!abbrevNum) 1.2057 + { 1.2058 + return; 1.2059 + } 1.2060 + 1.2061 + ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2062 + 1.2063 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2064 + { 1.2065 + ELFAttr *attr = &abbrev->attrs[i]; 1.2066 + data = elfReadAttribute(data, attr); 1.2067 + switch (attr->name) 1.2068 + { 1.2069 + case DW_AT_location: 1.2070 + o->location = attr->block; 1.2071 + break; 1.2072 + case DW_AT_name: 1.2073 + if (o->name == NULL) 1.2074 + o->name = attr->string; 1.2075 + break; 1.2076 + case DW_AT_MIPS_linkage_name: 1.2077 + o->name = attr->string; 1.2078 + break; 1.2079 + case DW_AT_decl_file: 1.2080 + o->file = attr->value; 1.2081 + break; 1.2082 + case DW_AT_decl_line: 1.2083 + o->line = attr->value; 1.2084 + break; 1.2085 + case DW_AT_type: 1.2086 + o->type = elfParseType(unit, attr->value); 1.2087 + break; 1.2088 + case DW_AT_external: 1.2089 + o->external = attr->flag; 1.2090 + break; 1.2091 + case DW_AT_const_value: 1.2092 + case DW_AT_abstract_origin: 1.2093 + case DW_AT_declaration: 1.2094 + case DW_AT_artificial: 1.2095 + // todo 1.2096 + break; 1.2097 + case DW_AT_specification: 1.2098 + // TODO: 1.2099 + break; 1.2100 + default: 1.2101 + fprintf(stderr, "Unknown object attribute %02x\n", attr->name); 1.2102 + break; 1.2103 + } 1.2104 + } 1.2105 +} 1.2106 + 1.2107 +u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, 1.2108 + Object **object) 1.2109 +{ 1.2110 + Object *o = (Object *)calloc(sizeof(Object), 1); 1.2111 + 1.2112 + o->next = NULL; 1.2113 + 1.2114 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2115 + { 1.2116 + ELFAttr *attr = &abbrev->attrs[i]; 1.2117 + data = elfReadAttribute(data, attr); 1.2118 + switch (attr->name) 1.2119 + { 1.2120 + case DW_AT_location: 1.2121 + o->location = attr->block; 1.2122 + break; 1.2123 + case DW_AT_name: 1.2124 + if (o->name == NULL) 1.2125 + o->name = attr->string; 1.2126 + break; 1.2127 + case DW_AT_MIPS_linkage_name: 1.2128 + o->name = attr->string; 1.2129 + break; 1.2130 + case DW_AT_decl_file: 1.2131 + o->file = attr->value; 1.2132 + break; 1.2133 + case DW_AT_decl_line: 1.2134 + o->line = attr->value; 1.2135 + break; 1.2136 + case DW_AT_type: 1.2137 + o->type = elfParseType(unit, attr->value); 1.2138 + break; 1.2139 + case DW_AT_external: 1.2140 + o->external = attr->flag; 1.2141 + break; 1.2142 + case DW_AT_abstract_origin: 1.2143 + elfGetObjectAttributes(unit, attr->value, o); 1.2144 + break; 1.2145 + case DW_AT_const_value: 1.2146 + case DW_AT_declaration: 1.2147 + case DW_AT_artificial: 1.2148 + break; 1.2149 + case DW_AT_specification: 1.2150 + // TODO: 1.2151 + break; 1.2152 + default: 1.2153 + fprintf(stderr, "Unknown object attribute %02x\n", attr->name); 1.2154 + break; 1.2155 + } 1.2156 + } 1.2157 + *object = o; 1.2158 + return data; 1.2159 +} 1.2160 + 1.2161 +u8 *elfParseBlock(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, 1.2162 + Function *func, Object **lastVar) 1.2163 +{ 1.2164 + int bytes; 1.2165 + u32 start = func->lowPC; 1.2166 + u32 end = func->highPC; 1.2167 + 1.2168 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2169 + { 1.2170 + ELFAttr *attr = &abbrev->attrs[i]; 1.2171 + data = elfReadAttribute(data, attr); 1.2172 + switch (attr->name) 1.2173 + { 1.2174 + case DW_AT_sibling: 1.2175 + break; 1.2176 + case DW_AT_low_pc: 1.2177 + start = attr->value; 1.2178 + break; 1.2179 + case DW_AT_high_pc: 1.2180 + end = attr->value; 1.2181 + break; 1.2182 + case DW_AT_ranges: // ignore for now 1.2183 + break; 1.2184 + default: 1.2185 + fprintf(stderr, "Unknown block attribute %02x\n", attr->name); 1.2186 + break; 1.2187 + } 1.2188 + } 1.2189 + 1.2190 + if (abbrev->hasChildren) 1.2191 + { 1.2192 + int nesting = 1; 1.2193 + 1.2194 + while (nesting) 1.2195 + { 1.2196 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2197 + data += bytes; 1.2198 + 1.2199 + if (!abbrevNum) 1.2200 + { 1.2201 + nesting--; 1.2202 + continue; 1.2203 + } 1.2204 + 1.2205 + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2206 + 1.2207 + switch (abbrev->tag) 1.2208 + { 1.2209 +CASE_TYPE_TAG: // types only parsed when used 1.2210 + case DW_TAG_label: // not needed 1.2211 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2212 + break; 1.2213 + case DW_TAG_lexical_block: 1.2214 + data = elfParseBlock(data, abbrev, unit, func, lastVar); 1.2215 + break; 1.2216 + case DW_TAG_subprogram: 1.2217 + { 1.2218 + Function *f = NULL; 1.2219 + data = elfParseFunction(data, abbrev, unit, &f); 1.2220 + if (f != NULL) 1.2221 + { 1.2222 + if (unit->lastFunction) 1.2223 + unit->lastFunction->next = f; 1.2224 + else 1.2225 + unit->functions = f; 1.2226 + unit->lastFunction = f; 1.2227 + } 1.2228 + break; 1.2229 + } 1.2230 + case DW_TAG_variable: 1.2231 + { 1.2232 + Object *o; 1.2233 + data = elfParseObject(data, abbrev, unit, &o); 1.2234 + if (o->startScope == 0) 1.2235 + o->startScope = start; 1.2236 + if (o->endScope == 0) 1.2237 + o->endScope = 0; 1.2238 + if (func->variables) 1.2239 + (*lastVar)->next = o; 1.2240 + else 1.2241 + func->variables = o; 1.2242 + *lastVar = o; 1.2243 + break; 1.2244 + } 1.2245 + case DW_TAG_inlined_subroutine: 1.2246 + // TODO: 1.2247 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2248 + break; 1.2249 + default: 1.2250 + { 1.2251 + fprintf(stderr, "Unknown block TAG %02x\n", abbrev->tag); 1.2252 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2253 + break; 1.2254 + } 1.2255 + } 1.2256 + } 1.2257 + } 1.2258 + return data; 1.2259 +} 1.2260 + 1.2261 +void elfGetFunctionAttributes(CompileUnit *unit, u32 offset, Function *func) 1.2262 +{ 1.2263 + u8 *data = unit->top + offset; 1.2264 + int bytes; 1.2265 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2266 + data += bytes; 1.2267 + 1.2268 + if (!abbrevNum) 1.2269 + { 1.2270 + return; 1.2271 + } 1.2272 + 1.2273 + ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2274 + 1.2275 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2276 + { 1.2277 + ELFAttr *attr = &abbrev->attrs[i]; 1.2278 + data = elfReadAttribute(data, attr); 1.2279 + 1.2280 + switch (attr->name) 1.2281 + { 1.2282 + case DW_AT_sibling: 1.2283 + break; 1.2284 + case DW_AT_name: 1.2285 + if (func->name == NULL) 1.2286 + func->name = attr->string; 1.2287 + break; 1.2288 + case DW_AT_MIPS_linkage_name: 1.2289 + func->name = attr->string; 1.2290 + break; 1.2291 + case DW_AT_low_pc: 1.2292 + func->lowPC = attr->value; 1.2293 + break; 1.2294 + case DW_AT_high_pc: 1.2295 + func->highPC = attr->value; 1.2296 + break; 1.2297 + case DW_AT_decl_file: 1.2298 + func->file = attr->value; 1.2299 + break; 1.2300 + case DW_AT_decl_line: 1.2301 + func->line = attr->value; 1.2302 + break; 1.2303 + case DW_AT_external: 1.2304 + func->external = attr->flag; 1.2305 + break; 1.2306 + case DW_AT_frame_base: 1.2307 + func->frameBase = attr->block; 1.2308 + break; 1.2309 + case DW_AT_type: 1.2310 + func->returnType = elfParseType(unit, attr->value); 1.2311 + break; 1.2312 + case DW_AT_inline: 1.2313 + case DW_AT_specification: 1.2314 + case DW_AT_declaration: 1.2315 + case DW_AT_artificial: 1.2316 + case DW_AT_prototyped: 1.2317 + case DW_AT_proc_body: 1.2318 + case DW_AT_save_offset: 1.2319 + case DW_AT_user_2002: 1.2320 + case DW_AT_virtuality: 1.2321 + case DW_AT_containing_type: 1.2322 + case DW_AT_accessibility: 1.2323 + // todo; 1.2324 + break; 1.2325 + case DW_AT_vtable_elem_location: 1.2326 + free(attr->block); 1.2327 + break; 1.2328 + default: 1.2329 + fprintf(stderr, "Unknown function attribute %02x\n", attr->name); 1.2330 + break; 1.2331 + } 1.2332 + } 1.2333 + 1.2334 + return; 1.2335 +} 1.2336 + 1.2337 +u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, 1.2338 + Function **f) 1.2339 +{ 1.2340 + Function *func = (Function *)calloc(sizeof(Function), 1); 1.2341 + *f = func; 1.2342 + 1.2343 + int bytes; 1.2344 + bool mangled = false; 1.2345 + bool declaration = false; 1.2346 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2347 + { 1.2348 + ELFAttr *attr = &abbrev->attrs[i]; 1.2349 + data = elfReadAttribute(data, attr); 1.2350 + switch (attr->name) 1.2351 + { 1.2352 + case DW_AT_sibling: 1.2353 + break; 1.2354 + case DW_AT_name: 1.2355 + if (func->name == NULL) 1.2356 + func->name = attr->string; 1.2357 + break; 1.2358 + case DW_AT_MIPS_linkage_name: 1.2359 + func->name = attr->string; 1.2360 + mangled = true; 1.2361 + break; 1.2362 + case DW_AT_low_pc: 1.2363 + func->lowPC = attr->value; 1.2364 + break; 1.2365 + case DW_AT_high_pc: 1.2366 + func->highPC = attr->value; 1.2367 + break; 1.2368 + case DW_AT_prototyped: 1.2369 + break; 1.2370 + case DW_AT_decl_file: 1.2371 + func->file = attr->value; 1.2372 + break; 1.2373 + case DW_AT_decl_line: 1.2374 + func->line = attr->value; 1.2375 + break; 1.2376 + case DW_AT_external: 1.2377 + func->external = attr->flag; 1.2378 + break; 1.2379 + case DW_AT_frame_base: 1.2380 + func->frameBase = attr->block; 1.2381 + break; 1.2382 + case DW_AT_type: 1.2383 + func->returnType = elfParseType(unit, attr->value); 1.2384 + break; 1.2385 + case DW_AT_abstract_origin: 1.2386 + elfGetFunctionAttributes(unit, attr->value, func); 1.2387 + break; 1.2388 + case DW_AT_declaration: 1.2389 + declaration = attr->flag; 1.2390 + break; 1.2391 + case DW_AT_inline: 1.2392 + case DW_AT_specification: 1.2393 + case DW_AT_artificial: 1.2394 + case DW_AT_proc_body: 1.2395 + case DW_AT_save_offset: 1.2396 + case DW_AT_user_2002: 1.2397 + case DW_AT_virtuality: 1.2398 + case DW_AT_containing_type: 1.2399 + case DW_AT_accessibility: 1.2400 + // todo; 1.2401 + break; 1.2402 + case DW_AT_vtable_elem_location: 1.2403 + free(attr->block); 1.2404 + break; 1.2405 + default: 1.2406 + fprintf(stderr, "Unknown function attribute %02x\n", attr->name); 1.2407 + break; 1.2408 + } 1.2409 + } 1.2410 + 1.2411 + if (declaration) 1.2412 + { 1.2413 + elfCleanUp(func); 1.2414 + free(func); 1.2415 + *f = NULL; 1.2416 + 1.2417 + while (1) 1.2418 + { 1.2419 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2420 + data += bytes; 1.2421 + 1.2422 + if (!abbrevNum) 1.2423 + { 1.2424 + return data; 1.2425 + } 1.2426 + 1.2427 + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2428 + 1.2429 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2430 + } 1.2431 + } 1.2432 + 1.2433 + if (abbrev->hasChildren) 1.2434 + { 1.2435 + int nesting = 1; 1.2436 + Object *lastParam = NULL; 1.2437 + Object *lastVar = NULL; 1.2438 + 1.2439 + while (nesting) 1.2440 + { 1.2441 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2442 + data += bytes; 1.2443 + 1.2444 + if (!abbrevNum) 1.2445 + { 1.2446 + nesting--; 1.2447 + continue; 1.2448 + } 1.2449 + 1.2450 + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2451 + 1.2452 + switch (abbrev->tag) 1.2453 + { 1.2454 +CASE_TYPE_TAG: // no need to parse types. only parsed when used 1.2455 + case DW_TAG_label: // not needed 1.2456 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2457 + break; 1.2458 + case DW_TAG_subprogram: 1.2459 + { 1.2460 + Function *fnc = NULL; 1.2461 + data = elfParseFunction(data, abbrev, unit, &fnc); 1.2462 + if (fnc != NULL) 1.2463 + { 1.2464 + if (unit->lastFunction == NULL) 1.2465 + unit->functions = fnc; 1.2466 + else 1.2467 + unit->lastFunction->next = fnc; 1.2468 + unit->lastFunction = fnc; 1.2469 + } 1.2470 + break; 1.2471 + } 1.2472 + case DW_TAG_lexical_block: 1.2473 + { 1.2474 + data = elfParseBlock(data, abbrev, unit, func, &lastVar); 1.2475 + break; 1.2476 + } 1.2477 + case DW_TAG_formal_parameter: 1.2478 + { 1.2479 + Object *o; 1.2480 + data = elfParseObject(data, abbrev, unit, &o); 1.2481 + if (func->parameters) 1.2482 + lastParam->next = o; 1.2483 + else 1.2484 + func->parameters = o; 1.2485 + lastParam = o; 1.2486 + break; 1.2487 + } 1.2488 + case DW_TAG_variable: 1.2489 + { 1.2490 + Object *o; 1.2491 + data = elfParseObject(data, abbrev, unit, &o); 1.2492 + if (func->variables) 1.2493 + lastVar->next = o; 1.2494 + else 1.2495 + func->variables = o; 1.2496 + lastVar = o; 1.2497 + break; 1.2498 + } 1.2499 + case DW_TAG_unspecified_parameters: 1.2500 + case DW_TAG_inlined_subroutine: 1.2501 + { 1.2502 + // todo 1.2503 + for (int i = 0; i < abbrev->numAttrs; i++) 1.2504 + { 1.2505 + data = elfReadAttribute(data, &abbrev->attrs[i]); 1.2506 + if (abbrev->attrs[i].form == DW_FORM_block1) 1.2507 + free(abbrev->attrs[i].block); 1.2508 + } 1.2509 + 1.2510 + if (abbrev->hasChildren) 1.2511 + nesting++; 1.2512 + break; 1.2513 + } 1.2514 + default: 1.2515 + { 1.2516 + fprintf(stderr, "Unknown function TAG %02x\n", abbrev->tag); 1.2517 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2518 + break; 1.2519 + } 1.2520 + } 1.2521 + } 1.2522 + } 1.2523 + return data; 1.2524 +} 1.2525 + 1.2526 +u8 *elfParseUnknownData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs) 1.2527 +{ 1.2528 + int i; 1.2529 + int bytes; 1.2530 + // switch(abbrev->tag) { 1.2531 + // default: 1.2532 + fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag); 1.2533 + 1.2534 + for (i = 0; i < abbrev->numAttrs; i++) 1.2535 + { 1.2536 + data = elfReadAttribute(data, &abbrev->attrs[i]); 1.2537 + if (abbrev->attrs[i].form == DW_FORM_block1) 1.2538 + free(abbrev->attrs[i].block); 1.2539 + } 1.2540 + 1.2541 + if (abbrev->hasChildren) 1.2542 + { 1.2543 + int nesting = 1; 1.2544 + while (nesting) 1.2545 + { 1.2546 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2547 + data += bytes; 1.2548 + 1.2549 + if (!abbrevNum) 1.2550 + { 1.2551 + nesting--; 1.2552 + continue; 1.2553 + } 1.2554 + 1.2555 + abbrev = elfGetAbbrev(abbrevs, abbrevNum); 1.2556 + 1.2557 + fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag); 1.2558 + 1.2559 + for (i = 0; i < abbrev->numAttrs; i++) 1.2560 + { 1.2561 + data = elfReadAttribute(data, &abbrev->attrs[i]); 1.2562 + if (abbrev->attrs[i].form == DW_FORM_block1) 1.2563 + free(abbrev->attrs[i].block); 1.2564 + } 1.2565 + 1.2566 + if (abbrev->hasChildren) 1.2567 + { 1.2568 + nesting++; 1.2569 + } 1.2570 + } 1.2571 + } 1.2572 + // } 1.2573 + return data; 1.2574 +} 1.2575 + 1.2576 +u8 *elfParseCompileUnitChildren(u8 *data, CompileUnit *unit) 1.2577 +{ 1.2578 + int bytes; 1.2579 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2580 + data += bytes; 1.2581 + Object *lastObj = NULL; 1.2582 + while (abbrevNum) 1.2583 + { 1.2584 + ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); 1.2585 + switch (abbrev->tag) 1.2586 + { 1.2587 + case DW_TAG_subprogram: 1.2588 + { 1.2589 + Function *func = NULL; 1.2590 + data = elfParseFunction(data, abbrev, unit, &func); 1.2591 + if (func != NULL) 1.2592 + { 1.2593 + if (unit->lastFunction) 1.2594 + unit->lastFunction->next = func; 1.2595 + else 1.2596 + unit->functions = func; 1.2597 + unit->lastFunction = func; 1.2598 + } 1.2599 + break; 1.2600 + } 1.2601 +CASE_TYPE_TAG: 1.2602 + data = elfSkipData(data, abbrev, unit->abbrevs); 1.2603 + break; 1.2604 + case DW_TAG_variable: 1.2605 + { 1.2606 + Object *var = NULL; 1.2607 + data = elfParseObject(data, abbrev, unit, &var); 1.2608 + if (lastObj) 1.2609 + lastObj->next = var; 1.2610 + else 1.2611 + unit->variables = var; 1.2612 + lastObj = var; 1.2613 + break; 1.2614 + } 1.2615 + default: 1.2616 + data = elfParseUnknownData(data, abbrev, unit->abbrevs); 1.2617 + break; 1.2618 + } 1.2619 + 1.2620 + abbrevNum = elfReadLEB128(data, &bytes); 1.2621 + data += bytes; 1.2622 + } 1.2623 + return data; 1.2624 +} 1.2625 + 1.2626 +CompileUnit *elfParseCompUnit(u8 *data, u8 *abbrevData) 1.2627 +{ 1.2628 + int bytes; 1.2629 + u8 *top = data; 1.2630 + 1.2631 + u32 length = elfRead4Bytes(data); 1.2632 + data += 4; 1.2633 + 1.2634 + u16 version = elfRead2Bytes(data); 1.2635 + data += 2; 1.2636 + 1.2637 + u32 offset = elfRead4Bytes(data); 1.2638 + data += 4; 1.2639 + 1.2640 + u8 addrSize = *data++; 1.2641 + 1.2642 + if (version != 2) 1.2643 + { 1.2644 + fprintf(stderr, "Unsupported debugging information version %d\n", version); 1.2645 + return NULL; 1.2646 + } 1.2647 + 1.2648 + if (addrSize != 4) 1.2649 + { 1.2650 + fprintf(stderr, "Unsupported address size %d\n", addrSize); 1.2651 + return NULL; 1.2652 + } 1.2653 + 1.2654 + ELFAbbrev **abbrevs = elfReadAbbrevs(abbrevData, offset); 1.2655 + 1.2656 + u32 abbrevNum = elfReadLEB128(data, &bytes); 1.2657 + data += bytes; 1.2658 + 1.2659 + ELFAbbrev *abbrev = elfGetAbbrev(abbrevs, abbrevNum); 1.2660 + 1.2661 + CompileUnit *unit = (CompileUnit *)calloc(sizeof(CompileUnit), 1); 1.2662 + unit->top = top; 1.2663 + unit->length = length; 1.2664 + unit->abbrevs = abbrevs; 1.2665 + unit->next = NULL; 1.2666 + 1.2667 + elfCurrentUnit = unit; 1.2668 + 1.2669 + int i; 1.2670 + 1.2671 + for (i = 0; i < abbrev->numAttrs; i++) 1.2672 + { 1.2673 + ELFAttr *attr = &abbrev->attrs[i]; 1.2674 + data = elfReadAttribute(data, attr); 1.2675 + 1.2676 + switch (attr->name) 1.2677 + { 1.2678 + case DW_AT_name: 1.2679 + unit->name = attr->string; 1.2680 + break; 1.2681 + case DW_AT_stmt_list: 1.2682 + unit->hasLineInfo = true; 1.2683 + unit->lineInfo = attr->value; 1.2684 + break; 1.2685 + case DW_AT_low_pc: 1.2686 + unit->lowPC = attr->value; 1.2687 + break; 1.2688 + case DW_AT_high_pc: 1.2689 + unit->highPC = attr->value; 1.2690 + break; 1.2691 + case DW_AT_compdir: 1.2692 + unit->compdir = attr->string; 1.2693 + break; 1.2694 + // ignore 1.2695 + case DW_AT_language: 1.2696 + case DW_AT_producer: 1.2697 + case DW_AT_macro_info: 1.2698 + case DW_AT_entry_pc: 1.2699 + break; 1.2700 + default: 1.2701 + fprintf(stderr, "Unknown attribute %02x\n", attr->name); 1.2702 + break; 1.2703 + } 1.2704 + } 1.2705 + 1.2706 + if (abbrev->hasChildren) 1.2707 + elfParseCompileUnitChildren(data, unit); 1.2708 + 1.2709 + return unit; 1.2710 +} 1.2711 + 1.2712 +void elfParseAranges(u8 *data) 1.2713 +{ 1.2714 + ELFSectionHeader *sh = elfGetSectionByName(".debug_aranges"); 1.2715 + if (sh == NULL) 1.2716 + { 1.2717 + fprintf(stderr, "No aranges found\n"); 1.2718 + return; 1.2719 + } 1.2720 + 1.2721 + data = elfReadSection(data, sh); 1.2722 + u8 *end = data + READ32LE(&sh->size); 1.2723 + 1.2724 + int max = 4; 1.2725 + ARanges *ranges = (ARanges *)calloc(sizeof(ARanges), 4); 1.2726 + 1.2727 + int index = 0; 1.2728 + 1.2729 + while (data < end) 1.2730 + { 1.2731 + u32 len = elfRead4Bytes(data); 1.2732 + data += 4; 1.2733 + // u16 version = elfRead2Bytes(data); 1.2734 + data += 2; 1.2735 + u32 offset = elfRead4Bytes(data); 1.2736 + data += 4; 1.2737 + // u8 addrSize = *data++; 1.2738 + // u8 segSize = *data++; 1.2739 + data += 2; // remove if uncommenting above 1.2740 + data += 4; 1.2741 + ranges[index].count = (len-20)/8; 1.2742 + ranges[index].offset = offset; 1.2743 + ranges[index].ranges = (ARange *)calloc(sizeof(ARange), (len-20)/8); 1.2744 + int i = 0; 1.2745 + while (true) 1.2746 + { 1.2747 + u32 addr = elfRead4Bytes(data); 1.2748 + data += 4; 1.2749 + u32 len = elfRead4Bytes(data); 1.2750 + data += 4; 1.2751 + if (addr == 0 && len == 0) 1.2752 + break; 1.2753 + ranges[index].ranges[i].lowPC = addr; 1.2754 + ranges[index].ranges[i].highPC = addr+len; 1.2755 + i++; 1.2756 + } 1.2757 + index++; 1.2758 + if (index == max) 1.2759 + { 1.2760 + max += 4; 1.2761 + ranges = (ARanges *)realloc(ranges, max*sizeof(ARanges)); 1.2762 + } 1.2763 + } 1.2764 + elfDebugInfo->numRanges = index; 1.2765 + elfDebugInfo->ranges = ranges; 1.2766 +} 1.2767 + 1.2768 +void elfReadSymtab(u8 *data) 1.2769 +{ 1.2770 + ELFSectionHeader *sh = elfGetSectionByName(".symtab"); 1.2771 + int table = READ32LE(&sh->link); 1.2772 + 1.2773 + char *strtable = (char *)elfReadSection(data, elfGetSectionByNumber(table)); 1.2774 + 1.2775 + ELFSymbol *symtab = (ELFSymbol *)elfReadSection(data, sh); 1.2776 + 1.2777 + int count = READ32LE(&sh->size) / sizeof(ELFSymbol); 1.2778 + elfSymbolsCount = 0; 1.2779 + 1.2780 + elfSymbols = (Symbol *)malloc(sizeof(Symbol)*count); 1.2781 + 1.2782 + int i; 1.2783 + 1.2784 + for (i = 0; i < count; i++) 1.2785 + { 1.2786 + ELFSymbol *s = &symtab[i]; 1.2787 + int type = s->info & 15; 1.2788 + int binding = s->info >> 4; 1.2789 + 1.2790 + if (binding) 1.2791 + { 1.2792 + Symbol *sym = &elfSymbols[elfSymbolsCount]; 1.2793 + sym->name = &strtable[READ32LE(&s->name)]; 1.2794 + sym->binding = binding; 1.2795 + sym->type = type; 1.2796 + sym->value = READ32LE(&s->value); 1.2797 + sym->size = READ32LE(&s->size); 1.2798 + elfSymbolsCount++; 1.2799 + } 1.2800 + } 1.2801 + for (i = 0; i < count; i++) 1.2802 + { 1.2803 + ELFSymbol *s = &symtab[i]; 1.2804 + int bind = s->info>>4; 1.2805 + int type = s->info & 15; 1.2806 + 1.2807 + if (!bind) 1.2808 + { 1.2809 + Symbol *sym = &elfSymbols[elfSymbolsCount]; 1.2810 + sym->name = &strtable[READ32LE(&s->name)]; 1.2811 + sym->binding = (s->info >> 4); 1.2812 + sym->type = type; 1.2813 + sym->value = READ32LE(&s->value); 1.2814 + sym->size = READ32LE(&s->size); 1.2815 + elfSymbolsCount++; 1.2816 + } 1.2817 + } 1.2818 + elfSymbolsStrTab = strtable; 1.2819 + // free(symtab); 1.2820 +} 1.2821 + 1.2822 +bool elfReadProgram(ELFHeader *eh, u8 *data, int& size, bool parseDebug) 1.2823 +{ 1.2824 + int count = READ16LE(&eh->e_phnum); 1.2825 + int i; 1.2826 + 1.2827 + if (READ32LE(&eh->e_entry) == 0x2000000) 1.2828 + cpuIsMultiBoot = true; 1.2829 + 1.2830 + // read program headers... should probably move this code down 1.2831 + u8 *p = data + READ32LE(&eh->e_phoff); 1.2832 + size = 0; 1.2833 + for (i = 0; i < count; i++) 1.2834 + { 1.2835 + ELFProgramHeader *ph = (ELFProgramHeader *)p; 1.2836 + p += sizeof(ELFProgramHeader); 1.2837 + if (READ16LE(&eh->e_phentsize) != sizeof(ELFProgramHeader)) 1.2838 + { 1.2839 + p += READ16LE(&eh->e_phentsize) - sizeof(ELFProgramHeader); 1.2840 + } 1.2841 + 1.2842 + // printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n", 1.2843 + // i, ph->type, ph->offset, ph->vaddr, ph->paddr, 1.2844 + // ph->filesz, ph->memsz, ph->flags, ph->align); 1.2845 + if (cpuIsMultiBoot) 1.2846 + { 1.2847 + if (READ32LE(&ph->paddr) >= 0x2000000 && 1.2848 + READ32LE(&ph->paddr) <= 0x203ffff) 1.2849 + { 1.2850 + memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff], 1.2851 + data + READ32LE(&ph->offset), 1.2852 + READ32LE(&ph->filesz)); 1.2853 + } 1.2854 + } 1.2855 + else 1.2856 + { 1.2857 + if (READ32LE(&ph->paddr) >= 0x8000000 && 1.2858 + READ32LE(&ph->paddr) <= 0x9ffffff) 1.2859 + { 1.2860 + memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff], 1.2861 + data + READ32LE(&ph->offset), 1.2862 + READ32LE(&ph->filesz)); 1.2863 + size += READ32LE(&ph->filesz); 1.2864 + } 1.2865 + } 1.2866 + } 1.2867 + 1.2868 + char *stringTable = NULL; 1.2869 + 1.2870 + // read section headers 1.2871 + p = data + READ32LE(&eh->e_shoff); 1.2872 + count = READ16LE(&eh->e_shnum); 1.2873 + 1.2874 + ELFSectionHeader **sh = (ELFSectionHeader * *) 1.2875 + malloc(sizeof(ELFSectionHeader *) * count); 1.2876 + 1.2877 + for (i = 0; i < count; i++) 1.2878 + { 1.2879 + sh[i] = (ELFSectionHeader *)p; 1.2880 + p += sizeof(ELFSectionHeader); 1.2881 + if (READ16LE(&eh->e_shentsize) != sizeof(ELFSectionHeader)) 1.2882 + p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader); 1.2883 + } 1.2884 + 1.2885 + if (READ16LE(&eh->e_shstrndx) != 0) 1.2886 + { 1.2887 + stringTable = (char *)elfReadSection(data, 1.2888 + sh[READ16LE(&eh->e_shstrndx)]); 1.2889 + } 1.2890 + 1.2891 + elfSectionHeaders = sh; 1.2892 + elfSectionHeadersStringTable = stringTable; 1.2893 + elfSectionHeadersCount = count; 1.2894 + 1.2895 + for (i = 0; i < count; i++) 1.2896 + { 1.2897 + // printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n", 1.2898 + // i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type, 1.2899 + // sh[i]->flags, sh[i]->addr, sh[i]->offset, sh[i]->size, 1.2900 + // sh[i]->link, sh[i]->info); 1.2901 + if (READ32LE(&sh[i]->flags) & 2) // load section 1.2902 + { 1.2903 + if (cpuIsMultiBoot) 1.2904 + { 1.2905 + if (READ32LE(&sh[i]->addr) >= 0x2000000 && 1.2906 + READ32LE(&sh[i]->addr) <= 0x203ffff) 1.2907 + { 1.2908 + memcpy(&workRAM[READ32LE(&sh[i]->addr) & 0x3ffff], data + 1.2909 + READ32LE(&sh[i]->offset), 1.2910 + READ32LE(&sh[i]->size)); 1.2911 + } 1.2912 + } 1.2913 + else 1.2914 + { 1.2915 + if (READ32LE(&sh[i]->addr) >= 0x8000000 && 1.2916 + READ32LE(&sh[i]->addr) <= 0x9ffffff) 1.2917 + { 1.2918 + memcpy(&rom[READ32LE(&sh[i]->addr) & 0x1ffffff], 1.2919 + data + READ32LE(&sh[i]->offset), 1.2920 + READ32LE(&sh[i]->size)); 1.2921 + size += READ32LE(&sh[i]->size); 1.2922 + } 1.2923 + } 1.2924 + } 1.2925 + } 1.2926 + 1.2927 + if (parseDebug) 1.2928 + { 1.2929 + fprintf(stderr, "Parsing debug info\n"); 1.2930 + 1.2931 + ELFSectionHeader *dbgHeader = elfGetSectionByName(".debug_info"); 1.2932 + if (dbgHeader == NULL) 1.2933 + { 1.2934 + fprintf(stderr, "Cannot find debug information\n"); 1.2935 + goto end; 1.2936 + } 1.2937 + 1.2938 + ELFSectionHeader *h = elfGetSectionByName(".debug_abbrev"); 1.2939 + if (h == NULL) 1.2940 + { 1.2941 + fprintf(stderr, "Cannot find abbreviation table\n"); 1.2942 + goto end; 1.2943 + } 1.2944 + 1.2945 + elfDebugInfo = (DebugInfo *)calloc(sizeof(DebugInfo), 1); 1.2946 + u8 *abbrevdata = elfReadSection(data, h); 1.2947 + 1.2948 + h = elfGetSectionByName(".debug_str"); 1.2949 + 1.2950 + if (h == NULL) 1.2951 + elfDebugStrings = NULL; 1.2952 + else 1.2953 + elfDebugStrings = (char *)elfReadSection(data, h); 1.2954 + 1.2955 + u8 *debugdata = elfReadSection(data, dbgHeader); 1.2956 + 1.2957 + elfDebugInfo->debugdata = data; 1.2958 + elfDebugInfo->infodata = debugdata; 1.2959 + 1.2960 + u32 total = READ32LE(&dbgHeader->size); 1.2961 + u8 *end = debugdata + total; 1.2962 + u8 *ddata = debugdata; 1.2963 + 1.2964 + CompileUnit *last = NULL; 1.2965 + CompileUnit *unit = NULL; 1.2966 + 1.2967 + while (ddata < end) 1.2968 + { 1.2969 + unit = elfParseCompUnit(ddata, abbrevdata); 1.2970 + unit->offset = ddata-debugdata; 1.2971 + elfParseLineInfo(unit, data); 1.2972 + if (last == NULL) 1.2973 + elfCompileUnits = unit; 1.2974 + else 1.2975 + last->next = unit; 1.2976 + last = unit; 1.2977 + ddata += 4 + unit->length; 1.2978 + } 1.2979 + elfParseAranges(data); 1.2980 + CompileUnit *comp = elfCompileUnits; 1.2981 + while (comp) 1.2982 + { 1.2983 + ARanges *r = elfDebugInfo->ranges; 1.2984 + for (int i = 0; i < elfDebugInfo->numRanges; i++) 1.2985 + if (r[i].offset == comp->offset) 1.2986 + { 1.2987 + comp->ranges = &r[i]; 1.2988 + break; 1.2989 + } 1.2990 + comp = comp->next; 1.2991 + } 1.2992 + elfParseCFA(data); 1.2993 + elfReadSymtab(data); 1.2994 + } 1.2995 +end: 1.2996 + if (sh) 1.2997 + { 1.2998 + free(sh); 1.2999 + } 1.3000 + 1.3001 + elfSectionHeaders = NULL; 1.3002 + elfSectionHeadersStringTable = NULL; 1.3003 + elfSectionHeadersCount = 0; 1.3004 + 1.3005 + return true; 1.3006 +} 1.3007 + 1.3008 +extern bool8 parseDebug; 1.3009 + 1.3010 +bool elfRead(const char *name, int& siz, FILE *f) 1.3011 +{ 1.3012 + fseek(f, 0, SEEK_END); 1.3013 + long size = ftell(f); 1.3014 + elfFileData = (u8 *)malloc(size); 1.3015 + fseek(f, 0, SEEK_SET); 1.3016 + fread(elfFileData, 1, size, f); 1.3017 + fclose(f); 1.3018 + 1.3019 + ELFHeader *header = (ELFHeader *)elfFileData; 1.3020 + 1.3021 + if (READ32LE(&header->magic) != 0x464C457F || 1.3022 + READ16LE(&header->e_machine) != 40 || 1.3023 + header->clazz != 1) 1.3024 + { 1.3025 + systemMessage(0, N_("Not a valid ELF file %s"), name); 1.3026 + free(elfFileData); 1.3027 + elfFileData = NULL; 1.3028 + return false; 1.3029 + } 1.3030 + 1.3031 + if (!elfReadProgram(header, elfFileData, siz, parseDebug)) 1.3032 + { 1.3033 + free(elfFileData); 1.3034 + elfFileData = NULL; 1.3035 + return false; 1.3036 + } 1.3037 + 1.3038 + return true; 1.3039 +} 1.3040 + 1.3041 +void elfCleanUp(Object *o) 1.3042 +{ 1.3043 + free(o->location); 1.3044 +} 1.3045 + 1.3046 +void elfCleanUp(Function *func) 1.3047 +{ 1.3048 + Object *o = func->parameters; 1.3049 + while (o) 1.3050 + { 1.3051 + elfCleanUp(o); 1.3052 + Object *next = o->next; 1.3053 + free(o); 1.3054 + o = next; 1.3055 + } 1.3056 + 1.3057 + o = func->variables; 1.3058 + while (o) 1.3059 + { 1.3060 + elfCleanUp(o); 1.3061 + Object *next = o->next; 1.3062 + free(o); 1.3063 + o = next; 1.3064 + } 1.3065 + free(func->frameBase); 1.3066 +} 1.3067 + 1.3068 +void elfCleanUp(ELFAbbrev **abbrevs) 1.3069 +{ 1.3070 + for (int i = 0; i < 121; i++) 1.3071 + { 1.3072 + ELFAbbrev *abbrev = abbrevs[i]; 1.3073 + 1.3074 + while (abbrev) 1.3075 + { 1.3076 + free(abbrev->attrs); 1.3077 + ELFAbbrev *next = abbrev->next; 1.3078 + free(abbrev); 1.3079 + 1.3080 + abbrev = next; 1.3081 + } 1.3082 + } 1.3083 +} 1.3084 + 1.3085 +void elfCleanUp(Type *t) 1.3086 +{ 1.3087 + switch (t->type) 1.3088 + { 1.3089 + case TYPE_function: 1.3090 + if (t->function) 1.3091 + { 1.3092 + Object *o = t->function->args; 1.3093 + while (o) 1.3094 + { 1.3095 + elfCleanUp(o); 1.3096 + Object *next = o->next; 1.3097 + free(o); 1.3098 + o = next; 1.3099 + } 1.3100 + free(t->function); 1.3101 + } 1.3102 + break; 1.3103 + case TYPE_array: 1.3104 + if (t->array) 1.3105 + { 1.3106 + free(t->array->bounds); 1.3107 + free(t->array); 1.3108 + } 1.3109 + break; 1.3110 + case TYPE_struct: 1.3111 + case TYPE_union: 1.3112 + if (t->structure) 1.3113 + { 1.3114 + for (int i = 0; i < t->structure->memberCount; i++) 1.3115 + { 1.3116 + free(t->structure->members[i].location); 1.3117 + } 1.3118 + free(t->structure->members); 1.3119 + free(t->structure); 1.3120 + } 1.3121 + break; 1.3122 + case TYPE_enum: 1.3123 + if (t->enumeration) 1.3124 + { 1.3125 + free(t->enumeration->members); 1.3126 + free(t->enumeration); 1.3127 + } 1.3128 + break; 1.3129 + case TYPE_base: 1.3130 + case TYPE_pointer: 1.3131 + case TYPE_void: 1.3132 + case TYPE_reference: 1.3133 + break; // nothing to do 1.3134 + } 1.3135 +} 1.3136 + 1.3137 +void elfCleanUp(CompileUnit *comp) 1.3138 +{ 1.3139 + elfCleanUp(comp->abbrevs); 1.3140 + free(comp->abbrevs); 1.3141 + Function *func = comp->functions; 1.3142 + while (func) 1.3143 + { 1.3144 + elfCleanUp(func); 1.3145 + Function *next = func->next; 1.3146 + free(func); 1.3147 + func = next; 1.3148 + } 1.3149 + Type *t = comp->types; 1.3150 + while (t) 1.3151 + { 1.3152 + elfCleanUp(t); 1.3153 + Type *next = t->next; 1.3154 + free(t); 1.3155 + t = next; 1.3156 + } 1.3157 + Object *o = comp->variables; 1.3158 + while (o) 1.3159 + { 1.3160 + elfCleanUp(o); 1.3161 + Object *next = o->next; 1.3162 + free(o); 1.3163 + o = next; 1.3164 + } 1.3165 + if (comp->lineInfoTable) 1.3166 + { 1.3167 + free(comp->lineInfoTable->lines); 1.3168 + free(comp->lineInfoTable->files); 1.3169 + free(comp->lineInfoTable); 1.3170 + } 1.3171 +} 1.3172 + 1.3173 +void elfCleanUp() 1.3174 +{ 1.3175 + CompileUnit *comp = elfCompileUnits; 1.3176 + 1.3177 + while (comp) 1.3178 + { 1.3179 + elfCleanUp(comp); 1.3180 + CompileUnit *next = comp->next; 1.3181 + free(comp); 1.3182 + comp = next; 1.3183 + } 1.3184 + elfCompileUnits = NULL; 1.3185 + free(elfSymbols); 1.3186 + elfSymbols = NULL; 1.3187 + // free(elfSymbolsStrTab); 1.3188 + elfSymbolsStrTab = NULL; 1.3189 + 1.3190 + elfDebugStrings = NULL; 1.3191 + if (elfDebugInfo) 1.3192 + { 1.3193 + int num = elfDebugInfo->numRanges; 1.3194 + int i; 1.3195 + for (i = 0; i < num; i++) 1.3196 + { 1.3197 + free(elfDebugInfo->ranges[i].ranges); 1.3198 + } 1.3199 + free(elfDebugInfo->ranges); 1.3200 + free(elfDebugInfo); 1.3201 + elfDebugInfo = NULL; 1.3202 + } 1.3203 + 1.3204 + if (elfFdes) 1.3205 + { 1.3206 + if (elfFdeCount) 1.3207 + { 1.3208 + for (int i = 0; i < elfFdeCount; i++) 1.3209 + free(elfFdes[i]); 1.3210 + } 1.3211 + free(elfFdes); 1.3212 + 1.3213 + elfFdes = NULL; 1.3214 + elfFdeCount = 0; 1.3215 + } 1.3216 + 1.3217 + ELFcie *cie = elfCies; 1.3218 + while (cie) 1.3219 + { 1.3220 + ELFcie *next = cie->next; 1.3221 + free(cie); 1.3222 + cie = next; 1.3223 + } 1.3224 + elfCies = NULL; 1.3225 + 1.3226 + if (elfFileData) 1.3227 + { 1.3228 + free(elfFileData); 1.3229 + elfFileData = NULL; 1.3230 + } 1.3231 +} 1.3232 +