Skip to content

Commit 36f3510

Browse files
committed
[DWARFLinkerParallel][Reland] Add interface files, create a skeleton implementation.
This patch creates skeleton implementation for the DWARFLinkerParallel. It also integrates DWARFLinkerParallel into dsymutil and llvm-dwarfutil, so that empty DWARFLinker::link() can be called. To do this new command line option is added "--linker apple/llvm". Additionally it changes existing DWARFLinker interfaces/implementations to be compatible: use Error for error reporting for the DWARFStreamer, make DWARFFile to owner of referenced resources, other small refactorings. Differential Revision: https://reviews.llvm.org/D147952
1 parent 7226162 commit 36f3510

32 files changed

+2157
-337
lines changed

llvm/include/llvm/DWARFLinker/DWARFLinker.h

Lines changed: 80 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
#include "llvm/CodeGen/AccelTable.h"
1515
#include "llvm/CodeGen/NonRelocatableStringpool.h"
1616
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
17+
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
1718
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
1819
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
1920
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
2021
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
2122
#include <map>
2223

2324
namespace llvm {
24-
class DWARFContext;
2525
class DWARFExpression;
2626
class DWARFUnit;
2727
class DataExtractor;
@@ -30,13 +30,6 @@ template <typename T> class SmallVectorImpl;
3030

3131
enum class DwarfLinkerClient { Dsymutil, LLD, General };
3232

33-
/// The kind of accelerator tables we should emit.
34-
enum class DwarfLinkerAccelTableKind : uint8_t {
35-
Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
36-
Pub, ///< .debug_pubnames, .debug_pubtypes
37-
DebugNames ///< .debug_names.
38-
};
39-
4033
/// AddressesMap represents information about valid addresses used
4134
/// by debug information. Valid addresses are those which points to
4235
/// live code sections. i.e. relocations for these addresses point
@@ -221,39 +214,48 @@ class DwarfEmitter {
221214

222215
/// Returns size of generated .debug_loclists section.
223216
virtual uint64_t getLocListsSectionSize() const = 0;
217+
218+
/// Dump the file to the disk.
219+
virtual void finish() = 0;
220+
221+
/// Emit the swift_ast section stored in \p Buffer.
222+
virtual void emitSwiftAST(StringRef Buffer) = 0;
223+
224+
/// Emit the swift reflection section stored in \p Buffer.
225+
virtual void emitSwiftReflectionSection(
226+
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
227+
StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
228+
229+
/// Returns underlying AsmPrinter.
230+
virtual AsmPrinter &getAsmPrinter() const = 0;
224231
};
225232

233+
class DwarfStreamer;
226234
using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
227235

228236
/// This class represents DWARF information for source file
229237
/// and its address map.
230238
class DWARFFile {
231239
public:
232-
DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
240+
DWARFFile(StringRef Name, std::unique_ptr<DWARFContext> Dwarf,
241+
std::unique_ptr<AddressesMap> Addresses,
233242
const std::vector<std::string> &Warnings)
234-
: FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
235-
}
243+
: FileName(Name), Dwarf(std::move(Dwarf)),
244+
Addresses(std::move(Addresses)), Warnings(Warnings) {}
236245

237246
/// The object file name.
238247
StringRef FileName;
239248

240249
/// The source DWARF information.
241-
DWARFContext *Dwarf = nullptr;
250+
std::unique_ptr<DWARFContext> Dwarf;
242251

243252
/// Helpful address information(list of valid address ranges, relocations).
244-
AddressesMap *Addresses = nullptr;
253+
std::unique_ptr<AddressesMap> Addresses;
245254

246255
/// Warnings for this object file.
247256
const std::vector<std::string> &Warnings;
248257
};
249258

250-
typedef std::function<void(const Twine &Warning, StringRef Context,
251-
const DWARFDie *DIE)>
252-
messageHandler;
253-
typedef std::function<void(const DWARFFile &File)> inputVerificationHandler;
254-
typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
255-
StringRef Path)>
256-
objFileLoader;
257259
typedef std::map<std::string, std::string> swiftInterfacesMap;
258260
typedef std::map<std::string, std::string> objectPrefixMap;
259261

