Skip to content

Commit da34ce4

Browse files
committed
[llvm-dwp] Add a new flag --exec-dwo-path-remapping-file=<filename> that allows remapping the dwo paths embedded in executables and libraries.
1 parent 253d18d commit da34ce4

File tree

3 files changed

+176
-2
lines changed

3 files changed

+176
-2
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Test remapping old DWO paths in the executables and libraries to new paths.
2+
3+
RUN: rm -rf %t
4+
RUN: mkdir %t
5+
RUN: cd %t
6+
7+
RUN: cp %p/../Inputs/dwos_list_from_exec/main main
8+
RUN: cp %p/../Inputs/dwos_list_from_exec/libd.so libd.so
9+
10+
// Test remapping full DWO paths (<DW_AT_comp_dir>/<DW_AT_dwo_name>) to absolute paths
11+
RUN: touch remapping_path_to_absolute.txt
12+
RUN: echo "./a.dwo %p/../Inputs/dwos_list_from_exec/a.dwo" >> remapping_path_to_absolute.txt
13+
RUN: echo "./b.dwo %p/../Inputs/dwos_list_from_exec/b.dwo" >> remapping_path_to_absolute.txt
14+
RUN: echo "./d.dwo %p/../Inputs/dwos_list_from_exec/d.dwo" >> remapping_path_to_absolute.txt
15+
RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \
16+
RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_path_to_absolute.txt -o - | llvm-dwarfdump -v - | FileCheck %s
17+
18+
// Test remapping full DWO paths (<DW_AT_comp_dir>/<DW_AT_dwo_name>) to relative paths
19+
RUN: mkdir foo && cp %p/../Inputs/dwos_list_from_exec/a.dwo foo/a.dwo
20+
RUN: mkdir bar && cp %p/../Inputs/dwos_list_from_exec/b.dwo bar/b.dwo
21+
RUN: mkdir qux && cp %p/../Inputs/dwos_list_from_exec/d.dwo qux/d.dwo
22+
RUN: touch remapping_path_to_relative.txt
23+
RUN: echo "./a.dwo foo/a.dwo" >> remapping_path_to_relative.txt
24+
RUN: echo "./b.dwo bar/b.dwo" >> remapping_path_to_relative.txt
25+
RUN: echo "./d.dwo qux/d.dwo" >> remapping_path_to_relative.txt
26+
RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \
27+
RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_path_to_relative.txt -o - | llvm-dwarfdump -v - | FileCheck %s
28+
29+
// Test remapping DWO name (<DW_AT_dwo_name>) to relative paths
30+
RUN: touch remapping_name_to_relative.txt
31+
RUN: echo "a.dwo foo/a.dwo" >> remapping_name_to_relative.txt
32+
RUN: echo "b.dwo bar/b.dwo" >> remapping_name_to_relative.txt
33+
RUN: echo "d.dwo qux/d.dwo" >> remapping_name_to_relative.txt
34+
RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \
35+
RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_name_to_relative.txt -o - | llvm-dwarfdump -v - | FileCheck %s
36+
37+
// Test remapping with multiple files
38+
RUN: touch remapping_main.txt
39+
RUN: echo "./a.dwo %p/../Inputs/dwos_list_from_exec/a.dwo" >> remapping_main.txt
40+
RUN: echo "./b.dwo %p/../Inputs/dwos_list_from_exec/b.dwo" >> remapping_main.txt
41+
RUN: echo "./d.dwo %p/../Inputs/dwos_list_from_exec/d.dwo" > remapping_libd.txt
42+
RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \
43+
RUN: -e main -e libd.so \
44+
RUN: --exec-dwo-path-remapping-file=remapping_main.txt \
45+
RUN: --exec-dwo-path-remapping-file=remapping_libd.txt \
46+
RUN: -o - | llvm-dwarfdump -v - | FileCheck %s
47+
48+
Build commands for the test binaries:
49+
50+
clang++ -Xclang -fdebug-compilation-dir -Xclang "./" -g -O0 -gsplit-dwarf a.cpp b.cpp -o main
51+
clang++ -g -O0 -gsplit-dwarf -c c.cpp -o c.o
52+
clang++ -Xclang -fdebug-compilation-dir -Xclang "./" -g -O0 -gsplit-dwarf -fPIC -shared d.cpp -o libd.so
53+
clang++ -g -O0 -gsplit-dwarf -c e.cpp -o e.o
54+
55+
sources:
56+
a.cpp:
57+
void a() {}
58+
59+
b.cpp:
60+
void b() {}
61+
int main() {
62+
return 0;
63+
}
64+
65+
c.cpp:
66+
void c() {}
67+
68+
d.cpp:
69+
void d() {}
70+
71+
e.cpp:
72+
void e() {}
73+
74+
CHECK-LABEL: .debug_abbrev.dwo contents:
75+
76+
CHECK-LABEL: Abbrev table for offset:
77+
CHECK: DW_TAG_compile_unit
78+
CHECK: DW_TAG_subprogram
79+
80+
CHECK-LABEL: Abbrev table for offset:
81+
CHECK: DW_TAG_compile_unit
82+
CHECK: DW_TAG_subprogram
83+
84+
CHECK-LABEL: Abbrev table for offset:
85+
CHECK: DW_TAG_compile_unit
86+
CHECK: DW_TAG_subprogram
87+
88+
CHECK-LABEL: Abbrev table for offset:
89+
CHECK: DW_TAG_compile_unit
90+
CHECK: DW_TAG_subprogram
91+
92+
CHECK-LABEL: Abbrev table for offset:
93+
CHECK: DW_TAG_compile_unit
94+
CHECK: DW_TAG_subprogram
95+
96+
CHECK: .debug_info.dwo contents:
97+
CHECK: [[AOFF:0x[0-9a-f]*]]:
98+
99+
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004
100+
CHECK: DW_TAG_compile_unit
101+
CHECK: DW_AT_name {{.*}} "c.cpp"
102+
CHECK: DW_TAG_subprogram
103+
CHECK: DW_AT_name {{.*}} "c"
104+
105+
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004
106+
CHECK: DW_TAG_compile_unit
107+
CHECK: DW_AT_name {{.*}} "e.cpp"
108+
CHECK: DW_TAG_subprogram
109+
CHECK: DW_AT_name {{.*}} "e"
110+
111+
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004
112+
CHECK: DW_TAG_compile_unit
113+
CHECK: DW_AT_name {{.*}} "a.cpp"
114+
CHECK: DW_TAG_subprogram
115+
CHECK: DW_AT_name {{.*}} "a"
116+
117+
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004
118+
CHECK: DW_TAG_compile_unit
119+
CHECK: DW_AT_name {{.*}} "b.cpp"
120+
CHECK: DW_TAG_subprogram
121+
CHECK: DW_AT_name {{.*}} "b"
122+
CHECK: DW_TAG_subprogram
123+
CHECK: DW_AT_name {{.*}} "main"
124+
125+
CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004
126+
CHECK: DW_TAG_compile_unit
127+
CHECK: DW_AT_name {{.*}} "d.cpp"
128+
CHECK: DW_TAG_subprogram
129+
CHECK: DW_AT_name {{.*}} "d"

