Skip to content

Commit c758592

Browse files
authored
[dsymutil] Add support for code signing dSYM bundles (#190676)
This PR adds support for code signing the dSYM bundle using the `codesign` command line utility.
1 parent 83dfe3d commit c758592

5 files changed

Lines changed: 84 additions & 0 deletions

File tree

llvm/docs/CommandGuide/dsymutil.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ OPTIONS
4646
'profile'. Setting the DYLD_IMAGE_SUFFIX environment variable will
4747
cause dyld to load the specified variant at runtime.
4848

49+
.. option:: --codesign <identity>
50+
51+
Code sign the dSYM bundle with the given signing identity after linking.
52+
Cannot be used with :option:`--flat` or :option:`--no-output`.
53+
4954
.. option:: --disallow <path>
5055

5156
Exclude debug map objects listed in the YAML file at <path>. Only filters

llvm/test/tools/dsymutil/cmdline.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHECK: -accelerator
99
CHECK: -allow <path>
1010
CHECK: -arch <arch>
1111
CHECK: -build-variant-suffix <suffix=buildvariant>
12+
CHECK: -codesign <identity>
1213
CHECK: -disallow <path>
1314
CHECK: -dump-debug-map
1415
CHECK: -D <path>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
REQUIRES: system-darwin, x86-registered-target
2+
3+
## Verify --codesign signs the dSYM bundle.
4+
RUN: dsymutil -oso-prepend-path %p %p/Inputs/basic.macho.x86_64 -o %t.dSYM --codesign=-
5+
RUN: codesign -v %t.dSYM
6+
7+
## Verify --codesign is incompatible with --flat.
8+
RUN: not dsymutil -oso-prepend-path %p %p/Inputs/basic.macho.x86_64 -o %t.flat --flat --codesign=- 2>&1 \
9+
RUN: | FileCheck %s --check-prefix=FLAT
10+
FLAT: error: --codesign is not supported with --flat: no bundle to sign
11+
12+
## Verify --codesign is incompatible with --no-output.
13+
RUN: not dsymutil -oso-prepend-path %p %p/Inputs/basic.macho.x86_64 --no-output --codesign=- 2>&1 \
14+
RUN: | FileCheck %s --check-prefix=NOOUT
15+
NOOUT: error: --codesign is not supported with --no-output: nothing to sign

llvm/tools/dsymutil/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ def disallow: Separate<["--", "-"], "disallow">,
256256
Group<grp_general>;
257257
def: Joined<["--", "-"], "disallow=">, Alias<disallow>;
258258

259+
def codesign: Separate<["--", "-"], "codesign">,
260+
MetaVarName<"<identity>">,
261+
HelpText<"Code sign the dSYM bundle with the given signing identity after linking.">,
262+
Group<grp_general>;
263+
def: Joined<["--", "-"], "codesign=">, Alias<codesign>;
264+
259265
def dsym_search_path: Separate<["-", "--"], "D">,
260266
MetaVarName<"<path>">,
261267
HelpText<"Specify a directory that contain dSYM files to search for.">,

llvm/tools/dsymutil/dsymutil.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/Support/LLVMDriver.h"
4242
#include "llvm/Support/MemoryBuffer.h"
4343
#include "llvm/Support/Path.h"
44+
#include "llvm/Support/Program.h"
4445
#include "llvm/Support/TargetSelect.h"
4546
#include "llvm/Support/ThreadPool.h"
4647
#include "llvm/Support/WithColor.h"
@@ -116,6 +117,7 @@ struct DsymutilOptions {
116117
bool NoObjectTimestamp = false;
117118
std::string OutputFile;
118119
std::string Toolchain;
120+
std::string CodesignIdentity;
119121
std::string ReproducerPath;
120122
std::string AllowFile;
121123
std::string DisallowFile;
@@ -221,6 +223,16 @@ static Error verifyOptions(const DsymutilOptions &Options) {
221223
"--embed-resource is not supported with --flat",
222224
errc::invalid_argument);
223225

226+
if (!Options.CodesignIdentity.empty() && Options.Flat)
227+
return make_error<StringError>(
228+
"--codesign is not supported with --flat: no bundle to sign",
229+
errc::invalid_argument);
230+
231+
if (!Options.CodesignIdentity.empty() && Options.LinkOpts.NoOutput)
232+
return make_error<StringError>(
233+
"--codesign is not supported with --no-output: nothing to sign",
234+
errc::invalid_argument);
235+
224236
return Error::success();
225237
}
226238

@@ -388,6 +400,9 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
388400
if (opt::Arg *Toolchain = Args.getLastArg(OPT_toolchain))
389401
Options.Toolchain = Toolchain->getValue();
390402

403+
if (opt::Arg *Codesign = Args.getLastArg(OPT_codesign))
404+
Options.CodesignIdentity = Codesign->getValue();
405+
391406
if (Args.hasArg(OPT_assembly))
392407
Options.LinkOpts.FileType = DWARFLinkerBase::OutputFileType::Assembly;
393408

@@ -657,6 +672,33 @@ getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) {
657672
return OutputLocation(std::string(Path), ResourceDir);
658673
}
659674

675+
static Error codesignBundle(StringRef BundlePath, StringRef Identity,
676+
StringRef SDKPath) {
677+
auto Path = sys::findProgramByName("codesign", ArrayRef(SDKPath));
678+
if (!Path)
679+
Path = sys::findProgramByName("codesign");
680+
681+
if (!Path)
682+
return make_error<StringError>(
683+
"codesign not found: " + Path.getError().message(), Path.getError());
684+
685+
SmallVector<StringRef, 5> Args;
686+
Args.push_back("codesign");
687+
Args.push_back("-f");
688+
Args.push_back("-s");
689+
Args.push_back(Identity);
690+
Args.push_back(BundlePath);
691+
692+
std::string ErrMsg;
693+
int Result =
694+
sys::ExecuteAndWait(*Path, Args, std::nullopt, {}, 0, 0, &ErrMsg);
695+
if (Result)
696+
return make_error<StringError>("codesign failed: " + ErrMsg,
697+
inconvertibleErrorCode());
698+
699+
return Error::success();
700+
}
701+
660702
int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
661703
// Parse arguments.
662704
DsymutilOptTable T;
@@ -985,6 +1027,21 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
9851027
SDKPath, Fat64))
9861028
return EXIT_FAILURE;
9871029
}
1030+
1031+
if (!Options.CodesignIdentity.empty()) {
1032+
StringRef DWARFFile = OutputLocationOrErr->DWARFFile;
1033+
auto Pos = DWARFFile.find(".dSYM/");
1034+
if (Pos == StringRef::npos)
1035+
Pos = DWARFFile.find(".dSYM");
1036+
if (Pos != StringRef::npos) {
1037+
std::string BundlePath = DWARFFile.substr(0, Pos + 5).str();
1038+
if (auto E =
1039+
codesignBundle(BundlePath, Options.CodesignIdentity, SDKPath)) {
1040+
WithColor::error() << toString(std::move(E)) << '\n';
1041+
return EXIT_FAILURE;
1042+
}
1043+
}
1044+
}
9881045
}
9891046

9901047
return EXIT_SUCCESS;

0 commit comments

Comments
 (0)