[PATCH] D55542: [llvm-xray] Support for PIE

Petr Hosek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 10 19:30:45 PST 2018


phosek created this revision.
phosek added reviewers: dberris, MaskRay.
Herald added subscribers: llvm-commits, hiraditya.

When the instrumented binary is linked as PIE, we need to apply the
relative relocations to sleds. This is handled by the dynamic linker
at runtime, but when processing the file we have to do it ourselves.


Repository:
  rL LLVM

https://reviews.llvm.org/D55542

Files:
  llvm/lib/XRay/InstrumentationMap.cpp
  llvm/test/tools/llvm-xray/X86/Inputs/elf64-pie.bin
  llvm/test/tools/llvm-xray/X86/extract-instrmap-pie.ll


Index: llvm/test/tools/llvm-xray/X86/extract-instrmap-pie.ll
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-xray/X86/extract-instrmap-pie.ll
@@ -0,0 +1,11 @@
+; This test makes sure we can extract the instrumentation map from an
+; XRay-instrumented PIE file.
+;
+; RUN: llvm-xray extract %S/Inputs/elf64-pie.bin -s | FileCheck %s
+
+; CHECK:      ---
+; CHECK-NEXT: - { id: 1, address: 0x00000000000299C0, function: 0x00000000000299C0, kind: function-enter, always-instrument: true, function-name: {{.*foo.*}} }
+; CHECK-NEXT: - { id: 1, address: 0x00000000000299D0, function: 0x00000000000299C0, kind: function-exit, always-instrument: true, function-name: {{.*foo.*}} }
+; CHECK-NEXT: - { id: 2, address: 0x00000000000299E0, function: 0x00000000000299E0, kind: function-enter, always-instrument: true, function-name: {{.*bar.*}} }
+; CHECK-NEXT: - { id: 2, address: 0x00000000000299F6, function: 0x00000000000299E0, kind: function-exit, always-instrument: true, function-name: {{.*bar.*}} }
+; CHECK-NEXT: ...
Index: llvm/lib/XRay/InstrumentationMap.cpp
===================================================================
--- llvm/lib/XRay/InstrumentationMap.cpp
+++ 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"
@@ -79,6 +81,27 @@
     return errorCodeToError(
         std::make_error_code(std::errc::executable_format_error));
 
+  using RelocMap = DenseMap<uint64_t, uint64_t>;
+  RelocMap Relocs;
+
+  if (ObjFile.getBinary()->isELF()) {
+    for (const object::SectionRef &Section : Sections) {
+      // Skip sections that will never have any relocations.
+      if (Section.isBSS() || Section.isVirtual())
+        continue;
+
+      for (const object::RelocationRef &Reloc : Section.relocations()) {
+        // We assume the R_*_RELATIVE relocations are being used so we
+        // compute the addend here and later use it as the value. This
+        // logic will need to be extended if other relocation types are
+        // ever being used.
+        auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend();
+        if (AddendOrErr)
+          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 +112,17 @@
               "an XRay sled entry in ELF64."),
         std::make_error_code(std::errc::executable_format_error));
 
+  auto RelocIfNeeded = [&](DataExtractor &Extractor, uint32_t *Offset) {
+    uint64_t Address = I->getAddress() + C - Contents.bytes_begin() + *Offset;
+    uint64_t Value = Extractor.getU64(Offset);
+    if (!Value) {
+      RelocMap::const_iterator R = Relocs.find(Address);
+      if (R != Relocs.end())
+        return R->second;
+    }
+    return Value;
+  };
+
   int32_t FuncId = 1;
   uint64_t CurFn = 0;
   for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) {
@@ -98,8 +132,8 @@
     Sleds.push_back({});
     auto &Entry = Sleds.back();
     uint32_t OffsetPtr = 0;
-    Entry.Address = Extractor.getU64(&OffsetPtr);
-    Entry.Function = Extractor.getU64(&OffsetPtr);
+    Entry.Address = RelocIfNeeded(Extractor, &OffsetPtr);
+    Entry.Function = RelocIfNeeded(Extractor, &OffsetPtr);
     auto Kind = Extractor.getU8(&OffsetPtr);
     static constexpr SledEntry::FunctionKinds Kinds[] = {
         SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55542.177648.patch
Type: text/x-patch
Size: 3993 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181211/02a3de57/attachment.bin>


More information about the llvm-commits mailing list