diff --git a/tccgen.c b/tccgen.c index 9ad6062a..c78f1b29 100644 --- a/tccgen.c +++ b/tccgen.c @@ -276,7 +276,7 @@ static const unsigned char dwarf_abbrev_init[] = { #else DW_AT_high_pc, DW_FORM_data8, #endif - DW_AT_stmt_list, DW_FORM_data4, + DW_AT_stmt_list, DW_FORM_sec_offset, 0, 0, DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0, DW_AT_byte_size, DW_FORM_udata, @@ -289,24 +289,24 @@ static const unsigned char dwarf_abbrev_init[] = { DW_AT_decl_line, DW_FORM_udata, DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag, - DW_AT_location, DW_FORM_block1, + DW_AT_location, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0, DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_udata, DW_AT_decl_line, DW_FORM_udata, DW_AT_type, DW_FORM_ref4, - DW_AT_location, DW_FORM_block1, + DW_AT_location, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0, DW_AT_name, DW_FORM_strp, DW_AT_type, DW_FORM_ref4, - DW_AT_location, DW_FORM_block1, + DW_AT_location, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0, DW_AT_name, DW_FORM_strp, DW_AT_type, DW_FORM_ref4, - DW_AT_location, DW_FORM_block1, + DW_AT_location, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0, DW_AT_byte_size, DW_FORM_data1, @@ -381,7 +381,7 @@ static const unsigned char dwarf_abbrev_init[] = { DW_AT_high_pc, DW_FORM_data8, #endif DW_AT_sibling, DW_FORM_ref4, - DW_AT_frame_base, DW_FORM_block1, + DW_AT_frame_base, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1, DW_AT_name, DW_FORM_strp, @@ -395,7 +395,7 @@ static const unsigned char dwarf_abbrev_init[] = { DW_AT_high_pc, DW_FORM_data8, #endif DW_AT_sibling, DW_FORM_ref4, - DW_AT_frame_base, DW_FORM_block1, + DW_AT_frame_base, DW_FORM_exprloc, 0, 0, DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1, DW_AT_low_pc, DW_FORM_addr, @@ -838,7 +838,6 @@ ST_FUNC void tcc_debug_start(TCCState *s1) #ifdef _WIN32 normalize_slashes(buf); #endif - pstrcat(buf, sizeof(buf), "/"); if (s1->dwarf) { int start_abbrev; @@ -855,8 +854,19 @@ ST_FUNC void tcc_debug_start(TCCState *s1) while (*ptr) { if (ptr[1] == DW_FORM_line_strp) ptr[1] = DW_FORM_strp; + if (s1->dwarf < 4) { + /* These are compatable for DW_TAG_compile_unit + DW_AT_stmt_list. */ + if (ptr[1] == DW_FORM_sec_offset) + ptr[1] = DW_FORM_data4; + /* This code uses only size < 0x80 so these are + compatible. */ + if (ptr[1] == DW_FORM_exprloc) + ptr[1] = DW_FORM_block1; + } ptr += 2; } + ptr += 2; } } @@ -949,6 +959,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1) } else { /* file info: full path + filename */ + pstrcat(buf, sizeof(buf), "/"); section_sym = put_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, text_section->sh_num, NULL); @@ -1374,7 +1385,8 @@ static void tcc_debug_fix_anon(CType *t) debug_type = tcc_get_dwarf_info(s1, &sym); for (j = 0; j < debug_anon_hash[i].n_debug_type; j++) write32le(dwarf_info_section->data + - debug_anon_hash[i].debug_type[j], debug_type); + debug_anon_hash[i].debug_type[j], + debug_type - dwarf_info.start); tcc_free(debug_anon_hash[i].debug_type); n_debug_anon_hash--; for (; i < n_debug_anon_hash; i++) diff --git a/tccrun.c b/tccrun.c index 4e529f51..479ce84a 100644 --- a/tccrun.c +++ b/tccrun.c @@ -590,11 +590,28 @@ found: #define MAX_128 ((8 * sizeof (long long) + 6) / 7) -#define DW_GETC(s,e) ((s) < (e) ? *(s)++ : 0) - #define DIR_TABLE_SIZE (64) #define FILE_TABLE_SIZE (256) +#define dwarf_read_1(ln,end) \ + ((ln) < (end) ? *(ln)++ : 0) +#define dwarf_read_2(ln,end) \ + ((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0) +#define dwarf_read_4(ln,end) \ + ((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0) +#define dwarf_read_8(ln,end) \ + ((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0) +#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \ + switch (entry_format[j].form) { \ + case DW_FORM_data1: (ln) += 1; break; \ + case DW_FORM_data2: (ln) += 2; break; \ + case DW_FORM_data4: (ln) += 3; break; \ + case DW_FORM_data8: (ln) += 8; break; \ + case DW_FORM_data16: (ln) += 16; break; \ + case DW_FORM_udata: dwarf_read_uleb128(&(ln), (end)); break; \ + default: goto next_line; \ + } + static unsigned long long dwarf_read_uleb128(unsigned char **ln, unsigned char *end) { @@ -603,7 +620,7 @@ dwarf_read_uleb128(unsigned char **ln, unsigned char *end) int i; for (i = 0; i < MAX_128; i++) { - unsigned long long byte = DW_GETC(cp, end); + unsigned long long byte = dwarf_read_1(cp, end); retval |= (byte & 0x7f) << (i * 7); if ((byte & 0x80) == 0) @@ -621,7 +638,7 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end) int i; for (i = 0; i < MAX_128; i++) { - unsigned long long byte = DW_GETC(cp, end); + unsigned long long byte = dwarf_read_1(cp, end); retval |= (byte & 0x7f) << (i * 7); if ((byte & 0x80) == 0) { @@ -634,25 +651,6 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end) return retval; } -#define dwarf_read_1(ln,end) \ - DW_GETC((ln), (end)) -#define dwarf_read_2(ln,end) \ - ((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0) -#define dwarf_read_4(ln,end) \ - ((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0) -#define dwarf_read_8(ln,end) \ - ((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0) -#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \ - switch (entry_format[j].form) { \ - case DW_FORM_data1: (ln) += 1; break; \ - case DW_FORM_data2: (ln) += 2; break; \ - case DW_FORM_data4: (ln) += 3; break; \ - case DW_FORM_data8: (ln) += 8; break; \ - case DW_FORM_data16: (ln) += 16; break; \ - case DW_FORM_udata: dwarf_read_uleb128(&(ln), (end)); break; \ - default: goto next_line; \ - } - static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, const char *msg, const char *skip) { @@ -706,26 +704,25 @@ next: function = NULL; size = dwarf_read_4(ln, rc->dwarf_line_end); end = ln + size; - version = DW_GETC(ln, end); - version += DW_GETC(ln, end) << 8; + version = dwarf_read_2(ln, end); if (version >= 5) ln += 6; // address size, segment selector, prologue Length else ln += 4; // prologue Length - min_insn_length = DW_GETC(ln, end); + min_insn_length = dwarf_read_1(ln, end); if (version >= 4) - max_ops_per_insn = DW_GETC(ln, end); + max_ops_per_insn = dwarf_read_1(ln, end); else max_ops_per_insn = 1; ln++; // Initial value of 'is_stmt' - line_base = DW_GETC(ln, end); + line_base = dwarf_read_1(ln, end); line_base |= line_base >= 0x80 ? ~0xff : 0; - line_range = DW_GETC(ln, end); - opcode_base = DW_GETC(ln, end); + line_range = dwarf_read_1(ln, end); + opcode_base = dwarf_read_1(ln, end); opindex = 0; ln += 12; if (version >= 5) { - col = DW_GETC(ln, end); + col = dwarf_read_1(ln, end); for (i = 0; i < col; i++) { entry_format[i].type = dwarf_read_uleb128(&ln, end); entry_format[i].form = dwarf_read_uleb128(&ln, end); @@ -748,7 +745,7 @@ next: dwarf_ignore_type(ln, end); } } - col = DW_GETC(ln, end); + col = dwarf_read_1(ln, end); for (i = 0; i < col; i++) { entry_format[i].type = dwarf_read_uleb128(&ln, end); entry_format[i].form = dwarf_read_uleb128(&ln, end); @@ -780,22 +777,22 @@ next: } } else { - while ((DW_GETC(ln, end))) { + while ((dwarf_read_1(ln, end))) { #if 0 if (++dir_size < DIR_TABLE_SIZE) dirs[dir_size - 1] = (char *)ln - 1; #endif - while (DW_GETC(ln, end)) {} + while (dwarf_read_1(ln, end)) {} } - while ((DW_GETC(ln, end))) { + while ((dwarf_read_1(ln, end))) { if (++filename_size < FILE_TABLE_SIZE) { filename_table[filename_size - 1].name = (char *)ln - 1; - while (DW_GETC(ln, end)) {} + while (dwarf_read_1(ln, end)) {} filename_table[filename_size - 1].dir_entry = dwarf_read_uleb128(&ln, end); } else { - while (DW_GETC(ln, end)) {} + while (dwarf_read_1(ln, end)) {} dwarf_read_uleb128(&ln, end); } dwarf_read_uleb128(&ln, end); // time @@ -806,14 +803,14 @@ next: filename = filename_table[0].name; while (ln < end) { last_pc = pc; - switch (DW_GETC(ln, end)) { + switch (dwarf_read_1(ln, end)) { case 0: len = dwarf_read_uleb128(&ln, end); cp = ln; ln += len; if (len == 0) goto next_line; - switch (DW_GETC(cp, end)) { + switch (dwarf_read_1(cp, end)) { case DW_LNE_end_sequence: goto next_line; case DW_LNE_set_address: @@ -829,20 +826,17 @@ next: case DW_LNE_define_file: /* deprecated */ if (++filename_size < FILE_TABLE_SIZE) { filename_table[filename_size - 1].name = (char *)ln - 1; - while (DW_GETC(ln, end)) {} + while (dwarf_read_1(ln, end)) {} filename_table[filename_size - 1].dir_entry = dwarf_read_uleb128(&ln, end); } else { - while (DW_GETC(ln, end)) {} + while (dwarf_read_1(ln, end)) {} dwarf_read_uleb128(&ln, end); } dwarf_read_uleb128(&ln, end); // time dwarf_read_uleb128(&ln, end); // size break; - case DW_LNE_set_discriminator: - dwarf_read_uleb128(&cp, end); - break; case DW_LNE_hi_user - 1: function = (char *)cp; func_addr = pc; @@ -893,8 +887,7 @@ next: i = 0; goto check_pc; case DW_LNS_fixed_advance_pc: - i = DW_GETC(ln, end); - i += DW_GETC(ln, end) << 8; + i = dwarf_read_2(ln, end); pc += i; opindex = 0; i = 0;