Skip to content

Commit 0241120

Browse files
committed
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.
1 parent 499cf23 commit 0241120

File tree

2 files changed

+60
-55
lines changed

2 files changed

+60
-55
lines changed

tccgen.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ static const unsigned char dwarf_abbrev_init[] = {
276276
#else
277277
DW_AT_high_pc, DW_FORM_data8,
278278
#endif
279-
DW_AT_stmt_list, DW_FORM_data4,
279+
DW_AT_stmt_list, DW_FORM_sec_offset,
280280
0, 0,
281281
DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0,
282282
DW_AT_byte_size, DW_FORM_udata,
@@ -289,24 +289,24 @@ static const unsigned char dwarf_abbrev_init[] = {
289289
DW_AT_decl_line, DW_FORM_udata,
290290
DW_AT_type, DW_FORM_ref4,
291291
DW_AT_external, DW_FORM_flag,
292-
DW_AT_location, DW_FORM_block1,
292+
DW_AT_location, DW_FORM_exprloc,
293293
0, 0,
294294
DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0,
295295
DW_AT_name, DW_FORM_strp,
296296
DW_AT_decl_file, DW_FORM_udata,
297297
DW_AT_decl_line, DW_FORM_udata,
298298
DW_AT_type, DW_FORM_ref4,
299-
DW_AT_location, DW_FORM_block1,
299+
DW_AT_location, DW_FORM_exprloc,
300300
0, 0,
301301
DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0,
302302
DW_AT_name, DW_FORM_strp,
303303
DW_AT_type, DW_FORM_ref4,
304-
DW_AT_location, DW_FORM_block1,
304+
DW_AT_location, DW_FORM_exprloc,
305305
0, 0,
306306
DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0,
307307
DW_AT_name, DW_FORM_strp,
308308
DW_AT_type, DW_FORM_ref4,
309-
DW_AT_location, DW_FORM_block1,
309+
DW_AT_location, DW_FORM_exprloc,
310310
0, 0,
311311
DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
312312
DW_AT_byte_size, DW_FORM_data1,
@@ -381,7 +381,7 @@ static const unsigned char dwarf_abbrev_init[] = {
381381
DW_AT_high_pc, DW_FORM_data8,
382382
#endif
383383
DW_AT_sibling, DW_FORM_ref4,
384-
DW_AT_frame_base, DW_FORM_block1,
384+
DW_AT_frame_base, DW_FORM_exprloc,
385385
0, 0,
386386
DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1,
387387
DW_AT_name, DW_FORM_strp,
@@ -395,7 +395,7 @@ static const unsigned char dwarf_abbrev_init[] = {
395395
DW_AT_high_pc, DW_FORM_data8,
396396
#endif
397397
DW_AT_sibling, DW_FORM_ref4,
398-
DW_AT_frame_base, DW_FORM_block1,
398+
DW_AT_frame_base, DW_FORM_exprloc,
399399
0, 0,
400400
DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1,
401401
DW_AT_low_pc, DW_FORM_addr,
@@ -838,7 +838,6 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
838838
#ifdef _WIN32
839839
normalize_slashes(buf);
840840
#endif
841-
pstrcat(buf, sizeof(buf), "/");
842841

843842
if (s1->dwarf) {
844843
int start_abbrev;
@@ -855,8 +854,19 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
855854
while (*ptr) {
856855
if (ptr[1] == DW_FORM_line_strp)
857856
ptr[1] = DW_FORM_strp;
857+
if (s1->dwarf < 4) {
858+
/* These are compatable for DW_TAG_compile_unit
859+
DW_AT_stmt_list. */
860+
if (ptr[1] == DW_FORM_sec_offset)
861+
ptr[1] = DW_FORM_data4;
862+
/* This code uses only size < 0x80 so these are
863+
compatible. */
864+
if (ptr[1] == DW_FORM_exprloc)
865+
ptr[1] = DW_FORM_block1;
866+
}
858867
ptr += 2;
859868
}
869+
ptr += 2;
860870
}
861871
}
862872

@@ -949,6 +959,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
949959
}
950960
else {
951961
/* file info: full path + filename */
962+
pstrcat(buf, sizeof(buf), "/");
952963
section_sym = put_elf_sym(symtab_section, 0, 0,
953964
ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
954965
text_section->sh_num, NULL);
@@ -1374,7 +1385,8 @@ static void tcc_debug_fix_anon(CType *t)
13741385
debug_type = tcc_get_dwarf_info(s1, &sym);
13751386
for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
13761387
write32le(dwarf_info_section->data +
1377-
debug_anon_hash[i].debug_type[j], debug_type);
1388+
debug_anon_hash[i].debug_type[j],
1389+
debug_type - dwarf_info.start);
13781390
tcc_free(debug_anon_hash[i].debug_type);
13791391
n_debug_anon_hash--;
13801392
for (; i < n_debug_anon_hash; i++)

tccrun.c

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,28 @@ static addr_t rt_printline (rt_context *rc, addr_t wanted_pc,
590590

591591
#define MAX_128 ((8 * sizeof (long long) + 6) / 7)
592592

593-
#define DW_GETC(s,e) ((s) < (e) ? *(s)++ : 0)
594-
595593
#define DIR_TABLE_SIZE (64)
596594
#define FILE_TABLE_SIZE (256)
597595

596+
#define dwarf_read_1(ln,end) \
597+
((ln) < (end) ? *(ln)++ : 0)
598+
#define dwarf_read_2(ln,end) \
599+
((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
600+
#define dwarf_read_4(ln,end) \
601+
((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
602+
#define dwarf_read_8(ln,end) \
603+
((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
604+
#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
605+
switch (entry_format[j].form) { \
606+
case DW_FORM_data1: (ln) += 1; break; \
607+
case DW_FORM_data2: (ln) += 2; break; \
608+
case DW_FORM_data4: (ln) += 3; break; \
609+
case DW_FORM_data8: (ln) += 8; break; \
610+
case DW_FORM_data16: (ln) += 16; break; \
611+
case DW_FORM_udata: dwarf_read_uleb128(&(ln), (end)); break; \
612+
default: goto next_line; \
613+
}
614+
598615
static unsigned long long
599616
dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
600617
{
@@ -603,7 +620,7 @@ dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
603620
int i;
604621

605622
for (i = 0; i < MAX_128; i++) {
606-
unsigned long long byte = DW_GETC(cp, end);
623+
unsigned long long byte = dwarf_read_1(cp, end);
607624

608625
retval |= (byte & 0x7f) << (i * 7);
609626
if ((byte & 0x80) == 0)
@@ -621,7 +638,7 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
621638
int i;
622639

623640
for (i = 0; i < MAX_128; i++) {
624-
unsigned long long byte = DW_GETC(cp, end);
641+
unsigned long long byte = dwarf_read_1(cp, end);
625642

626643
retval |= (byte & 0x7f) << (i * 7);
627644
if ((byte & 0x80) == 0) {
@@ -634,25 +651,6 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
634651
return retval;
635652
}
636653

637-
#define dwarf_read_1(ln,end) \
638-
DW_GETC((ln), (end))
639-
#define dwarf_read_2(ln,end) \
640-
((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
641-
#define dwarf_read_4(ln,end) \
642-
((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
643-
#define dwarf_read_8(ln,end) \
644-
((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
645-
#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
646-
switch (entry_format[j].form) { \
647-
case DW_FORM_data1: (ln) += 1; break; \
648-
case DW_FORM_data2: (ln) += 2; break; \
649-
case DW_FORM_data4: (ln) += 3; break; \
650-
case DW_FORM_data8: (ln) += 8; break; \
651-
case DW_FORM_data16: (ln) += 16; break; \
652-
case DW_FORM_udata: dwarf_read_uleb128(&(ln), (end)); break; \
653-
default: goto next_line; \
654-
}
655-
656654
static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
657655
const char *msg, const char *skip)
658656
{
@@ -706,26 +704,25 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
706704
function = NULL;
707705
size = dwarf_read_4(ln, rc->dwarf_line_end);
708706
end = ln + size;
709-
version = DW_GETC(ln, end);
710-
version += DW_GETC(ln, end) << 8;
707+
version = dwarf_read_2(ln, end);
711708
if (version >= 5)
712709
ln += 6; // address size, segment selector, prologue Length
713710
else
714711
ln += 4; // prologue Length
715-
min_insn_length = DW_GETC(ln, end);
712+
min_insn_length = dwarf_read_1(ln, end);
716713
if (version >= 4)
717-
max_ops_per_insn = DW_GETC(ln, end);
714+
max_ops_per_insn = dwarf_read_1(ln, end);
718715
else
719716
max_ops_per_insn = 1;
720717
ln++; // Initial value of 'is_stmt'
721-
line_base = DW_GETC(ln, end);
718+
line_base = dwarf_read_1(ln, end);
722719
line_base |= line_base >= 0x80 ? ~0xff : 0;
723-
line_range = DW_GETC(ln, end);
724-
opcode_base = DW_GETC(ln, end);
720+
line_range = dwarf_read_1(ln, end);
721+
opcode_base = dwarf_read_1(ln, end);
725722
opindex = 0;
726723
ln += 12;
727724
if (version >= 5) {
728-
col = DW_GETC(ln, end);
725+
col = dwarf_read_1(ln, end);
729726
for (i = 0; i < col; i++) {
730727
entry_format[i].type = dwarf_read_uleb128(&ln, end);
731728
entry_format[i].form = dwarf_read_uleb128(&ln, end);
@@ -748,7 +745,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
748745
dwarf_ignore_type(ln, end);
749746
}
750747
}
751-
col = DW_GETC(ln, end);
748+
col = dwarf_read_1(ln, end);
752749
for (i = 0; i < col; i++) {
753750
entry_format[i].type = dwarf_read_uleb128(&ln, end);
754751
entry_format[i].form = dwarf_read_uleb128(&ln, end);
@@ -780,22 +777,22 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
780777
}
781778
}
782779
else {
783-
while ((DW_GETC(ln, end))) {
780+
while ((dwarf_read_1(ln, end))) {
784781
#if 0
785782
if (++dir_size < DIR_TABLE_SIZE)
786783
dirs[dir_size - 1] = (char *)ln - 1;
787784
#endif
788-
while (DW_GETC(ln, end)) {}
785+
while (dwarf_read_1(ln, end)) {}
789786
}
790-
while ((DW_GETC(ln, end))) {
787+
while ((dwarf_read_1(ln, end))) {
791788
if (++filename_size < FILE_TABLE_SIZE) {
792789
filename_table[filename_size - 1].name = (char *)ln - 1;
793-
while (DW_GETC(ln, end)) {}
790+
while (dwarf_read_1(ln, end)) {}
794791
filename_table[filename_size - 1].dir_entry =
795792
dwarf_read_uleb128(&ln, end);
796793
}
797794
else {
798-
while (DW_GETC(ln, end)) {}
795+
while (dwarf_read_1(ln, end)) {}
799796
dwarf_read_uleb128(&ln, end);
800797
}
801798
dwarf_read_uleb128(&ln, end); // time
@@ -806,14 +803,14 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
806803
filename = filename_table[0].name;
807804
while (ln < end) {
808805
last_pc = pc;
809-
switch (DW_GETC(ln, end)) {
806+
switch (dwarf_read_1(ln, end)) {
810807
case 0:
811808
len = dwarf_read_uleb128(&ln, end);
812809
cp = ln;
813810
ln += len;
814811
if (len == 0)
815812
goto next_line;
816-
switch (DW_GETC(cp, end)) {
813+
switch (dwarf_read_1(cp, end)) {
817814
case DW_LNE_end_sequence:
818815
goto next_line;
819816
case DW_LNE_set_address:
@@ -829,20 +826,17 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
829826
case DW_LNE_define_file: /* deprecated */
830827
if (++filename_size < FILE_TABLE_SIZE) {
831828
filename_table[filename_size - 1].name = (char *)ln - 1;
832-
while (DW_GETC(ln, end)) {}
829+
while (dwarf_read_1(ln, end)) {}
833830
filename_table[filename_size - 1].dir_entry =
834831
dwarf_read_uleb128(&ln, end);
835832
}
836833
else {
837-
while (DW_GETC(ln, end)) {}
834+
while (dwarf_read_1(ln, end)) {}
838835
dwarf_read_uleb128(&ln, end);
839836
}
840837
dwarf_read_uleb128(&ln, end); // time
841838
dwarf_read_uleb128(&ln, end); // size
842839
break;
843-
case DW_LNE_set_discriminator:
844-
dwarf_read_uleb128(&cp, end);
845-
break;
846840
case DW_LNE_hi_user - 1:
847841
function = (char *)cp;
848842
func_addr = pc;
@@ -893,8 +887,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
893887
i = 0;
894888
goto check_pc;
895889
case DW_LNS_fixed_advance_pc:
896-
i = DW_GETC(ln, end);
897-
i += DW_GETC(ln, end) << 8;
890+
i = dwarf_read_2(ln, end);
898891
pc += i;
899892
opindex = 0;
900893
i = 0;

0 commit comments

Comments
 (0)