Skip to content

Commit adda6c4

Browse files
committed
Extend DWARF abbrevs
1 parent aee624d commit adda6c4

File tree

3 files changed

+182
-126
lines changed

3 files changed

+182
-126
lines changed

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfAbbrevSectionImpl.java

Lines changed: 81 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,24 @@
2929
import com.oracle.objectfile.LayoutDecision;
3030
import org.graalvm.compiler.debug.DebugContext;
3131

32-
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_compile_unit_1;
33-
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_compile_unit_2;
32+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_compile_unit_stmt_list;
33+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_compile_unit_no_stmt_list;
34+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_inlined_subroutine_with_children;
35+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_subprogram_inline;
36+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_inlined_subroutine;
3437
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_subprogram;
38+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_subprogram_inline_with_children;
39+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_subprogram_with_children;
3540
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_SECTION_NAME;
41+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_abstract_origin;
42+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_call_file;
43+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_call_line;
3644
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_comp_dir;
45+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_decl_file;
46+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_decl_line;
3747
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_external;
3848
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_hi_pc;
49+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_inline;
3950
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_language;
4051
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_low_pc;
4152
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_AT_name;
@@ -48,9 +59,11 @@
4859
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FORM_data4;
4960
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FORM_flag;
5061
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FORM_null;
62+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FORM_ref4;
5163
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FORM_strp;
5264
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_FRAME_SECTION_NAME;
5365
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_TAG_compile_unit;
66+
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_TAG_inlined_subroutine;
5467
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_TAG_subprogram;
5568

5669
/**
@@ -70,81 +83,7 @@ public String getSectionName() {
7083
@Override
7184
public void createContent() {
7285
int pos = 0;
73-
/*
74-
* An abbrev table contains abbrev entries for one or more CUs. the table includes a
75-
* sequence of abbrev entries each of which defines a specific DIE layout employed to
76-
* describe some DIE in a CU. a table is terminated by a null entry.
77-
*
78-
* A null entry has consists of just a 0 abbrev code.
79-
*
80-
* <ul>
81-
*
82-
* <li><code>LEB128 abbrev_code; ...... == 0</code>
83-
*
84-
* </ul>
85-
*
86-
* Mon-null entries have the following format.
87-
*
88-
* <ul>
89-
*
90-
* <li><code>LEB128 abbrev_code; ......unique noncode for this layout != 0</code>
91-
*
92-
* <li><code>LEB128 tag; .............. defines the type of the DIE (class, subprogram, var
93-
* etc)</code>
94-
*
95-
* <li><code>uint8 has_chldren; ....... is the DIE followed by child DIEs or a sibling
96-
* DIE</code>
97-
*
98-
* <li><code>attribute_spec* .......... zero or more attributes</code>
99-
*
100-
* <li><code>null_attribute_spec ...... terminator</code> </ul>
101-
*
102-
* An attribute_spec consists of an attribute name and form
103-
*
104-
* <ul>
105-
*
106-
* <li><code>LEB128 attr_name; ........ 0 for the null attribute name</code>
107-
*
108-
* <li><code>LEB128 attr_form; ........ 0 for the null attribute form</code>
109-
*
110-
* </ul>
111-
*
112-
* For the moment we only use one abbrev table for all CUs. It contains three DIEs. The
113-
* first two describe the compilation unit itself and the third describes each method within
114-
* that compilation unit.
115-
*
116-
* The DIE layouts are as follows:
117-
*
118-
* <ul> <li><code>abbrev_code == 1 or 2, tag == DW_TAG_compilation_unit, has_children</code>
119-
*
120-
* <li><code>DW_AT_language : ... DW_FORM_data1</code>
121-
*
122-
* <li><code>DW_AT_name : ....... DW_FORM_strp</code>
123-
*
124-
* <li><code>DW_AT_low_pc : ..... DW_FORM_address</code>
125-
*
126-
* <li><code>DW_AT_hi_pc : ...... DW_FORM_address</code>
127-
*
128-
* <li><code>DW_AT_stmt_list : .. DW_FORM_data4</code> n.b only for <code>abbrev-code ==
129-
* 2</code>
130-
*
131-
* </ul>
132-
*
133-
* <ul> <li><code>abbrev_code == 3, tag == DW_TAG_subprogram, no_children</code>
134-
*
135-
* <li><code>DW_AT_name : ....... DW_FORM_strp</code>
136-
*
137-
* <li><code>DW_AT_hi_pc : ...... DW_FORM_addr</code>
138-
*
139-
* <li><code>DW_AT_external : ... DW_FORM_flag</code>
140-
*
141-
* </ul>
142-
*/
143-
144-
pos = writeCUAbbrev1(null, null, pos);
145-
pos = writeCUAbbrev2(null, null, pos);
146-
pos = writeMethodAbbrev(null, null, pos);
147-
86+
pos = writeContent(null, pos);
14887
byte[] buffer = new byte[pos];
14988
super.setContent(buffer);
15089
}
@@ -154,23 +93,22 @@ public void writeContent(DebugContext context) {
15493
byte[] buffer = getContent();
15594
int size = buffer.length;
15695
int pos = 0;
157-
15896
enableLog(context, pos);
159-
160-
pos = writeCUAbbrev1(context, buffer, pos);
161-
pos = writeCUAbbrev2(context, buffer, pos);
162-
pos = writeMethodAbbrev(context, buffer, pos);
97+
pos = writeContent(buffer, pos);
16398
assert pos == size;
16499
}
165100

