[llvm] r278551 - [sancov] MachO indirect symbols support.

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 12:25:59 PDT 2016


Author: aizatsky
Date: Fri Aug 12 14:25:59 2016
New Revision: 278551

URL: http://llvm.org/viewvc/llvm-project?rev=278551&view=rev
Log:
[sancov] MachO indirect symbols support.

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

Added:
    llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64   (with props)
Modified:
    llvm/trunk/test/tools/sancov/print_coverage_pcs.test
    llvm/trunk/tools/sancov/sancov.cc

Added: llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64?rev=278551&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64 (added) and llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64 Fri Aug 12 14:25:59 2016 differ

Propchange: llvm/trunk/test/tools/sancov/Inputs/test-darwin_x86_64
------------------------------------------------------------------------------
    svn:executable = *

Modified: llvm/trunk/test/tools/sancov/print_coverage_pcs.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/sancov/print_coverage_pcs.test?rev=278551&r1=278550&r2=278551&view=diff
==============================================================================
--- llvm/trunk/test/tools/sancov/print_coverage_pcs.test (original)
+++ llvm/trunk/test/tools/sancov/print_coverage_pcs.test Fri Aug 12 14:25:59 2016
@@ -2,6 +2,7 @@ REQUIRES: x86-registered-target
 RUN: sancov -print-coverage-pcs %p/Inputs/test-linux_x86_64 | FileCheck %s --check-prefix=LINUX
 RUN: llvm-objdump -d %p/Inputs/test-windows_x86_64 | FileCheck %s --check-prefix=DISAS_WIN
 RUN: sancov -print-coverage-pcs %p/Inputs/test-windows_x86_64 | FileCheck %s --check-prefix=WINDOWS
+RUN: sancov -print-coverage-pcs %p/Inputs/test-darwin_x86_64 | FileCheck %s --check-prefix=DARWIN
 
 LINUX: 0x4e132b
 LINUX: 0x4e1472
