Skip to content

Commit 647f3cb

Browse files
author
git apple-llvm automerger
committed
Merge commit '1ee18f275e60' from llvm.org/master into apple/master
2 parents 7bb2b47 + 1ee18f2 commit 647f3cb

24 files changed

+233
-1
lines changed

llvm/test/tools/dsymutil/Inputs/basic1.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
Archive compilation (after basic compilation):
2020
ar -q libbasic.a basic2.macho.x86_64.o basic3.macho.x86_64.o
2121
clang basic1.macho.x86_64.o -lbasic -o basic-archive.macho.x86_64 -Wl,-dead_strip -L.
22+
23+
Remarks compilation:
24+
for FILE in basic1.c basic2.c basic3.c; do
25+
clang -gline-tables-only -c $FILE -fsave-optimization-record=bitstream -foptimization-remarks-file=/tmp/${FILE%.c}.macho.remarks.x86_64.opt.bitstream -mllvm -remarks-section -o ${FILE%.c}.macho.remarks.x86_64.o
26+
done
27+
clang basic1.macho.remarks.x86_64.o basic2.macho.remarks.x86_64.o basic3.macho.remarks.x86_64.o -o basic.macho.remarks.x86_64 -Wl,-dead_strip
28+
2229
*/
2330

2431
int foo(int);
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* This file was used to generate:
2+
* - fat.macho.remarks.x86.o
3+
* - fat.macho.remarks.x86.opt.bitstream
4+
* - fat.macho.remarks.x86
5+
*/
6+
7+
/* for ARCH in x86_64 x86_64h i386
8+
* do
9+
* clang -gline-tables-only -c fat.macho.remarks.x86.c -fsave-optimization-record=bitstream -foptimization-record-file=fat.macho.remarks."$ARCH".opt.bitstream -mllvm -remarks-section -arch "$ARCH"
10+
* done
11+
* lipo -create -output fat.macho.remarks.x86.o fat.macho.remarks.x86_64.o fat.macho.remarks.x86_64h.o fat.macho.remarks.i386.o
12+
* clang -gline-tables-only fat.macho.remarks.x86.o -arch x86_64 -arch x86_64h -arch i386 -o fat.macho.remarks.x86
13+
*/
14+
int main(void) { return 0; }
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

llvm/test/tools/dsymutil/X86/basic-linking-bundle.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ RUN: dsymutil -oso-prepend-path=%p/.. %t/basic.macho.x86_64
77
Check that the object file in the bundle exists and is sane:
88
RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test
99

