[llvm-objdump] Implement --prefix-strip option

The option `--prefix-strip` is only used when `--prefix` is not empty.
It removes N initial directories from absolute paths before adding the
prefix.

This matches GNU's objdump behavior.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D96679
This commit is contained in:
Vinicius Tinti 2020-07-31 22:45:05 -03:00
parent cfc36bf017
commit 804ff7f293
5 changed files with 92 additions and 5 deletions

View File

@ -172,6 +172,12 @@ OPTIONS
When disassembling with the :option:`--source` option, prepend ``prefix`` to
absolute paths.
.. option:: --prefix-strip=<level>
When disassembling with the :option:`--source` option, strip out ``level``
initial directories from absolute paths. This option has no effect without
:option:`--prefix`.
.. option:: --print-imm-hex
Use hex format when printing immediate values in disassembly output.

View File

@ -109,6 +109,11 @@ When disassembling instructions, do not print the instruction bytes.
When disassembling, add
.Ar PREFIX
to absolute paths.
.It Fl -prefix-strip Ns = Ns Ar LEVEL
When disassembling, strip out
.Ar LEVEL
initial directories from absolute paths. This option has no effect without
.Fl -prefix Ns = Ns PREFIX .
.It Fl -print-imm-hex
Use hex format for immediate values.
.It Fl -private-header

View File

@ -12,8 +12,8 @@
; 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
; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-relative-path.o -DPREFIX=. -DCOMPDIR=/Inputs
; CHECK-BROKEN-PREFIX: warning: '[[FILE]]': failed to find source [[PREFIX]][[COMPDIR]]{{[/\\]}}source-interleave-x86_64.c
;; Test invalid source interleave fixed by adding the correct prefix.
@ -28,16 +28,64 @@
; 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
; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-correct-prefix.o -DPREFIX=myprefix%/p -DCOMPDIR=/Inputs
;; 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=''
; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-missing-prefix.o -DPREFIX='' -DCOMPDIR=/Inputs
;; 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
; RUN: FileCheck %s --check-prefix=CHECK-BROKEN-PREFIX -DFILE=%t-missing-prefix.o -DPREFIX=myprefix -DCOMPDIR=/Inputs
;; Test invalid source interleave fixed by adding the correct prefix and
;; stripping out an extra directory from the path.
; RUN: sed -e "s,SRC_COMPDIR,/extra/Inputs,g" %p/Inputs/source-interleave.ll > %t-extra-path-prefix.ll
; RUN: llc -o %t-extra-path-prefix.o -filetype=obj -mtriple=x86_64-pc-linux %t-extra-path-prefix.ll
; RUN: llvm-objdump --prefix %p --prefix-strip 1 --source %t-extra-path-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX
;; Test do not skip extra separators. The --prefix-strip should take into
;; account each separator individually. Hence, to fix '/extra/Inputs'
;; --prefix-strip needs to be 1. To fix '//extra/Inputs' --prefix-strip
;; needs to be 2.
; RUN: sed -e "s,SRC_COMPDIR,//extra/Inputs,g" %p/Inputs/source-interleave.ll > %t-extra-sep-path-prefix.ll
; RUN: llc -o %t-extra-sep-path-prefix.o -filetype=obj -mtriple=x86_64-pc-linux %t-extra-sep-path-prefix.ll
; RUN: llvm-objdump --prefix %p --prefix-strip 2 --source %t-extra-sep-path-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX
;; Test --prefix-strip value of 0. No effect.
;; SRC_COMPDIR is set to '/Inputs' before and after --prefix-strip 0.
; RUN: llvm-objdump --prefix %p --prefix-strip 0 --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX
;; Test --prefix-strip value equal to the number of directory components.
;; SRC_COMPDIR is set to '/Inputs' before --prefix-strip 1.
;; SRC_COMPDIR becomes '' after --prefix-strip 1.
; RUN: llvm-objdump --prefix %p/Inputs --prefix-strip 1 --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX
;; Test --prefix-strip value greater than the number of components.
;; SRC_COMPDIR is set to '/Inputs' before --prefix-strip 2.
;; SRC_COMPDIR becomes '' after --prefix-strip 2.
; RUN: llvm-objdump --prefix %p/Inputs --prefix-strip 2 --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-MISSING-PREFIX-FIX
;; Test negative value --prefix-strip. Reports an error.
; RUN: not llvm-objdump --prefix %p --prefix-strip '-1' --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-INVALID-PREFIX-STRIP -DOPTION='-1'
; CHECK-INVALID-PREFIX-STRIP: llvm-objdump{{.*}}: for the --prefix-strip option: '[[OPTION]]' value invalid for uint argument!
;; Test text value --prefix-strip. Reports an error.
; RUN: not llvm-objdump --prefix %p --prefix-strip foo --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-INVALID-PREFIX-STRIP -DOPTION='foo'

View File

@ -358,6 +358,12 @@ cl::opt<std::string> objdump::Prefix("prefix",
cl::desc("Add prefix to absolute paths"),
cl::cat(ObjdumpCat));
cl::opt<uint32_t>
objdump::PrefixStrip("prefix-strip",
cl::desc("Strip out initial directories from absolute "
"paths. No effect without --prefix"),
cl::init(0), cl::cat(ObjdumpCat));
enum DebugVarsFormat {
DVDisabled,
DVUnicode,
@ -1031,6 +1037,27 @@ void SourcePrinter::printSourceLine(formatted_raw_ostream &OS,
}
if (!Prefix.empty() && sys::path::is_absolute_gnu(LineInfo.FileName)) {
// FileName has at least one character since is_absolute_gnu is false for
// an empty string.
assert(!LineInfo.FileName.empty());
if (PrefixStrip > 0) {
uint32_t Level = 0;
auto StrippedNameStart = LineInfo.FileName.begin();
// Path.h iterator skips extra separators. Therefore it cannot be used
// here to keep compatibility with GNU Objdump.
for (auto Pos = StrippedNameStart + 1, End = LineInfo.FileName.end();
Pos != End && Level < PrefixStrip; ++Pos) {
if (sys::path::is_separator(*Pos)) {
StrippedNameStart = Pos;
++Level;
}
}
LineInfo.FileName =
std::string(StrippedNameStart, LineInfo.FileName.end());
}
SmallString<128> FilePath;
sys::path::append(FilePath, Prefix, LineInfo.FileName);

View File

@ -42,6 +42,7 @@ extern cl::opt<std::string> MCPU;
extern cl::opt<bool> NoShowRawInsn;
extern cl::opt<bool> NoLeadingAddr;
extern cl::opt<std::string> Prefix;
extern cl::opt<uint32_t> PrefixStrip;
extern cl::opt<bool> PrintImmHex;
extern cl::opt<bool> PrivateHeaders;
extern cl::opt<bool> Relocations;