DWARFLinker.h 32 KB

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