From 7f8c512ee7403b53d874fc2655c4c220967eca27 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 5 Aug 2019 20:59:25 +0000 Subject: [PATCH] llvm-symbolizer: Untag addresses in object files by default. Any addresses that we pass to llvm-symbolizer are going to be untagged, while any HWASAN instrumented globals are going to be tagged in the symbol table. Therefore we need to untag the addresses before using them. Differential Revision: https://reviews.llvm.org/D65769 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367926 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/Symbolize/Symbolize.h | 1 + .../Symbolize/SymbolizableObjectFile.cpp | 16 ++++++++++++---- lib/DebugInfo/Symbolize/SymbolizableObjectFile.h | 7 +++++-- lib/DebugInfo/Symbolize/Symbolize.cpp | 4 ++-- test/tools/llvm-symbolizer/untag-addresses.test | 16 ++++++++++++++++ tools/llvm-symbolizer/llvm-symbolizer.cpp | 6 ++++++ 6 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 test/tools/llvm-symbolizer/untag-addresses.test diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h index d3da28ca0b7..11599fc1797 100644 --- a/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -39,6 +39,7 @@ public: bool UseSymbolTable = true; bool Demangle = true; bool RelativeAddresses = false; + bool UntagAddresses = false; std::string DefaultArch; std::vector DsymHints; std::string FallbackDebugPath; diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp index 2765bf44d50..03c5c6b8e10 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -43,10 +43,11 @@ getDILineInfoSpecifier(FunctionNameKind FNKind) { ErrorOr> SymbolizableObjectFile::create(const object::ObjectFile *Obj, - std::unique_ptr DICtx) { + std::unique_ptr DICtx, + bool UntagAddresses) { assert(DICtx); std::unique_ptr res( - new SymbolizableObjectFile(Obj, std::move(DICtx))); + new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses)); std::unique_ptr OpdExtractor; uint64_t OpdAddress = 0; // Find the .opd (function descriptor) section if any, for big-endian @@ -103,8 +104,10 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj, } SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj, - std::unique_ptr DICtx) - : Module(Obj), DebugInfoContext(std::move(DICtx)) {} + std::unique_ptr DICtx, + bool UntagAddresses) + : Module(Obj), DebugInfoContext(std::move(DICtx)), + UntagAddresses(UntagAddresses) {} namespace { @@ -172,6 +175,11 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, if (!SymbolAddressOrErr) return errorToErrorCode(SymbolAddressOrErr.takeError()); uint64_t SymbolAddress = *SymbolAddressOrErr; + if (UntagAddresses) { + // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55 + // into bits 56-63 instead of masking them out. + SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8; + } if (OpdExtractor) { // For big-endian PowerPC64 ELF, symbols in the .opd section refer to // function descriptors. The first word of the descriptor is a pointer to diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h index 9cab94178c1..b5b9793a44d 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h @@ -31,7 +31,8 @@ namespace symbolize { class SymbolizableObjectFile : public SymbolizableModule { public: static ErrorOr> - create(const object::ObjectFile *Obj, std::unique_ptr DICtx); + create(const object::ObjectFile *Obj, std::unique_ptr DICtx, + bool UntagAddresses); DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, @@ -70,6 +71,7 @@ private: const object::ObjectFile *Module; std::unique_ptr DebugInfoContext; + bool UntagAddresses; struct SymbolDesc { uint64_t Addr; @@ -85,7 +87,8 @@ private: std::vector> Objects; SymbolizableObjectFile(const object::ObjectFile *Obj, - std::unique_ptr DICtx); + std::unique_ptr DICtx, + bool UntagAddresses); }; } // end namespace symbolize diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp index 6a619f8f2f3..51aa0d781f6 100644 --- a/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -418,8 +418,8 @@ Expected LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj, std::unique_ptr Context, StringRef ModuleName) { - auto InfoOrErr = - SymbolizableObjectFile::create(Obj, std::move(Context)); + auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context), + Opts.UntagAddresses); std::unique_ptr SymMod; if (InfoOrErr) SymMod = std::move(*InfoOrErr); diff --git a/test/tools/llvm-symbolizer/untag-addresses.test b/test/tools/llvm-symbolizer/untag-addresses.test new file mode 100644 index 00000000000..aa4c5c53127 --- /dev/null +++ b/test/tools/llvm-symbolizer/untag-addresses.test @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo DATA %t.o 0 | llvm-symbolizer | FileCheck --check-prefix=UNTAG %s +# RUN: echo DATA %t.o 0 | llvm-symbolizer -untag-addresses=0 | FileCheck --check-prefix=NOUNTAG %s +# RUN: echo DATA %t.o 0 | llvm-addr2line | FileCheck --check-prefix=NOUNTAG %s + +# UNTAG: foo +# UNTAG: 0 4 +# NOUNTAG: ?? +# NOUNTAG: 0 0 + +.data +.globl foo +.type foo, @object +.size foo, 4 +foo = . + 0x1100000000000000 +.4byte 1 diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index ea94cf9b69a..54ce87d4797 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -55,6 +55,10 @@ static cl::opt cl::desc("Interpret addresses as relative addresses"), cl::ReallyHidden); +static cl::opt ClUntagAddresses( + "untag-addresses", cl::init(true), + cl::desc("Remove memory tags from addresses before symbolization")); + static cl::opt ClPrintInlining("inlining", cl::init(true), cl::desc("Print all inlined frames for a given address")); @@ -274,6 +278,7 @@ int main(int argc, char **argv) { ClDemangle.setInitialValue(false); ClPrintFunctions.setInitialValue(FunctionNameKind::None); ClPrintInlining.setInitialValue(false); + ClUntagAddresses.setInitialValue(false); ClOutputStyle.setInitialValue(DIPrinter::OutputStyle::GNU); } @@ -290,6 +295,7 @@ int main(int argc, char **argv) { Opts.UseSymbolTable = ClUseSymbolTable; Opts.Demangle = ClDemangle; Opts.RelativeAddresses = ClUseRelativeAddress; + Opts.UntagAddresses = ClUntagAddresses; Opts.DefaultArch = ClDefaultArch; Opts.FallbackDebugPath = ClFallbackDebugPath; Opts.DWPName = ClDwpName; -- 2.50.1