166-
@SuppressWarnings("unused")
167-
private int writeCUAbbrev1(DebugContext context, byte[] buffer, int p) {
168-
return writeCUAbbrev(context, DW_ABBREV_CODE_compile_unit_1, buffer, p);
169-
}
170-
171-
@SuppressWarnings("unused")
172-
private int writeCUAbbrev2(DebugContext context, byte[] buffer, int p) {
173-
return writeCUAbbrev(context, DW_ABBREV_CODE_compile_unit_2, buffer, p);
101+
private int writeContent(byte[] buffer, int p) {
102+
int pos = p;
103+
pos = writeCUAbbrev(DW_ABBREV_CODE_compile_unit_stmt_list, buffer, pos);
104+
pos = writeCUAbbrev(DW_ABBREV_CODE_compile_unit_no_stmt_list, buffer, pos);
105+
pos = writeMethodAbbrev(buffer, pos, false, false);
106+
pos = writeMethodAbbrev(buffer, pos, false, true);
107+
pos = writeMethodAbbrev(buffer, pos, true, false);
108+
pos = writeMethodAbbrev(buffer, pos, true, true);
109+
pos = writeInlinedSubroutineAbbrevs(buffer, pos, false);
110+
pos = writeInlinedSubroutineAbbrevs(buffer, pos, true);
111+
return pos;
174112
}
175113

176114
private int writeAttrType(long code, byte[] buffer, int pos) {
@@ -189,12 +127,8 @@ private int writeAttrForm(long code, byte[] buffer, int pos) {
189127
}
190128
}
191129

192-
@SuppressWarnings("unused")
193-
private int writeCUAbbrev(DebugContext context, int abbrevCode, byte[] buffer, int p) {
130+
private int writeCUAbbrev(int abbrevCode, byte[] buffer, int p) {
194131
int pos = p;
195-
/*
196-
* Abbrev 1/2 compile unit.
197-
*/
198132
pos = writeAbbrevCode(abbrevCode, buffer, pos);
199133
pos = writeTag(DW_TAG_compile_unit, buffer, pos);
200134
pos = writeFlag(DW_CHILDREN_yes, buffer, pos);
@@ -208,38 +142,74 @@ private int writeCUAbbrev(DebugContext context, int abbrevCode, byte[] buffer, i
208142
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
209143
pos = writeAttrType(DW_AT_hi_pc, buffer, pos);
210144
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
211-
if (abbrevCode == DW_ABBREV_CODE_compile_unit_1) {
145+
if (abbrevCode == DW_ABBREV_CODE_compile_unit_stmt_list) {
212146
pos = writeAttrType(DW_AT_stmt_list, buffer, pos);
213147
pos = writeAttrForm(DW_FORM_data4, buffer, pos);
214148
}
215-
/*
216-
* Now terminate.
217-
*/
149+
/* Now terminate. */
218150
pos = writeAttrType(DW_AT_null, buffer, pos);
219151
pos = writeAttrForm(DW_FORM_null, buffer, pos);
220152
return pos;
221153
}
222154

223-
@SuppressWarnings("unused")
224-
private int writeMethodAbbrev(DebugContext context, byte[] buffer, int p) {
155+
private int writeMethodAbbrev(byte[] buffer, int p, boolean inline, boolean withChildren) {
225156
int pos = p;
226-
/*
227-
* Abbrev 2 compile unit.
228-
*/
229-
pos = writeAbbrevCode(DW_ABBREV_CODE_subprogram, buffer, pos);
157+
final int code;
158+
if (inline) {
159+
if (withChildren) {
160+
code = DW_ABBREV_CODE_subprogram_inline_with_children;
161+
} else {
162+
code = DW_ABBREV_CODE_subprogram_inline;
163+
}
164+
} else {
165+
if (withChildren) {
166+
code = DW_ABBREV_CODE_subprogram_with_children;
167+
} else {
168+
code = DW_ABBREV_CODE_subprogram;
169+
}
170+
}
171+
pos = writeAbbrevCode(code, buffer, pos);
230172
pos = writeTag(DW_TAG_subprogram, buffer, pos);
231-
pos = writeFlag(DW_CHILDREN_no, buffer, pos);
173+
pos = writeFlag(withChildren ? DW_CHILDREN_yes : DW_CHILDREN_no, buffer, pos);
232174
pos = writeAttrType(DW_AT_name, buffer, pos);
233175
pos = writeAttrForm(DW_FORM_strp, buffer, pos);
176+
if (inline) {
177+
pos = writeAttrType(DW_AT_inline, buffer, pos);
178+
pos = writeAttrForm(DW_FORM_data1, buffer, pos);
179+
} else {
180+
pos = writeAttrType(DW_AT_low_pc, buffer, pos);
181+
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
182+
pos = writeAttrType(DW_AT_hi_pc, buffer, pos);
183+
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
184+
}
185+
pos = writeAttrType(DW_AT_decl_file, buffer, pos);
186+
pos = writeAttrForm(DW_FORM_data4, buffer, pos);
187+
pos = writeAttrType(DW_AT_decl_line, buffer, pos);
188+
pos = writeAttrForm(DW_FORM_data4, buffer, pos);
189+
pos = writeAttrType(DW_AT_external, buffer, pos);
190+
pos = writeAttrForm(DW_FORM_flag, buffer, pos);
191+
/* Now terminate. */
192+
pos = writeAttrType(DW_AT_null, buffer, pos);
193+
pos = writeAttrForm(DW_FORM_null, buffer, pos);
194+
return pos;
195+
}
196+
197+
private int writeInlinedSubroutineAbbrevs(byte[] buffer, int p, boolean withChildren) {
198+
int pos = p;
199+
pos = writeAbbrevCode(withChildren ? DW_ABBREV_CODE_inlined_subroutine_with_children : DW_ABBREV_CODE_inlined_subroutine, buffer, pos);
200+
pos = writeTag(DW_TAG_inlined_subroutine, buffer, pos);
201+
pos = writeFlag(withChildren ? DW_CHILDREN_yes : DW_CHILDREN_no, buffer, pos);
202+
pos = writeAttrType(DW_AT_abstract_origin, buffer, pos);
203+
pos = writeAttrForm(DW_FORM_ref4, buffer, pos);
234204
pos = writeAttrType(DW_AT_low_pc, buffer, pos);
235205
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
236206
pos = writeAttrType(DW_AT_hi_pc, buffer, pos);
237207
pos = writeAttrForm(DW_FORM_addr, buffer, pos);
238-
pos = writeAttrType(DW_AT_external, buffer, pos);
239-
pos = writeAttrForm(DW_FORM_flag, buffer, pos);
240-
/*
241-
* Now terminate.
242-
*/
208+
pos = writeAttrType(DW_AT_call_file, buffer, pos);
209+
pos = writeAttrForm(DW_FORM_data4, buffer, pos);
210+
pos = writeAttrType(DW_AT_call_line, buffer, pos);
211+
pos = writeAttrForm(DW_FORM_data4, buffer, pos);
212+
/* Now terminate. */
243213
pos = writeAttrType(DW_AT_null, buffer, pos);
244214
pos = writeAttrForm(DW_FORM_null, buffer, pos);
245215
return pos;

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfDebugInfo.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,21 @@ public class DwarfDebugInfo extends DebugInfoBase {
5959
* Define all the abbrev section codes we need for our DIEs.
6060
*/
6161
@SuppressWarnings("unused") public static final int DW_ABBREV_CODE_null = 0;
62-
public static final int DW_ABBREV_CODE_compile_unit_1 = 1;
63-
public static final int DW_ABBREV_CODE_compile_unit_2 = 2;
62+
public static final int DW_ABBREV_CODE_compile_unit_stmt_list = 1;
63+
public static final int DW_ABBREV_CODE_compile_unit_no_stmt_list = 2;
6464
public static final int DW_ABBREV_CODE_subprogram = 3;
65+
public static final int DW_ABBREV_CODE_subprogram_with_children = 4;
66+
public static final int DW_ABBREV_CODE_subprogram_inline = 5;
67+
public static final int DW_ABBREV_CODE_subprogram_inline_with_children = 6;
68+
public static final int DW_ABBREV_CODE_inlined_subroutine = 7;
69+
public static final int DW_ABBREV_CODE_inlined_subroutine_with_children = 8;
6570

6671
/*
6772
* Define all the Dwarf tags we need for our DIEs.
6873
*/
6974
public static final int DW_TAG_compile_unit = 0x11;
7075
public static final int DW_TAG_subprogram = 0x2e;
76+
public static final int DW_TAG_inlined_subroutine = 0x1d;
7177
/*
7278
* Define all the Dwarf attributes we need for our DIEs.
7379
*/
@@ -78,6 +84,12 @@ public class DwarfDebugInfo extends DebugInfoBase {
7884
public static final int DW_AT_low_pc = 0x11;
7985
public static final int DW_AT_hi_pc = 0x12;
8086
public static final int DW_AT_language = 0x13;
87+
public static final int DW_AT_inline = 0x20;
88+
public static final int DW_AT_abstract_origin = 0x31;
89+
public static final int DW_AT_decl_file = 0x3a;
90+
public static final int DW_AT_decl_line = 0x3b;
91+
public static final int DW_AT_call_file = 0x58;
92+
public static final int DW_AT_call_line = 0x59;
8193
public static final int DW_AT_external = 0x3f;
8294
@SuppressWarnings("unused") public static final int DW_AT_return_addr = 0x2a;
8395
@SuppressWarnings("unused") public static final int DW_AT_frame_base = 0x40;
@@ -88,6 +100,11 @@ public class DwarfDebugInfo extends DebugInfoBase {
88100
@SuppressWarnings("unused") private static final int DW_FORM_string = 0x8;
89101
public static final int DW_FORM_strp = 0xe;
90102
public static final int DW_FORM_addr = 0x1;
103+
@SuppressWarnings("unused") public static final int DW_FORM_ref_addr = 0x10;
104+
@SuppressWarnings("unused") public static final int DW_FORM_ref1 = 0x11;
105+
@SuppressWarnings("unused") public static final int DW_FORM_ref2 = 0x12;
106+
public static final int DW_FORM_ref4 = 0x13;
107+
@SuppressWarnings("unused") public static final int DW_FORM_ref8 = 0x14;
91108
public static final int DW_FORM_data1 = 0x0b;
92109
public static final int DW_FORM_data4 = 0x6;
93110
@SuppressWarnings("unused") public static final int DW_FORM_data8 = 0x7;
@@ -111,6 +128,13 @@ public class DwarfDebugInfo extends DebugInfoBase {
111128
* Value for DW_AT_language attribute with form DATA1.
112129
*/
113130
public static final byte DW_LANG_Java = 0xb;
131+
/*
132+
* Values for {@link DW_AT_inline} attribute with form DATA1.
133+
*/
134+
@SuppressWarnings("unused") public static final byte DW_INL_not_inlined = 0;
135+
public static final byte DW_INL_inlined = 1;
136+
@SuppressWarnings("unused") public static final byte DW_INL_declared_not_inlined = 2;
137+
@SuppressWarnings("unused") public static final byte DW_INL_declared_inlined = 3;
114138

115139
/*
116140
* DW_AT_Accessibility attribute values.

0 commit comments

Comments
 (0)