diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst --- a/llvm/docs/CommandGuide/llvm-objdump.rst +++ b/llvm/docs/CommandGuide/llvm-objdump.rst @@ -167,6 +167,11 @@ When disassembling, do not print the raw bytes of each instruction. +.. option:: --prefix= + + When disassembling with the :option:`--source` option, prepend ``prefix`` to + absolute paths. + .. option:: --print-imm-hex Use hex format when printing immediate values in disassembly output. diff --git a/llvm/docs/llvm-objdump.1 b/llvm/docs/llvm-objdump.1 --- a/llvm/docs/llvm-objdump.1 +++ b/llvm/docs/llvm-objdump.1 @@ -105,6 +105,10 @@ Print no leading headers. .It Fl -no-show-raw-insn When disassembling instructions, do not print the instruction bytes. +.It Fl -prefix Ns = Ns Ar PREFIX +When disassembling, add +.Ar PREFIX +to absolute paths. .It Fl -print-imm-hex Use hex format for immediate values. .It Fl -private-header diff --git a/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-non-windows.test b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-non-windows.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-non-windows.test @@ -0,0 +1,10 @@ +;; Test --prefix option platform specific behavior. +; UNSUPPORTED: system-windows + +;; Test removal of trailing separators (only '/'). +;; The prefix 'myprefix/\' is not changed. + +; RUN: sed -e "s,SRC_COMPDIR,/Inputs,g" %p/Inputs/source-interleave.ll > %t.ll +; RUN: llc -o %t.o -filetype=obj -mtriple=x86_64-pc-linux %t.ll +; RUN: llvm-objdump --prefix 'myprefix/\' --source %t.o 2>&1 | FileCheck %s -DFILE=%t.o -DPREFIX='myprefix/\' +; CHECK: warning: '[[FILE]]': failed to find source [[PREFIX]]/Inputs/source-interleave-x86_64.c diff --git a/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-windows.test b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-windows.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix-windows.test @@ -0,0 +1,10 @@ +;; Test --prefix option platform specific behavior. +; REQUIRES: system-windows + +;; Test removal of trailing separators (both '/' and '\'). +;; The prefix 'myprefix/\' is changed to 'myprefix'. + +; RUN: sed -e "s,SRC_COMPDIR,/Inputs,g" %p/Inputs/source-interleave.ll > %t.ll +; RUN: llc -o %t.o -filetype=obj -mtriple=x86_64-pc-linux %t.ll +; RUN: llvm-objdump --prefix 'myprefix/\' --source %t.o 2>&1 | FileCheck %s -DFILE=%t.o -DPREFIX='myprefix' +; CHECK: warning: '[[FILE]]': failed to find source [[PREFIX]]/Inputs/source-interleave-x86_64.c diff --git a/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test @@ -0,0 +1,44 @@ +;; Test --prefix option. + +;; Test prefix option ignored for relative paths. + +; RUN: sed -e "s,SRC_COMPDIR,./Inputs,g" %p/Inputs/source-interleave.ll > %t-relative-path.ll +; RUN: llc -o %t-relative-path.o -filetype=obj -mtriple=x86_64-pc-linux %t-relative-path.ll +; RUN: llvm-objdump --prefix myprefix --source %t-relative-path.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-relative-path.o -DPREFIX=. +; CHECK-BROKEN-PREFIX: warning: '[[FILE]]': failed to find source [[PREFIX]]/Inputs/source-interleave-x86_64.c + +;; Test invalid source interleave fixed by adding the correct prefix. + +; RUN: sed -e "s,SRC_COMPDIR,/Inputs,g" %p/Inputs/source-interleave.ll > %t-missing-prefix.ll +; RUN: llc -o %t-missing-prefix.o -filetype=obj -mtriple=x86_64-pc-linux %t-missing-prefix.ll +; RUN: llvm-objdump --prefix %p --source %t-missing-prefix.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX +; CHECK-MISSING-PREFIX-FIX: ; int foo() { + +;; Test valid source interleave broken by adding an incorrect prefix. + +; RUN: sed -e "s,SRC_COMPDIR,%/p/Inputs,g" %p/Inputs/source-interleave.ll > %t-correct-prefix.ll +; RUN: llc -o %t-correct-prefix.o -filetype=obj -mtriple=x86_64-pc-linux %t-correct-prefix.ll +; RUN: llvm-objdump --prefix myprefix --source %t-correct-prefix.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-correct-prefix.o -DPREFIX=myprefix%/p + +;; Test malformed input. + +; RUN: sed -e "s,SRC_COMPDIR,,g" -e "s,filename: \"source-interleave-x86_64.c\",filename: \"\",g" \ +; RUN: %p/Inputs/source-interleave.ll > %t-malformed.ll +; RUN: llc -o %t-malformed.o -filetype=obj -mtriple=x86_64-pc-linux %t-malformed.ll +; RUN: llvm-objdump --prefix myprefix --source %t-malformed.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-MALFORMED -DFILE=%t-malformed.o +; CHECK-MALFORMED: warning: '[[FILE]]': failed to parse debug information for [[FILE]] + +;; Using only a prefix separator is the same as not using the `--prefix` option. + +; RUN: llvm-objdump --prefix / --source %t-missing-prefix.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-missing-prefix.o -DPREFIX='' + +;; All trailing separators on the prefix are discarded. +;; The prefix 'myprefix//' is converted to 'myprefix'. + +; RUN: llvm-objdump --prefix myprefix// --source %t-missing-prefix.o 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-missing-prefix.o -DPREFIX=myprefix diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h --- a/llvm/tools/llvm-objdump/llvm-objdump.h +++ b/llvm/tools/llvm-objdump/llvm-objdump.h @@ -39,6 +39,7 @@ extern cl::opt MCPU; extern cl::opt NoShowRawInsn; extern cl::opt NoLeadingAddr; +extern cl::opt Prefix; extern cl::opt PrintImmHex; extern cl::opt PrivateHeaders; extern cl::opt Relocations; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -353,6 +353,10 @@ cl::cat(ObjdumpCat)); static cl::alias WideShort("w", cl::Grouping, cl::aliasopt(Wide)); +cl::opt objdump::Prefix("prefix", + cl::desc("Add prefix to absolute paths"), + cl::cat(ObjdumpCat)); + enum DebugVarsFormat { DVDisabled, DVUnicode, @@ -1031,6 +1035,13 @@ } } + if (!Prefix.empty() && sys::path::is_absolute_gnu(LineInfo.FileName)) { + SmallString<128> FilePath; + sys::path::append(FilePath, Prefix, LineInfo.FileName); + + LineInfo.FileName = std::string(FilePath); + } + if (PrintLines) printLines(OS, LineInfo, Delimiter, LVP); if (PrintSource) @@ -2961,6 +2972,10 @@ if (InputFilenames.empty()) InputFilenames.push_back("a.out"); + // Removes trailing separators from prefix. + while (!Prefix.empty() && sys::path::is_separator(Prefix.back())) + Prefix.pop_back(); + if (AllHeaders) ArchiveHeaders = FileHeaders = PrivateHeaders = Relocations = SectionHeaders = SymbolTable = true;