mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
Dwarf update for readelf
readelf complained about DW_AT_stmt_list and DW_AT_location. For dwarf >= 4 we should use DW_FORM_sec_offset instead of DW_FORM_data4 and DW_FORM_exprloc instead of DW_FORM_block1. This is fixed in tccgen.c I also updated tccrun.c to use dwarf_read_1 instead of DW_GETC.
This commit is contained in:
parent
499cf2305b
commit
0241120b54
30
tccgen.c
30
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++)
|
||||
|
85
tccrun.c
85
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;
|
||||
|
Loading…
Reference in New Issue
Block a user