summaryrefslogtreecommitdiffstats
path: root/llvm/lib/XRay/InstrumentationMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/XRay/InstrumentationMap.cpp')
-rw-r--r--llvm/lib/XRay/InstrumentationMap.cpp43
1 files changed, 41 insertions, 2 deletions
diff --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp
index 84317708d3f..d33fb4a2b80 100644
--- a/llvm/lib/XRay/InstrumentationMap.cpp
+++ b/llvm/lib/XRay/InstrumentationMap.cpp
@@ -12,12 +12,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/InstrumentationMap.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Object/Binary.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
@@ -46,6 +48,8 @@ Optional<uint64_t> InstrumentationMap::getFunctionAddr(int32_t FuncId) const {
return None;
}
+using RelocMap = DenseMap<uint64_t, uint64_t>;
+
static Error
loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
InstrumentationMap::SledContainer &Sleds,
@@ -79,6 +83,31 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
return errorCodeToError(
std::make_error_code(std::errc::executable_format_error));
+ RelocMap Relocs;
+ if (ObjFile.getBinary()->isELF()) {
+ uint32_t RelrRelocationType = [](object::ObjectFile *ObjFile) {
+ if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(ObjFile))
+ return ELFObj->getELFFile()->getRelrRelocationType();
+ else if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(ObjFile))
+ return ELFObj->getELFFile()->getRelrRelocationType();
+ else if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(ObjFile))
+ return ELFObj->getELFFile()->getRelrRelocationType();
+ else if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(ObjFile))
+ return ELFObj->getELFFile()->getRelrRelocationType();
+ else
+ return static_cast<uint32_t>(0);
+ }(ObjFile.getBinary());
+
+ for (const object::SectionRef &Section : Sections) {
+ for (const object::RelocationRef &Reloc : Section.relocations()) {
+ if (Reloc.getType() != RelrRelocationType)
+ continue;
+ if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend())
+ Relocs.insert({Reloc.getOffset(), *AddendOrErr});
+ }
+ }
+ }
+
// Copy the instrumentation map data into the Sleds data structure.
auto C = Contents.bytes_begin();
static constexpr size_t ELF64SledEntrySize = 32;
@@ -89,6 +118,16 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
"an XRay sled entry in ELF64."),
std::make_error_code(std::errc::executable_format_error));
+ auto RelocateOrElse = [&](uint32_t Offset, uint64_t Address) {
+ if (!Address) {
+ uint64_t A = I->getAddress() + C - Contents.bytes_begin() + Offset;
+ RelocMap::const_iterator R = Relocs.find(A);
+ if (R != Relocs.end())
+ return R->second;
+ }
+ return Address;
+ };
+
int32_t FuncId = 1;
uint64_t CurFn = 0;
for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) {
@@ -98,8 +137,8 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
Sleds.push_back({});
auto &Entry = Sleds.back();
uint32_t OffsetPtr = 0;
- Entry.Address = Extractor.getU64(&OffsetPtr);
- Entry.Function = Extractor.getU64(&OffsetPtr);
+ Entry.Address = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
+ Entry.Function = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
auto Kind = Extractor.getU8(&OffsetPtr);
static constexpr SledEntry::FunctionKinds Kinds[] = {
SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT,
OpenPOWER on IntegriCloud