10+
Check that we don't create an empty Remarks directory if there are no remarks.
11+
RUN: not ls %t/basic.macho.x86_64.dSYM/Contents/Resources/Remarks
12+
1013
Check that llvm-dwarfdump -a recognizes the bundle as a dSYM:
1114
RUN: llvm-dwarfdump -a %t/basic.macho.x86_64.dSYM | FileCheck %S/basic-linking-x86.test
1215

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
RUN: rm -rf %t
2+
RUN: mkdir -p %t
3+
RUN: cat %p/../Inputs/remarks/basic.macho.remarks.x86_64 > %t/basic.macho.remarks.x86_64
4+
5+
RUN: dsymutil -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.x86_64
6+
7+
Check that the remark file in the bundle exists and is sane:
8+
RUN: llvm-bcanalyzer %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s
9+
10+
Now emit it in a different format: YAML.
11+
RUN: dsymutil -remarks-output-format=yaml -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/basic.macho.remarks.x86_64
12+
RUN: cat %t/basic.macho.remarks.x86_64.dSYM/Contents/Resources/Remarks/basic.macho.remarks.x86_64 | FileCheck %s --check-prefix=CHECK-YAML
13+
14+
CHECK: <Meta
15+
CHECK: <Remark Num
16+
CHECK: <Remark Num
17+
CHECK: <Remark Num
18+
CHECK: <Remark Num
19+
CHECK: <Remark Num
20+
CHECK: <Remark Num
21+
CHECK: <Remark Num
22+
CHECK: <Remark Num
23+
CHECK: <Remark Num
24+
CHECK: <Remark Num
25+
CHECK: <Remark Num
26+
CHECK: <Remark Num
27+
CHECK: <Remark Num
28+
CHECK: <Remark Num
29+
CHECK: <Remark Num
30+
CHECK: <Remark Num
31+
CHECK: <Remark Num
32+
CHECK: <Remark Num
33+
CHECK: <Remark Num
34+
CHECK: <Remark Num
35+
CHECK: <Remark Num
36+
CHECK-NOT: <Remark Num
37+
38+
CHECK-YAML:--- !Missed
39+
CHECK-YAML:--- !Missed
40+
CHECK-YAML:--- !Missed
41+
CHECK-YAML:--- !Missed
42+
CHECK-YAML:--- !Missed
43+
CHECK-YAML:--- !Missed
44+
CHECK-YAML:--- !Missed
45+
CHECK-YAML:--- !Analysis
46+
CHECK-YAML:--- !Analysis
47+
CHECK-YAML:--- !Analysis
48+
CHECK-YAML:--- !Analysis
49+
CHECK-YAML:--- !Analysis
50+
CHECK-YAML:--- !Analysis
51+
CHECK-YAML:--- !Analysis
52+
CHECK-YAML:--- !Analysis
53+
CHECK-YAML:--- !Analysis
54+
CHECK-YAML:--- !Analysis
55+
CHECK-YAML:--- !Analysis
56+
CHECK-YAML:--- !Analysis
57+
CHECK-YAML:--- !Analysis
58+
CHECK-YAML:--- !Analysis
59+
CHECK-NOT: --- !
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
RUN: rm -rf %t
2+
RUN: mkdir -p %t
3+
RUN: cat %p/../Inputs/remarks/fat.macho.remarks.x86 > %t/fat.macho.remarks.x86
4+
5+
RUN: dsymutil -oso-prepend-path=%p/../Inputs -remarks-prepend-path=%p/../Inputs %t/fat.macho.remarks.x86
6+
7+
Check that the remark files in the bundle exist and are all sane:
8+
RUN: llvm-bcanalyzer %t/fat.macho.remarks.x86.dSYM/Contents/Resources/Remarks/fat.macho.remarks.x86-x86_64h | FileCheck %s
9+
RUN: llvm-bcanalyzer %t/fat.macho.remarks.x86.dSYM/Contents/Resources/Remarks/fat.macho.remarks.x86-x86_64 | FileCheck %s
10+
RUN: llvm-bcanalyzer %t/fat.macho.remarks.x86.dSYM/Contents/Resources/Remarks/fat.macho.remarks.x86-i386 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-i386
11+
12+
CHECK: <Meta
13+
CHECK: <Remark Num
14+
CHECK: <Remark Num
15+
CHECK-i386: <Remark Num
16+
CHECK-NOT: <Remark Num

llvm/test/tools/dsymutil/cmdline.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ HELP: -num-threads <threads>
1515
HELP: -oso-prepend-path <path>
1616
HELP: -o <filename>
1717
HELP: -papertrail
18+
HELP: -remarks-output-format <format>
19+
HELP: -remarks-prepend-path <path>
1820
HELP: -symbol-map
1921
HELP: -symtab
2022
HELP: -toolchain

llvm/tools/dsymutil/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(LLVM_LINK_COMPONENTS
1212
MC
1313
Object
1414
Option
15+
Remarks
1516
Support
1617
Target
1718
)

llvm/tools/dsymutil/DwarfLinker.cpp

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
#include "llvm/Object/MachO.h"
6464
#include "llvm/Object/ObjectFile.h"
6565
#include "llvm/Object/SymbolicFile.h"
66+
#include "llvm/Remarks/RemarkFormat.h"
67+
#include "llvm/Remarks/RemarkLinker.h"
6668
#include "llvm/Support/Allocator.h"
6769
#include "llvm/Support/Casting.h"
6870
#include "llvm/Support/Compiler.h"
@@ -2540,6 +2542,42 @@ static Error copySwiftInterfaces(
25402542
return Error::success();
25412543
}
25422544

