[memprof] Return an error for unsupported symbolization.
authorSnehasish Kumar <snehasishk@google.com>
Fri, 24 Jun 2022 23:34:18 +0000 (16:34 -0700)
committerSnehasish Kumar <snehasishk@google.com>
Mon, 27 Jun 2022 16:43:26 +0000 (09:43 -0700)
Add a check to detect that the profiled binary was build with position
independent code. Add a test with a pie binary to which can be reused
later when support is added. Also clean up the error messages with
trailing colons.

Reviewed By: tejohnson

Differential Revision: https://reviews.llvm.org/D128564

llvm/lib/ProfileData/RawMemProfReader.cpp
llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe [new file with mode: 0755]
llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw [new file with mode: 0644]
llvm/test/tools/llvm-profdata/memprof-pic.test [new file with mode: 0644]

index 9165bc2..2423fd3 100644 (file)
@@ -261,6 +261,24 @@ Error RawMemProfReader::initialize(std::unique_ptr<MemoryBuffer> DataBuffer) {
                   FileName);
   }
 
+  // Check whether the profiled binary was built with position independent code
+  // (PIC). For now we provide a error message until symbolization support
+  // is added for pic.
+  auto* Elf64LEObject = llvm::cast<llvm::object::ELF64LEObjectFile>(ElfObject);
+  const llvm::object::ELF64LEFile& ElfFile = Elf64LEObject->getELFFile();
+  auto PHdrsOr = ElfFile.program_headers();
+  if(!PHdrsOr) 
+    return report(make_error<StringError>(Twine("Could not read program headers: "),
+                                          inconvertibleErrorCode()),
+                  FileName);
+  auto FirstLoadHeader = PHdrsOr->begin();
+  while (FirstLoadHeader->p_type != llvm::ELF::PT_LOAD)
+    ++FirstLoadHeader;
+  if(FirstLoadHeader->p_vaddr == 0)
+    return report(make_error<StringError>(Twine("Unsupported position independent code"),
+                                          inconvertibleErrorCode()),
+                  FileName);
+
   auto Triple = ElfObject->makeTriple();
   if (!Triple.isX86())
     return report(make_error<StringError>(Twine("Unsupported target: ") +
diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe
new file mode 100755 (executable)
index 0000000..e3a6e1f
Binary files /dev/null and b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw
new file mode 100644 (file)
index 0000000..7057af5
Binary files /dev/null and b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw differ
diff --git a/llvm/test/tools/llvm-profdata/memprof-pic.test b/llvm/test/tools/llvm-profdata/memprof-pic.test
new file mode 100644 (file)
index 0000000..1df2637
--- /dev/null
@@ -0,0 +1,40 @@
+REQUIRES: x86_64-linux
+
+This test ensures that llvm-profdata fails with a descriptive error message
+when invoked on a memprof profiled binary which was built with position
+independent code.
+
+The input raw profile test has been generated from the following source code:
+
+```
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+  char *x = (char *)malloc(10);
+  memset(x, 0, 10);
+  free(x);
+  x = (char *)malloc(10);
+  memset(x, 0, 10);
+  free(x);
+  return 0;
+}
+```
+
+The following commands were used to compile the source to a memprof instrumented
+executable and collect a raw binary format profile. Since the profile contains
+virtual addresses for the callstack, we do not expect the raw binary profile to
+be deterministic. The summary should be deterministic apart from changes to
+the shared libraries linked in which could change the number of segments
+recorded.
+
+```
+clang -fuse-ld=lld -Wl,--no-rosegment -gmlt -fdebug-info-for-profiling \
+      -fmemory-profile -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer \
+      -fno-optimize-sibling-calls -m64 -Wl,-build-id -pie \
+      source.c -o pic.memprofexe
+
+env MEMPROF_OPTIONS=log_path=stdout ./pic.memprofexe > pic.memprofraw
+```
+
+RUN: not llvm-profdata show --memory %p/Inputs/pic.memprofraw --profiled-binary %p/Inputs/pic.memprofexe -o - |& FileCheck %s
+CHECK: Unsupported position independent code