@@ -275,9 +277,43 @@ typedef function_ref<void(const DWARFUnit &Unit)> CompileUnitHandler;
275277
/// processing a object file.
276278
class DWARFLinker {
277279
public:
278-
DWARFLinker(DwarfEmitter *Emitter,
279-
DwarfLinkerClient ClientID = DwarfLinkerClient::General)
280-
: TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
280+
typedef std::function<void(const Twine &Warning, StringRef Context,
281+
const DWARFDie *DIE)>
282+
messageHandler;
283+
DWARFLinker(messageHandler ErrorHandler, messageHandler WarningHandler,
284+
std::function<StringRef(StringRef)> StringsTranslator)
285+
: DwarfLinkerClientID(DwarfLinkerClient::Dsymutil),
286+
StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
287+
WarningHandler(WarningHandler) {}
288+
289+
static std::unique_ptr<DWARFLinker> createLinker(
290+
messageHandler ErrorHandler, messageHandler WarningHandler,
291+
std::function<StringRef(StringRef)> StringsTranslator = nullptr) {
292+
return std::make_unique<DWARFLinker>(ErrorHandler, WarningHandler,
293+
StringsTranslator);
294+
}
295+
296+
/// Type of output file.
297+
enum class OutputFileType {
298+
Object,
299+
Assembly,
300+
};
301+
302+
/// The kind of accelerator tables we should emit.
303+
enum class AccelTableKind : uint8_t {
304+
Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
305+
Pub, ///< .debug_pubnames, .debug_pubtypes
306+
DebugNames ///< .debug_names.
307+
};
308+
typedef std::function<void(const DWARFFile &File)> inputVerificationHandler;
309+
typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
310+
StringRef Path)>
311+
objFileLoader;
312+
313+
Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
314+
raw_pwrite_stream &OutFile);
315+
316+
DwarfEmitter *getEmitter();
281317

282318
/// Add object file to be linked. Pre-load compile unit die. Call
283319
/// \p OnCUDieLoaded for each compile unit die. If specified \p File
@@ -289,8 +325,7 @@ class DWARFLinker {
289325
DWARFFile &File, objFileLoader Loader = nullptr,
290326
CompileUnitHandler OnCUDieLoaded = [](const DWARFUnit &) {});
291327

292-
/// Link debug info for added objFiles. Object
293-
/// files are linked all together.
328+
/// Link debug info for added objFiles. Object files are linked all together.
294329
Error link();
295330

