Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
DWP.cpp
Go to the documentation of this file.
1//===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
10// package files).
11//
12//===----------------------------------------------------------------------===//
13#include "llvm/DWP/DWP.h"
14#include "llvm/ADT/Twine.h"
15#include "llvm/DWP/DWPError.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCObjectFileInfo.h"
18#include "llvm/MC/MCTargetOptionsCommandFlags.h"
19#include "llvm/Object/Decompressor.h"
20#include "llvm/Object/ELFObjectFile.h"
21#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/MemoryBuffer.h"
23#include <limits>
24
25using namespacellvm;
26using namespacellvm::object;
27
28staticmc::RegisterMCTargetOptionsFlagsMCTargetOptionsFlags;
29
30// Returns the size of debug_str_offsets section headers in bytes.
31staticuint64_tdebugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
32uint16_t DwarfVersion) {
33if (DwarfVersion <= 4)
34return 0;// There is no header before dwarf 5.
35uint64_tOffset = 0;
36uint64_tLength = StrOffsetsData.getU32(&Offset);
37if (Length ==llvm::dwarf::DW_LENGTH_DWARF64)
38return 16;// unit length: 12 bytes, version: 2 bytes, padding: 2 bytes.
39return 8;// unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
40}
41
42staticuint64_tgetCUAbbrev(StringRef Abbrev,uint64_t AbbrCode) {
43uint64_tOffset = 0;
44DataExtractor AbbrevData(Abbrev,true, 0);
45while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
46// Tag
47 AbbrevData.getULEB128(&Offset);
48// DW_CHILDREN
49 AbbrevData.getU8(&Offset);
50// Attributes
51while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
52 ;
53 }
54returnOffset;
55}
56
57staticExpected<const char *>
58getIndexedString(dwarf::Form Form,DataExtractor InfoData,uint64_t &InfoOffset,
59StringRef StrOffsets,StringRef Str,uint16_t Version) {
60if (Form == dwarf::DW_FORM_string)
61return InfoData.getCStr(&InfoOffset);
62uint64_t StrIndex;
63switch (Form) {
64case dwarf::DW_FORM_strx1:
65 StrIndex = InfoData.getU8(&InfoOffset);
66break;
67case dwarf::DW_FORM_strx2:
68 StrIndex = InfoData.getU16(&InfoOffset);
69break;
70case dwarf::DW_FORM_strx3:
71 StrIndex = InfoData.getU24(&InfoOffset);
72break;
73case dwarf::DW_FORM_strx4:
74 StrIndex = InfoData.getU32(&InfoOffset);
75break;
76case dwarf::DW_FORM_strx:
77case dwarf::DW_FORM_GNU_str_index:
78 StrIndex = InfoData.getULEB128(&InfoOffset);
79break;
80default:
81return make_error<DWPError>(
82"string field must be encoded with one of the following: "
83"DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
84"DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
85 }
86DataExtractor StrOffsetsData(StrOffsets,true, 0);
87uint64_t StrOffsetsOffset = 4 * StrIndex;
88 StrOffsetsOffset +=debugStrOffsetsHeaderSize(StrOffsetsData, Version);
89
90uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
91DataExtractor StrData(Str,true, 0);
92return StrData.getCStr(&StrOffset);
93}
94
95staticExpected<CompileUnitIdentifiers>
96getCUIdentifiers(InfoSectionUnitHeader &Header,StringRef Abbrev,
97StringRef Info,StringRef StrOffsets,StringRef Str) {
98DataExtractor InfoData(Info,true, 0);
99uint64_tOffset = Header.HeaderSize;
100if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
101return make_error<DWPError>(
102 std::string("unit type DW_UT_split_compile type not found in "
103"debug_info header. Unexpected unit type 0x" +
104 utostr(Header.UnitType) +" found"));
105
106CompileUnitIdentifiersID;
107
108uint32_t AbbrCode = InfoData.getULEB128(&Offset);
109DataExtractor AbbrevData(Abbrev,true, 0);
110uint64_t AbbrevOffset =getCUAbbrev(Abbrev, AbbrCode);
111auto Tag =static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
112if (Tag != dwarf::DW_TAG_compile_unit)
113return make_error<DWPError>("top level DIE is not a compile unit");
114// DW_CHILDREN
115 AbbrevData.getU8(&AbbrevOffset);
116uint32_tName;
117dwarf::Form Form;
118while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
119 (Form =static_cast<dwarf::Form>(
120 AbbrevData.getULEB128(&AbbrevOffset))) &&
121 (Name != 0 || Form != 0)) {
122switch (Name) {
123case dwarf::DW_AT_name: {
124Expected<const char *> EName =getIndexedString(
125 Form, InfoData,Offset, StrOffsets, Str, Header.Version);
126if (!EName)
127return EName.takeError();
128ID.Name = *EName;
129break;
130 }
131case dwarf::DW_AT_GNU_dwo_name:
132case dwarf::DW_AT_dwo_name: {
133Expected<const char *> EName =getIndexedString(
134 Form, InfoData,Offset, StrOffsets, Str, Header.Version);
135if (!EName)
136return EName.takeError();
137ID.DWOName = *EName;
138break;
139 }
140case dwarf::DW_AT_GNU_dwo_id:
141 Header.Signature = InfoData.getU64(&Offset);
142break;
143default:
144DWARFFormValue::skipValue(
145 Form, InfoData, &Offset,
146dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
147 }
148 }
149if (!Header.Signature)
150return make_error<DWPError>("compile unit missing dwo_id");
151ID.Signature = *Header.Signature;
152returnID;
153}
154
155staticboolisSupportedSectionKind(DWARFSectionKindKind) {
156returnKind !=DW_SECT_EXT_unknown;
157}
158
159namespacellvm {
160// Convert an internal section identifier into the index to use with
161// UnitIndexEntry::Contributions.
162unsignedgetContributionIndex(DWARFSectionKindKind,uint32_t IndexVersion) {
163assert(serializeSectionKind(Kind, IndexVersion) >= DW_SECT_INFO);
164returnserializeSectionKind(Kind, IndexVersion) - DW_SECT_INFO;
165}
166}// namespace llvm
167
168// Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
169// value of the section identifier.
170staticunsignedgetOnDiskSectionId(unsigned Index) {
171return Index + DW_SECT_INFO;
172}
173
174staticStringRefgetSubsection(StringRef Section,
175constDWARFUnitIndex::Entry &Entry,
176DWARFSectionKindKind) {
177constauto *Off = Entry.getContribution(Kind);
178if (!Off)
179returnStringRef();
180return Section.substr(Off->getOffset(), Off->getLength());
181}
182
183staticErrorsectionOverflowErrorOrWarning(uint32_t PrevOffset,
184uint32_t OverflowedOffset,
185StringRefSectionName,
186OnCuIndexOverflow OverflowOptValue,
187bool &AnySectionOverflow) {
188 std::string Msg =
189 (SectionName +
190Twine(" Section Contribution Offset overflow 4G. Previous Offset ") +
191Twine(PrevOffset) +Twine(", After overflow offset ") +
192Twine(OverflowedOffset) +Twine("."))
193 .str();
194if (OverflowOptValue == OnCuIndexOverflow::Continue) {
195WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
196returnError::success();
197 }elseif (OverflowOptValue == OnCuIndexOverflow::SoftStop) {
198 AnySectionOverflow =true;
199WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
200returnError::success();
201 }
202return make_error<DWPError>(Msg);
203}
204
205staticErroraddAllTypesFromDWP(
206MCStreamer &Out,MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
207constDWARFUnitIndex &TUIndex,MCSection *OutputTypes,StringRef Types,
208constUnitIndexEntry &TUEntry,uint32_t &TypesOffset,
209unsigned TypesContributionIndex,OnCuIndexOverflow OverflowOptValue,
210bool &AnySectionOverflow) {
211 Out.switchSection(OutputTypes);
212for (constDWARFUnitIndex::Entry &E : TUIndex.getRows()) {
213auto *I = E.getContributions();
214if (!I)
215continue;
216autoP = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
217if (!P.second)
218continue;
219auto &Entry =P.first->second;
220// Zero out the debug_info contribution
221 Entry.Contributions[0] = {};
222for (autoKind : TUIndex.getColumnKinds()) {
223if (!isSupportedSectionKind(Kind))
224continue;
225auto &C =
226 Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
227C.setOffset(C.getOffset() +I->getOffset());
228C.setLength(I->getLength());
229 ++I;
230 }
231auto &C = Entry.Contributions[TypesContributionIndex];
232 Out.emitBytes(Types.substr(
233C.getOffset() -
234 TUEntry.Contributions[TypesContributionIndex].getOffset(),
235C.getLength()));
236C.setOffset(TypesOffset);
237uint32_t OldOffset = TypesOffset;
238static_assert(sizeof(OldOffset) ==sizeof(TypesOffset));
239 TypesOffset +=C.getLength();
240if (OldOffset > TypesOffset) {
241if (Error Err =sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
242"Types", OverflowOptValue,
243 AnySectionOverflow))
244return Err;
245if (AnySectionOverflow) {
246 TypesOffset = OldOffset;
247returnError::success();
248 }
249 }
250 }
251returnError::success();
252}
253
254staticErroraddAllTypesFromTypesSection(
255MCStreamer &Out,MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
256MCSection *OutputTypes,const std::vector<StringRef> &TypesSections,
257constUnitIndexEntry &CUEntry,uint32_t &TypesOffset,
258OnCuIndexOverflow OverflowOptValue,bool &AnySectionOverflow) {
259for (StringRef Types : TypesSections) {
260 Out.switchSection(OutputTypes);
261uint64_tOffset = 0;
262DataExtractor Data(Types,true, 0);
263while (Data.isValidOffset(Offset)) {
264UnitIndexEntry Entry = CUEntry;
265// Zero out the debug_info contribution
266 Entry.Contributions[0] = {};
267auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
268C.setOffset(TypesOffset);
269auto PrevOffset =Offset;
270// Length of the unit, including the 4 byte length field.
271C.setLength(Data.getU32(&Offset) + 4);
272
273 Data.getU16(&Offset);// Version
274 Data.getU32(&Offset);// Abbrev offset
275 Data.getU8(&Offset);// Address size
276auto Signature = Data.getU64(&Offset);
277Offset = PrevOffset +C.getLength32();
278
279autoP = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
280if (!P.second)
281continue;
282
283 Out.emitBytes(Types.substr(PrevOffset,C.getLength32()));
284uint32_t OldOffset = TypesOffset;
285 TypesOffset +=C.getLength32();
286if (OldOffset > TypesOffset) {
287if (Error Err =sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
288"Types", OverflowOptValue,
289 AnySectionOverflow))
290return Err;
291if (AnySectionOverflow) {
292 TypesOffset = OldOffset;
293returnError::success();
294 }
295 }
296 }
297 }
298returnError::success();
299}
300
301static std::stringbuildDWODescription(StringRefName,StringRef DWPName,
302StringRef DWOName) {
303 std::string Text ="\'";
304 Text +=Name;
305 Text +='\'';
306bool HasDWO = !DWOName.empty();
307bool HasDWP = !DWPName.empty();
308if (HasDWO || HasDWP) {
309 Text +=" (from ";
310if (HasDWO) {
311 Text +='\'';
312 Text += DWOName;
313 Text +='\'';
314 }
315if (HasDWO && HasDWP)
316 Text +=" in ";
317if (!DWPName.empty()) {
318 Text +='\'';
319 Text += DWPName;
320 Text +='\'';
321 }
322 Text +=")";
323 }
324return Text;
325}
326
327staticErrorcreateError(StringRefName,Error E) {
328return make_error<DWPError>(
329 ("failure while decompressing compressed section: '" +Name +"', " +
330llvm::toString(std::move(E)))
331 .str());
332}
333
334staticError
335handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
336SectionRef Sec,StringRefName,StringRef &Contents) {
337auto *Obj = dyn_cast<ELFObjectFileBase>(Sec.getObject());
338if (!Obj ||
339 !(static_cast<ELFSectionRef>(Sec).getFlags() &ELF::SHF_COMPRESSED))
340returnError::success();
341bool IsLE = isa<object::ELF32LEObjectFile>(Obj) ||
342 isa<object::ELF64LEObjectFile>(Obj);
343bool Is64 = isa<object::ELF64LEObjectFile>(Obj) ||
344 isa<object::ELF64BEObjectFile>(Obj);
345Expected<Decompressor> Dec =Decompressor::create(Name, Contents, IsLE, Is64);
346if (!Dec)
347returncreateError(Name, Dec.takeError());
348
349 UncompressedSections.emplace_back();
350if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
351returncreateError(Name, std::move(E));
352
353 Contents = UncompressedSections.back();
354returnError::success();
355}
356
357namespacellvm {
358// Parse and return the header of an info section compile/type unit.
359Expected<InfoSectionUnitHeader>parseInfoSectionUnitHeader(StringRef Info) {
360InfoSectionUnitHeader Header;
361Error Err =Error::success();
362uint64_tOffset = 0;
363DWARFDataExtractor InfoData(Info,true, 0);
364 std::tie(Header.Length, Header.Format) =
365 InfoData.getInitialLength(&Offset, &Err);
366if (Err)
367return make_error<DWPError>("cannot parse compile unit length: " +
368llvm::toString(std::move(Err)));
369
370if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
371return make_error<DWPError>(
372"compile unit exceeds .debug_info section range: " +
373 utostr(Offset + Header.Length) +" >= " + utostr(InfoData.size()));
374 }
375
376 Header.Version = InfoData.getU16(&Offset, &Err);
377if (Err)
378return make_error<DWPError>("cannot parse compile unit version: " +
379llvm::toString(std::move(Err)));
380
381uint64_t MinHeaderLength;
382if (Header.Version >= 5) {
383// Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
384// Signature (8)
385 MinHeaderLength = 16;
386 }else {
387// Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
388 MinHeaderLength = 7;
389 }
390if (Header.Length < MinHeaderLength) {
391return make_error<DWPError>("unit length is too small: expected at least " +
392 utostr(MinHeaderLength) +" got " +
393 utostr(Header.Length) +".");
394 }
395if (Header.Version >= 5) {
396 Header.UnitType = InfoData.getU8(&Offset);
397 Header.AddrSize = InfoData.getU8(&Offset);
398 Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
399 Header.Signature = InfoData.getU64(&Offset);
400if (Header.UnitType == dwarf::DW_UT_split_type) {
401// Type offset.
402 MinHeaderLength += 4;
403if (Header.Length < MinHeaderLength)
404return make_error<DWPError>("type unit is missing type offset");
405 InfoData.getU32(&Offset);
406 }
407 }else {
408// Note that, address_size and debug_abbrev_offset fields have switched
409// places between dwarf version 4 and 5.
410 Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
411 Header.AddrSize = InfoData.getU8(&Offset);
412 }
413
414 Header.HeaderSize =Offset;
415return Header;
416}
417
418staticvoidwriteNewOffsetsTo(MCStreamer &Out,DataExtractor &Data,
419DenseMap<uint64_t, uint32_t> &OffsetRemapping,
420uint64_t &Offset,uint64_t &Size) {
421
422while (Offset <Size) {
423auto OldOffset =Data.getU32(&Offset);
424auto NewOffset = OffsetRemapping[OldOffset];
425 Out.emitIntValue(NewOffset, 4);
426 }
427}
428
429voidwriteStringsAndOffsets(MCStreamer &Out,DWPStringPool &Strings,
430MCSection *StrOffsetSection,
431StringRef CurStrSection,
432StringRef CurStrOffsetSection,uint16_tVersion) {
433// Could possibly produce an error or warning if one of these was non-null but
434// the other was null.
435if (CurStrSection.empty() || CurStrOffsetSection.empty())
436return;
437
438DenseMap<uint64_t, uint32_t> OffsetRemapping;
439
440DataExtractorData(CurStrSection,true, 0);
441uint64_t LocalOffset = 0;
442uint64_t PrevOffset = 0;
443while (constchar *S =Data.getCStr(&LocalOffset)) {
444 OffsetRemapping[PrevOffset] =
445 Strings.getOffset(S, LocalOffset - PrevOffset);
446 PrevOffset = LocalOffset;
447 }
448
449Data =DataExtractor(CurStrOffsetSection,true, 0);
450
451 Out.switchSection(StrOffsetSection);
452
453uint64_tOffset = 0;
454uint64_tSize = CurStrOffsetSection.size();
455if (Version > 4) {
456while (Offset <Size) {
457uint64_t HeaderSize =debugStrOffsetsHeaderSize(Data,Version);
458assert(HeaderSize <=Size -Offset &&
459"StrOffsetSection size is less than its header");
460
461uint64_t ContributionEnd = 0;
462uint64_t ContributionSize = 0;
463uint64_t HeaderLengthOffset =Offset;
464if (HeaderSize == 8) {
465 ContributionSize =Data.getU32(&HeaderLengthOffset);
466 }elseif (HeaderSize == 16) {
467 HeaderLengthOffset += 4;// skip the dwarf64 marker
468 ContributionSize =Data.getU64(&HeaderLengthOffset);
469 }
470 ContributionEnd = ContributionSize + HeaderLengthOffset;
471 Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
472writeNewOffsetsTo(Out,Data, OffsetRemapping,Offset, ContributionEnd);
473 }
474
475 }else {
476writeNewOffsetsTo(Out,Data, OffsetRemapping,Offset,Size);
477 }
478}
479
480enumAccessField {Offset,Length };
481voidwriteIndexTable(MCStreamer &Out,ArrayRef<unsigned> ContributionOffsets,
482constMapVector<uint64_t, UnitIndexEntry> &IndexEntries,
483constAccessField &Field) {
484for (constauto &E : IndexEntries)
485for (size_tI = 0;I != std::size(E.second.Contributions); ++I)
486if (ContributionOffsets[I])
487 Out.emitIntValue((Field ==AccessField::Offset
488 ? E.second.Contributions[I].getOffset32()
489 : E.second.Contributions[I].getLength32()),
490 4);
491}
492
493voidwriteIndex(MCStreamer &Out,MCSection *Section,
494ArrayRef<unsigned> ContributionOffsets,
495constMapVector<uint64_t, UnitIndexEntry> &IndexEntries,
496uint32_t IndexVersion) {
497if (IndexEntries.empty())
498return;
499
500unsigned Columns = 0;
501for (auto &C : ContributionOffsets)
502if (C)
503 ++Columns;
504
505 std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
506uint64_t Mask = Buckets.size() - 1;
507size_tI = 0;
508for (constauto &P : IndexEntries) {
509auto S =P.first;
510autoH = S & Mask;
511auto HP = ((S >> 32) & Mask) | 1;
512while (Buckets[H]) {
513assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
514"Duplicate unit");
515H = (H + HP) & Mask;
516 }
517 Buckets[H] =I + 1;
518 ++I;
519 }
520
521 Out.switchSection(Section);
522 Out.emitIntValue(IndexVersion, 4);// Version
523 Out.emitIntValue(Columns, 4);// Columns
524 Out.emitIntValue(IndexEntries.size(), 4);// Num Units
525 Out.emitIntValue(Buckets.size(), 4);// Num Buckets
526
527// Write the signatures.
528for (constauto &I : Buckets)
529 Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
530
531// Write the indexes.
532for (constauto &I : Buckets)
533 Out.emitIntValue(I, 4);
534
535// Write the column headers (which sections will appear in the table)
536for (size_tI = 0;I != ContributionOffsets.size(); ++I)
537if (ContributionOffsets[I])
538 Out.emitIntValue(getOnDiskSectionId(I), 4);
539
540// Write the offsets.
541writeIndexTable(Out, ContributionOffsets, IndexEntries,AccessField::Offset);
542
543// Write the lengths.
544writeIndexTable(Out, ContributionOffsets, IndexEntries,AccessField::Length);
545}
546
547ErrorbuildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
548constCompileUnitIdentifiers &ID,StringRef DWPName) {
549return make_error<DWPError>(
550 std::string("duplicate DWO ID (") + utohexstr(PrevE.first) +") in " +
551buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
552 PrevE.second.DWOName) +
553" and " +buildDWODescription(ID.Name, DWPName,ID.DWOName));
554}
555
556ErrorhandleSection(
557constStringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
558constMCSection *StrSection,constMCSection *StrOffsetSection,
559constMCSection *TypesSection,constMCSection *CUIndexSection,
560constMCSection *TUIndexSection,constMCSection *InfoSection,
561constSectionRef &Section,MCStreamer &Out,
562 std::deque<SmallString<32>> &UncompressedSections,
563uint32_t (&ContributionOffsets)[8],UnitIndexEntry &CurEntry,
564StringRef &CurStrSection,StringRef &CurStrOffsetSection,
565 std::vector<StringRef> &CurTypesSection,
566 std::vector<StringRef> &CurInfoSection,StringRef &AbbrevSection,
567StringRef &CurCUIndexSection,StringRef &CurTUIndexSection,
568 std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
569if (Section.isBSS())
570returnError::success();
571
572if (Section.isVirtual())
573returnError::success();
574
575Expected<StringRef> NameOrErr = Section.getName();
576if (!NameOrErr)
577return NameOrErr.takeError();
578StringRefName = *NameOrErr;
579
580Expected<StringRef> ContentsOrErr = Section.getContents();
581if (!ContentsOrErr)
582return ContentsOrErr.takeError();
583StringRef Contents = *ContentsOrErr;
584
585if (auto Err =handleCompressedSection(UncompressedSections, Section,Name,
586 Contents))
587return Err;
588
589Name =Name.substr(Name.find_first_not_of("._"));
590
591auto SectionPair = KnownSections.find(Name);
592if (SectionPair == KnownSections.end())
593returnError::success();
594
595if (DWARFSectionKindKind = SectionPair->second.second) {
596if (Kind !=DW_SECT_EXT_TYPES &&Kind != DW_SECT_INFO) {
597 SectionLength.push_back(std::make_pair(Kind, Contents.size()));
598 }
599
600if (Kind == DW_SECT_ABBREV) {
601 AbbrevSection = Contents;
602 }
603 }
604
605MCSection *OutSection = SectionPair->second.first;
606if (OutSection == StrOffsetSection)
607 CurStrOffsetSection = Contents;
608elseif (OutSection == StrSection)
609 CurStrSection = Contents;
610elseif (OutSection == TypesSection)
611 CurTypesSection.push_back(Contents);
612elseif (OutSection == CUIndexSection)
613 CurCUIndexSection = Contents;
614elseif (OutSection == TUIndexSection)
615 CurTUIndexSection = Contents;
616elseif (OutSection == InfoSection)
617 CurInfoSection.push_back(Contents);
618else {
619 Out.switchSection(OutSection);
620 Out.emitBytes(Contents);
621 }
622returnError::success();
623}
624
625Errorwrite(MCStreamer &Out,ArrayRef<std::string> Inputs,
626OnCuIndexOverflow OverflowOptValue) {
627constauto &MCOFI = *Out.getContext().getObjectFileInfo();
628MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
629MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
630MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
631MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
632MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
633MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
634constStringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
635 {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
636 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(),DW_SECT_EXT_TYPES}},
637 {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
638 {"debug_str.dwo", {StrSection,static_cast<DWARFSectionKind>(0)}},
639 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(),DW_SECT_EXT_LOC}},
640 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
641 {"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
642 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
643 {"debug_loclists.dwo",
644 {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
645 {"debug_rnglists.dwo",
646 {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
647 {"debug_cu_index", {CUIndexSection,static_cast<DWARFSectionKind>(0)}},
648 {"debug_tu_index", {TUIndexSection,static_cast<DWARFSectionKind>(0)}}};
649
650MapVector<uint64_t, UnitIndexEntry> IndexEntries;
651MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
652
653uint32_t ContributionOffsets[8] = {};
654uint16_tVersion = 0;
655uint32_t IndexVersion = 0;
656bool AnySectionOverflow =false;
657
658DWPStringPool Strings(Out, StrSection);
659
660SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
661 Objects.reserve(Inputs.size());
662
663 std::deque<SmallString<32>> UncompressedSections;
664
665for (constauto &Input : Inputs) {
666auto ErrOrObj =object::ObjectFile::createObjectFile(Input);
667if (!ErrOrObj) {
668returnhandleErrors(ErrOrObj.takeError(),
669 [&](std::unique_ptr<ECError> EC) ->Error {
670 return createFileError(Input, Error(std::move(EC)));
671 });
672 }
673
674auto &Obj = *ErrOrObj->getBinary();
675 Objects.push_back(std::move(*ErrOrObj));
676
677UnitIndexEntry CurEntry = {};
678
679StringRef CurStrSection;
680StringRef CurStrOffsetSection;
681 std::vector<StringRef> CurTypesSection;
682 std::vector<StringRef> CurInfoSection;
683StringRef AbbrevSection;
684StringRef CurCUIndexSection;
685StringRef CurTUIndexSection;
686
687// This maps each section contained in this file to its length.
688// This information is later on used to calculate the contributions,
689// i.e. offset and length, of each compile/type unit to a section.
690 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
691
692for (constauto &Section : Obj.sections())
693if (auto Err =handleSection(
694 KnownSections, StrSection, StrOffsetSection, TypesSection,
695 CUIndexSection, TUIndexSection, InfoSection, Section, Out,
696 UncompressedSections, ContributionOffsets, CurEntry,
697 CurStrSection, CurStrOffsetSection, CurTypesSection,
698 CurInfoSection, AbbrevSection, CurCUIndexSection,
699 CurTUIndexSection, SectionLength))
700return Err;
701
702if (CurInfoSection.empty())
703continue;
704
705Expected<InfoSectionUnitHeader> HeaderOrErr =
706parseInfoSectionUnitHeader(CurInfoSection.front());
707if (!HeaderOrErr)
708return HeaderOrErr.takeError();
709InfoSectionUnitHeader &Header = *HeaderOrErr;
710
711if (Version == 0) {
712Version = Header.Version;
713 IndexVersion =Version < 5 ? 2 : 5;
714 }elseif (Version != Header.Version) {
715return make_error<DWPError>("incompatible DWARF compile unit versions.");
716 }
717
718writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
719 CurStrOffsetSection, Header.Version);
720
721for (auto Pair : SectionLength) {
722auto Index =getContributionIndex(Pair.first, IndexVersion);
723 CurEntry.Contributions[Index].setOffset(ContributionOffsets[Index]);
724 CurEntry.Contributions[Index].setLength(Pair.second);
725uint32_t OldOffset = ContributionOffsets[Index];
726 ContributionOffsets[Index] += CurEntry.Contributions[Index].getLength32();
727if (OldOffset > ContributionOffsets[Index]) {
728uint32_t SectionIndex = 0;
729for (auto &Section : Obj.sections()) {
730if (SectionIndex == Index) {
731if (Error Err =sectionOverflowErrorOrWarning(
732 OldOffset, ContributionOffsets[Index], *Section.getName(),
733 OverflowOptValue, AnySectionOverflow))
734return Err;
735 }
736 ++SectionIndex;
737 }
738if (AnySectionOverflow)
739break;
740 }
741 }
742
743uint32_t &InfoSectionOffset =
744 ContributionOffsets[getContributionIndex(DW_SECT_INFO, IndexVersion)];
745if (CurCUIndexSection.empty()) {
746bool FoundCUUnit =false;
747 Out.switchSection(InfoSection);
748for (StringRefInfo : CurInfoSection) {
749uint64_t UnitOffset = 0;
750while (Info.size() > UnitOffset) {
751Expected<InfoSectionUnitHeader> HeaderOrError =
752parseInfoSectionUnitHeader(Info.substr(UnitOffset,Info.size()));
753if (!HeaderOrError)
754return HeaderOrError.takeError();
755InfoSectionUnitHeader &Header = *HeaderOrError;
756
757UnitIndexEntry Entry = CurEntry;
758auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
759 IndexVersion)];
760C.setOffset(InfoSectionOffset);
761C.setLength(Header.Length + 4);
762
763if (std::numeric_limits<uint32_t>::max() - InfoSectionOffset <
764C.getLength32()) {
765if (Error Err =sectionOverflowErrorOrWarning(
766 InfoSectionOffset, InfoSectionOffset +C.getLength32(),
767"debug_info", OverflowOptValue, AnySectionOverflow))
768return Err;
769if (AnySectionOverflow) {
770if (Header.Version < 5 ||
771 Header.UnitType == dwarf::DW_UT_split_compile)
772 FoundCUUnit =true;
773break;
774 }
775 }
776
777 UnitOffset +=C.getLength32();
778if (Header.Version < 5 ||
779 Header.UnitType == dwarf::DW_UT_split_compile) {
780Expected<CompileUnitIdentifiers> EID =getCUIdentifiers(
781 Header, AbbrevSection,
782Info.substr(UnitOffset -C.getLength32(),C.getLength32()),
783 CurStrOffsetSection, CurStrSection);
784
785if (!EID)
786returncreateFileError(Input, EID.takeError());
787constauto &ID = *EID;
788autoP = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
789if (!P.second)
790returnbuildDuplicateError(*P.first,ID,"");
791P.first->second.Name =ID.Name;
792P.first->second.DWOName =ID.DWOName;
793
794 FoundCUUnit =true;
795 }elseif (Header.UnitType == dwarf::DW_UT_split_type) {
796autoP = TypeIndexEntries.insert(
797 std::make_pair(*Header.Signature, Entry));
798if (!P.second)
799continue;
800 }
801 Out.emitBytes(
802Info.substr(UnitOffset -C.getLength32(),C.getLength32()));
803 InfoSectionOffset +=C.getLength32();
804 }
805if (AnySectionOverflow)
806break;
807 }
808
809if (!FoundCUUnit)
810return make_error<DWPError>("no compile unit found in file: " + Input);
811
812if (IndexVersion == 2) {
813// Add types from the .debug_types section from DWARF < 5.
814if (Error Err =addAllTypesFromTypesSection(
815 Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
816 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)],
817 OverflowOptValue, AnySectionOverflow))
818return Err;
819 }
820if (AnySectionOverflow)
821break;
822continue;
823 }
824
825if (CurInfoSection.size() != 1)
826return make_error<DWPError>("expected exactly one occurrence of a debug "
827"info section in a .dwp file");
828StringRef DwpSingleInfoSection = CurInfoSection.front();
829
830DWARFUnitIndex CUIndex(DW_SECT_INFO);
831DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
832if (!CUIndex.parse(CUIndexData))
833return make_error<DWPError>("failed to parse cu_index");
834if (CUIndex.getVersion() != IndexVersion)
835return make_error<DWPError>("incompatible cu_index versions, found " +
836 utostr(CUIndex.getVersion()) +
837" and expecting " + utostr(IndexVersion));
838
839 Out.switchSection(InfoSection);
840for (constDWARFUnitIndex::Entry &E : CUIndex.getRows()) {
841auto *I = E.getContributions();
842if (!I)
843continue;
844autoP = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
845StringRef CUInfoSection =
846getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
847Expected<InfoSectionUnitHeader> HeaderOrError =
848parseInfoSectionUnitHeader(CUInfoSection);
849if (!HeaderOrError)
850return HeaderOrError.takeError();
851InfoSectionUnitHeader &Header = *HeaderOrError;
852
853Expected<CompileUnitIdentifiers> EID =getCUIdentifiers(
854 Header,getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
855 CUInfoSection,
856getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
857 CurStrSection);
858if (!EID)
859returncreateFileError(Input, EID.takeError());
860constauto &ID = *EID;
861if (!P.second)
862returnbuildDuplicateError(*P.first,ID, Input);
863auto &NewEntry =P.first->second;
864 NewEntry.Name =ID.Name;
865 NewEntry.DWOName =ID.DWOName;
866 NewEntry.DWPName = Input;
867for (autoKind : CUIndex.getColumnKinds()) {
868if (!isSupportedSectionKind(Kind))
869continue;
870auto &C =
871 NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
872C.setOffset(C.getOffset() +I->getOffset());
873C.setLength(I->getLength());
874 ++I;
875 }
876unsigned Index =getContributionIndex(DW_SECT_INFO, IndexVersion);
877auto &C = NewEntry.Contributions[Index];
878 Out.emitBytes(CUInfoSection);
879C.setOffset(InfoSectionOffset);
880 InfoSectionOffset +=C.getLength32();
881 }
882
883if (!CurTUIndexSection.empty()) {
884llvm::DWARFSectionKind TUSectionKind;
885MCSection *OutSection;
886StringRef TypeInputSection;
887// Write type units into debug info section for DWARFv5.
888if (Version >= 5) {
889 TUSectionKind = DW_SECT_INFO;
890 OutSection = InfoSection;
891 TypeInputSection = DwpSingleInfoSection;
892 }else {
893// Write type units into debug types section for DWARF < 5.
894if (CurTypesSection.size() != 1)
895return make_error<DWPError>(
896"multiple type unit sections in .dwp file");
897
898 TUSectionKind =DW_SECT_EXT_TYPES;
899 OutSection = TypesSection;
900 TypeInputSection = CurTypesSection.front();
901 }
902
903DWARFUnitIndex TUIndex(TUSectionKind);
904DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
905if (!TUIndex.parse(TUIndexData))
906return make_error<DWPError>("failed to parse tu_index");
907if (TUIndex.getVersion() != IndexVersion)
908return make_error<DWPError>("incompatible tu_index versions, found " +
909 utostr(TUIndex.getVersion()) +
910" and expecting " + utostr(IndexVersion));
911
912unsigned TypesContributionIndex =
913getContributionIndex(TUSectionKind, IndexVersion);
914if (Error Err =addAllTypesFromDWP(
915 Out, TypeIndexEntries, TUIndex, OutSection, TypeInputSection,
916 CurEntry, ContributionOffsets[TypesContributionIndex],
917 TypesContributionIndex, OverflowOptValue, AnySectionOverflow))
918return Err;
919 }
920if (AnySectionOverflow)
921break;
922 }
923
924if (Version < 5) {
925// Lie about there being no info contributions so the TU index only includes
926// the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
927// contribution to the info section, so we do not want to lie about it.
928 ContributionOffsets[0] = 0;
929 }
930writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
931 TypeIndexEntries, IndexVersion);
932
933if (Version < 5) {
934// Lie about the type contribution for DWARF < 5. In DWARFv5 the type
935// section does not exist, so no need to do anything about this.
936 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
937// Unlie about the info contribution
938 ContributionOffsets[0] = 1;
939 }
940
941writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
942 IndexEntries, IndexVersion);
943
944returnError::success();
945}
946}// namespace llvm
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
CommandLine.h
DWPError.h
getCUAbbrev
static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode)
Definition:DWP.cpp:42
handleCompressedSection
static Error handleCompressedSection(std::deque< SmallString< 32 > > &UncompressedSections, SectionRef Sec, StringRef Name, StringRef &Contents)
Definition:DWP.cpp:335
buildDWODescription
static std::string buildDWODescription(StringRef Name, StringRef DWPName, StringRef DWOName)
Definition:DWP.cpp:301
debugStrOffsetsHeaderSize
static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData, uint16_t DwarfVersion)
Definition:DWP.cpp:31
getIndexedString
static Expected< const char * > getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset, StringRef StrOffsets, StringRef Str, uint16_t Version)
Definition:DWP.cpp:58
addAllTypesFromTypesSection
static Error addAllTypesFromTypesSection(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, MCSection *OutputTypes, const std::vector< StringRef > &TypesSections, const UnitIndexEntry &CUEntry, uint32_t &TypesOffset, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
Definition:DWP.cpp:254
getOnDiskSectionId
static unsigned getOnDiskSectionId(unsigned Index)
Definition:DWP.cpp:170
getCUIdentifiers
static Expected< CompileUnitIdentifiers > getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev, StringRef Info, StringRef StrOffsets, StringRef Str)
Definition:DWP.cpp:96
sectionOverflowErrorOrWarning
static Error sectionOverflowErrorOrWarning(uint32_t PrevOffset, uint32_t OverflowedOffset, StringRef SectionName, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
Definition:DWP.cpp:183
MCTargetOptionsFlags
static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags
Definition:DWP.cpp:28
getSubsection
static StringRef getSubsection(StringRef Section, const DWARFUnitIndex::Entry &Entry, DWARFSectionKind Kind)
Definition:DWP.cpp:174
createError
static Error createError(StringRef Name, Error E)
Definition:DWP.cpp:327
isSupportedSectionKind
static bool isSupportedSectionKind(DWARFSectionKind Kind)
Definition:DWP.cpp:155
addAllTypesFromDWP
static Error addAllTypesFromDWP(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types, const UnitIndexEntry &TUEntry, uint32_t &TypesOffset, unsigned TypesContributionIndex, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
Definition:DWP.cpp:205
DWP.h
Decompressor.h
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
ELFObjectFile.h
MCContext.h
MCObjectFileInfo.h
MCTargetOptionsCommandFlags.h
I
#define I(x, y, z)
Definition:MD5.cpp:58
H
#define H(x, y, z)
Definition:MD5.cpp:57
MemoryBuffer.h
P
#define P(N)
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
getFlags
static uint32_t getFlags(const Symbol *Sym)
Definition:TapiFile.cpp:26
Twine.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition:DWARFDataExtractor.h:21
llvm::DWARFDataExtractor::getInitialLength
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
Definition:DWARFDataExtractor.cpp:17
llvm::DWARFFormValue::skipValue
bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const
Skip a form's value in DebugInfoData at the offset specified by OffsetPtr.
Definition:DWARFFormValue.h:146
llvm::DWARFUnitIndex::Entry::SectionContribution::setOffset
void setOffset(uint64_t Value)
Definition:DWARFUnitIndex.h:123
llvm::DWARFUnitIndex::Entry::SectionContribution::setLength
void setLength(uint64_t Value)
Definition:DWARFUnitIndex.h:124
llvm::DWARFUnitIndex::Entry::SectionContribution::getLength32
uint32_t getLength32() const
Definition:DWARFUnitIndex.h:128
llvm::DWARFUnitIndex::Entry::SectionContribution::getOffset
uint64_t getOffset() const
Definition:DWARFUnitIndex.h:125
llvm::DWARFUnitIndex::Entry
Definition:DWARFUnitIndex.h:111
llvm::DWARFUnitIndex
Definition:DWARFUnitIndex.h:99
llvm::DWARFUnitIndex::getVersion
uint32_t getVersion() const
Definition:DWARFUnitIndex.h:176
llvm::DWARFUnitIndex::parse
bool parse(DataExtractor IndexData)
Definition:DWARFUnitIndex.cpp:119
llvm::DWARFUnitIndex::getColumnKinds
ArrayRef< DWARFSectionKind > getColumnKinds() const
Definition:DWARFUnitIndex.h:181
llvm::DWARFUnitIndex::getRows
ArrayRef< Entry > getRows() const
Definition:DWARFUnitIndex.h:185
llvm::DWPStringPool
Definition:DWPStringPool.h:10
llvm::DataExtractor
Definition:DataExtractor.h:41
llvm::DataExtractor::getU32
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
Definition:DataExtractor.cpp:108
llvm::DataExtractor::size
size_t size() const
Return the number of bytes in the underlying buffer.
Definition:DataExtractor.h:688
llvm::DataExtractor::getCStr
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
Definition:DataExtractor.h:129
llvm::DataExtractor::getU8
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Definition:DataExtractor.cpp:80
llvm::DataExtractor::getULEB128
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Definition:DataExtractor.cpp:221
llvm::DataExtractor::getU16
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
Definition:DataExtractor.cpp:93
llvm::DataExtractor::getU64
uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
Definition:DataExtractor.cpp:117
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition:DataExtractor.h:665
llvm::DataExtractor::getU24
uint32_t getU24(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
Definition:DataExtractor.cpp:102
llvm::DenseMap
Definition:DenseMap.h:727
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition:MCContext.h:416
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition:MCSection.h:36
llvm::MCStreamer
Streaming machine code generation interface.
Definition:MCStreamer.h:213
llvm::MCStreamer::getContext
MCContext & getContext() const
Definition:MCStreamer.h:300
llvm::MCStreamer::emitIntValue
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition:MCStreamer.cpp:133
llvm::MCStreamer::switchSection
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
Definition:MCStreamer.cpp:1303
llvm::MCStreamer::emitBytes
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Definition:MCStreamer.cpp:1266
llvm::MapVector
This class implements a map that also provides access to all stored values in a deterministic order.
Definition:MapVector.h:36
llvm::MapVector::empty
bool empty() const
Definition:MapVector.h:79
llvm::MapVector::begin
iterator begin()
Definition:MapVector.h:69
llvm::MapVector::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition:MapVector.h:141
llvm::MapVector::size
size_type size() const
Definition:MapVector.h:60
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition:SmallVector.h:663
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition:StringMap.h:128
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::back
char back() const
back - Get the last character in the string.
Definition:StringRef.h:159
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::front
char front() const
front - Get the first character in the string.
Definition:StringRef.h:153
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::WithColor::defaultWarningHandler
static void defaultWarningHandler(Error Warning)
Implement default handling for Warning.
Definition:WithColor.cpp:164
llvm::object::Decompressor::create
static Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
Definition:Decompressor.cpp:21
llvm::object::ELFSectionRef
Definition:ELFObjectFile.h:130
llvm::object::ObjectFile::createObjectFile
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition:ObjectFile.cpp:209
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition:ObjectFile.h:81
llvm::object::SectionRef::getObject
const ObjectFile * getObject() const
Definition:ObjectFile.h:602
uint16_t
uint32_t
uint64_t
unsigned
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::ELF::SHF_COMPRESSED
@ SHF_COMPRESSED
Definition:ELF.h:1226
llvm::dwarf::Form
Form
Definition:Dwarf.h:130
llvm::dwarf::Tag
Tag
Definition:Dwarf.h:103
llvm::dwarf::DW_LENGTH_DWARF64
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition:Dwarf.h:55
llvm::object
Definition:DWARFDebugLoc.h:24
llvm::object::Kind
Kind
Definition:COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::AccessField
AccessField
Definition:DWP.cpp:480
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::Length
@ Length
Definition:DWP.cpp:480
llvm::createFileError
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition:Error.h:1385
llvm::buildDuplicateError
Error buildDuplicateError(const std::pair< uint64_t, UnitIndexEntry > &PrevE, const CompileUnitIdentifiers &ID, StringRef DWPName)
Definition:DWP.cpp:547
llvm::writeIndex
void writeIndex(MCStreamer &Out, MCSection *Section, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, uint32_t IndexVersion)
Definition:DWP.cpp:493
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition:Error.h:954
llvm::writeNewOffsetsTo
static void writeNewOffsetsTo(MCStreamer &Out, DataExtractor &Data, DenseMap< uint64_t, uint32_t > &OffsetRemapping, uint64_t &Offset, uint64_t &Size)
Definition:DWP.cpp:418
llvm::writeStringsAndOffsets
void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings, MCSection *StrOffsetSection, StringRef CurStrSection, StringRef CurStrOffsetSection, uint16_t Version)
Definition:DWP.cpp:429
llvm::DWARFSectionKind
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
Definition:DWARFUnitIndex.h:56
llvm::DW_SECT_EXT_LOC
@ DW_SECT_EXT_LOC
Definition:DWARFUnitIndex.h:63
llvm::DW_SECT_EXT_unknown
@ DW_SECT_EXT_unknown
Denotes a value read from an index section that does not correspond to any of the supported standards...
Definition:DWARFUnitIndex.h:59
llvm::DW_SECT_EXT_TYPES
@ DW_SECT_EXT_TYPES
Definition:DWARFUnitIndex.h:62
llvm::serializeSectionKind
uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion)
Convert the internal value for a section kind to an on-disk value.
Definition:DWARFUnitIndex.cpp:42
llvm::write
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition:DWP.cpp:625
llvm::handleSection
Error handleSection(const StringMap< std::pair< MCSection *, DWARFSectionKind > > &KnownSections, const MCSection *StrSection, const MCSection *StrOffsetSection, const MCSection *TypesSection, const MCSection *CUIndexSection, const MCSection *TUIndexSection, const MCSection *InfoSection, const object::SectionRef &Section, MCStreamer &Out, std::deque< SmallString< 32 > > &UncompressedSections, uint32_t(&ContributionOffsets)[8], UnitIndexEntry &CurEntry, StringRef &CurStrSection, StringRef &CurStrOffsetSection, std::vector< StringRef > &CurTypesSection, std::vector< StringRef > &CurInfoSection, StringRef &AbbrevSection, StringRef &CurCUIndexSection, StringRef &CurTUIndexSection, std::vector< std::pair< DWARFSectionKind, uint32_t > > &SectionLength)
Definition:DWP.cpp:556
llvm::writeIndexTable
void writeIndexTable(MCStreamer &Out, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, const AccessField &Field)
Definition:DWP.cpp:481
llvm::getContributionIndex
unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion)
Definition:DWP.cpp:162
llvm::parseInfoSectionUnitHeader
Expected< InfoSectionUnitHeader > parseInfoSectionUnitHeader(StringRef Info)
Definition:DWP.cpp:359
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition:DWARFUnitIndex.h:67
llvm::OnCuIndexOverflow
OnCuIndexOverflow
Definition:DWP.h:18
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::Version
@ Version
Definition:PGOCtxProfWriter.h:22
llvm::NextPowerOf2
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition:MathExtras.h:383
llvm::CompileUnitIdentifiers
Definition:DWP.h:63
llvm::InfoSectionUnitHeader
Definition:DWP.h:34
llvm::OptimizedStructLayoutField
A field in a structure.
Definition:OptimizedStructLayout.h:45
llvm::SectionName
Definition:DWARFSection.h:21
llvm::UnitIndexEntry
Definition:DWP.h:24
llvm::UnitIndexEntry::Contributions
DWARFUnitIndex::Entry::SectionContribution Contributions[8]
Definition:DWP.h:25
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition:Dwarf.h:1084
llvm::mc::RegisterMCTargetOptionsFlags
Create this object with static storage to register mc-related command line options.
Definition:MCTargetOptionsCommandFlags.h:68

Generated on Thu Jul 17 2025 12:05:56 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp