llvm.org GIT mirror llvm / af511be
[dsymutil] Implement dSYM bundle creation A dSYM bundle is a file hierarchy that looks slike this: <bundle name>.dSYM/ Contents/ Info.plist Resources/ DWARF/ <DWARF file(s)> This is the default output mode of dsymutil. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244270 91177308-0d34-0410-b5e6-96231b3b80d8 Frederic Riss 5 years ago
3 changed file(s) with 166 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
0 REQUIRES: shell
1 RUN: rm -rf %T/basic-linking-bundle
2 RUN: mkdir -p %T/basic-linking-bundle/dsymdest
3 RUN: cat %p/../Inputs/basic.macho.x86_64 > %T/basic-linking-bundle/basic.macho.x86_64
4
5 RUN: llvm-dsymutil -oso-prepend-path=%p/.. %T/basic-linking-bundle/basic.macho.x86_64
6 RUN: llvm-dwarfdump %T/basic-linking-bundle/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test
7 RUN: FileCheck %s --input-file %T/basic-linking-bundle/basic.macho.x86_64.dSYM/Contents/Info.plist
8
9 RUN: llvm-dsymutil -oso-prepend-path=%p/.. %T/basic-linking-bundle/basic.macho.x86_64 -o %T/basic-linking-bundle/dsymdest/basic.macho.x86_64.dSYM
10 RUN: llvm-dwarfdump %T/basic-linking-bundle/dsymdest/basic.macho.x86_64.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 | FileCheck %S/basic-linking-x86.test
11 RUN: FileCheck %s --input-file %T/basic-linking-bundle/dsymdest/basic.macho.x86_64.dSYM/Contents/Info.plist
12
13 CHECK:
14 CHECK-NEXT:
15 CHECK-NEXT:
16 CHECK-NEXT:
17 CHECK-NEXT: CFBundleDevelopmentRegion
18 CHECK-NEXT: English
19 CHECK-NEXT: CFBundleIdentifier
20 CHECK-NEXT: com.apple.xcode.dsym.basic.macho.x86_64
21 CHECK-NEXT: CFBundleInfoDictionaryVersion
22 CHECK-NEXT: 6.0
23 CHECK-NEXT: CFBundlePackageType
24 CHECK-NEXT: dSYM
25 CHECK-NEXT: CFBundleSignature
26 CHECK-NEXT: ????
27 CHECK-NEXT: CFBundleShortVersionString
28 CHECK-NEXT: 1.0
29 CHECK-NEXT: CFBundleVersion
30 CHECK-NEXT: 1
31 CHECK-NEXT:
32 CHECK-NEXT:
0 REQUIRES: shell
1 RUN: cat %p/../Inputs/basic.macho.x86_64 > %t1
2 RUN: cat %p/../Inputs/basic-archive.macho.x86_64 > %t2
3 RUN: cat %p/../Inputs/basic-lto.macho.x86_64 > %t3
4 RUN: cat %p/../Inputs/basic-lto-dw4.macho.x86_64 > %t4
5 RUN: llvm-dsymutil -f -oso-prepend-path=%p/.. %t1 %t2 %t3 %t4
6 RUN: llvm-dwarfdump %t1.dwarf \
7 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=BASIC
8 RUN: llvm-dwarfdump %t2.dwarf \
9 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=ARCHIVE
10 RUN: llvm-dwarfdump %t3.dwarf | FileCheck %S/basic-lto-linking-x86.test
11 RUN: llvm-dwarfdump %t4.dwarf | FileCheck %S/basic-lto-dw4-linking-x86.test
1 RUN: rm -rf %T/multiple-inputs
2 RUN: mkdir -p %T/multiple-inputs
3
4 RUN: cat %p/../Inputs/basic.macho.x86_64 > %T/multiple-inputs/basic.macho.x86_64
5 RUN: cat %p/../Inputs/basic-archive.macho.x86_64 > %T/multiple-inputs/basic-archive.macho.x86_64
6 RUN: cat %p/../Inputs/basic-lto.macho.x86_64 > %T/multiple-inputs/basic-lto.macho.x86_64
7 RUN: cat %p/../Inputs/basic-lto-dw4.macho.x86_64 > %T/multiple-inputs/basic-lto-dw4.macho.x86_64
8
9 # Multiple inputs in flat mode
10 RUN: llvm-dsymutil -f -oso-prepend-path=%p/.. %T/multiple-inputs/basic.macho.x86_64 %T/multiple-inputs/basic-archive.macho.x86_64 %T/multiple-inputs/basic-lto.macho.x86_64 %T/multiple-inputs/basic-lto-dw4.macho.x86_64
11 RUN: llvm-dwarfdump %T/multiple-inputs/basic.macho.x86_64.dwarf \
12 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=BASIC
13 RUN: llvm-dwarfdump %T/multiple-inputs/basic-archive.macho.x86_64.dwarf \
14 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=ARCHIVE
15 RUN: llvm-dwarfdump %T/multiple-inputs/basic-lto.macho.x86_64.dwarf | FileCheck %S/basic-lto-linking-x86.test
16 RUN: llvm-dwarfdump %T/multiple-inputs/basic-lto-dw4.macho.x86_64.dwarf | FileCheck %S/basic-lto-dw4-linking-x86.test
17
18 # Multiple inputs that end up in the same named bundle
19 RUN: llvm-dsymutil -oso-prepend-path=%p/.. %T/multiple-inputs/basic.macho.x86_64 %T/multiple-inputs/basic-archive.macho.x86_64 %T/multiple-inputs/basic-lto.macho.x86_64 %T/multiple-inputs/basic-lto-dw4.macho.x86_64 -o %t.dSYM
20 RUN: llvm-dwarfdump %t.dSYM/Contents/Resources/DWARF/basic.macho.x86_64 \
21 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=BASIC
22 RUN: llvm-dwarfdump %t.dSYM/Contents/Resources/DWARF/basic-archive.macho.x86_64 \
23 RUN: | FileCheck %S/basic-linking-x86.test --check-prefix=CHECK --check-prefix=ARCHIVE
24 RUN: llvm-dwarfdump %t.dSYM/Contents/Resources/DWARF/basic-lto.macho.x86_64 | FileCheck %S/basic-lto-linking-x86.test
25 RUN: llvm-dwarfdump %t.dSYM/Contents/Resources/DWARF/basic-lto-dw4.macho.x86_64 | FileCheck %S/basic-lto-dw4-linking-x86.test
26
27 # Multiple inputs in a named bundle in flat mode... impossible.
28 RUN: not llvm-dsymutil -f -oso-prepend-path=%p/.. %T/multiple-inputs/basic.macho.x86_64 %T/multiple-inputs/basic-archive.macho.x86_64 %T/multiple-inputs/basic-lto.macho.x86_64 %T/multiple-inputs/basic-lto-dw4.macho.x86_64 -o %t.dSYM 2>&1 | FileCheck %s
29
30 CHECK: error: cannot use -o with multiple inputs in flat mode
31
1515 #include "MachOUtils.h"
1616 #include "dsymutil.h"
1717 #include "llvm/Object/MachO.h"
18 #include "llvm/Support/FileSystem.h"
1819 #include "llvm/Support/FileUtilities.h"
1920 #include "llvm/Support/ManagedStatic.h"
2021 #include "llvm/Support/Options.h"
8182 static opt InputIsYAMLDebugMap(
8283 "y", desc("Treat the input file is a YAML debug map rather than a binary."),
8384 init(false), cat(DsymCategory));
85 }
86
87 static bool createPlistFile(llvm::StringRef BundleRoot) {
88 if (NoOutput)
89 return true;
90
91 // Create plist file to write to.
92 llvm::SmallString<128> InfoPlist(BundleRoot);
93 llvm::sys::path::append(InfoPlist, "Contents/Info.plist");
94 std::error_code EC;
95 llvm::raw_fd_ostream PL(InfoPlist, EC, llvm::sys::fs::F_Text);
96 if (EC) {
97 llvm::errs() << "error: cannot create plist file " << InfoPlist << ": "
98 << EC.message() << '\n';
99 return false;
100 }
101
102 // FIXME: Use CoreFoundation to get executable bundle info. Use
103 // dummy values for now.
104 std::string bundleVersionStr = "1", bundleShortVersionStr = "1.0",
105 bundleIDStr;
106
107 llvm::StringRef BundleID = *llvm::sys::path::rbegin(BundleRoot);
108 if (llvm::sys::path::extension(BundleRoot) == ".dSYM")
109 bundleIDStr = llvm::sys::path::stem(BundleID);
110 else
111 bundleIDStr = BundleID;
112
113 // Print out information to the plist file.
114 PL << "\n"
115 << "
116 << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
117 << "\n"
118 << "\t\n"
119 << "\t\tCFBundleDevelopmentRegion\n"
120 << "\t\tEnglish\n"
121 << "\t\tCFBundleIdentifier\n"
122 << "\t\tcom.apple.xcode.dsym." << bundleIDStr << "\n"
123 << "\t\tCFBundleInfoDictionaryVersion\n"
124 << "\t\t6.0\n"
125 << "\t\tCFBundlePackageType\n"
126 << "\t\tdSYM\n"
127 << "\t\tCFBundleSignature\n"
128 << "\t\t\?\?\?\?\n"
129 << "\t\tCFBundleShortVersionString\n"
130 << "\t\t" << bundleShortVersionStr << "\n"
131 << "\t\tCFBundleVersion\n"
132 << "\t\t" << bundleVersionStr << "\n"
133 << "\t\n"
134 << "\n";
135
136 PL.close();
137 return true;
138 }
139
140 static bool createBundleDir(llvm::StringRef BundleBase) {
141 if (NoOutput)
142 return true;
143
144 llvm::SmallString<128> Bundle(BundleBase);
145 llvm::sys::path::append(Bundle, "Contents", "Resources", "DWARF");
146 if (std::error_code EC = create_directories(Bundle.str(), true,
147 llvm::sys::fs::perms::all_all)) {
148 llvm::errs() << "error: cannot create directory " << Bundle << ": "
149 << EC.message() << "\n";
150 return false;
151 }
152 return true;
84153 }
85154
86155 static std::error_code getUniqueFile(const llvm::Twine &Model, int &ResultFD,
98167 static std::string getOutputFileName(llvm::StringRef InputFile,
99168 bool TempFile = false) {
100169 if (TempFile) {
101 llvm::Twine OutputFile = InputFile + ".tmp%%%%%%.dwarf";
170 llvm::StringRef Basename =
171 OutputFileOpt.empty() ? InputFile : llvm::StringRef(OutputFileOpt);
172 llvm::Twine OutputFile = Basename + ".tmp%%%%%%.dwarf";
102173 int FD;
103174 llvm::SmallString<128> UniqueFile;
104175 if (auto EC = getUniqueFile(OutputFile, FD, UniqueFile)) {
115186 return UniqueFile.str();
116187 }
117188
118 if (OutputFileOpt.empty()) {
119 if (InputFile == "-")
120 return "a.out.dwarf";
121 return (InputFile + ".dwarf").str();
122 }
123 return OutputFileOpt;
189 if (FlatOut) {
190 // If a flat dSYM has been requested, things are pretty simple.
191 if (OutputFileOpt.empty()) {
192 if (InputFile == "-")
193 return "a.out.dwarf";
194 return (InputFile + ".dwarf").str();
195 }
196
197 return OutputFileOpt;
198 }
199
200 // We need to create/update a dSYM bundle.
201 // A bundle hierarchy looks like this:
202 // .dSYM/
203 // Contents/
204 // Info.plist
205 // Resources/
206 // DWARF/
207 //
208 std::string DwarfFile =
209 InputFile == "-" ? llvm::StringRef("a.out") : InputFile;
210 llvm::SmallString<128> BundleDir(OutputFileOpt);
211 if (BundleDir.empty())
212 BundleDir = DwarfFile + ".dSYM";
213 if (!createBundleDir(BundleDir) || !createPlistFile(BundleDir))
214 return "";
215
216 llvm::sys::path::append(BundleDir, "Contents", "Resources", "DWARF",
217 llvm::sys::path::filename(DwarfFile));
218 return BundleDir.str();
124219 }
125220
126221 void llvm::dsymutil::exitDsymutil(int ExitStatus) {