2545+
static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
2546+
StringRef ArchName,
2547+
const remarks::RemarkLinker &RL) {
2548+
// Make sure we don't create the directories and the file if there is nothing
2549+
// to serialize.
2550+
if (RL.empty())
2551+
return Error::success();
2552+
2553+
SmallString<128> InputPath;
2554+
SmallString<128> Path;
2555+
// Create the "Remarks" directory in the "Resources" directory.
2556+
sys::path::append(Path, *Options.ResourceDir, "Remarks");
2557+
if (std::error_code EC = sys::fs::create_directories(Path.str(), true,
2558+
sys::fs::perms::all_all))
2559+
return errorCodeToError(EC);
2560+
2561+
// Append the file name.
2562+
// For fat binaries, also append a dash and the architecture name.
2563+
sys::path::append(Path, sys::path::filename(BinaryPath));
2564+
if (Options.NumDebugMaps > 1) {
2565+
// More than one debug map means we have a fat binary.
2566+
Path += '-';
2567+
Path += ArchName;
2568+
}
2569+
2570+
std::error_code EC;
2571+
raw_fd_ostream OS(Options.NoOutput ? "-" : Path.str(), EC, sys::fs::OF_None);
2572+
if (EC)
2573+
return errorCodeToError(EC);
2574+
2575+
if (Error E = RL.serialize(OS, Options.RemarksFormat))
2576+
return E;
2577+
2578+
return Error::success();
2579+
}
2580+
25432581
bool DwarfLinker::link(const DebugMap &Map) {
25442582
if (!createStreamer(Map.getTriple(), OutFile))
25452583
return false;
@@ -2803,6 +2841,18 @@ bool DwarfLinker::link(const DebugMap &Map) {
28032841
}
28042842
};
28052843

