aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp120
1 files changed, 117 insertions, 3 deletions
diff --git a/contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp b/contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
index 40b57b5e40ea..ec0271f774ec 100644
--- a/contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
+++ b/contrib/llvm-project/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
@@ -12,11 +12,13 @@
#include "llvm/TextAPI/DylibReader.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Support/Endian.h"
#include "llvm/TargetParser/Triple.h"
+#include "llvm/TextAPI/InterfaceFile.h"
#include "llvm/TextAPI/RecordsSlice.h"
#include "llvm/TextAPI/TextAPIError.h"
#include <iomanip>
@@ -292,8 +294,11 @@ static Error readSymbols(MachOObjectFile *Obj, RecordsSlice &Slice,
RecordLinkage Linkage = RecordLinkage::Unknown;
SymbolFlags RecordFlags = SymbolFlags::None;
- if (Opt.Undefineds && (Flags & SymbolRef::SF_Undefined)) {
- Linkage = RecordLinkage::Undefined;
+ if (Flags & SymbolRef::SF_Undefined) {
+ if (Opt.Undefineds)
+ Linkage = RecordLinkage::Undefined;
+ else
+ continue;
if (Flags & SymbolRef::SF_Weak)
RecordFlags |= SymbolFlags::WeakReferenced;
} else if (Flags & SymbolRef::SF_Exported) {
@@ -408,6 +413,7 @@ Expected<Records> DylibReader::readFile(MemoryBufferRef Buffer,
Results.emplace_back(std::make_shared<RecordsSlice>(RecordsSlice({T})));
if (auto Err = load(&Obj, *Results.back(), Opt, Arch))
return std::move(Err);
+ Results.back()->getBinaryAttrs().Path = Buffer.getBufferIdentifier();
}
break;
}
@@ -427,3 +433,111 @@ DylibReader::get(MemoryBufferRef Buffer) {
return convertToInterfaceFile(*SlicesOrErr);
}
+
+static void DWARFErrorHandler(Error Err) { /**/ }
+
+static SymbolToSourceLocMap
+accumulateLocs(MachOObjectFile &Obj,
+ const std::unique_ptr<DWARFContext> &DiCtx) {
+ SymbolToSourceLocMap LocMap;
+ for (const auto &Symbol : Obj.symbols()) {
+ Expected<uint32_t> FlagsOrErr = Symbol.getFlags();
+ if (!FlagsOrErr) {
+ consumeError(FlagsOrErr.takeError());
+ continue;
+ }
+
+ if (!(*FlagsOrErr & SymbolRef::SF_Exported))
+ continue;
+
+ Expected<uint64_t> AddressOrErr = Symbol.getAddress();
+ if (!AddressOrErr) {
+ consumeError(AddressOrErr.takeError());
+ continue;
+ }
+ const uint64_t Address = *AddressOrErr;
+
+ auto TypeOrErr = Symbol.getType();
+ if (!TypeOrErr) {
+ consumeError(TypeOrErr.takeError());
+ continue;
+ }
+ const bool IsCode = (*TypeOrErr & SymbolRef::ST_Function);
+
+ auto *DWARFCU = IsCode ? DiCtx->getCompileUnitForCodeAddress(Address)
+ : DiCtx->getCompileUnitForDataAddress(Address);
+ if (!DWARFCU)
+ continue;
+
+ const DWARFDie &DIE = IsCode ? DWARFCU->getSubroutineForAddress(Address)
+ : DWARFCU->getVariableForAddress(Address);
+ const std::string File = DIE.getDeclFile(
+ llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);
+ const uint64_t Line = DIE.getDeclLine();
+
+ auto NameOrErr = Symbol.getName();
+ if (!NameOrErr) {
+ consumeError(NameOrErr.takeError());
+ continue;
+ }
+ auto Name = *NameOrErr;
+ auto Sym = parseSymbol(Name);
+
+ if (!File.empty() && Line != 0)
+ LocMap.insert({Sym.Name, RecordLoc(File, Line)});
+ }
+
+ return LocMap;
+}
+
+SymbolToSourceLocMap
+DylibReader::accumulateSourceLocFromDSYM(const StringRef DSYM,
+ const Target &T) {
+ // Find sidecar file.
+ auto DSYMsOrErr = MachOObjectFile::findDsymObjectMembers(DSYM);
+ if (!DSYMsOrErr) {
+ consumeError(DSYMsOrErr.takeError());
+ return SymbolToSourceLocMap();
+ }
+ if (DSYMsOrErr->empty())
+ return SymbolToSourceLocMap();
+
+ const StringRef Path = DSYMsOrErr->front();
+ auto BufOrErr = MemoryBuffer::getFile(Path);
+ if (auto Err = BufOrErr.getError())
+ return SymbolToSourceLocMap();
+
+ auto BinOrErr = createBinary(*BufOrErr.get());
+ if (!BinOrErr) {
+ consumeError(BinOrErr.takeError());
+ return SymbolToSourceLocMap();
+ }
+ // Handle single arch.
+ if (auto *Single = dyn_cast<MachOObjectFile>(BinOrErr->get())) {
+ auto DiCtx = DWARFContext::create(
+ *Single, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
+ DWARFErrorHandler, DWARFErrorHandler);
+
+ return accumulateLocs(*Single, DiCtx);
+ }
+ // Handle universal companion file.
+ if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get())) {
+ auto ObjForArch = Fat->getObjectForArch(getArchitectureName(T.Arch));
+ if (!ObjForArch) {
+ consumeError(ObjForArch.takeError());
+ return SymbolToSourceLocMap();
+ }
+ auto MachOOrErr = ObjForArch->getAsObjectFile();
+ if (!MachOOrErr) {
+ consumeError(MachOOrErr.takeError());
+ return SymbolToSourceLocMap();
+ }
+ auto &Obj = **MachOOrErr;
+ auto DiCtx = DWARFContext::create(
+ Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
+ DWARFErrorHandler, DWARFErrorHandler);
+
+ return accumulateLocs(Obj, DiCtx);
+ }
+ return SymbolToSourceLocMap();
+}