1//===-- LVBinaryReader.cpp ------------------------------------------------===// 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 7//===----------------------------------------------------------------------===// 9// This implements the LVBinaryReader class. 11//===----------------------------------------------------------------------===// 21#define DEBUG_TYPE "BinaryReader" 23// Function names extracted from the object symbol table. 26 std::string SymbolName(
Name);
27if (SymbolNames.find(SymbolName) == SymbolNames.end()) {
29 std::piecewise_construct, std::forward_as_tuple(SymbolName),
30 std::forward_as_tuple(
Function, 0, SectionIndex,
false));
32// Update a recorded entry with its logical scope and section index. 33 SymbolNames[SymbolName].Scope =
Function;
35 SymbolNames[SymbolName].SectionIndex = SectionIndex;
38if (
Function && SymbolNames[SymbolName].IsComdat)
46 std::string SymbolName(
Name);
47if (SymbolNames.find(SymbolName) == SymbolNames.end())
49 std::piecewise_construct, std::forward_as_tuple(SymbolName),
50 std::forward_as_tuple(
nullptr,
Address, SectionIndex, IsComdat));
52// Update a recorded symbol name with its logical scope. 53 SymbolNames[SymbolName].Address =
Address;
66 std::string SymbolName(
Name);
68if (SymbolName.empty() || (SymbolNames.find(SymbolName) == SymbolNames.end()))
71// Update a recorded entry with its logical scope, only if the scope has 72// ranges. That is the case when in DWARF there are 2 DIEs connected via 73// the DW_AT_specification. 75 SymbolNames[SymbolName].Scope =
Function;
76 SectionIndex = SymbolNames[SymbolName].SectionIndex;
81if (SymbolNames[SymbolName].IsComdat)
90 LVSymbolNames::iterator Iter = SymbolNames.find(
Name);
91return Iter != SymbolNames.end() ? Iter->second : Empty;
94 LVSymbolNames::iterator Iter = SymbolNames.find(
Name);
95return Iter != SymbolNames.end() ? Iter->second.Address : 0;
98 LVSymbolNames::iterator Iter = SymbolNames.find(
Name);
99return Iter != SymbolNames.end() ? Iter->second.SectionIndex
103 LVSymbolNames::iterator Iter = SymbolNames.find(
Name);
104return Iter != SymbolNames.end() ? Iter->second.IsComdat :
false;
108OS <<
"Symbol Table\n";
109for (LVSymbolNames::reference Entry : SymbolNames) {
111LVScope *Scope = SymbolName.Scope;
113OS <<
"Index: " <<
hexValue(SymbolName.SectionIndex, 5)
114 <<
" Comdat: " << (SymbolName.IsComdat ?
"Y" :
"N")
116 <<
" Address: " <<
hexValue(SymbolName.Address)
117 <<
" Name: " << Entry.first <<
"\n";
152if (!SectionNameOrErr)
155Name = *SectionNameOrErr;
157 <<
"Address: " <<
hexValue(Section.getAddress()) <<
", " 158 <<
"Size: " <<
hexValue(Section.getSize()) <<
", " 159 <<
"Name: " <<
Name <<
"\n";
160dbgs() <<
"isCompressed: " << Section.isCompressed() <<
", " 161 <<
"isText: " << Section.isText() <<
", " 162 <<
"isData: " << Section.isData() <<
", " 163 <<
"isBSS: " << Section.isBSS() <<
", " 164 <<
"isVirtual: " << Section.isVirtual() <<
"\n";
165dbgs() <<
"isBitcode: " << Section.isBitcode() <<
", " 166 <<
"isStripped: " << Section.isStripped() <<
", " 167 <<
"isBerkeleyText: " << Section.isBerkeleyText() <<
", " 168 <<
"isBerkeleyData: " << Section.isBerkeleyData() <<
", " 169 <<
"isDebugSection: " << Section.isDebugSection() <<
"\n";
173if (!Section.isText() || Section.isVirtual() || !Section.getSize())
176// Record section information required for symbol resolution. 177// Note: The section index returned by 'getIndex()' is one based. 178 Sections.emplace(Section.getIndex(), Section);
179 addSectionAddress(Section);
181// Identify the ".text" section. 183if (!SectionNameOrErr) {
187if (*SectionNameOrErr ==
".text" || *SectionNameOrErr ==
"CODE" ||
188 *SectionNameOrErr ==
".code") {
190// If the object is WebAssembly, update the address offset that 191// will be added to DWARF DW_AT_* attributes. 197// Process the symbol table. 201dbgs() <<
"\nSections Information:\n";
202for (LVSections::reference Entry : Sections) {
206if (!SectionNameOrErr)
209 <<
" Name: " << *SectionNameOrErr <<
"\n" 210 <<
"Size: " <<
hexValue(Section.getSize()) <<
"\n" 211 <<
"VirtualAddress: " <<
hexValue(VirtualAddress) <<
"\n" 212 <<
"SectionAddress: " <<
hexValue(Section.getAddress()) <<
"\n";
214dbgs() <<
"\nObject Section Information:\n";
215for (LVSectionAddresses::const_reference Entry : SectionAddresses)
217 <<
hexValue(Entry.first + Entry.second.getSize())
218 <<
"] Size: " <<
hexValue(Entry.second.getSize()) <<
"\n";
225 ImageBaseAddress = ImageBase.
get();
228dbgs() <<
"ImageBaseAddress: " <<
hexValue(ImageBaseAddress) <<
"\n";
234if (!Section.isText() || Section.isVirtual() || !Section.getSize())
241// Record section information required for symbol resolution. 242// Note: The section index returned by 'getIndex()' is zero based. 243 Sections.emplace(Section.getIndex() + 1, Section);
244 addSectionAddress(Section);
246// Additional initialization on the specific object format. 251dbgs() <<
"\nSections Information:\n";
252for (LVSections::reference Entry : Sections) {
257if (!SectionNameOrErr)
260 <<
" Name: " << *SectionNameOrErr <<
"\n" 261 <<
"Size: " <<
hexValue(Section.getSize()) <<
"\n" 262 <<
"VirtualAddress: " <<
hexValue(VirtualAddress) <<
"\n" 263 <<
"SectionAddress: " <<
hexValue(Section.getAddress()) <<
"\n" 269dbgs() <<
"\nObject Section Information:\n";
270for (LVSectionAddresses::const_reference Entry : SectionAddresses)
272 <<
hexValue(Entry.first + Entry.second.getSize())
273 <<
"] Size: " <<
hexValue(Entry.second.getSize()) <<
"\n";
279 std::string TargetLookupError;
285// Register information. 289"no register info for target " + TheTriple);
290MRI.reset(RegisterInfo);
292// Assembler properties and features. 297"no assembly info for target " + TheTriple);
306"no subtarget info for target " + TheTriple);
307STI.reset(SubtargetInfo);
313"no instruction info for target " + TheTriple);
314MII.reset(InstructionInfo);
316MC = std::make_unique<MCContext>(
Triple(TheTriple),
MAI.get(),
MRI.get(),
323"no disassembler for target " + TheTriple);
328if (!InstructionPrinter)
330"no target assembly language printer for target " +
332MIP.reset(InstructionPrinter);
341// Return the 'text' section with the code for this logical scope. 342// COFF: SectionIndex is zero. Use 'SectionAddresses' data. 343// ELF: SectionIndex is the section index in the file. 345 LVSections::iterator Iter = Sections.find(SectionIndex);
346if (Iter == Sections.end()) {
348"invalid section index for: '%s'",
349 Scope->getName().str().c_str());
352return std::make_pair(Section.getAddress(), Section);
355// Ensure a valid starting address for the public names. 356 LVSectionAddresses::const_iterator Iter =
357 SectionAddresses.upper_bound(
Address);
358if (Iter == SectionAddresses.begin())
360"invalid section address for: '%s'",
361 Scope->getName().str().c_str());
363// Get section that contains the code for this function. 364 Iter = SectionAddresses.lower_bound(
Address);
365if (Iter != SectionAddresses.begin())
367return std::make_pair(Iter->first, Iter->second);
380 ScopesWithRanges->
addEntry(Scope, LowerAddress, UpperAddress);
384// Check if we already have a mapping for this section index. 385 LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);
386if (IterSection == SectionRanges.end())
388 SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;
397assert(Scope &&
"Scope is null.");
399// Skip stripped functions. 400if (Scope->getIsDiscarded())
403// Find associated address and size for the given function entry point. 408dbgs() <<
"\nPublic Name instructions: '" << Scope->getName() <<
"' / '" 409 << Scope->getLinkageName() <<
"'\n" 410 <<
"DIE Offset: " <<
hexValue(Scope->getOffset()) <<
" Range: [" 417return SectionOrErr.takeError();
419uint64_t SectionAddress = (*SectionOrErr).first;
422if (!SectionContentsOrErr)
423return SectionOrErr.takeError();
425// There are cases where the section size is smaller than the [LowPC,HighPC] 426// range; it causes us to decode invalid addresses. The recorded size in the 427// logical scope is one less than the real size. 430 <<
", Section Size: " <<
hexValue(Section.getSize()) <<
"\n";
432Size = std::min(
Size + 1, Section.getSize());
441if (!SectionNameOrErr)
444dbgs() <<
"Section Index: " <<
hexValue(Section.getIndex()) <<
" [" 447 <<
"] Name: '" << *SectionNameOrErr <<
"'\n" 452// Address for first instruction line. 454auto InstructionsSP = std::make_unique<LVLines>();
456 DiscoveredLines.emplace_back(std::move(InstructionsSP));
469if (BytesConsumed == 0)
482 std::string BufferCodes;
494// Here we add logical lines to the Instructions. Later on, 495// the 'processLines()' function will move each created logical line 496// to its enclosing logical scope, using the debug ranges information 497// and they will be released when its scope parent is deleted. 506 Begin += BytesConsumed;
512 <<
" Scope DIE: " <<
hexValue(Scope->getOffset()) <<
"\n" 513 <<
"Address: " <<
hexValue(FirstAddress)
514 <<
format(
" - Collected instructions lines: %d\n",
522// The scope in the assembler names is linked to its own instructions. 523 ScopeInstructions.add(SectionIndex, Scope, &
Instructions);
524 AssemblerMappings.add(SectionIndex, FirstAddress, Scope);
531if (!
options().getPrintInstructions())
542if (!
options().getPrintInstructions())
547dbgs() <<
"\nPublic Names (Scope):\n";
548for (LVPublicNames::const_reference
Name :
CompileUnit->getPublicNames()) {
554 <<
"DIE Offset: " <<
hexValue(Scope->getOffset()) <<
" Range: [" 556 <<
"Name: '" << Scope->getName() <<
"' / '" 557 << Scope->getLinkageName() <<
"'\n";
561// For each public name in the current compile unit, create the line 562// records that represent the executable instructions. 563for (LVPublicNames::const_reference
Name :
CompileUnit->getPublicNames()) {
565// The symbol table extracted from the object file always contains a 566// non-empty name (linkage name). However, the logical scope does not 567// guarantee to have a name for the linkage name (main is one case). 568// For those cases, set the linkage name the same as the name. 569if (!Scope->getLinkageNameIndex())
570 Scope->setLinkageName(Scope->getName());
579// During the traversal of the debug information sections, we created the 580// logical lines representing the disassembled instructions from the text 581// section and the logical lines representing the line records from the 582// debug line section. Using the ranges associated with the logical scopes, 583// we will allocate those logical lines to their logical scopes. 587assert(DebugLines &&
"DebugLines is null.");
589// Just return if this compilation unit does not have any line records 590// and no instruction lines were created. 591if (DebugLines->
empty() && !
options().getPrintInstructions())
594// Merge the debug lines and instruction lines using their text address; 595// the logical line representing the debug line record is followed by the 596// line(s) representing the disassembled instructions, whose addresses are 597// equal or greater that the line address and less than the address of the 598// next debug line record. 602dbgs() <<
format(
"\nProcess debug lines: %d\n", DebugLines->
size());
605 <<
", (" <<
Line->getLineNumber() <<
")" 606 << ((Index % PerLine) ?
" " :
"\n");
609dbgs() << ((Index % PerLine) ?
"\n" :
"");
612bool TraverseLines =
true;
614while (TraverseLines && Iter != DebugLines->
end()) {
615uint64_t DebugAddress = (*Iter)->getAddress();
617// Get the function with an entry point that matches this line and 618// its associated assembler entries. In the case of COMDAT, the input 619// 'Function' is not null. Use it to find its address ranges. 622 Scope = AssemblerMappings.find(SectionIndex, DebugAddress);
629// Get the associated instructions for the found 'Scope'. 631LVLines *
Lines = ScopeInstructions.find(SectionIndex, Scope);
633 InstructionLines = std::move(*
Lines);
638 <<
" Scope DIE: " <<
hexValue(Scope->getOffset()) <<
"\n" 639 <<
format(
"Process instruction lines: %d\n",
640 InstructionLines.
size());
647// Continue with next debug line if there are not instructions lines. 648if (InstructionLines.
empty()) {
653for (
LVLine *InstructionLine : InstructionLines) {
654uint64_t InstructionAddress = InstructionLine->getAddress();
656dbgs() <<
"Instruction address: " <<
hexValue(InstructionAddress)
660while (Iter != DebugLines->
end()) {
661 DebugAddress = (*Iter)->getAddress();
663bool IsDebug = (*Iter)->getIsLineDebug();
664dbgs() <<
"Line " << (IsDebug ?
"dbg:" :
"ins:") <<
" [" 667dbgs() <<
format(
" %d", (*Iter)->getLineNumber());
670// Instruction address before debug line. 671if (InstructionAddress < DebugAddress) {
673dbgs() <<
"Inserted instruction address: " 674 <<
hexValue(InstructionAddress) <<
" before line: " 675 <<
format(
"%d", (*Iter)->getLineNumber()) <<
" [" 678 Iter = DebugLines->
insert(Iter, InstructionLine);
679// The returned iterator points to the inserted instruction. 680// Skip it and point to the line acting as reference. 686if (Iter == DebugLines->
end()) {
687// We have reached the end of the source lines and the current 688// instruction line address is greater than the last source line. 689 TraverseLines =
false;
704 << ((
Line->getIsLineDebug())
705 ?
Line->lineNumberAsStringStripped(
/*ShowZero=*/true)
711// If this compilation unit does not have line records, traverse its scopes 712// and take any collected instruction lines as the working set in order 713// to move them to their associated scope. 714if (DebugLines->
empty()) {
723 <<
" Scope DIE: " <<
hexValue(Scope->getOffset()) <<
"\n" 731if (Scope->getIsArtificial()) {
732// Add the instruction lines to their artificial scope. 734 Scope->addElement(
Line);
746// Process collected lines. 749// Using the current line address, get its associated lexical scope and 750// add the line information to it. 753// If missing scope, use the compile unit. 757 << ((
Line->getIsLineDebug())
758 ?
Line->lineNumberAsStringStripped(
/*ShowZero=*/true)
764// Add line object to scope. 765 Scope->addElement(
Line);
767// Report any line zero. 768if (
options().getWarningLines() &&
Line->getIsLineDebug() &&
769 !
Line->getLineNumber())
772// Some compilers generate ranges in the compile unit; other compilers 773// only DW_AT_low_pc/DW_AT_high_pc. In order to correctly map global 774// variables, we need to generate the map ranges for the compile unit. 775// If we use the ranges stored at the scope level, there are cases where 776// the address referenced by a symbol location, is not in the enclosing 777// scope, but in an outer one. By using the ranges stored in the compile 778// unit, we can catch all those addresses. 779if (
Line->getIsLineDebug())
782// Resolve any given pattern. 791assert(DebugLines &&
"DebugLines is null.");
792if (DebugLines->
empty() && !ScopeInstructions.findMap(SectionIndex))
795// If the Compile Unit does not contain comdat functions, use the whole 796// set of debug lines, as the addresses don't have conflicts. 802// Find the indexes for the lines whose address is zero. 803 std::vector<size_t> AddressZero;
805 std::find_if(std::begin(*DebugLines), std::end(*DebugLines),
807while (It != std::end(*DebugLines)) {
808 AddressZero.emplace_back(std::distance(std::begin(*DebugLines), It));
809 It = std::find_if(std::next(It), std::end(*DebugLines),
813// If the set of debug lines does not contain any line with address zero, 814// use the whole set. It means we are dealing with an initialization 815// section from a fully linked binary. 816if (AddressZero.empty()) {
821// The Compile unit contains comdat functions. Traverse the collected 822// debug lines and identify logical groups based on their start and 823// address. Each group starts with a zero address. 824// Begin, End, Address, IsDone. 825usingLVBucket = std::tuple<size_t, size_t, LVAddress, bool>;
826 std::vector<LVBucket> Buckets;
832for (Index = 0; Index < AddressZero.size() - 1; ++Index) {
833 Begin = AddressZero[Index];
834End = AddressZero[Index + 1] - 1;
836 Buckets.emplace_back(Begin,
End,
Address,
false);
839// Add the last bucket. 841 Begin = AddressZero[Index];
844 Buckets.emplace_back(Begin,
End,
Address,
false);
848dbgs() <<
"\nDebug Lines buckets: " << Buckets.size() <<
"\n";
849for (LVBucket &Bucket : Buckets) {
852 <<
"Address: " <<
hexValue(std::get<2>(Bucket)) <<
"\n";
856// Traverse the sections and buckets looking for matches on the section 857// sizes. In the unlikely event of different buckets with the same size 858// process them in order and mark them as done. 860for (LVSections::reference Entry : Sections) {
866 <<
" , Section Size: " <<
hexValue(Section.getSize())
867 <<
" , Section Address: " <<
hexValue(Section.getAddress())
871for (LVBucket &Bucket : Buckets) {
872if (std::get<3>(Bucket))
873// Already done for previous section. 875if (
Size == std::get<2>(Bucket)) {
876// We have a match on the section size. 880 DebugLines->
begin() + std::get<1>(Bucket) + 1;
882 Group.push_back(*Iter);
884 std::get<3>(Bucket) =
true;
891// Traverse the scopes for the given 'Function' looking for any inlined 892// scopes with inlined lines, which are found in 'CUInlineeLines'. 896 std::function<void(
LVScope * Parent)> FindInlinedScopes =
900 LVInlineeLine::iterator Iter = CUInlineeLines.find(Scope);
901if (Iter != CUInlineeLines.end())
903 FindInlinedScopes(Scope);
907// Find all inlined scopes for the given 'Function'. 909for (LVInlineeLine::iterator InlineeIter : InlineeIters) {
910LVScope *Scope = InlineeIter->first;
913// TODO: Convert this into a reference. 916dbgs() <<
"Inlined lines for: " << Scope->getName() <<
"\n";
919 <<
Line->getLineNumber() <<
"\n";
923 <<
Line->getLineNumber() <<
")\n";
927// The inlined lines must be merged using its address, in order to keep 928// the real order of the instructions. The inlined lines are mixed with 929// the other non-inlined lines. 931// First address of inlinee code. 935 return Item->getAddress() == InlineeStart;
938// 'Iter' points to the line where the inlined function is called. 939// Emulate the DW_AT_call_line attribute. 940 Scope->setCallLineNumber((*Iter)->getLineNumber());
941// Mark the referenced line as the start of the inlined function. 942// Skip the first line during the insertion, as the address and 943// line number as the same. Otherwise we have to erase and insert. 944 (*Iter)->setLineNumber((*
InlineeLines->begin())->getLineNumber());
950// Remove this set of lines from the container; each inlined function 951// creates an unique set of lines. Remove only the created container. 952 CUInlineeLines.erase(InlineeIter);
960 <<
Line->getLineNumber() <<
")\n";
966OS <<
"LVBinaryReader\n";
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Value * getAddress(const DbgVariableIntrinsic *DVI)
Annotations lets you mark points and ranges inside source code, for tests:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class is intended to be used as a base class for asm properties and features specific to the tar...
unsigned getAssemblerDialect() const
Superclass for all disassemblers.
DecodeStatus
Ternary decode status.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
void setPrintImmHex(bool Value)
Instances of this class represent a single low-level machine instruction.
Interface to description of machine instruction set.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Target - Wrapper for Target specific information.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
MCDisassembler * createMCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) const
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
MCInstPrinter * createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) const
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Triple - Helper class for working with autoconf configuration names.
StringRef getName() const
Return a constant reference to the value's name.
Stores all information relating to a compile unit, be it in its original instance in the object file ...
const LVSymbolTableEntry & getSymbolTableEntry(StringRef Name)
LVSectionIndex updateSymbolTable(LVScope *Function)
Expected< std::pair< LVSectionIndex, object::SectionRef > > getSection(LVScope *Scope, LVAddress Address, LVSectionIndex SectionIndex)
std::unique_ptr< MCContext > MC
void includeInlineeLines(LVSectionIndex SectionIndex, LVScope *Function)
std::unique_ptr< const MCInstrInfo > MII
LVAddress getSymbolTableAddress(StringRef Name)
void print(raw_ostream &OS) const
std::unique_ptr< const MCSubtargetInfo > STI
void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)
virtual void mapRangeAddress(const object::ObjectFile &Obj)
void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex)
void mapVirtualAddress(const object::ObjectFile &Obj)
std::unique_ptr< const MCAsmInfo > MAI
LVSectionIndex getSymbolTableIndex(StringRef Name)
bool getSymbolTableIsComdat(StringRef Name)
std::unique_ptr< const MCRegisterInfo > MRI
std::unique_ptr< const MCDisassembler > MD
LVRange * getSectionRanges(LVSectionIndex SectionIndex)
Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures)
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope)
Error createInstructions()
std::unique_ptr< MCInstPrinter > MIP
LVAddress WasmCodeSectionOffset
void resolvePatternMatch(LVLine *Line)
LVScope * getEntry(LVAddress Address) const
void addEntry(LVScope *Scope, LVAddress LowerAddress, LVAddress UpperAddress)
LVSectionIndex getDotTextSectionIndex() const
LVScopeCompileUnit * CompileUnit
LVSectionIndex DotTextSectionIndex
const LVScopes * getScopes() const
LVSectionIndex getIndex(StringRef Name)
bool getIsComdat(StringRef Name)
void print(raw_ostream &OS)
LVAddress getAddress(StringRef Name)
void add(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)
LVSectionIndex update(LVScope *Function)
const LVSymbolTableEntry & getEntry(StringRef Name)
uint64_t getImageBase() const
const coff_section * getCOFFSection(const SectionRef &Section) const
This class is the base class for all object file types.
section_iterator_range sections() const
This is a value type class that represents a single section in the list of sections in the object fil...
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
A raw_ostream that writes to an SmallVector or SmallString.
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
std::pair< LVAddress, uint64_t > LVNameInfo
constexpr LVSectionIndex UndefinedSectionIndex
This is an optimization pass for GlobalISel generic memory operations.
FormattedNumber format_decimal(int64_t N, unsigned Width)
format_decimal - Output N as a right justified, fixed-width decimal.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void consumeError(Error Err)
Consume a Error without doing anything.
FormattedBytes format_bytes(ArrayRef< uint8_t > Bytes, std::optional< uint64_t > FirstByteOffset=std::nullopt, uint32_t NumPerLine=16, uint8_t ByteGroupSize=4, uint32_t IndentLevel=0, bool Upper=false)
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
support::ulittle32_t PointerToRawData
support::ulittle32_t Characteristics
support::ulittle32_t SizeOfRawData
support::ulittle32_t VirtualAddress