2844+
remarks::RemarkLinker RL;
2845+
if (!Options.RemarksPrependPath.empty())
2846+
RL.setExternalFilePrependPath(Options.RemarksPrependPath);
2847+
auto RemarkLinkLambda = [&](size_t i) {
2848+
// Link remarks from one object file.
2849+
auto &LinkContext = ObjectContexts[i];
2850+
if (const object::ObjectFile *Obj = LinkContext.ObjectFile)
2851+
if (Error E = RL.link(*Obj))
2852+
return E;
2853+
return Error(Error::success());
2854+
};
2855+
28062856
auto AnalyzeAll = [&]() {
28072857
for (unsigned i = 0, e = NumObjects; i != e; ++i) {
28082858
AnalyzeLambda(i);
@@ -2828,20 +2878,56 @@ bool DwarfLinker::link(const DebugMap &Map) {
28282878
EmitLambda();
28292879
};
28302880

2881+
auto EmitRemarksLambda = [&]() {
2882+
StringRef ArchName = Map.getTriple().getArchName();
2883+
return emitRemarks(Options, Map.getBinaryPath(), ArchName, RL);
2884+
};
2885+
2886+
// Instead of making error handling a lot more complicated using futures,
2887+
// write to one llvm::Error instance if something went wrong.
2888+
// We're assuming RemarkLinkAllError is alive longer than the thread
2889+
// executing RemarkLinkAll.
2890+
auto RemarkLinkAll = [&](Error &RemarkLinkAllError) {
2891+
// Allow assigning to the error only within the lambda.
2892+
ErrorAsOutParameter EAO(&RemarkLinkAllError);
2893+
for (unsigned i = 0, e = NumObjects; i != e; ++i)
2894+
if ((RemarkLinkAllError = RemarkLinkLambda(i)))
2895+
return;
2896+
2897+
if ((RemarkLinkAllError = EmitRemarksLambda()))
2898+
return;
2899+
};
2900+
28312901
// To limit memory usage in the single threaded case, analyze and clone are
28322902
// run sequentially so the LinkContext is freed after processing each object
28332903
// in endDebugObject.
28342904
if (Options.Threads == 1) {
28352905
for (unsigned i = 0, e = NumObjects; i != e; ++i) {
28362906
AnalyzeLambda(i);
28372907
CloneLambda(i);
2908+
2909+
if (Error E = RemarkLinkLambda(i))
2910+
return error(toString(std::move(E)));
28382911
}
28392912
EmitLambda();
2913+
2914+
if (Error E = EmitRemarksLambda())
2915+
return error(toString(std::move(E)));
2916+
28402917
} else {
2841-
ThreadPool pool(2);
2918+
// This should not be constructed on the single-threaded path to avoid fatal
2919+
// errors from unchecked llvm::Error objects.
2920+
Error RemarkLinkAllError = Error::success();
2921+
2922+
ThreadPool pool(3);
28422923
pool.async(AnalyzeAll);
28432924
pool.async(CloneAll);
2925+
pool.async(RemarkLinkAll, std::ref(RemarkLinkAllError));
28442926
pool.wait();
2927+
2928+
// Report errors from RemarkLinkAll, if any.
2929+
if (Error E = std::move(RemarkLinkAllError))
2930+
return error(toString(std::move(E)));
28452931
}
28462932

28472933
if (Options.NoOutput)

llvm/tools/dsymutil/LinkUtils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "SymbolMap.h"
1313

1414
#include "llvm/ADT/Twine.h"
15+
#include "llvm/Remarks/RemarkFormat.h"
1516
#include "llvm/Support/WithColor.h"
1617

1718
#include <string>
@@ -68,6 +69,21 @@ struct LinkOptions {
6869
/// Symbol map translator.
6970
SymbolMapTranslator Translator;
7071

72+
/// Fields used for linking and placing remarks into the .dSYM bundle.
73+
/// @{
74+
75+
/// Number of debug maps processed in total.
76+
unsigned NumDebugMaps = 0;
77+
78+
/// -remarks-prepend-path: prepend a path to all the external remark file
79+
/// paths found in remark metadata.
80+
std::string RemarksPrependPath;
81+
82+
/// The output format of the remarks.
83+
remarks::Format RemarksFormat = remarks::Format::Bitstream;
84+
85+
/// @}
86+
7187
LinkOptions() = default;
7288
};
7389

llvm/tools/dsymutil/Options.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,15 @@ def: Separate<["-"], "j">,
144144
Alias<threads>,
145145
HelpText<"Alias for --num-threads">,
146146
Group<grp_general>;
147+
148+
def remarks_prepend_path: Separate<["--", "-"], "remarks-prepend-path">,
149+
MetaVarName<"<path>">,
150+
HelpText<"Specify a directory to prepend to the paths of the external remark files.">,
151+
Group<grp_general>;
152+
def: Joined<["--", "-"], "remarks-prepend-path=">, Alias<remarks_prepend_path>;
153+
154+
def remarks_output_format: Separate<["--", "-"], "remarks-output-format">,
155+
MetaVarName<"<format>">,
156+
HelpText<"Specify the format to be used when serializing the linked remarks.">,
157+
Group<grp_general>;
158+
def: Joined<["--", "-"], "remarks-output-format=">, Alias<remarks_output_format>;

llvm/tools/dsymutil/dsymutil.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,18 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
266266
if (getenv("RC_DEBUG_OPTIONS"))
267267
Options.PaperTrailWarnings = true;
268268

269+
if (opt::Arg *RemarksPrependPath = Args.getLastArg(OPT_remarks_prepend_path))
270+
Options.LinkOpts.RemarksPrependPath = RemarksPrependPath->getValue();
271+
272+
if (opt::Arg *RemarksOutputFormat =
273+
Args.getLastArg(OPT_remarks_output_format)) {
274+
if (Expected<remarks::Format> FormatOrErr =
275+
remarks::parseFormat(RemarksOutputFormat->getValue()))
276+
Options.LinkOpts.RemarksFormat = *FormatOrErr;
277+
else
278+
return FormatOrErr.takeError();
279+
}
280+
269281
if (Error E = verifyOptions(Options))
270282
return std::move(E);
271283
return Options;
@@ -507,6 +519,10 @@ int main(int argc, char **argv) {
507519
return 1;
508520
}
509521

522+
// Remember the number of debug maps that are being processed to decide how
523+
// to name the remark files.
524+
Options.LinkOpts.NumDebugMaps = DebugMapPtrsOrErr->size();
525+
510526
if (Options.LinkOpts.Update) {
511527
// The debug map should be empty. Add one object file corresponding to
512528
// the input file.

0 commit comments

Comments
 (0)