23 using namespace object;
25 static DILineInfoSpecifier
33 std::unique_ptr<DIContext> DICtx) {
34 std::unique_ptr<SymbolizableObjectFile> res(
36 std::unique_ptr<DataExtractor> OpdExtractor;
37 uint64_t OpdAddress = 0;
44 if (
auto EC =
Section->getName(Name))
47 if (
auto EC =
Section->getContents(Data))
51 OpdAddress =
Section->getAddress();
56 std::vector<std::pair<SymbolRef, uint64_t>> Symbols =
58 for (
auto &
P : Symbols)
59 res->addSymbol(
P.first,
P.second, OpdExtractor.get(), OpdAddress);
63 if (Symbols.empty()) {
64 if (
auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
65 if (
auto EC = res->addCoffExportSymbols(CoffObj))
68 return std::move(res);
71 SymbolizableObjectFile::SymbolizableObjectFile(
ObjectFile *Obj,
72 std::unique_ptr<DIContext> DICtx)
73 :
Module(Obj), DebugInfoContext(std::move(DICtx)) {}
76 struct OffsetNamePair {
79 bool operator<(
const OffsetNamePair &R)
const {
85 std::error_code SymbolizableObjectFile::addCoffExportSymbols(
86 const COFFObjectFile *CoffObj) {
88 std::vector<OffsetNamePair> ExportSyms;
89 for (
const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
92 if (
auto EC = Ref.getSymbolName(Name))
94 if (
auto EC = Ref.getExportRVA(Offset))
96 ExportSyms.push_back(OffsetNamePair{
Offset, Name});
98 if (ExportSyms.empty())
99 return std::error_code();
106 uint64_t ImageBase = CoffObj->getImageBase();
107 for (
auto I = ExportSyms.begin(),
E = ExportSyms.end();
I !=
E; ++
I) {
110 uint32_t NextOffset =
I !=
E ?
I->Offset : Export.Offset + 1;
111 uint64_t SymbolStart = ImageBase + Export.Offset;
112 uint64_t SymbolSize = NextOffset - Export.Offset;
113 SymbolDesc SD = {SymbolStart, SymbolSize};
114 Functions.insert(std::make_pair(SD, Export.Name));
116 return std::error_code();
119 std::error_code SymbolizableObjectFile::addSymbol(
const SymbolRef &
Symbol,
121 DataExtractor *OpdExtractor,
122 uint64_t OpdAddress) {
123 Expected<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType();
124 if (!SymbolTypeOrErr)
128 return std::error_code();
129 Expected<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
130 if (!SymbolAddressOrErr)
132 uint64_t SymbolAddress = *SymbolAddressOrErr;
139 uint64_t OpdOffset = SymbolAddress - OpdAddress;
141 if (OpdOffset == OpdOffset32 &&
142 OpdExtractor->isValidOffsetForAddress(OpdOffset32))
143 SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
145 Expected<StringRef> SymbolNameOrErr = Symbol.getName();
146 if (!SymbolNameOrErr)
148 StringRef SymbolName = *SymbolNameOrErr;
150 if (Module->
isMachO() && SymbolName.size() > 0 && SymbolName[0] ==
'_')
151 SymbolName = SymbolName.drop_front();
155 SymbolDesc SD = { SymbolAddress, SymbolSize };
156 M.insert(std::make_pair(SD, SymbolName));
157 return std::error_code();
167 if (
auto *CoffObject = dyn_cast<COFFObjectFile>(
Module))
168 return CoffObject->getImageBase();
176 uint64_t &Size)
const {
178 if (SymbolMap.empty())
180 SymbolDesc SD = {
Address, Address };
181 auto SymbolIterator = SymbolMap.upper_bound(SD);
182 if (SymbolIterator == SymbolMap.begin())
185 if (SymbolIterator->first.Size != 0 &&
186 SymbolIterator->first.Addr + SymbolIterator->first.Size <= Address)
188 Name = SymbolIterator->second.str();
189 Addr = SymbolIterator->first.Addr;
190 Size = SymbolIterator->first.Size;
194 bool SymbolizableObjectFile::shouldOverrideWithSymbolTable(
201 isa<DWARFContext>(DebugInfoContext.get());
206 bool UseSymbolTable)
const {
208 if (DebugInfoContext) {
209 LineInfo = DebugInfoContext->getLineInfoForAddress(
213 if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) {
214 std::string FunctionName;
215 uint64_t Start, Size;
217 FunctionName, Start, Size)) {
225 uint64_t ModuleOffset,
FunctionNameKind FNKind,
bool UseSymbolTable)
const {
228 if (DebugInfoContext)
229 InlinedContext = DebugInfoContext->getInliningInfoForAddress(
236 if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) {
237 std::string FunctionName;
238 uint64_t Start, Size;
240 FunctionName, Start, Size)) {
242 ->FunctionName = FunctionName;
246 return InlinedContext;
Represents either an error or a value T.
bool isWin32Module() const override
DILineInfo * getMutableFrame(unsigned Index)
A Module instance is used to store all the information related to an LLVM module. ...
static ErrorOr< std::unique_ptr< SymbolizableObjectFile > > create(object::ObjectFile *Obj, std::unique_ptr< DIContext > DICtx)
This class is the base class for all object file types.
void addFrame(const DILineInfo &Frame)
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
virtual unsigned getArch() const =0
DILineInfo - a format-neutral container for source line information.
DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const override
DIGlobal symbolizeData(uint64_t ModuleOffset) const override
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
uint32_t getNumberOfFrames() const
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
The instances of the Type class are immutable: once they are created, they are never changed...
uint16_t getMachine() const
DILineInfoSpecifier - controls which fields of DILineInfo container should be filled with data...
DIInliningInfo - a format-neutral container for inlined code description.
uint64_t getModulePreferredBase() const override
section_iterator_range sections() const
static DILineInfoSpecifier getDILineInfoSpecifier(FunctionNameKind FNKind)
std::vector< std::pair< SymbolRef, uint64_t > > computeSymbolSizes(const ObjectFile &O)
DILineInfoSpecifier::FunctionNameKind FunctionNameKind
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isLittleEndian() const
bool operator<(int64_t V1, const APSInt &V2)
DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const override
StringRef - Represent a constant reference to a string, i.e.
Export typeid resolutions to summary and globals.
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
DIGlobal - container for description of a global variable.