llvm.org GIT mirror llvm / e9d757c
[DWARFv5] Support DW_FORM_strp in the .debug_line header. Supporting this form in .debug_line.dwo will be done as a follow-up. Differential Revision: https://reviews.llvm.org/D33155 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317607 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 1 year, 9 months ago
12 changed file(s) with 54 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
2121
2222 namespace llvm {
2323
24 class DWARFUnit;
2425 class raw_ostream;
2526
2627 class DWARFDebugLine {
9495
9596 void clear();
9697 void dump(raw_ostream &OS) const;
97 bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr);
98 bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
99 const DWARFUnit *U = nullptr);
98100 };
99101
100102 /// Standard .debug_line state machine structure.
217219
218220 /// Parse prologue and all rows.
219221 bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
220 raw_ostream *OS = nullptr);
222 const DWARFUnit *U, raw_ostream *OS = nullptr);
221223
222224 using RowVector = std::vector;
223225 using RowIter = RowVector::const_iterator;
235237
236238 const LineTable *getLineTable(uint32_t Offset) const;
237239 const LineTable *getOrParseLineTable(const DWARFDataExtractor &DebugLineData,
238 uint32_t Offset);
240 uint32_t Offset, const DWARFUnit *U);
239241
240242 private:
241243 struct ParsingState {
103103 const DWARFUnit *getUnit() const { return U; }
104104 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
105105
106 /// Extracts a value in \p Data at offset \p *OffsetPtr.
107 ///
108 /// The passed DWARFUnit is allowed to be nullptr, in which case some
109 /// kind of forms that depend on Unit information are disallowed.
110 /// \param Data The DWARFDataExtractor to use.
111 /// \param OffsetPtr The offset within \p Data where the data starts.
112 /// \param U The optional DWARFUnit supplying information for some forms.
113 /// \returns whether the extraction succeeded.
106 /// Extracts a value in \p Data at offset \p *OffsetPtr. The information
107 /// in \p FormParams is needed to interpret some forms. The optional
108 /// \p Unit allows extracting information if the form refers to other
109 /// sections (e.g., .debug_str).
114110 bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
115 const DWARFUnit *U);
111 DWARFFormParams FormParams, const DWARFUnit *U = nullptr);
116112
117113 bool isInlinedCStr() const {
118114 return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr;
183183 FormValue.setSValue(Spec.getImplicitConstValue());
184184 return FormValue;
185185 }
186 if (FormValue.extractValue(DebugInfoData, &Offset, &U))
186 if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
187187 return FormValue;
188188 }
189189 // March Offset along until we get to the attribute we want.
8989 DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
9090 uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
9191 dwarf::Tag DieTag = dwarf::DW_TAG_null;
92 DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
9293
9394 for (auto Atom : getAtomsDesc()) {
9495 DWARFFormValue FormValue(Atom.second);
95 FormValue.extractValue(AccelSection, &HashDataOffset, NULL);
96 FormValue.extractValue(AccelSection, &HashDataOffset, FormParams);
9697 switch (Atom.first) {
9798 case dwarf::DW_ATOM_die_offset:
9899 DieOffset = *FormValue.getAsUnsignedConstant();
144145 uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
145146 unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
146147 unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
148 DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
147149
148150 for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
149151 unsigned Index = AccelSection.getU32(&Offset);
180182 unsigned i = 0;
181183 for (auto &Atom : AtomForms) {
182184 OS << format("{Atom[%d]: ", i++);
183 if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
185 if (Atom.extractValue(AccelSection, &DataOffset, FormParams))
184186 Atom.dump(OS);
185187 else
186188 OS << "Error extracting the value";
215217 NumData = 0;
216218 return;
217219 }
220 DWARFFormParams FormParams = {AccelTable->Hdr.Version, 0,
221 dwarf::DwarfFormat::DWARF32};
218222 for (auto &Atom : AtomForms)
219 Atom.extractValue(AccelSection, &DataOffset, nullptr);
223 Atom.extractValue(AccelSection, &DataOffset, FormParams);
220224 ++Data;
221225 }
222226
328328 // representation.
329329 OS << "debug_line[" << format("0x%8.8x", Offset) << "]\n";
330330 if (DumpOpts.Verbose) {
331 LineTable.parse(lineData, &Offset, &OS);
331 LineTable.parse(lineData, &Offset, &*CU, &OS);
332332 } else {
333 LineTable.parse(lineData, &Offset);
333 LineTable.parse(lineData, &Offset, &*CU);
334334 LineTable.dump(OS);
335335 }
336336 }
348348 DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
349349 isLittleEndian(), savedAddressByteSize);
350350 DWARFDebugLine::LineTable LineTable;
351 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
351 while (LineTable.Prologue.parse(lineData, &stmtOffset, nullptr)) {
352352 LineTable.dump(OS);
353353 LineTable.clear();
354354 }
680680 // We have to parse it first.
681681 DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
682682 U->getAddressByteSize());
683 return Line->getOrParseLineTable(lineData, stmtOffset);
683 return Line->getOrParseLineTable(lineData, stmtOffset, U);
684684 }
685685
686686 void DWARFContext::parseCompileUnits() {
143143 static bool
144144 parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
145145 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
146 const DWARFFormParams &FormParams,
146 const DWARFFormParams &FormParams, const DWARFUnit *U,
147147 std::vector &IncludeDirectories,
148148 std::vector &FileNames) {
149149 // Get the directory entry description.
161161 DWARFFormValue Value(Descriptor.Form);
162162 switch (Descriptor.Type) {
163163 case DW_LNCT_path:
164 if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr))
164 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, U))
165165 return false;
166166 IncludeDirectories.push_back(Value.getAsCString().getValue());
167167 break;
186186 DWARFDebugLine::FileNameEntry FileEntry;
187187 for (auto Descriptor : FileDescriptors) {
188188 DWARFFormValue Value(Descriptor.Form);
189 if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr))
189 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, U))
190190 return false;
191191 switch (Descriptor.Type) {
192192 case DW_LNCT_path:
212212 }
213213
214214 bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
215 uint32_t *OffsetPtr) {
215 uint32_t *OffsetPtr, const DWARFUnit *U) {
216216 const uint64_t PrologueOffset = *OffsetPtr;
217217
218218 clear();
252252
253253 if (getVersion() >= 5) {
254254 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
255 getFormParams(), IncludeDirectories, FileNames)) {
255 getFormParams(), U, IncludeDirectories,
256 FileNames)) {
256257 fprintf(stderr,
257258 "warning: parsing line table prologue at 0x%8.8" PRIx64
258259 " found an invalid directory or file table description at"
381382
382383 const DWARFDebugLine::LineTable *
383384 DWARFDebugLine::getOrParseLineTable(const DWARFDataExtractor &DebugLineData,
384 uint32_t Offset) {
385 uint32_t Offset, const DWARFUnit *U) {
385386 std::pair Pos =
386387 LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
387388 LineTable *LT = &Pos.first->second;
388389 if (Pos.second) {
389 if (!LT->parse(DebugLineData, &Offset))
390 if (!LT->parse(DebugLineData, &Offset, U))
390391 return nullptr;
391392 }
392393 return LT;
393394 }
394395
395396 bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData,
396 uint32_t *OffsetPtr, raw_ostream *OS) {
397 uint32_t *OffsetPtr, const DWARFUnit *U,
398 raw_ostream *OS) {
397399 const uint32_t DebugLineOffset = *OffsetPtr;
398400
399401 clear();
400402
401 if (!Prologue.parse(DebugLineData, OffsetPtr)) {
403 if (!Prologue.parse(DebugLineData, OffsetPtr, U)) {
402404 // Restore our offset and return false to indicate failure!
403405 *OffsetPtr = DebugLineOffset;
404406 return false;
207207 DWARFUnit *U = Die.getDwarfUnit();
208208 DWARFFormValue formValue(Form);
209209
210 if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U))
210 if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
211 U->getFormParams(), U))
211212 return;
212213
213214 OS << "\t(";
549550 auto U = Die.getDwarfUnit();
550551 assert(U && "Die must have valid DWARF unit");
551552 bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(),
552 &ParseOffset, U);
553 &ParseOffset, U->getFormParams(), U);
553554 (void)b;
554555 assert(b && "extractValue cannot fail on fully parsed DWARF");
555556 AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
275275 }
276276
277277 bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
278 uint32_t *OffsetPtr, const DWARFUnit *CU) {
278 uint32_t *OffsetPtr, DWARFFormParams FP,
279 const DWARFUnit *CU) {
279280 U = CU;
280281 bool Indirect = false;
281282 bool IsBlock = false;
287288 switch (Form) {
288289 case DW_FORM_addr:
289290 case DW_FORM_ref_addr: {
290 if (!U)
291 return false;
292 uint16_t Size = (Form == DW_FORM_addr) ? U->getAddressByteSize()
293 : U->getRefAddrByteSize();
291 uint16_t Size =
292 (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
294293 Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
295294 break;
296295 }
359358 case DW_FORM_GNU_strp_alt:
360359 case DW_FORM_line_strp:
361360 case DW_FORM_strp_sup: {
362 if (!U)
363 return false;
364361 Value.uval =
365 Data.getRelocatedValue(U->getDwarfOffsetByteSize(), OffsetPtr);
362 Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
366363 break;
367364 }
368365 case DW_FORM_flag_present:
1414 .asciz "V5_compile_unit"
1515 str_TU_4:
1616 .asciz "V4_type_unit"
17 str_LT_5a:
18 .asciz "Directory5a"
19 str_LT_5b:
20 .asciz "Directory5b"
1721
1822 .section .debug_str.dwo,"MS",@progbits,1
1923 dwo_TU_5:
226230 # Directory table format
227231 .byte 1 # One element per directory entry
228232 .byte 1 # DW_LNCT_path
229 .byte 0x08 # DW_FORM_string
233 .byte 0x0e # DW_FORM_strp (-> .debug_str)
230234 # Directory table entries
231235 .byte 2 # Two directories
232 .asciz "Directory5a"
233 .asciz "Directory5b"
236 .long str_LT_5a
237 .long str_LT_5b
234238 # File table format
235239 .byte 4 # Four elements per file entry
236240 .byte 1 # DW_LNCT_path
23652365 continue;
23662366 }
23672367
2368 Val.extractValue(Data, &Offset, &Unit);
2368 Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit);
23692369 CompileUnit *ReferencedCU;
23702370 if (auto RefDie =
23712371 resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) {
29642964
29652965 DWARFFormValue Val(AttrSpec.Form);
29662966 uint32_t AttrSize = Offset;
2967 Val.extractValue(Data, &Offset, &U);
2967 Val.extractValue(Data, &Offset, U.getFormParams(), &U);
29682968 AttrSize = Offset - AttrSize;
29692969
29702970 OutOffset +=
31573157 DWARFDataExtractor LineExtractor(
31583158 OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(),
31593159 OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize());
3160 LineTable.parse(LineExtractor, &StmtOffset);
3160 LineTable.parse(LineExtractor, &StmtOffset, &Unit.getOrigUnit());
31613161
31623162 // This vector is the output line table.
31633163 std::vector NewRows;
9898 DWARFFormValue Result(Form);
9999 DWARFDataExtractor Data(StringRef(Raw, sizeof(RawTypeT)),
100100 sys::IsLittleEndianHost, sizeof(void *));
101 Result.extractValue(Data, &Offset, nullptr);
101 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});
102102 return Result;
103103 }
104104
109109 uint32_t Offset = 0;
110110 DWARFFormValue Result(DW_FORM_udata);
111111 DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *));
112 Result.extractValue(Data, &Offset, nullptr);
112 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});
113113 return Result;
114114 }
115115
120120 uint32_t Offset = 0;
121121 DWARFFormValue Result(DW_FORM_sdata);
122122 DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *));
123 Result.extractValue(Data, &Offset, nullptr);
123 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});
124124 return Result;
125125 }
126126