DWARFLinker.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- DWARFLinker.h --------------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DWARFLINKER_DWARFLINKER_H
  14. #define LLVM_DWARFLINKER_DWARFLINKER_H
  15. #include "llvm/CodeGen/AccelTable.h"
  16. #include "llvm/CodeGen/NonRelocatableStringpool.h"
  17. #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
  18. #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  20. #include "llvm/MC/MCDwarf.h"
  21. #include <map>
  22. namespace llvm {
  23. enum class DwarfLinkerClient { Dsymutil, LLD, General };
  24. /// The kind of accelerator tables we should emit.
  25. enum class AccelTableKind {
  26. Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
  27. Dwarf, ///< DWARF v5 .debug_names.
  28. Default, ///< Dwarf for DWARF5 or later, Apple otherwise.
  29. };
  30. /// Partial address range. Besides an offset, only the
  31. /// HighPC is stored. The structure is stored in a map where the LowPC is the
  32. /// key.
  33. struct ObjFileAddressRange {
  34. /// Function HighPC.
  35. uint64_t HighPC;
  36. /// Offset to apply to the linked address.
  37. /// should be 0 for not-linked object file.
  38. int64_t Offset;
  39. ObjFileAddressRange(uint64_t EndPC, int64_t Offset)
  40. : HighPC(EndPC), Offset(Offset) {}
  41. ObjFileAddressRange() : HighPC(0), Offset(0) {}
  42. };
  43. /// Map LowPC to ObjFileAddressRange.
  44. using RangesTy = std::map<uint64_t, ObjFileAddressRange>;
  45. /// AddressesMap represents information about valid addresses used
  46. /// by debug information. Valid addresses are those which points to
  47. /// live code sections. i.e. relocations for these addresses point
  48. /// into sections which would be/are placed into resulting binary.
  49. class AddressesMap {
  50. public:
  51. virtual ~AddressesMap();
  52. /// Returns true if represented addresses are from linked file.
  53. /// Returns false if represented addresses are from not-linked
  54. /// object file.
  55. virtual bool areRelocationsResolved() const = 0;
  56. /// Checks that there are valid relocations against a .debug_info
  57. /// section. Reset current relocation pointer if neccessary.
  58. virtual bool hasValidRelocs(bool ResetRelocsPtr = true) = 0;
  59. /// Checks that the specified DIE has a DW_AT_Location attribute
  60. /// that references into a live code section. This function
  61. /// must be called with DIE offsets in strictly ascending order.
  62. virtual bool hasLiveMemoryLocation(const DWARFDie &DIE,
  63. CompileUnit::DIEInfo &Info) = 0;
  64. /// Checks that the specified DIE has a DW_AT_Low_pc attribute
  65. /// that references into a live code section. This function
  66. /// must be called with DIE offsets in strictly ascending order.
  67. virtual bool hasLiveAddressRange(const DWARFDie &DIE,
  68. CompileUnit::DIEInfo &Info) = 0;
  69. /// Apply the valid relocations to the buffer \p Data, taking into
  70. /// account that Data is at \p BaseOffset in the debug_info section.
  71. ///
  72. /// This function must be called with monotonic \p BaseOffset values.
  73. ///
  74. /// \returns true whether any reloc has been applied.
  75. virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
  76. bool IsLittleEndian) = 0;
  77. /// Relocate the given address offset if a valid relocation exists.
  78. virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) = 0;
  79. /// Returns all valid functions address ranges(i.e., those ranges
  80. /// which points to sections with code).
  81. virtual RangesTy &getValidAddressRanges() = 0;
  82. /// Erases all data.
  83. virtual void clear() = 0;
  84. };
  85. /// DwarfEmitter presents interface to generate all debug info tables.
  86. class DwarfEmitter {
  87. public:
  88. virtual ~DwarfEmitter();
  89. /// Emit DIE containing warnings.
  90. virtual void emitPaperTrailWarningsDie(DIE &Die) = 0;
  91. /// Emit section named SecName with data SecData.
  92. virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
  93. /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
  94. virtual void
  95. emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
  96. unsigned DwarfVersion) = 0;
  97. /// Emit the string table described by \p Pool.
  98. virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
  99. /// Emit DWARF debug names.
  100. virtual void
  101. emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0;
  102. /// Emit Apple namespaces accelerator table.
  103. virtual void
  104. emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
  105. /// Emit Apple names accelerator table.
  106. virtual void
  107. emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
  108. /// Emit Apple Objective-C accelerator table.
  109. virtual void
  110. emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
  111. /// Emit Apple type accelerator table.
  112. virtual void
  113. emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
  114. /// Emit debug_ranges for \p FuncRange by translating the
  115. /// original \p Entries.
  116. virtual void emitRangesEntries(
  117. int64_t UnitPcOffset, uint64_t OrigLowPc,
  118. const FunctionIntervals::const_iterator &FuncRange,
  119. const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
  120. unsigned AddressSize) = 0;
  121. /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
  122. /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
  123. /// DW_AT_ranges attribute.
  124. virtual void emitUnitRangesEntries(CompileUnit &Unit,
  125. bool DoRangesSection) = 0;
  126. /// Copy the debug_line over to the updated binary while unobfuscating the
  127. /// file names and directories.
  128. virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0;
  129. /// Emit the line table described in \p Rows into the debug_line section.
  130. virtual void emitLineTableForUnit(MCDwarfLineTableParams Params,
  131. StringRef PrologueBytes,
  132. unsigned MinInstLength,
  133. std::vector<DWARFDebugLine::Row> &Rows,
  134. unsigned AdddressSize) = 0;
  135. /// Emit the .debug_pubnames contribution for \p Unit.
  136. virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
  137. /// Emit the .debug_pubtypes contribution for \p Unit.
  138. virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
  139. /// Emit a CIE.
  140. virtual void emitCIE(StringRef CIEBytes) = 0;
  141. /// Emit an FDE with data \p Bytes.
  142. virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
  143. StringRef Bytes) = 0;
  144. /// Emit the debug_loc contribution for \p Unit by copying the entries from
  145. /// \p Dwarf and offsetting them. Update the location attributes to point to
  146. /// the new entries.
  147. virtual void emitLocationsForUnit(
  148. const CompileUnit &Unit, DWARFContext &Dwarf,
  149. std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
  150. ProcessExpr) = 0;
  151. /// Emit the compilation unit header for \p Unit in the
  152. /// debug_info section.
  153. ///
  154. /// As a side effect, this also switches the current Dwarf version
  155. /// of the MC layer to the one of U.getOrigUnit().
  156. virtual void emitCompileUnitHeader(CompileUnit &Unit,
  157. unsigned DwarfVersion) = 0;
  158. /// Recursively emit the DIE tree rooted at \p Die.
  159. virtual void emitDIE(DIE &Die) = 0;
  160. /// Returns size of generated .debug_line section.
  161. virtual uint64_t getLineSectionSize() const = 0;
  162. /// Returns size of generated .debug_frame section.
  163. virtual uint64_t getFrameSectionSize() const = 0;
  164. /// Returns size of generated .debug_ranges section.
  165. virtual uint64_t getRangesSectionSize() const = 0;
  166. /// Returns size of generated .debug_info section.
  167. virtual uint64_t getDebugInfoSectionSize() const = 0;
  168. };
  169. using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
  170. /// this class represents DWARF information for source file
  171. /// and it`s address map.
  172. class DWARFFile {
  173. public:
  174. DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
  175. const std::vector<std::string> &Warnings)
  176. : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
  177. }
  178. /// object file name.
  179. StringRef FileName;
  180. /// source DWARF information.
  181. DWARFContext *Dwarf = nullptr;
  182. /// helpful address information(list of valid address ranges, relocations).
  183. AddressesMap *Addresses = nullptr;
  184. /// warnings for object file.
  185. const std::vector<std::string> &Warnings;
  186. };
  187. typedef std::function<void(const Twine &Warning, StringRef Context,
  188. const DWARFDie *DIE)>
  189. messageHandler;
  190. typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
  191. StringRef Path)>
  192. objFileLoader;
  193. typedef std::map<std::string, std::string> swiftInterfacesMap;
  194. typedef std::map<std::string, std::string> objectPrefixMap;
  195. /// The core of the Dwarf linking logic.
  196. ///
  197. /// The generation of the dwarf information from the object files will be
  198. /// driven by the selection of 'root DIEs', which are DIEs that
  199. /// describe variables or functions that resolves to the corresponding
  200. /// code section(and thus have entries in the Addresses map). All the debug
  201. /// information that will be generated(the DIEs, but also the line
  202. /// tables, ranges, ...) is derived from that set of root DIEs.
  203. ///
  204. /// The root DIEs are identified because they contain relocations that
  205. /// points to code section(the low_pc for a function, the location for
  206. /// a variable). These relocations are called ValidRelocs in the
  207. /// AddressesInfo and are gathered as a very first step when we start
  208. /// processing a object file.
  209. class DWARFLinker {
  210. public:
  211. DWARFLinker(DwarfEmitter *Emitter,
  212. DwarfLinkerClient ClientID = DwarfLinkerClient::General)
  213. : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
  214. /// Add object file to be linked.
  215. void addObjectFile(DWARFFile &File);
  216. /// Link debug info for added objFiles. Object
  217. /// files are linked all together.
  218. bool link();
  219. /// A number of methods setting various linking options:
  220. /// Allows to generate log of linking process to the standard output.
  221. void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
  222. /// Print statistics to standard output.
  223. void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
  224. /// Do not emit linked dwarf info.
  225. void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
  226. /// Do not unique types according to ODR.
  227. void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
  228. /// update existing DWARF info(for the linked binary).
  229. void setUpdate(bool Update) { Options.Update = Update; }
  230. /// Use specified number of threads for parallel files linking.
  231. void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
  232. /// Set kind of accelerator tables to be generated.
  233. void setAccelTableKind(AccelTableKind Kind) {
  234. Options.TheAccelTableKind = Kind;
  235. }
  236. /// Set prepend path for clang modules.
  237. void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
  238. /// Set translator which would be used for strings.
  239. void
  240. setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
  241. this->StringsTranslator = StringsTranslator;
  242. }
  243. /// Set estimated objects files amount, for preliminary data allocation.
  244. void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
  245. ObjectContexts.reserve(ObjFilesNum);
  246. }
  247. /// Set warning handler which would be used to report warnings.
  248. void setWarningHandler(messageHandler Handler) {
  249. Options.WarningHandler = Handler;
  250. }
  251. /// Set error handler which would be used to report errors.
  252. void setErrorHandler(messageHandler Handler) {
  253. Options.ErrorHandler = Handler;
  254. }
  255. /// Set object files loader which would be used to load
  256. /// additional objects for splitted dwarf.
  257. void setObjFileLoader(objFileLoader Loader) {
  258. Options.ObjFileLoader = Loader;
  259. }
  260. /// Set map for Swift interfaces.
  261. void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
  262. Options.ParseableSwiftInterfaces = Map;
  263. }
  264. /// Set prefix map for objects.
  265. void setObjectPrefixMap(objectPrefixMap *Map) {
  266. Options.ObjectPrefixMap = Map;
  267. }
  268. private:
  269. /// Flags passed to DwarfLinker::lookForDIEsToKeep
  270. enum TraversalFlags {
  271. TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
  272. TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
  273. TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
  274. TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
  275. TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
  276. TF_SkipPC = 1 << 5, ///< Skip all location attributes.
  277. };
  278. /// The distinct types of work performed by the work loop.
  279. enum class WorklistItemType {
  280. /// Given a DIE, look for DIEs to be kept.
  281. LookForDIEsToKeep,
  282. /// Given a DIE, look for children of this DIE to be kept.
  283. LookForChildDIEsToKeep,
  284. /// Given a DIE, look for DIEs referencing this DIE to be kept.
  285. LookForRefDIEsToKeep,
  286. /// Given a DIE, look for parent DIEs to be kept.
  287. LookForParentDIEsToKeep,
  288. /// Given a DIE, update its incompleteness based on whether its children are
  289. /// incomplete.
  290. UpdateChildIncompleteness,
  291. /// Given a DIE, update its incompleteness based on whether the DIEs it
  292. /// references are incomplete.
  293. UpdateRefIncompleteness,
  294. };
  295. /// This class represents an item in the work list. The type defines what kind
  296. /// of work needs to be performed when processing the current item. The flags
  297. /// and info fields are optional based on the type.
  298. struct WorklistItem {
  299. DWARFDie Die;
  300. WorklistItemType Type;
  301. CompileUnit &CU;
  302. unsigned Flags;
  303. union {
  304. const unsigned AncestorIdx;
  305. CompileUnit::DIEInfo *OtherInfo;
  306. };
  307. WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
  308. WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
  309. : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
  310. WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
  311. CompileUnit::DIEInfo *OtherInfo = nullptr)
  312. : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
  313. WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
  314. : Die(), Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
  315. Flags(Flags), AncestorIdx(AncestorIdx) {}
  316. };
  317. /// returns true if we need to translate strings.
  318. bool needToTranslateStrings() { return StringsTranslator != nullptr; }
  319. void reportWarning(const Twine &Warning, const DWARFFile &File,
  320. const DWARFDie *DIE = nullptr) const {
  321. if (Options.WarningHandler != nullptr)
  322. Options.WarningHandler(Warning, File.FileName, DIE);
  323. }
  324. void reportError(const Twine &Warning, const DWARFFile &File,
  325. const DWARFDie *DIE = nullptr) const {
  326. if (Options.ErrorHandler != nullptr)
  327. Options.ErrorHandler(Warning, File.FileName, DIE);
  328. }
  329. /// Remembers the oldest and newest DWARF version we've seen in a unit.
  330. void updateDwarfVersion(unsigned Version) {
  331. MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
  332. MinDwarfVersion = std::min(MinDwarfVersion, Version);
  333. }
  334. /// Remembers the kinds of accelerator tables we've seen in a unit.
  335. void updateAccelKind(DWARFContext &Dwarf);
  336. /// Emit warnings as Dwarf compile units to leave a trail after linking.
  337. bool emitPaperTrailWarnings(const DWARFFile &File,
  338. OffsetsStringPool &StringPool);
  339. void copyInvariantDebugSection(DWARFContext &Dwarf);
  340. /// Keeps track of data associated with one object during linking.
  341. struct LinkContext {
  342. DWARFFile &File;
  343. UnitListTy CompileUnits;
  344. bool Skip = false;
  345. LinkContext(DWARFFile &File) : File(File) {}
  346. /// Clear part of the context that's no longer needed when we're done with
  347. /// the debug object.
  348. void clear() {
  349. CompileUnits.clear();
  350. File.Addresses->clear();
  351. }
  352. };
  353. /// Called before emitting object data
  354. void cleanupAuxiliarryData(LinkContext &Context);
  355. /// Look at the parent of the given DIE and decide whether they should be
  356. /// kept.
  357. void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
  358. unsigned Flags,
  359. SmallVectorImpl<WorklistItem> &Worklist);
  360. /// Look at the children of the given DIE and decide whether they should be
  361. /// kept.
  362. void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
  363. unsigned Flags,
  364. SmallVectorImpl<WorklistItem> &Worklist);
  365. /// Look at DIEs referenced by the given DIE and decide whether they should be
  366. /// kept. All DIEs referenced though attributes should be kept.
  367. void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
  368. unsigned Flags, const UnitListTy &Units,
  369. const DWARFFile &File,
  370. SmallVectorImpl<WorklistItem> &Worklist);
  371. /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
  372. ///
  373. /// @{
  374. /// Recursively walk the \p DIE tree and look for DIEs to
  375. /// keep. Store that information in \p CU's DIEInfo.
  376. ///
  377. /// The return value indicates whether the DIE is incomplete.
  378. void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
  379. const UnitListTy &Units, const DWARFDie &DIE,
  380. const DWARFFile &File, CompileUnit &CU,
  381. unsigned Flags);
  382. /// If this compile unit is really a skeleton CU that points to a
  383. /// clang module, register it in ClangModules and return true.
  384. ///
  385. /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
  386. /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
  387. /// hash.
  388. bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
  389. const DWARFFile &File,
  390. OffsetsStringPool &OffsetsStringPool,
  391. DeclContextTree &ODRContexts,
  392. uint64_t ModulesEndOffset, unsigned &UnitID,
  393. bool IsLittleEndian, unsigned Indent = 0,
  394. bool Quiet = false);
  395. /// Recursively add the debug info in this clang module .pcm
  396. /// file (and all the modules imported by it in a bottom-up fashion)
  397. /// to Units.
  398. Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
  399. StringRef ModuleName, uint64_t DwoId,
  400. const DWARFFile &File,
  401. OffsetsStringPool &OffsetsStringPool,
  402. DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
  403. unsigned &UnitID, bool IsLittleEndian,
  404. unsigned Indent = 0, bool Quiet = false);
  405. /// Mark the passed DIE as well as all the ones it depends on as kept.
  406. void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
  407. const UnitListTy &Units, const DWARFDie &DIE,
  408. CompileUnit::DIEInfo &MyInfo,
  409. const DWARFFile &File, CompileUnit &CU,
  410. bool UseODR);
  411. unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
  412. const DWARFDie &DIE, const DWARFFile &File,
  413. CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
  414. unsigned Flags);
  415. /// Check if a variable describing DIE should be kept.
  416. /// \returns updated TraversalFlags.
  417. unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
  418. CompileUnit::DIEInfo &MyInfo, unsigned Flags);
  419. unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
  420. const DWARFDie &DIE, const DWARFFile &File,
  421. CompileUnit &Unit,
  422. CompileUnit::DIEInfo &MyInfo,
  423. unsigned Flags);
  424. /// Resolve the DIE attribute reference that has been extracted in \p
  425. /// RefValue. The resulting DIE might be in another CompileUnit which is
  426. /// stored into \p ReferencedCU. \returns null if resolving fails for any
  427. /// reason.
  428. DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
  429. const DWARFFormValue &RefValue,
  430. const DWARFDie &DIE, CompileUnit *&RefCU);
  431. /// @}
  432. /// \defgroup Methods used to link the debug information
  433. ///
  434. /// @{
  435. struct DWARFLinkerOptions;
  436. class DIECloner {
  437. DWARFLinker &Linker;
  438. DwarfEmitter *Emitter;
  439. DWARFFile &ObjFile;
  440. /// Allocator used for all the DIEValue objects.
  441. BumpPtrAllocator &DIEAlloc;
  442. std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
  443. bool Update;
  444. public:
  445. DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
  446. BumpPtrAllocator &DIEAlloc,
  447. std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
  448. bool Update)
  449. : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
  450. DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
  451. /// Recursively clone \p InputDIE into an tree of DIE objects
  452. /// where useless (as decided by lookForDIEsToKeep()) bits have been
  453. /// stripped out and addresses have been rewritten according to the
  454. /// address map.
  455. ///
  456. /// \param OutOffset is the offset the cloned DIE in the output
  457. /// compile unit.
  458. /// \param PCOffset (while cloning a function scope) is the offset
  459. /// applied to the entry point of the function to get the linked address.
  460. /// \param Die the output DIE to use, pass NULL to create one.
  461. /// \returns the root of the cloned tree or null if nothing was selected.
  462. DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
  463. CompileUnit &U, OffsetsStringPool &StringPool,
  464. int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
  465. bool IsLittleEndian, DIE *Die = nullptr);
  466. /// Construct the output DIE tree by cloning the DIEs we
  467. /// chose to keep above. If there are no valid relocs, then there's
  468. /// nothing to clone/emit.
  469. uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
  470. const DWARFFile &File,
  471. OffsetsStringPool &StringPool,
  472. bool IsLittleEndian);
  473. private:
  474. using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
  475. /// Information gathered and exchanged between the various
  476. /// clone*Attributes helpers about the attributes of a particular DIE.
  477. struct AttributesInfo {
  478. /// Names.
  479. DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
  480. /// Offsets in the string pool.
  481. uint32_t NameOffset = 0;
  482. uint32_t MangledNameOffset = 0;
  483. /// Value of AT_low_pc in the input DIE
  484. uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
  485. /// Value of AT_high_pc in the input DIE
  486. uint64_t OrigHighPc = 0;
  487. /// Value of DW_AT_call_return_pc in the input DIE
  488. uint64_t OrigCallReturnPc = 0;
  489. /// Value of DW_AT_call_pc in the input DIE
  490. uint64_t OrigCallPc = 0;
  491. /// Offset to apply to PC addresses inside a function.
  492. int64_t PCOffset = 0;
  493. /// Does the DIE have a low_pc attribute?
  494. bool HasLowPc = false;
  495. /// Does the DIE have a ranges attribute?
  496. bool HasRanges = false;
  497. /// Is this DIE only a declaration?
  498. bool IsDeclaration = false;
  499. AttributesInfo() = default;
  500. };
  501. /// Helper for cloneDIE.
  502. unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
  503. const DWARFFile &File, CompileUnit &U,
  504. OffsetsStringPool &StringPool,
  505. const DWARFFormValue &Val,
  506. const AttributeSpec AttrSpec, unsigned AttrSize,
  507. AttributesInfo &AttrInfo, bool IsLittleEndian);
  508. /// Clone a string attribute described by \p AttrSpec and add
  509. /// it to \p Die.
  510. /// \returns the size of the new attribute.
  511. unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
  512. const DWARFFormValue &Val, const DWARFUnit &U,
  513. OffsetsStringPool &StringPool,
  514. AttributesInfo &Info);
  515. /// Clone an attribute referencing another DIE and add
  516. /// it to \p Die.
  517. /// \returns the size of the new attribute.
  518. unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
  519. AttributeSpec AttrSpec,
  520. unsigned AttrSize,
  521. const DWARFFormValue &Val,
  522. const DWARFFile &File,
  523. CompileUnit &Unit);
  524. /// Clone a DWARF expression that may be referencing another DIE.
  525. void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
  526. const DWARFFile &File, CompileUnit &Unit,
  527. SmallVectorImpl<uint8_t> &OutputBuffer);
  528. /// Clone an attribute referencing another DIE and add
  529. /// it to \p Die.
  530. /// \returns the size of the new attribute.
  531. unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File,
  532. CompileUnit &Unit, AttributeSpec AttrSpec,
  533. const DWARFFormValue &Val, unsigned AttrSize,
  534. bool IsLittleEndian);
  535. /// Clone an attribute referencing another DIE and add
  536. /// it to \p Die.
  537. /// \returns the size of the new attribute.
  538. unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
  539. const DWARFFormValue &Val,
  540. const CompileUnit &Unit,
  541. AttributesInfo &Info);
  542. /// Clone a scalar attribute and add it to \p Die.
  543. /// \returns the size of the new attribute.
  544. unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
  545. const DWARFFile &File, CompileUnit &U,
  546. AttributeSpec AttrSpec,
  547. const DWARFFormValue &Val, unsigned AttrSize,
  548. AttributesInfo &Info);
  549. /// Get the potential name and mangled name for the entity
  550. /// described by \p Die and store them in \Info if they are not
  551. /// already there.
  552. /// \returns is a name was found.
  553. bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
  554. OffsetsStringPool &StringPool, bool StripTemplate = false);
  555. /// Create a copy of abbreviation Abbrev.
  556. void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
  557. uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
  558. const DWARFFile &File,
  559. int RecurseDepth = 0);
  560. /// Helper for cloneDIE.
  561. void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
  562. DwarfStringPoolEntryRef Name,
  563. OffsetsStringPool &StringPool, bool SkipPubSection);
  564. };
  565. /// Assign an abbreviation number to \p Abbrev
  566. void assignAbbrev(DIEAbbrev &Abbrev);
  567. /// Compute and emit debug_ranges section for \p Unit, and
  568. /// patch the attributes referencing it.
  569. void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
  570. const DWARFFile &File) const;
  571. /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
  572. /// one.
  573. void generateUnitRanges(CompileUnit &Unit) const;
  574. /// Extract the line tables from the original dwarf, extract the relevant
  575. /// parts according to the linked function ranges and emit the result in the
  576. /// debug_line section.
  577. void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
  578. const DWARFFile &File);
  579. /// Emit the accelerator entries for \p Unit.
  580. void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
  581. void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
  582. void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
  583. /// Patch the frame info for an object file and emit it.
  584. void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges,
  585. DWARFContext &, unsigned AddressSize);
  586. /// FoldingSet that uniques the abbreviations.
  587. FoldingSet<DIEAbbrev> AbbreviationsSet;
  588. /// Storage for the unique Abbreviations.
  589. /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
  590. /// changed to a vector of unique_ptrs.
  591. std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
  592. /// DIELoc objects that need to be destructed (but not freed!).
  593. std::vector<DIELoc *> DIELocs;
  594. /// DIEBlock objects that need to be destructed (but not freed!).
  595. std::vector<DIEBlock *> DIEBlocks;
  596. /// Allocator used for all the DIEValue objects.
  597. BumpPtrAllocator DIEAlloc;
  598. /// @}
  599. DwarfEmitter *TheDwarfEmitter;
  600. std::vector<LinkContext> ObjectContexts;
  601. unsigned MaxDwarfVersion = 0;
  602. unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
  603. bool AtLeastOneAppleAccelTable = false;
  604. bool AtLeastOneDwarfAccelTable = false;
  605. /// The CIEs that have been emitted in the output section. The actual CIE
  606. /// data serves a the key to this StringMap, this takes care of comparing the
  607. /// semantics of CIEs defined in different object files.
  608. StringMap<uint32_t> EmittedCIEs;
  609. /// Offset of the last CIE that has been emitted in the output
  610. /// debug_frame section.
  611. uint32_t LastCIEOffset = 0;
  612. /// Apple accelerator tables.
  613. AccelTable<DWARF5AccelTableStaticData> DebugNames;
  614. AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
  615. AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
  616. AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
  617. AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
  618. /// Mapping the PCM filename to the DwoId.
  619. StringMap<uint64_t> ClangModules;
  620. DwarfLinkerClient DwarfLinkerClientID;
  621. std::function<StringRef(StringRef)> StringsTranslator = nullptr;
  622. /// linking options
  623. struct DWARFLinkerOptions {
  624. /// Generate processing log to the standard output.
  625. bool Verbose = false;
  626. /// Print statistics.
  627. bool Statistics = false;
  628. /// Skip emitting output
  629. bool NoOutput = false;
  630. /// Do not unique types according to ODR
  631. bool NoODR = false;
  632. /// Update
  633. bool Update = false;
  634. /// Number of threads.
  635. unsigned Threads = 1;
  636. /// The accelerator table kind
  637. AccelTableKind TheAccelTableKind = AccelTableKind::Default;
  638. /// Prepend path for the clang modules.
  639. std::string PrependPath;
  640. // warning handler
  641. messageHandler WarningHandler = nullptr;
  642. // error handler
  643. messageHandler ErrorHandler = nullptr;
  644. objFileLoader ObjFileLoader = nullptr;
  645. /// A list of all .swiftinterface files referenced by the debug
  646. /// info, mapping Module name to path on disk. The entries need to
  647. /// be uniqued and sorted and there are only few entries expected
  648. /// per compile unit, which is why this is a std::map.
  649. /// this is dsymutil specific fag.
  650. swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
  651. /// A list of remappings to apply to file paths.
  652. objectPrefixMap *ObjectPrefixMap = nullptr;
  653. } Options;
  654. };
  655. } // end namespace llvm
  656. #endif // LLVM_DWARFLINKER_DWARFLINKER_H
  657. #ifdef __GNUC__
  658. #pragma GCC diagnostic pop
  659. #endif