@@ -34,3 +35,26 @@ DISAS_WIN: 140001664: {{.*}}  callq   {{
 WINDOWS: 0x140001668
 DISAS_WIN: 1400016f2: {{.*}}  callq   {{.*}} <__sanitizer_cov>
 WINDOWS: 0x1400016f6
+
+CHECK: 0x4e132b
+CHECK: 0x4e1472
+CHECK: 0x4e14c2
+CHECK: 0x4e1520
+CHECK: 0x4e1553
+CHECK: 0x4e1586
+CHECK: 0x4e1635
+CHECK: 0x4e1690
+CHECK: 0x4e178c
+
+DARWIN: 0x100001527
+DARWIN: 0x100001668
+DARWIN: 0x1000016b7
+DARWIN: 0x1000016dd
+DARWIN: 0x10000179d
+DARWIN: 0x1000017cc
+DARWIN: 0x10000189d
+DARWIN: 0x1000018e0
+DARWIN: 0x100001906
+DARWIN: 0x1000019dc
+DARWIN: 0x100001a28
+>>>>>>> [sancov] MachO indirect symbols support.

Modified: llvm/trunk/tools/sancov/sancov.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/sancov.cc?rev=278551&r1=278550&r2=278551&view=diff
==============================================================================
--- llvm/trunk/tools/sancov/sancov.cc (original)
+++ llvm/trunk/tools/sancov/sancov.cc Fri Aug 12 14:25:59 2016
@@ -27,6 +27,7 @@
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
@@ -322,7 +323,49 @@ static std::vector<AddrInfo> getAddrInfo
 
 static bool isCoveragePointSymbol(StringRef Name) {
   return Name == "__sanitizer_cov" || Name == "__sanitizer_cov_with_check" ||
-         Name == "__sanitizer_cov_trace_func_enter";
+         Name == "__sanitizer_cov_trace_func_enter" ||
+         // Mac has '___' prefix
+         Name == "___sanitizer_cov" || Name == "___sanitizer_cov_with_check" ||
+         Name == "___sanitizer_cov_trace_func_enter";
+}
+
+// Locate __sanitizer_cov* function addresses inside the stubs table on MachO.
+static void findMachOIndirectCovFunctions(const object::MachOObjectFile &O,
+                                          std::set<uint64_t> *Result) {
+  MachO::dysymtab_command Dysymtab = O.getDysymtabLoadCommand();
+  MachO::symtab_command Symtab = O.getSymtabLoadCommand();
+
+  for (const auto &Load : O.load_commands()) {
+    if (Load.C.cmd == MachO::LC_SEGMENT_64) {
+      MachO::segment_command_64 Seg = O.getSegment64LoadCommand(Load);
+      for (unsigned J = 0; J < Seg.nsects; ++J) {
+        MachO::section_64 Sec = O.getSection64(Load, J);
+
+        uint32_t SectionType = Sec.flags & MachO::SECTION_TYPE;
+        if (SectionType == MachO::S_SYMBOL_STUBS) {
+          uint32_t Stride = Sec.reserved2;
+          uint32_t Cnt = Sec.size / Stride;
+          uint32_t N = Sec.reserved1;
+          for (uint32_t J = 0; J < Cnt && N + J < Dysymtab.nindirectsyms; J++) {
+            uint32_t IndirectSymbol =
+                O.getIndirectSymbolTableEntry(Dysymtab, N + J);
+            uint64_t Addr = Sec.addr + J * Stride;
+            if (IndirectSymbol < Symtab.nsyms) {
+              object::SymbolRef Symbol = *(O.getSymbolByIndex(IndirectSymbol));
+              Expected<StringRef> Name = Symbol.getName();
+              FailIfError(Name);
+              if (isCoveragePointSymbol(Name.get())) {
+                Result->insert(Addr);
+              }
+            }
+          }
+        }
+      }
+    }
+    if (Load.C.cmd == MachO::LC_SEGMENT) {
+      errs() << "ERROR: 32 bit MachO binaries not supported\n";
+    }
+  }
 }
 
 // Locate __sanitizer_cov* function addresses that are used for coverage
@@ -333,15 +376,16 @@ findSanitizerCovFunctions(const object::
 
   for (const object::SymbolRef &Symbol : O.symbols()) {
     Expected<uint64_t> AddressOrErr = Symbol.getAddress();
-    FailIfError(errorToErrorCode(AddressOrErr.takeError()));
+    FailIfError(AddressOrErr);
+    uint64_t Address = AddressOrErr.get();
 
     Expected<StringRef> NameOrErr = Symbol.getName();
-    FailIfError(errorToErrorCode(NameOrErr.takeError()));
+    FailIfError(NameOrErr);
     StringRef Name = NameOrErr.get();
 
-    if (isCoveragePointSymbol(Name)) {
-      if (!(Symbol.getFlags() & object::BasicSymbolRef::SF_Undefined))
-        Result.insert(AddressOrErr.get());
+    if (!(Symbol.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
+        isCoveragePointSymbol(Name)) {
+      Result.insert(Address);
     }
   }
 
@@ -361,6 +405,10 @@ findSanitizerCovFunctions(const object::
     }
   }
 
+  if (const auto *MO = dyn_cast<object::MachOObjectFile>(&O)) {
+    findMachOIndirectCovFunctions(*MO, &Result);
+  }
+
   return Result;
 }
 
@@ -446,7 +494,7 @@ visitObjectFiles(const object::Archive &
   Error Err;
   for (auto &C : A.children(Err)) {
     Expected<std::unique_ptr<object::Binary>> ChildOrErr = C.getAsBinary();
-    FailIfError(errorToErrorCode(ChildOrErr.takeError()));
+    FailIfError(ChildOrErr);
     if (auto *O = dyn_cast<object::ObjectFile>(&*ChildOrErr.get()))
       Fn(*O);
     else
@@ -461,7 +509,7 @@ visitObjectFiles(const std::string &File
   Expected<object::OwningBinary<object::Binary>> BinaryOrErr =
       object::createBinary(FileName);
   if (!BinaryOrErr)
-    FailIfError(errorToErrorCode(BinaryOrErr.takeError()));
+    FailIfError(BinaryOrErr);
 
   object::Binary &Binary = *BinaryOrErr.get().getBinary();
   if (object::Archive *A = dyn_cast<object::Archive>(&Binary))




More information about the llvm-commits mailing list