Index: llvm/docs/CommandGuide/llvm-objdump.rst =================================================================== --- llvm/docs/CommandGuide/llvm-objdump.rst +++ llvm/docs/CommandGuide/llvm-objdump.rst @@ -172,6 +172,12 @@ When disassembling with the :option:`--source` option, prepend ``prefix`` to absolute paths. +.. option:: --prefix-strip= + + When disassembling with the :option:`--source` option, strip out ``level`` + initial directories from absolute paths. It has no effect without + :option:`--prefix`. + .. option:: --print-imm-hex Use hex format when printing immediate values in disassembly output. Index: llvm/docs/llvm-objdump.1 =================================================================== --- llvm/docs/llvm-objdump.1 +++ llvm/docs/llvm-objdump.1 @@ -109,6 +109,11 @@ 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. It has no effect without +.Fl -prefix Ns = Ns PREFIX . .It Fl -print-imm-hex Use hex format for immediate values. .It Fl -private-header Index: llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test =================================================================== --- llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test +++ llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test @@ -41,3 +41,11 @@ ; 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 +;; Test invalid source interleave fixed by adding the correct prefix and +;; stripping out an extra directory in 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 + Index: llvm/tools/llvm-objdump/llvm-objdump.h =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.h +++ llvm/tools/llvm-objdump/llvm-objdump.h @@ -42,6 +42,7 @@ extern cl::opt NoShowRawInsn; extern cl::opt NoLeadingAddr; extern cl::opt Prefix; +extern cl::opt PrefixStrip; extern cl::opt PrintImmHex; extern cl::opt PrivateHeaders; extern cl::opt Relocations; Index: llvm/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -358,6 +358,12 @@ cl::desc("Add prefix to absolute paths"), cl::cat(ObjdumpCat)); +cl::opt + objdump::PrefixStrip("prefix-strip", + cl::desc("Strip out initial directories from absolute " + "paths. It has no effect without --prefix"), + cl::init(0), cl::cat(ObjdumpCat)); + enum DebugVarsFormat { DVDisabled, DVUnicode, @@ -1031,6 +1037,23 @@ } if (!Prefix.empty() && sys::path::is_absolute_gnu(LineInfo.FileName)) { + if (PrefixStrip > 0) { + int Level = 0; + const char *FileName = LineInfo.FileName.c_str(); + + // FileName has at least one character since is_absolute_gnu is false + // for an empty string. + for (const char *S = FileName + 1; *S != '\0' && Level < PrefixStrip; + ++S) { + if (sys::path::is_separator(*S)) { + FileName = S; + ++Level; + } + } + + LineInfo.FileName = std::string(FileName); + } + SmallString<128> FilePath; sys::path::append(FilePath, Prefix, LineInfo.FileName); @@ -2970,6 +2993,9 @@ if (StartAddress >= StopAddress) reportCmdLineError("start address should be less than stop address"); + if (PrefixStrip < 0) + reportCmdLineError("prefix strip must be non-negative"); + ToolName = argv[0]; // Defaults to a.out if no filenames specified.