296331
/// A number of methods setting various linking options:
@@ -304,14 +339,15 @@ class DWARFLinker {
304339
/// Verify the input DWARF.
305340
void setVerifyInputDWARF(bool Verify) { Options.VerifyInputDWARF = Verify; }
306341

307-
/// Do not emit linked dwarf info.
308-
void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
309-
310342
/// Do not unique types according to ODR.
311343
void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
312344

313-
/// update existing DWARF info(for the linked binary).
314-
void setUpdate(bool Update) { Options.Update = Update; }
345+
/// Update index tables only(do not modify rest of DWARF).
346+
void setUpdateIndexTablesOnly(bool Update) { Options.Update = Update; }
347+
348+
/// Allow generating valid, but non-deterministic output.
349+
void setAllowNonDeterministicOutput(bool) { /* Nothing to do. */
350+
}
315351

316352
/// Set whether to keep the enclosing function for a static variable.
317353
void setKeepFunctionForStatic(bool KeepFunctionForStatic) {
@@ -322,7 +358,7 @@ class DWARFLinker {
322358
void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
323359

324360
/// Add kind of accelerator tables to be generated.
325-
void addAccelTableKind(DwarfLinkerAccelTableKind Kind) {
361+
void addAccelTableKind(AccelTableKind Kind) {
326362
assert(std::find(Options.AccelTables.begin(), Options.AccelTables.end(),
327363
Kind) == Options.AccelTables.end());
328364
Options.AccelTables.emplace_back(Kind);
@@ -331,27 +367,11 @@ class DWARFLinker {
331367
/// Set prepend path for clang modules.
332368
void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
333369

334-
/// Set translator which would be used for strings.
335-
void
336-
setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
337-
this->StringsTranslator = StringsTranslator;
338-
}
339-
340370
/// Set estimated objects files amount, for preliminary data allocation.
341371
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
342372
ObjectContexts.reserve(ObjFilesNum);
343373
}
344374

345-
/// Set warning handler which would be used to report warnings.
346-
void setWarningHandler(messageHandler Handler) {
347-
Options.WarningHandler = Handler;
348-
}
349-
350-
/// Set error handler which would be used to report errors.
351-
void setErrorHandler(messageHandler Handler) {
352-
Options.ErrorHandler = Handler;
353-
}
354-
355375
/// Set verification handler which would be used to report verification
356376
/// errors.
357377
void setInputVerificationHandler(inputVerificationHandler Handler) {
@@ -370,7 +390,7 @@ class DWARFLinker {
370390

371391
/// Set target DWARF version.
372392
Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) {
373-
if (TargetDWARFVersion < 1 || TargetDWARFVersion > 5)
393+
if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
374394
return createStringError(std::errc::invalid_argument,
375395
"unsupported DWARF version: %d",
376396
TargetDWARFVersion);
@@ -444,14 +464,14 @@ class DWARFLinker {
444464

445465
void reportWarning(const Twine &Warning, const DWARFFile &File,
446466
const DWARFDie *DIE = nullptr) const {
447-
if (Options.WarningHandler != nullptr)
448-
Options.WarningHandler(Warning, File.FileName, DIE);
467+
if (WarningHandler != nullptr)
468+
WarningHandler(Warning, File.FileName, DIE);
449469
}
450470

451471
void reportError(const Twine &Warning, const DWARFFile &File,
452472
const DWARFDie *DIE = nullptr) const {
453-
if (Options.ErrorHandler != nullptr)
454-
Options.ErrorHandler(Warning, File.FileName, DIE);
473+
if (ErrorHandler != nullptr)
474+
ErrorHandler(Warning, File.FileName, DIE);
455475
}
456476

457477
/// Emit warnings as Dwarf compile units to leave a trail after linking.
@@ -799,7 +819,7 @@ class DWARFLinker {
799819
BumpPtrAllocator DIEAlloc;
800820
/// @}
801821

802-
DwarfEmitter *TheDwarfEmitter;
822+
std::unique_ptr<DwarfStreamer> TheDwarfEmitter;
803823
std::vector<LinkContext> ObjectContexts;
804824

805825
/// The CIEs that have been emitted in the output section. The actual CIE
@@ -828,6 +848,12 @@ class DWARFLinker {
828848
/// A unique ID that identifies each compile unit.
829849
unsigned UniqueUnitID = 0;
830850

851+
// error handler
852+
messageHandler ErrorHandler = nullptr;
853+
854+
// warning handler
855+
messageHandler WarningHandler = nullptr;
856+
831857
/// linking options
832858
struct DWARFLinkerOptions {
833859
/// DWARF version for the output.
@@ -842,9 +868,6 @@ class DWARFLinker {
842868
/// Verify the input DWARF.
843869
bool VerifyInputDWARF = false;
844870

845-
/// Skip emitting output
846-
bool NoOutput = false;
847-
848871
/// Do not unique types according to ODR
849872
bool NoODR = false;
850873

@@ -859,17 +882,11 @@ class DWARFLinker {
859882
unsigned Threads = 1;
860883

861884
/// The accelerator table kinds
862-
SmallVector<DwarfLinkerAccelTableKind, 1> AccelTables;
885+
SmallVector<AccelTableKind, 1> AccelTables;
863886

864887
/// Prepend path for the clang modules.
865888
std::string PrependPath;
866889

867-
// warning handler
868-
messageHandler WarningHandler = nullptr;
869-
870-
// error handler
871-
messageHandler ErrorHandler = nullptr;
872-
873890
// input verification handler
874891
inputVerificationHandler InputVerificationHandler = nullptr;
875892

llvm/include/llvm/DWARFLinker/DWARFStreamer.h

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@
2323
namespace llvm {
2424
template <typename DataT> class AccelTable;
2525

26-
enum class OutputFileType {
27-
Object,
28-
Assembly,
29-
};
30-
3126
/// User of DwarfStreamer should call initialization code
3227
/// for AsmPrinter:
3328
///
@@ -45,18 +40,19 @@ class DWARFDebugMacro;
4540
/// information binary representation are handled in this class.
4641
class DwarfStreamer : public DwarfEmitter {
4742
public:
48-
DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
43+
DwarfStreamer(DWARFLinker::OutputFileType OutFileType,
44+
raw_pwrite_stream &OutFile,
4945
std::function<StringRef(StringRef Input)> Translator,
50-
messageHandler Error, messageHandler Warning)
46+
DWARFLinker::messageHandler Warning)
5147
: OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
52-
ErrorHandler(Error), WarningHandler(Warning) {}
48+
WarningHandler(Warning) {}
5349

54-
bool init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
50+
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
5551

5652
/// Dump the file to the disk.
57-
void finish();
53+
void finish() override;
5854

59-
AsmPrinter &getAsmPrinter() const { return *Asm; }
55+
AsmPrinter &getAsmPrinter() const override { return *Asm; }
6056

6157
/// Set the current output section to debug_info and change
6258
/// the MC Dwarf version to \p DwarfVersion.
@@ -89,12 +85,12 @@ class DwarfStreamer : public DwarfEmitter {
8985
void emitLineStrings(const NonRelocatableStringpool &Pool) override;
9086

9187
/// Emit the swift_ast section stored in \p Buffer.
92-
void emitSwiftAST(StringRef Buffer);
88+
void emitSwiftAST(StringRef Buffer) override;
9389

9490
/// Emit the swift reflection section stored in \p Buffer.
9591
void emitSwiftReflectionSection(
9692
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
97-
StringRef Buffer, uint32_t Alignment, uint32_t Size);
93+
StringRef Buffer, uint32_t Alignment, uint32_t Size) override;
9894

9995
/// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
10096
MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
@@ -194,11 +190,6 @@ class DwarfStreamer : public DwarfEmitter {
194190
OffsetsStringPool &StringPool) override;
195191

196192
private:
197-
inline void error(const Twine &Error, StringRef Context = "") {
198-
if (ErrorHandler)
199-
ErrorHandler(Error, Context, nullptr);
200-
}
201-
202193
inline void warn(const Twine &Warning, StringRef Context = "") {
203194
if (WarningHandler)
204195
WarningHandler(Warning, Context, nullptr);
@@ -274,7 +265,7 @@ class DwarfStreamer : public DwarfEmitter {
274265

275266
/// The output file we stream the linked Dwarf to.
276267
raw_pwrite_stream &OutFile;
277-
OutputFileType OutFileType = OutputFileType::Object;
268+
DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
278269
std::function<StringRef(StringRef Input)> Translator;
279270

280271
uint64_t RangesSectionSize = 0;
@@ -300,8 +291,7 @@ class DwarfStreamer : public DwarfEmitter {
300291
const CompileUnit &Unit,
301292
const std::vector<CompileUnit::AccelInfo> &Names);
302293

303-
messageHandler ErrorHandler = nullptr;
304-
messageHandler WarningHandler = nullptr;
294+
DWARFLinker::messageHandler WarningHandler = nullptr;
305295
};
306296

307297
} // end namespace llvm

0 commit comments

Comments
 (0)