llvm.org GIT mirror llvm / b9c4ad2
[DWARF] Support for DW_FORM_strx3 and complete support for DW_FORM_strx{1,2,4} (consumer). Reviewer: aprantl Differential Revision: https://reviews.llvm.org/D34418 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305944 91177308-0d34-0410-b5e6-96231b3b80d8 Wolfgang Pieb 2 years ago
6 changed file(s) with 148 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
1313 #include "llvm/Support/DataTypes.h"
1414
1515 namespace llvm {
16
17 /// An auxiliary type to facilitate extraction of 3-byte entities.
18 struct Uint24 {
19 uint8_t Bytes[3];
20 Uint24(uint8_t U) {
21 Bytes[0] = Bytes[1] = Bytes[2] = U;
22 }
23 Uint24(uint8_t U0, uint8_t U1, uint8_t U2) {
24 Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2;
25 }
26 uint32_t getAsUint32(bool IsLittleEndian) const {
27 int LoIx = IsLittleEndian ? 0 : 2;
28 return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
29 }
30 };
31
32 using uint24_t = Uint24;
33 static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
34
35 /// Needed by swapByteOrder().
36 inline uint24_t getSwappedBytes(uint24_t C) {
37 return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
38 }
39
1640 class DataExtractor {
1741 StringRef Data;
1842 uint8_t IsLittleEndian;
235259 /// NULL otherise.
236260 uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
237261
262 /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
263 /// in a uint32_t.
264 ///
265 /// Extract 3 bytes from the binary data at the offset pointed to by
266 /// \a offset_ptr, construct a uint32_t from them and update the offset
267 /// on success.
268 ///
269 /// @param[in,out] offset_ptr
270 /// A pointer to an offset within the data that will be advanced
271 /// by the 3 bytes if the value is extracted correctly. If the offset
272 /// is out of bounds or there are not enough bytes to extract this value,
273 /// the offset will be left unmodified.
274 ///
275 /// @return
276 /// The extracted 24-bit value represented in a uint32_t.
277 uint32_t getU24(uint32_t *offset_ptr) const;
278
238279 /// Extract a uint32_t value from \a *offset_ptr.
239280 ///
240281 /// Extract a single uint32_t from the binary data at the offset
136136 case DW_FORM_strx2:
137137 case DW_FORM_addrx2:
138138 return 2;
139
140 case DW_FORM_strx3:
141 return 3;
139142
140143 case DW_FORM_data4:
141144 case DW_FORM_ref4:
301304 case DW_FORM_GNU_str_index:
302305 case DW_FORM_GNU_strp_alt:
303306 case DW_FORM_strx:
307 case DW_FORM_strx1:
308 case DW_FORM_strx2:
309 case DW_FORM_strx3:
310 case DW_FORM_strx4:
304311 return (FC == FC_String);
305312 case DW_FORM_implicit_const:
306313 return (FC == FC_Constant);
366373 case DW_FORM_strx2:
367374 case DW_FORM_addrx2:
368375 Value.uval = Data.getU16(OffsetPtr);
376 break;
377 case DW_FORM_strx3:
378 Value.uval = Data.getU24(OffsetPtr);
369379 break;
370380 case DW_FORM_data4:
371381 case DW_FORM_ref4:
544554 dumpString(OS);
545555 break;
546556 case DW_FORM_strx:
557 case DW_FORM_strx1:
558 case DW_FORM_strx2:
559 case DW_FORM_strx3:
560 case DW_FORM_strx4:
547561 case DW_FORM_GNU_str_index:
548562 OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
549563 dumpString(OS);
622636 if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
623637 return None;
624638 uint32_t Offset = Value.uval;
625 if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx) {
639 if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
640 Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
641 Form == DW_FORM_strx4) {
626642 uint64_t StrOffset;
627643 if (!U->getStringOffsetSectionItem(Offset, StrOffset))
628644 return None;
6565 uint32_t count) const {
6666 return getUs(offset_ptr, dst, count, this, IsLittleEndian,
6767 Data.data());
68 }
69
70 uint32_t DataExtractor::getU24(uint32_t *offset_ptr) const {
71 uint24_t ExtractedVal =
72 getU(offset_ptr, this, IsLittleEndian, Data.data());
73 // The 3 bytes are in the correct byte order for the host.
74 return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
6875 }
6976
7077 uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
1919 .asciz "Type_Unit"
2020 str_TU_type:
2121 .asciz "MyStruct"
22 str_Subprogram:
23 .asciz "MyFunc"
24 str_Variable1:
25 .asciz "MyVar1"
26 str_Variable2:
27 .asciz "MyVar2"
28 str_Variable3:
29 .asciz "MyVar3"
2230
2331 # Every unit contributes to the string_offsets table.
2432 .section .debug_str_offsets,"",@progbits
3038 .long str_producer
3139 .long str_CU1
3240 .long str_CU1_dir
41 .long str_Subprogram
42 .long str_Variable1
43 .long str_Variable2
44 .long str_Variable3
3345 .debug_str_offsets_segment0_end:
3446 # CU2's contribution
3547 .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
8496 .section .debug_abbrev,"",@progbits
8597 .byte 0x01 # Abbrev code
8698 .byte 0x11 # DW_TAG_compile_unit
87 .byte 0x00 # DW_CHILDREN_no
99 .byte 0x01 # DW_CHILDREN_yes
88100 .byte 0x25 # DW_AT_producer
89101 .byte 0x1a # DW_FORM_strx
90102 .byte 0x03 # DW_AT_name
111123 .byte 0x1a # DW_FORM_strx
112124 .byte 0x00 # EOM(1)
113125 .byte 0x00 # EOM(2)
126 .byte 0x04 # Abbrev code
127 .byte 0x2e # DW_TAG_subprogram
128 .byte 0x01 # DW_CHILDREN_yes
129 .byte 0x03 # DW_AT_name
130 .byte 0x25 # DW_FORM_strx1
131 .byte 0x00 # EOM(1)
132 .byte 0x00 # EOM(2)
133 .byte 0x05 # Abbrev code
134 .byte 0x34 # DW_TAG_variable
135 .byte 0x00 # DW_CHILDREN_no
136 .byte 0x03 # DW_AT_name
137 .byte 0x26 # DW_FORM_strx2
138 .byte 0x00 # EOM(1)
139 .byte 0x00 # EOM(2)
140 .byte 0x06 # Abbrev code
141 .byte 0x34 # DW_TAG_variable
142 .byte 0x00 # DW_CHILDREN_no
143 .byte 0x03 # DW_AT_name
144 .byte 0x27 # DW_FORM_strx3
145 .byte 0x00 # EOM(1)
146 .byte 0x00 # EOM(2)
147 .byte 0x07 # Abbrev code
148 .byte 0x34 # DW_TAG_variable
149 .byte 0x00 # DW_CHILDREN_no
150 .byte 0x03 # DW_AT_name
151 .byte 0x28 # DW_FORM_strx4
152 .byte 0x00 # EOM(1)
153 .byte 0x00 # EOM(2)
114154 .byte 0x00 # EOM(3)
115155
116 # And a .dwo copy for the .dwo sections.
156 # And a .dwo copy of a subset for the .dwo sections.
117157 .section .debug_abbrev.dwo,"",@progbits
118158 .byte 0x01 # Abbrev code
119159 .byte 0x11 # DW_TAG_compile_unit
162202 .byte 1 # The index of the CU name string
163203 .long .debug_str_offsets_base0
164204 .byte 2 # The index of the comp dir string
205 # A subprogram DIE with DW_AT_name, using DW_FORM_strx1.
206 .byte 4 # Abbreviation code
207 .byte 3 # Subprogram name string (DW_FORM_strx1)
208 # A variable DIE with DW_AT_name, using DW_FORM_strx2.
209 .byte 5 # Abbreviation code
210 .short 0x0004 # Subprogram name string (DW_FORM_strx2)
211 # A variable DIE with DW_AT_name, using DW_FORM_strx3.
212 .byte 6 # Abbreviation code
213 .byte 5 # Subprogram name string (DW_FORM_strx3)
214 .short 0 # Subprogram name string (DW_FORM_strx3)
215 # A variable DIE with DW_AT_name, using DW_FORM_strx4.
216 .byte 7 # Abbreviation code
217 .quad 0x00000006 # Subprogram name string (DW_FORM_strx4)
218 .byte 0 # NULL
219 .byte 0 # NULL
165220 .byte 0 # NULL
166221 CU1_5_end:
167222
1818 CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_1")
1919 CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
2020 CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU1")
21 CHECK-NOT: NULL
22 CHECK: DW_TAG_subprogram
23 CHECK-NEXT: DW_AT_name [DW_FORM_strx1] ( indexed (00000003) string = "MyFunc")
24 CHECK-NOT: NULL
25 CHECK: DW_TAG_variable
26 CHECK-NEXT: DW_AT_name [DW_FORM_strx2] ( indexed (00000004) string = "MyVar1")
27 CHECK-NOT: NULL
28 CHECK: DW_TAG_variable
29 CHECK-NEXT: DW_AT_name [DW_FORM_strx3] ( indexed (00000005) string = "MyVar2")
30 CHECK-NOT: NULL
31 CHECK: DW_TAG_variable
32 CHECK-NEXT: DW_AT_name [DW_FORM_strx4] ( indexed (00000006) string = "MyVar3")
2133
2234 ; Second compile unit (b.cpp)
2335 CHECK: DW_TAG_compile_unit
2436 CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
2537 CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_2")
26 CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
38 CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000002c)
2739 CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
2840
2941 ; The split CU
3951 CHECK: .debug_types contents:
4052 CHECK: DW_TAG_type_unit
4153 CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit")
42 CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000030)
54 CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000040)
4355 CHECK: DW_TAG_structure_type
4456 CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct")
4557
5365
5466 ; The .debug_str_offsets section
5567 CHECK: .debug_str_offsets contents:
56 CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5
68 CHECK-NEXT: 0x00000000: Contribution size = 28, Version = 5
5769 CHECK-NEXT: 0x00000008: 00000000 "Handmade DWARF producer"
5870 CHECK-NEXT: 0x0000000c: 00000018 "Compile_Unit_1"
5971 CHECK-NEXT: 0x00000010: 00000027 "/home/test/CU1"
60 CHECK-NEXT: 0x00000014: Contribution size = 12, Version = 5
61 CHECK-NEXT: 0x0000001c: 00000000 "Handmade DWARF producer"
62 CHECK-NEXT: 0x00000020: 00000036 "Compile_Unit_2"
63 CHECK-NEXT: 0x00000024: 00000045 "/home/test/CU2"
64 CHECK-NEXT: 0x00000028: Contribution size = 8, Version = 5
65 CHECK-NEXT: 0x00000030: 00000054 "Type_Unit"
66 CHECK-NEXT: 0x00000034: 0000005e "MyStruct"
72 CHECK-NEXT: 0x00000014: 00000067 "MyFunc"
73 CHECK-NEXT: 0x00000018: 0000006e "MyVar1"
74 CHECK-NEXT: 0x0000001c: 00000075 "MyVar2"
75 CHECK-NEXT: 0x00000020: 0000007c "MyVar3"
76 CHECK-NEXT: 0x00000024: Contribution size = 12, Version = 5
77 CHECK-NEXT: 0x0000002c: 00000000 "Handmade DWARF producer"
78 CHECK-NEXT: 0x00000030: 00000036 "Compile_Unit_2"
79 CHECK-NEXT: 0x00000034: 00000045 "/home/test/CU2"
80 CHECK-NEXT: 0x00000038: Contribution size = 8, Version = 5
81 CHECK-NEXT: 0x00000040: 00000054 "Type_Unit"
82 CHECK-NEXT: 0x00000044: 0000005e "MyStruct"
6783
6884 CHECK: .debug_str_offsets.dwo contents:
6985 CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5