llvm/tools/llvm-dwp/Opts.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ def continueOnCuIndexOverflow_EQ : Joined<["-", "--"], "continue-on-cu-index-ove
1616
"\t\ttruncated but valid DWP file, discarding any DWO files that would not fit within \n"
1717
"\t\tthe 32 bit/4GB limits of the format.">,
1818
Values<"continue,soft-stop">;
19+
def execDwoPathRemappingFile : Joined<["--"], "exec-dwo-path-remapping-file=">, MetaVarName<"<filename>">,
20+
HelpText<"Use the old and new paths described in <filename> to map old dwo paths in executables/libraries to the new paths.">;

llvm/tools/llvm-dwp/llvm-dwp.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// package files).
1111
//
1212
//===----------------------------------------------------------------------===//
13+
#include "llvm/ADT/StringMap.h"
1314
#include "llvm/DWP/DWP.h"
1415
#include "llvm/DWP/DWPError.h"
1516
#include "llvm/DWP/DWPStringPool.h"
@@ -75,7 +76,8 @@ static std::string OutputFilename;
7576
static std::string ContinueOption;
7677

7778
static Expected<SmallVector<std::string, 16>>
78-
getDWOFilenames(StringRef ExecFilename) {
79+
getDWOFilenames(StringRef ExecFilename,
80+
const StringMap<StringRef> &DWOPathMap) {
7981
auto ErrOrObj = object::ObjectFile::createObjectFile(ExecFilename);
8082
if (!ErrOrObj)
8183
return ErrOrObj.takeError();
@@ -95,11 +97,17 @@ getDWOFilenames(StringRef ExecFilename) {
9597
if (!DWOCompDir.empty()) {
9698
SmallString<16> DWOPath(DWOName);
9799
sys::fs::make_absolute(DWOCompDir, DWOPath);
100+
if (auto I = DWOPathMap.find(DWOPath); I != DWOPathMap.end())
101+
DWOPath = I->getValue();
102+
if (auto I = DWOPathMap.find(DWOName); I != DWOPathMap.end())
103+
DWOName = I->getValue();
98104
if (!sys::fs::exists(DWOPath) && sys::fs::exists(DWOName))
99105
DWOPaths.push_back(std::move(DWOName));
100106
else
101107
DWOPaths.emplace_back(DWOPath.data(), DWOPath.size());
102108
} else {
109+
if (auto I = DWOPathMap.find(DWOName); I != DWOPathMap.end())
110+
DWOName = I->getValue();
103111
DWOPaths.push_back(std::move(DWOName));
104112
}
105113
}
@@ -120,6 +128,33 @@ static Expected<Triple> readTargetTriple(StringRef FileName) {
120128
return ErrOrObj->getBinary()->makeTriple();
121129
}
122130

131+
static Error addPathsToRemapFromFile(StringMap<StringRef> &DWOPathMap,
132+
BumpPtrAllocator &Alloc,
133+
StringRef Filename) {
134+
StringSaver Saver(Alloc);
135+
SmallVector<StringRef, 16> Lines;
136+
auto BufOrErr = MemoryBuffer::getFile(Filename);
137+
if (!BufOrErr)
138+
return createFileError(Filename, BufOrErr.getError());
139+
140+
BufOrErr.get()->getBuffer().split(Lines, '\n');
141+
for (size_t LineNo = 0, NumLines = Lines.size(); LineNo < NumLines;
142+
++LineNo) {
143+
StringRef TrimmedLine = Lines[LineNo].split('#').first.trim();
144+
if (TrimmedLine.empty())
145+
continue;
146+
147+
std::pair<StringRef, StringRef> Pair = Saver.save(TrimmedLine).split(' ');
148+
StringRef NewName = Pair.second.trim();
149+
if (NewName.empty())
150+
return createStringError(errc::invalid_argument,
151+
"%s:%zu: missing new DWO path",
152+
Filename.str().c_str(), LineNo + 1);
153+
DWOPathMap.insert({Pair.first, NewName});
154+
}
155+
return Error::success();
156+
}
157+
123158
int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
124159
DwpOptTable Tbl;
125160
llvm::BumpPtrAllocator A;
@@ -173,8 +208,16 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
173208
llvm::InitializeAllTargets();
174209
llvm::InitializeAllAsmPrinters();
175210

211+
llvm::StringMap<StringRef> DWOPathMap;
212+
for (auto *Arg : Args.filtered(OPT_execDwoPathRemappingFile)) {
213+
if (Error E = addPathsToRemapFromFile(DWOPathMap, A, Arg->getValue())) {
214+
logAllUnhandledErrors(std::move(E), WithColor::error());
215+
return 1;
216+
}
217+
}
218+
176219
for (const auto &ExecFilename : ExecFilenames) {
177-
auto DWOs = getDWOFilenames(ExecFilename);
220+
auto DWOs = getDWOFilenames(ExecFilename, DWOPathMap);
178221
if (!DWOs) {
179222
logAllUnhandledErrors(
180223
handleErrors(DWOs.takeError(),

0 commit comments

Comments
 (0)