DwarfLinkerForBinary.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. //===- tools/dsymutil/DwarfLinkerForBinary.cpp ----------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "DwarfLinkerForBinary.h"
  9. #include "BinaryHolder.h"
  10. #include "DebugMap.h"
  11. #include "MachOUtils.h"
  12. #include "dsymutil.h"
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include "llvm/ADT/BitVector.h"
  15. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/DenseMapInfo.h"
  17. #include "llvm/ADT/DenseSet.h"
  18. #include "llvm/ADT/FoldingSet.h"
  19. #include "llvm/ADT/Hashing.h"
  20. #include "llvm/ADT/PointerIntPair.h"
  21. #include "llvm/ADT/STLExtras.h"
  22. #include "llvm/ADT/SmallString.h"
  23. #include "llvm/ADT/StringMap.h"
  24. #include "llvm/ADT/StringRef.h"
  25. #include "llvm/ADT/Triple.h"
  26. #include "llvm/ADT/Twine.h"
  27. #include "llvm/BinaryFormat/Dwarf.h"
  28. #include "llvm/BinaryFormat/MachO.h"
  29. #include "llvm/BinaryFormat/Swift.h"
  30. #include "llvm/CodeGen/AccelTable.h"
  31. #include "llvm/CodeGen/AsmPrinter.h"
  32. #include "llvm/CodeGen/DIE.h"
  33. #include "llvm/CodeGen/NonRelocatableStringpool.h"
  34. #include "llvm/Config/config.h"
  35. #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
  36. #include "llvm/DebugInfo/DIContext.h"
  37. #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
  38. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  39. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  40. #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
  41. #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
  42. #include "llvm/DebugInfo/DWARF/DWARFDie.h"
  43. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  44. #include "llvm/DebugInfo/DWARF/DWARFSection.h"
  45. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  46. #include "llvm/MC/MCAsmBackend.h"
  47. #include "llvm/MC/MCAsmInfo.h"
  48. #include "llvm/MC/MCCodeEmitter.h"
  49. #include "llvm/MC/MCContext.h"
  50. #include "llvm/MC/MCDwarf.h"
  51. #include "llvm/MC/MCInstrInfo.h"
  52. #include "llvm/MC/MCObjectFileInfo.h"
  53. #include "llvm/MC/MCObjectWriter.h"
  54. #include "llvm/MC/MCRegisterInfo.h"
  55. #include "llvm/MC/MCSection.h"
  56. #include "llvm/MC/MCStreamer.h"
  57. #include "llvm/MC/MCSubtargetInfo.h"
  58. #include "llvm/MC/MCTargetOptions.h"
  59. #include "llvm/MC/MCTargetOptionsCommandFlags.h"
  60. #include "llvm/MC/TargetRegistry.h"
  61. #include "llvm/Object/MachO.h"
  62. #include "llvm/Object/ObjectFile.h"
  63. #include "llvm/Object/SymbolicFile.h"
  64. #include "llvm/Support/Allocator.h"
  65. #include "llvm/Support/Casting.h"
  66. #include "llvm/Support/Compiler.h"
  67. #include "llvm/Support/DJB.h"
  68. #include "llvm/Support/DataExtractor.h"
  69. #include "llvm/Support/Error.h"
  70. #include "llvm/Support/ErrorHandling.h"
  71. #include "llvm/Support/ErrorOr.h"
  72. #include "llvm/Support/FileSystem.h"
  73. #include "llvm/Support/Format.h"
  74. #include "llvm/Support/LEB128.h"
  75. #include "llvm/Support/MathExtras.h"
  76. #include "llvm/Support/MemoryBuffer.h"
  77. #include "llvm/Support/Path.h"
  78. #include "llvm/Support/ThreadPool.h"
  79. #include "llvm/Support/ToolOutputFile.h"
  80. #include "llvm/Support/WithColor.h"
  81. #include "llvm/Support/raw_ostream.h"
  82. #include "llvm/Target/TargetMachine.h"
  83. #include "llvm/Target/TargetOptions.h"
  84. #include <algorithm>
  85. #include <cassert>
  86. #include <cinttypes>
  87. #include <climits>
  88. #include <cstdint>
  89. #include <cstdlib>
  90. #include <cstring>
  91. #include <limits>
  92. #include <map>
  93. #include <memory>
  94. #include <optional>
  95. #include <string>
  96. #include <system_error>
  97. #include <tuple>
  98. #include <utility>
  99. #include <vector>
  100. namespace llvm {
  101. static mc::RegisterMCTargetOptionsFlags MOF;
  102. namespace dsymutil {
  103. static Error copySwiftInterfaces(
  104. const std::map<std::string, std::string> &ParseableSwiftInterfaces,
  105. StringRef Architecture, const LinkOptions &Options) {
  106. std::error_code EC;
  107. SmallString<128> InputPath;
  108. SmallString<128> Path;
  109. sys::path::append(Path, *Options.ResourceDir, "Swift", Architecture);
  110. if ((EC = sys::fs::create_directories(Path.str(), true,
  111. sys::fs::perms::all_all)))
  112. return make_error<StringError>(
  113. "cannot create directory: " + toString(errorCodeToError(EC)), EC);
  114. unsigned BaseLength = Path.size();
  115. for (auto &I : ParseableSwiftInterfaces) {
  116. StringRef ModuleName = I.first;
  117. StringRef InterfaceFile = I.second;
  118. if (!Options.PrependPath.empty()) {
  119. InputPath.clear();
  120. sys::path::append(InputPath, Options.PrependPath, InterfaceFile);
  121. InterfaceFile = InputPath;
  122. }
  123. sys::path::append(Path, ModuleName);
  124. Path.append(".swiftinterface");
  125. if (Options.Verbose)
  126. outs() << "copy parseable Swift interface " << InterfaceFile << " -> "
  127. << Path.str() << '\n';
  128. // copy_file attempts an APFS clone first, so this should be cheap.
  129. if ((EC = sys::fs::copy_file(InterfaceFile, Path.str())))
  130. warn(Twine("cannot copy parseable Swift interface ") + InterfaceFile +
  131. ": " + toString(errorCodeToError(EC)));
  132. Path.resize(BaseLength);
  133. }
  134. return Error::success();
  135. }
  136. /// Report a warning to the user, optionally including information about a
  137. /// specific \p DIE related to the warning.
  138. void DwarfLinkerForBinary::reportWarning(const Twine &Warning,
  139. StringRef Context,
  140. const DWARFDie *DIE) const {
  141. warn(Warning, Context);
  142. if (!Options.Verbose || !DIE)
  143. return;
  144. DIDumpOptions DumpOpts;
  145. DumpOpts.ChildRecurseDepth = 0;
  146. DumpOpts.Verbose = Options.Verbose;
  147. WithColor::note() << " in DIE:\n";
  148. DIE->dump(errs(), 6 /* Indent */, DumpOpts);
  149. }
  150. bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple,
  151. raw_fd_ostream &OutFile) {
  152. if (Options.NoOutput)
  153. return true;
  154. Streamer = std::make_unique<DwarfStreamer>(
  155. Options.FileType, OutFile, Options.Translator,
  156. [&](const Twine &Error, StringRef Context, const DWARFDie *) {
  157. error(Error, Context);
  158. },
  159. [&](const Twine &Warning, StringRef Context, const DWARFDie *) {
  160. warn(Warning, Context);
  161. });
  162. return Streamer->init(TheTriple, "__DWARF");
  163. }
  164. ErrorOr<const object::ObjectFile &>
  165. DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
  166. const Triple &Triple) {
  167. auto ObjectEntry =
  168. BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp());
  169. if (!ObjectEntry) {
  170. auto Err = ObjectEntry.takeError();
  171. reportWarning(Twine(Obj.getObjectFilename()) + ": " +
  172. toString(std::move(Err)),
  173. Obj.getObjectFilename());
  174. return errorToErrorCode(std::move(Err));
  175. }
  176. auto Object = ObjectEntry->getObject(Triple);
  177. if (!Object) {
  178. auto Err = Object.takeError();
  179. reportWarning(Twine(Obj.getObjectFilename()) + ": " +
  180. toString(std::move(Err)),
  181. Obj.getObjectFilename());
  182. return errorToErrorCode(std::move(Err));
  183. }
  184. return *Object;
  185. }
  186. static Error remarksErrorHandler(const DebugMapObject &DMO,
  187. DwarfLinkerForBinary &Linker,
  188. std::unique_ptr<FileError> FE) {
  189. bool IsArchive = DMO.getObjectFilename().endswith(")");
  190. // Don't report errors for missing remark files from static
  191. // archives.
  192. if (!IsArchive)
  193. return Error(std::move(FE));
  194. std::string Message = FE->message();
  195. Error E = FE->takeError();
  196. Error NewE = handleErrors(std::move(E), [&](std::unique_ptr<ECError> EC) {
  197. if (EC->convertToErrorCode() != std::errc::no_such_file_or_directory)
  198. return Error(std::move(EC));
  199. Linker.reportWarning(Message, DMO.getObjectFilename());
  200. return Error(Error::success());
  201. });
  202. if (!NewE)
  203. return Error::success();
  204. return createFileError(FE->getFileName(), std::move(NewE));
  205. }
  206. static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
  207. StringRef ArchName, const remarks::RemarkLinker &RL) {
  208. // Make sure we don't create the directories and the file if there is nothing
  209. // to serialize.
  210. if (RL.empty())
  211. return Error::success();
  212. SmallString<128> InputPath;
  213. SmallString<128> Path;
  214. // Create the "Remarks" directory in the "Resources" directory.
  215. sys::path::append(Path, *Options.ResourceDir, "Remarks");
  216. if (std::error_code EC = sys::fs::create_directories(Path.str(), true,
  217. sys::fs::perms::all_all))
  218. return errorCodeToError(EC);
  219. // Append the file name.
  220. // For fat binaries, also append a dash and the architecture name.
  221. sys::path::append(Path, sys::path::filename(BinaryPath));
  222. if (Options.NumDebugMaps > 1) {
  223. // More than one debug map means we have a fat binary.
  224. Path += '-';
  225. Path += ArchName;
  226. }
  227. std::error_code EC;
  228. raw_fd_ostream OS(Options.NoOutput ? "-" : Path.str(), EC,
  229. Options.RemarksFormat == remarks::Format::Bitstream
  230. ? sys::fs::OF_None
  231. : sys::fs::OF_Text);
  232. if (EC)
  233. return errorCodeToError(EC);
  234. if (Error E = RL.serialize(OS, Options.RemarksFormat))
  235. return E;
  236. return Error::success();
  237. }
  238. ErrorOr<DWARFFile &>
  239. DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
  240. const DebugMap &DebugMap,
  241. remarks::RemarkLinker &RL) {
  242. auto ErrorOrObj = loadObject(Obj, DebugMap.getTriple());
  243. if (ErrorOrObj) {
  244. ContextForLinking.push_back(
  245. std::unique_ptr<DWARFContext>(DWARFContext::create(*ErrorOrObj)));
  246. AddressMapForLinking.push_back(
  247. std::make_unique<AddressManager>(*this, *ErrorOrObj, Obj));
  248. ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
  249. Obj.getObjectFilename(), ContextForLinking.back().get(),
  250. AddressMapForLinking.back().get(),
  251. Obj.empty() ? Obj.getWarnings() : EmptyWarnings));
  252. Error E = RL.link(*ErrorOrObj);
  253. if (Error NewE = handleErrors(
  254. std::move(E), [&](std::unique_ptr<FileError> EC) -> Error {
  255. return remarksErrorHandler(Obj, *this, std::move(EC));
  256. }))
  257. return errorToErrorCode(std::move(NewE));
  258. return *ObjectsForLinking.back();
  259. }
  260. return ErrorOrObj.getError();
  261. }
  262. static bool binaryHasStrippableSwiftReflectionSections(
  263. const DebugMap &Map, const LinkOptions &Options, BinaryHolder &BinHolder) {
  264. // If the input binary has strippable swift5 reflection sections, there is no
  265. // need to copy them to the .dSYM. Only copy them for binaries where the
  266. // linker omitted the reflection metadata.
  267. if (!Map.getBinaryPath().empty() &&
  268. Options.FileType == OutputFileType::Object) {
  269. auto ObjectEntry = BinHolder.getObjectEntry(Map.getBinaryPath());
  270. // If ObjectEntry or Object has an error, no binary exists, therefore no
  271. // reflection sections exist.
  272. if (!ObjectEntry) {
  273. // Any errors will be diagnosed later in the main loop, ignore them here.
  274. llvm::consumeError(ObjectEntry.takeError());
  275. return false;
  276. }
  277. auto Object =
  278. ObjectEntry->getObjectAs<object::MachOObjectFile>(Map.getTriple());
  279. if (!Object) {
  280. // Any errors will be diagnosed later in the main loop, ignore them here.
  281. llvm::consumeError(Object.takeError());
  282. return false;
  283. }
  284. for (auto &Section : Object->sections()) {
  285. llvm::Expected<llvm::StringRef> NameOrErr =
  286. Object->getSectionName(Section.getRawDataRefImpl());
  287. if (!NameOrErr) {
  288. llvm::consumeError(NameOrErr.takeError());
  289. continue;
  290. }
  291. NameOrErr->consume_back("__TEXT");
  292. auto ReflectionSectionKind =
  293. Object->mapReflectionSectionNameToEnumValue(*NameOrErr);
  294. if (Object->isReflectionSectionStrippable(ReflectionSectionKind)) {
  295. return true;
  296. }
  297. }
  298. }
  299. return false;
  300. }
  301. /// Calculate the start of the strippable swift reflection sections in Dwarf.
  302. /// Note that there's an assumption that the reflection sections will appear
  303. /// in alphabetic order.
  304. static std::vector<uint64_t>
  305. calculateStartOfStrippableReflectionSections(const DebugMap &Map) {
  306. using llvm::binaryformat::Swift5ReflectionSectionKind;
  307. uint64_t AssocTySize = 0;
  308. uint64_t FieldMdSize = 0;
  309. for (const auto &Obj : Map.objects()) {
  310. auto OF =
  311. llvm::object::ObjectFile::createObjectFile(Obj->getObjectFilename());
  312. if (!OF) {
  313. llvm::consumeError(OF.takeError());
  314. continue;
  315. }
  316. if (auto *MO = dyn_cast<llvm::object::MachOObjectFile>(OF->getBinary())) {
  317. for (auto &Section : MO->sections()) {
  318. llvm::Expected<llvm::StringRef> NameOrErr =
  319. MO->getSectionName(Section.getRawDataRefImpl());
  320. if (!NameOrErr) {
  321. llvm::consumeError(NameOrErr.takeError());
  322. continue;
  323. }
  324. NameOrErr->consume_back("__TEXT");
  325. auto ReflSectionKind =
  326. MO->mapReflectionSectionNameToEnumValue(*NameOrErr);
  327. switch (ReflSectionKind) {
  328. case Swift5ReflectionSectionKind::assocty:
  329. AssocTySize += Section.getSize();
  330. break;
  331. case Swift5ReflectionSectionKind::fieldmd:
  332. FieldMdSize += Section.getSize();
  333. break;
  334. default:
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. // Initialize the vector with enough space to fit every reflection section
  341. // kind.
  342. std::vector<uint64_t> SectionToOffset(Swift5ReflectionSectionKind::last, 0);
  343. SectionToOffset[Swift5ReflectionSectionKind::assocty] = 0;
  344. SectionToOffset[Swift5ReflectionSectionKind::fieldmd] =
  345. llvm::alignTo(AssocTySize, 4);
  346. SectionToOffset[Swift5ReflectionSectionKind::reflstr] = llvm::alignTo(
  347. SectionToOffset[Swift5ReflectionSectionKind::fieldmd] + FieldMdSize, 4);
  348. return SectionToOffset;
  349. }
  350. void DwarfLinkerForBinary::collectRelocationsToApplyToSwiftReflectionSections(
  351. const object::SectionRef &Section, StringRef &Contents,
  352. const llvm::object::MachOObjectFile *MO,
  353. const std::vector<uint64_t> &SectionToOffsetInDwarf,
  354. const llvm::dsymutil::DebugMapObject *Obj,
  355. std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply)
  356. const {
  357. for (auto It = Section.relocation_begin(); It != Section.relocation_end();
  358. ++It) {
  359. object::DataRefImpl RelocDataRef = It->getRawDataRefImpl();
  360. MachO::any_relocation_info MachOReloc = MO->getRelocation(RelocDataRef);
  361. if (!object::MachOObjectFile::isMachOPairedReloc(
  362. MO->getAnyRelocationType(MachOReloc), MO->getArch())) {
  363. reportWarning(
  364. "Unimplemented relocation type in strippable reflection section ",
  365. Obj->getObjectFilename());
  366. continue;
  367. }
  368. auto CalculateAddressOfSymbolInDwarfSegment =
  369. [&]() -> std::optional<int64_t> {
  370. auto Symbol = It->getSymbol();
  371. auto SymbolAbsoluteAddress = Symbol->getAddress();
  372. if (!SymbolAbsoluteAddress)
  373. return {};
  374. auto Section = Symbol->getSection();
  375. if (!Section) {
  376. llvm::consumeError(Section.takeError());
  377. return {};
  378. }
  379. if ((*Section)->getObject()->section_end() == *Section)
  380. return {};
  381. auto SectionStart = (*Section)->getAddress();
  382. auto SymbolAddressInSection = *SymbolAbsoluteAddress - SectionStart;
  383. auto SectionName = (*Section)->getName();
  384. if (!SectionName)
  385. return {};
  386. auto ReflSectionKind =
  387. MO->mapReflectionSectionNameToEnumValue(*SectionName);
  388. int64_t SectionStartInLinkedBinary =
  389. SectionToOffsetInDwarf[ReflSectionKind];
  390. auto Addr = SectionStartInLinkedBinary + SymbolAddressInSection;
  391. return Addr;
  392. };
  393. // The first symbol should always be in the section we're currently
  394. // iterating over.
  395. auto FirstSymbolAddress = CalculateAddressOfSymbolInDwarfSegment();
  396. ++It;
  397. bool ShouldSubtractDwarfVM = false;
  398. // For the second symbol there are two possibilities.
  399. std::optional<int64_t> SecondSymbolAddress;
  400. auto Sym = It->getSymbol();
  401. if (Sym != MO->symbol_end()) {
  402. Expected<StringRef> SymbolName = Sym->getName();
  403. if (SymbolName) {
  404. if (const auto *Mapping = Obj->lookupSymbol(*SymbolName)) {
  405. // First possibility: the symbol exists in the binary, and exists in a
  406. // non-strippable section (for example, typeref, or __TEXT,__const),
  407. // in which case we look up its address in the binary, which dsymutil
  408. // will copy verbatim.
  409. SecondSymbolAddress = Mapping->getValue().BinaryAddress;
  410. // Since the symbols live in different segments, we have to substract
  411. // the start of the Dwarf's vmaddr so the value calculated points to
  412. // the correct place.
  413. ShouldSubtractDwarfVM = true;
  414. }
  415. }
  416. }
  417. if (!SecondSymbolAddress) {
  418. // Second possibility, this symbol is not present in the main binary, and
  419. // must be in one of the strippable sections (for example, reflstr).
  420. // Calculate its address in the same way as we did the first one.
  421. SecondSymbolAddress = CalculateAddressOfSymbolInDwarfSegment();
  422. }
  423. if (!FirstSymbolAddress || !SecondSymbolAddress)
  424. continue;
  425. auto SectionName = Section.getName();
  426. if (!SectionName)
  427. continue;
  428. int32_t Addend;
  429. memcpy(&Addend, Contents.data() + It->getOffset(), sizeof(int32_t));
  430. int32_t Value = (*SecondSymbolAddress + Addend) - *FirstSymbolAddress;
  431. auto ReflSectionKind =
  432. MO->mapReflectionSectionNameToEnumValue(*SectionName);
  433. uint64_t AddressFromDwarfVM =
  434. SectionToOffsetInDwarf[ReflSectionKind] + It->getOffset();
  435. RelocationsToApply.emplace_back(AddressFromDwarfVM, Value,
  436. ShouldSubtractDwarfVM);
  437. }
  438. }
  439. void DwarfLinkerForBinary::copySwiftReflectionMetadata(
  440. const llvm::dsymutil::DebugMapObject *Obj, DwarfStreamer *Streamer,
  441. std::vector<uint64_t> &SectionToOffsetInDwarf,
  442. std::vector<MachOUtils::DwarfRelocationApplicationInfo>
  443. &RelocationsToApply) {
  444. using binaryformat::Swift5ReflectionSectionKind;
  445. auto OF =
  446. llvm::object::ObjectFile::createObjectFile(Obj->getObjectFilename());
  447. if (!OF) {
  448. llvm::consumeError(OF.takeError());
  449. return;
  450. }
  451. if (auto *MO = dyn_cast<llvm::object::MachOObjectFile>(OF->getBinary())) {
  452. // Collect the swift reflection sections before emitting them. This is
  453. // done so we control the order they're emitted.
  454. std::array<std::optional<object::SectionRef>,
  455. Swift5ReflectionSectionKind::last + 1>
  456. SwiftSections;
  457. for (auto &Section : MO->sections()) {
  458. llvm::Expected<llvm::StringRef> NameOrErr =
  459. MO->getSectionName(Section.getRawDataRefImpl());
  460. if (!NameOrErr) {
  461. llvm::consumeError(NameOrErr.takeError());
  462. continue;
  463. }
  464. NameOrErr->consume_back("__TEXT");
  465. auto ReflSectionKind =
  466. MO->mapReflectionSectionNameToEnumValue(*NameOrErr);
  467. if (MO->isReflectionSectionStrippable(ReflSectionKind))
  468. SwiftSections[ReflSectionKind] = Section;
  469. }
  470. // Make sure we copy the sections in alphabetic order.
  471. auto SectionKindsToEmit = {Swift5ReflectionSectionKind::assocty,
  472. Swift5ReflectionSectionKind::fieldmd,
  473. Swift5ReflectionSectionKind::reflstr};
  474. for (auto SectionKind : SectionKindsToEmit) {
  475. if (!SwiftSections[SectionKind])
  476. continue;
  477. auto &Section = *SwiftSections[SectionKind];
  478. llvm::Expected<llvm::StringRef> SectionContents = Section.getContents();
  479. if (!SectionContents)
  480. continue;
  481. const auto *MO =
  482. llvm::cast<llvm::object::MachOObjectFile>(Section.getObject());
  483. collectRelocationsToApplyToSwiftReflectionSections(
  484. Section, *SectionContents, MO, SectionToOffsetInDwarf, Obj,
  485. RelocationsToApply);
  486. // Update the section start with the current section's contribution, so
  487. // the next section we copy from a different .o file points to the correct
  488. // place.
  489. SectionToOffsetInDwarf[SectionKind] += Section.getSize();
  490. Streamer->emitSwiftReflectionSection(SectionKind, *SectionContents,
  491. Section.getAlignment().value(),
  492. Section.getSize());
  493. }
  494. }
  495. }
  496. bool DwarfLinkerForBinary::link(const DebugMap &Map) {
  497. if (!createStreamer(Map.getTriple(), OutFile))
  498. return false;
  499. ObjectsForLinking.clear();
  500. ContextForLinking.clear();
  501. AddressMapForLinking.clear();
  502. DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath());
  503. DWARFLinker GeneralLinker(Streamer.get(), DwarfLinkerClient::Dsymutil);
  504. remarks::RemarkLinker RL;
  505. if (!Options.RemarksPrependPath.empty())
  506. RL.setExternalFilePrependPath(Options.RemarksPrependPath);
  507. GeneralLinker.setObjectPrefixMap(&Options.ObjectPrefixMap);
  508. std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) {
  509. assert(Options.Translator);
  510. return Options.Translator(Input);
  511. };
  512. GeneralLinker.setVerbosity(Options.Verbose);
  513. GeneralLinker.setStatistics(Options.Statistics);
  514. GeneralLinker.setVerifyInputDWARF(Options.VerifyInputDWARF);
  515. GeneralLinker.setNoOutput(Options.NoOutput);
  516. GeneralLinker.setNoODR(Options.NoODR);
  517. GeneralLinker.setUpdate(Options.Update);
  518. GeneralLinker.setNumThreads(Options.Threads);
  519. GeneralLinker.setPrependPath(Options.PrependPath);
  520. GeneralLinker.setKeepFunctionForStatic(Options.KeepFunctionForStatic);
  521. if (Options.Translator)
  522. GeneralLinker.setStringsTranslator(TranslationLambda);
  523. GeneralLinker.setWarningHandler(
  524. [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) {
  525. reportWarning(Warning, Context, DIE);
  526. });
  527. GeneralLinker.setErrorHandler(
  528. [&](const Twine &Error, StringRef Context, const DWARFDie *) {
  529. error(Error, Context);
  530. });
  531. objFileLoader Loader = [&DebugMap, &RL,
  532. this](StringRef ContainerName,
  533. StringRef Path) -> ErrorOr<DWARFFile &> {
  534. auto &Obj = DebugMap.addDebugMapObject(
  535. Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO);
  536. if (auto ErrorOrObj = loadObject(Obj, DebugMap, RL)) {
  537. return *ErrorOrObj;
  538. } else {
  539. // Try and emit more helpful warnings by applying some heuristics.
  540. StringRef ObjFile = ContainerName;
  541. bool IsClangModule = sys::path::extension(Path).equals(".pcm");
  542. bool IsArchive = ObjFile.endswith(")");
  543. if (IsClangModule) {
  544. StringRef ModuleCacheDir = sys::path::parent_path(Path);
  545. if (sys::fs::exists(ModuleCacheDir)) {
  546. // If the module's parent directory exists, we assume that the
  547. // module cache has expired and was pruned by clang. A more
  548. // adventurous dsymutil would invoke clang to rebuild the module
  549. // now.
  550. if (!ModuleCacheHintDisplayed) {
  551. WithColor::note()
  552. << "The clang module cache may have expired since "
  553. "this object file was built. Rebuilding the "
  554. "object file will rebuild the module cache.\n";
  555. ModuleCacheHintDisplayed = true;
  556. }
  557. } else if (IsArchive) {
  558. // If the module cache directory doesn't exist at all and the
  559. // object file is inside a static library, we assume that the
  560. // static library was built on a different machine. We don't want
  561. // to discourage module debugging for convenience libraries within
  562. // a project though.
  563. if (!ArchiveHintDisplayed) {
  564. WithColor::note()
  565. << "Linking a static library that was built with "
  566. "-gmodules, but the module cache was not found. "
  567. "Redistributable static libraries should never be "
  568. "built with module debugging enabled. The debug "
  569. "experience will be degraded due to incomplete "
  570. "debug information.\n";
  571. ArchiveHintDisplayed = true;
  572. }
  573. }
  574. }
  575. return ErrorOrObj.getError();
  576. }
  577. llvm_unreachable("Unhandled DebugMap object");
  578. };
  579. GeneralLinker.setSwiftInterfacesMap(&ParseableSwiftInterfaces);
  580. bool ReflectionSectionsPresentInBinary = false;
  581. // If there is no output specified, no point in checking the binary for swift5
  582. // reflection sections.
  583. if (!Options.NoOutput) {
  584. ReflectionSectionsPresentInBinary =
  585. binaryHasStrippableSwiftReflectionSections(Map, Options, BinHolder);
  586. }
  587. std::vector<MachOUtils::DwarfRelocationApplicationInfo> RelocationsToApply;
  588. if (!Options.NoOutput && !ReflectionSectionsPresentInBinary) {
  589. auto SectionToOffsetInDwarf =
  590. calculateStartOfStrippableReflectionSections(Map);
  591. for (const auto &Obj : Map.objects())
  592. copySwiftReflectionMetadata(Obj.get(), Streamer.get(),
  593. SectionToOffsetInDwarf, RelocationsToApply);
  594. }
  595. uint16_t MaxDWARFVersion = 0;
  596. std::function<void(const DWARFUnit &Unit)> OnCUDieLoaded =
  597. [&MaxDWARFVersion](const DWARFUnit &Unit) {
  598. MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion);
  599. };
  600. for (const auto &Obj : Map.objects()) {
  601. // N_AST objects (swiftmodule files) should get dumped directly into the
  602. // appropriate DWARF section.
  603. if (Obj->getType() == MachO::N_AST) {
  604. if (Options.Verbose)
  605. outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
  606. StringRef File = Obj->getObjectFilename();
  607. auto ErrorOrMem = MemoryBuffer::getFile(File);
  608. if (!ErrorOrMem) {
  609. warn("Could not open '" + File + "'\n");
  610. continue;
  611. }
  612. sys::fs::file_status Stat;
  613. if (auto Err = sys::fs::status(File, Stat)) {
  614. warn(Err.message());
  615. continue;
  616. }
  617. if (!Options.NoTimestamp) {
  618. // The modification can have sub-second precision so we need to cast
  619. // away the extra precision that's not present in the debug map.
  620. auto ModificationTime =
  621. std::chrono::time_point_cast<std::chrono::seconds>(
  622. Stat.getLastModificationTime());
  623. if (Obj->getTimestamp() != sys::TimePoint<>() &&
  624. ModificationTime != Obj->getTimestamp()) {
  625. // Not using the helper here as we can easily stream TimePoint<>.
  626. WithColor::warning()
  627. << File << ": timestamp mismatch between swift interface file ("
  628. << sys::TimePoint<>(ModificationTime) << ") and debug map ("
  629. << sys::TimePoint<>(Obj->getTimestamp()) << ")\n";
  630. continue;
  631. }
  632. }
  633. // Copy the module into the .swift_ast section.
  634. if (!Options.NoOutput)
  635. Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer());
  636. continue;
  637. }
  638. if (auto ErrorOrObj = loadObject(*Obj, Map, RL))
  639. GeneralLinker.addObjectFile(*ErrorOrObj, Loader, OnCUDieLoaded);
  640. else {
  641. ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
  642. Obj->getObjectFilename(), nullptr, nullptr,
  643. Obj->empty() ? Obj->getWarnings() : EmptyWarnings));
  644. GeneralLinker.addObjectFile(*ObjectsForLinking.back());
  645. }
  646. }
  647. // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway.
  648. if (MaxDWARFVersion == 0)
  649. MaxDWARFVersion = 3;
  650. if (Error E = GeneralLinker.setTargetDWARFVersion(MaxDWARFVersion))
  651. return error(toString(std::move(E)));
  652. switch (Options.TheAccelTableKind) {
  653. case DsymutilAccelTableKind::Apple:
  654. GeneralLinker.addAccelTableKind(DwarfLinkerAccelTableKind::Apple);
  655. break;
  656. case DsymutilAccelTableKind::Dwarf:
  657. GeneralLinker.addAccelTableKind(DwarfLinkerAccelTableKind::DebugNames);
  658. break;
  659. case DsymutilAccelTableKind::Pub:
  660. GeneralLinker.addAccelTableKind(DwarfLinkerAccelTableKind::Pub);
  661. break;
  662. case DsymutilAccelTableKind::Default:
  663. if (MaxDWARFVersion >= 5)
  664. GeneralLinker.addAccelTableKind(DwarfLinkerAccelTableKind::DebugNames);
  665. else
  666. GeneralLinker.addAccelTableKind(DwarfLinkerAccelTableKind::Apple);
  667. break;
  668. case DsymutilAccelTableKind::None:
  669. // Nothing to do.
  670. break;
  671. }
  672. // link debug info for loaded object files.
  673. if (Error E = GeneralLinker.link())
  674. return error(toString(std::move(E)));
  675. StringRef ArchName = Map.getTriple().getArchName();
  676. if (Error E = emitRemarks(Options, Map.getBinaryPath(), ArchName, RL))
  677. return error(toString(std::move(E)));
  678. if (Options.NoOutput)
  679. return true;
  680. if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) {
  681. StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch());
  682. if (auto E =
  683. copySwiftInterfaces(ParseableSwiftInterfaces, ArchName, Options))
  684. return error(toString(std::move(E)));
  685. }
  686. if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() &&
  687. Options.FileType == OutputFileType::Object)
  688. return MachOUtils::generateDsymCompanion(
  689. Options.VFS, Map, Options.Translator,
  690. *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply);
  691. Streamer->finish();
  692. return true;
  693. }
  694. /// Iterate over the relocations of the given \p Section and
  695. /// store the ones that correspond to debug map entries into the
  696. /// ValidRelocs array.
  697. void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
  698. const object::SectionRef &Section, const object::MachOObjectFile &Obj,
  699. const DebugMapObject &DMO, std::vector<ValidReloc> &ValidRelocs) {
  700. Expected<StringRef> ContentsOrErr = Section.getContents();
  701. if (!ContentsOrErr) {
  702. consumeError(ContentsOrErr.takeError());
  703. Linker.reportWarning("error reading section", DMO.getObjectFilename());
  704. return;
  705. }
  706. DataExtractor Data(*ContentsOrErr, Obj.isLittleEndian(), 0);
  707. bool SkipNext = false;
  708. for (const object::RelocationRef &Reloc : Section.relocations()) {
  709. if (SkipNext) {
  710. SkipNext = false;
  711. continue;
  712. }
  713. object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl();
  714. MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef);
  715. if (object::MachOObjectFile::isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc),
  716. Obj.getArch())) {
  717. SkipNext = true;
  718. Linker.reportWarning("unsupported relocation in " + *Section.getName() +
  719. " section.",
  720. DMO.getObjectFilename());
  721. continue;
  722. }
  723. unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
  724. uint64_t Offset64 = Reloc.getOffset();
  725. if ((RelocSize != 4 && RelocSize != 8)) {
  726. Linker.reportWarning("unsupported relocation in " + *Section.getName() +
  727. " section.",
  728. DMO.getObjectFilename());
  729. continue;
  730. }
  731. uint64_t OffsetCopy = Offset64;
  732. // Mach-o uses REL relocations, the addend is at the relocation offset.
  733. uint64_t Addend = Data.getUnsigned(&OffsetCopy, RelocSize);
  734. uint64_t SymAddress;
  735. int64_t SymOffset;
  736. if (Obj.isRelocationScattered(MachOReloc)) {
  737. // The address of the base symbol for scattered relocations is
  738. // stored in the reloc itself. The actual addend will store the
  739. // base address plus the offset.
  740. SymAddress = Obj.getScatteredRelocationValue(MachOReloc);
  741. SymOffset = int64_t(Addend) - SymAddress;
  742. } else {
  743. SymAddress = Addend;
  744. SymOffset = 0;
  745. }
  746. auto Sym = Reloc.getSymbol();
  747. if (Sym != Obj.symbol_end()) {
  748. Expected<StringRef> SymbolName = Sym->getName();
  749. if (!SymbolName) {
  750. consumeError(SymbolName.takeError());
  751. Linker.reportWarning("error getting relocation symbol name.",
  752. DMO.getObjectFilename());
  753. continue;
  754. }
  755. if (const auto *Mapping = DMO.lookupSymbol(*SymbolName))
  756. ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping);
  757. } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) {
  758. // Do not store the addend. The addend was the address of the symbol in
  759. // the object file, the address in the binary that is stored in the debug
  760. // map doesn't need to be offset.
  761. ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping);
  762. }
  763. }
  764. }
  765. /// Dispatch the valid relocation finding logic to the
  766. /// appropriate handler depending on the object file format.
  767. bool DwarfLinkerForBinary::AddressManager::findValidRelocs(
  768. const object::SectionRef &Section, const object::ObjectFile &Obj,
  769. const DebugMapObject &DMO, std::vector<ValidReloc> &Relocs) {
  770. // Dispatch to the right handler depending on the file type.
  771. if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
  772. findValidRelocsMachO(Section, *MachOObj, DMO, Relocs);
  773. else
  774. Linker.reportWarning(Twine("unsupported object file type: ") +
  775. Obj.getFileName(),
  776. DMO.getObjectFilename());
  777. if (Relocs.empty())
  778. return false;
  779. // Sort the relocations by offset. We will walk the DIEs linearly in
  780. // the file, this allows us to just keep an index in the relocation
  781. // array that we advance during our walk, rather than resorting to
  782. // some associative container. See DwarfLinkerForBinary::NextValidReloc.
  783. llvm::sort(Relocs);
  784. return true;
  785. }
  786. /// Look for relocations in the debug_info and debug_addr section that match
  787. /// entries in the debug map. These relocations will drive the Dwarf link by
  788. /// indicating which DIEs refer to symbols present in the linked binary.
  789. /// \returns whether there are any valid relocations in the debug info.
  790. bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections(
  791. const object::ObjectFile &Obj, const DebugMapObject &DMO) {
  792. // Find the debug_info section.
  793. bool FoundValidRelocs = false;
  794. for (const object::SectionRef &Section : Obj.sections()) {
  795. StringRef SectionName;
  796. if (Expected<StringRef> NameOrErr = Section.getName())
  797. SectionName = *NameOrErr;
  798. else
  799. consumeError(NameOrErr.takeError());
  800. SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
  801. if (SectionName == "debug_info")
  802. FoundValidRelocs |=
  803. findValidRelocs(Section, Obj, DMO, ValidDebugInfoRelocs);
  804. if (SectionName == "debug_addr")
  805. FoundValidRelocs |=
  806. findValidRelocs(Section, Obj, DMO, ValidDebugAddrRelocs);
  807. }
  808. return FoundValidRelocs;
  809. }
  810. std::vector<DwarfLinkerForBinary::AddressManager::ValidReloc>
  811. DwarfLinkerForBinary::AddressManager::getRelocations(
  812. const std::vector<ValidReloc> &Relocs, uint64_t StartPos, uint64_t EndPos) {
  813. std::vector<DwarfLinkerForBinary::AddressManager::ValidReloc> Res;
  814. auto CurReloc = partition_point(Relocs, [StartPos](const ValidReloc &Reloc) {
  815. return Reloc.Offset < StartPos;
  816. });
  817. while (CurReloc != Relocs.end() && CurReloc->Offset >= StartPos &&
  818. CurReloc->Offset < EndPos) {
  819. Res.push_back(*CurReloc);
  820. CurReloc++;
  821. }
  822. return Res;
  823. }
  824. void DwarfLinkerForBinary::AddressManager::printReloc(const ValidReloc &Reloc) {
  825. const auto &Mapping = Reloc.Mapping->getValue();
  826. const uint64_t ObjectAddress = Mapping.ObjectAddress
  827. ? uint64_t(*Mapping.ObjectAddress)
  828. : std::numeric_limits<uint64_t>::max();
  829. outs() << "Found valid debug map entry: " << Reloc.Mapping->getKey() << "\t"
  830. << format("0x%016" PRIx64 " => 0x%016" PRIx64 "\n", ObjectAddress,
  831. uint64_t(Mapping.BinaryAddress));
  832. }
  833. void DwarfLinkerForBinary::AddressManager::fillDieInfo(
  834. const ValidReloc &Reloc, CompileUnit::DIEInfo &Info) {
  835. Info.AddrAdjust = relocate(Reloc);
  836. if (Reloc.Mapping->getValue().ObjectAddress)
  837. Info.AddrAdjust -= uint64_t(*Reloc.Mapping->getValue().ObjectAddress);
  838. Info.InDebugMap = true;
  839. }
  840. bool DwarfLinkerForBinary::AddressManager::hasValidRelocationAt(
  841. const std::vector<ValidReloc> &AllRelocs, uint64_t StartOffset,
  842. uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
  843. std::vector<ValidReloc> Relocs =
  844. getRelocations(AllRelocs, StartOffset, EndOffset);
  845. if (Relocs.size() == 0)
  846. return false;
  847. if (Linker.Options.Verbose)
  848. printReloc(Relocs[0]);
  849. fillDieInfo(Relocs[0], Info);
  850. return true;
  851. }
  852. /// Get the starting and ending (exclusive) offset for the
  853. /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
  854. /// supposed to point to the position of the first attribute described
  855. /// by \p Abbrev.
  856. /// \return [StartOffset, EndOffset) as a pair.
  857. static std::pair<uint64_t, uint64_t>
  858. getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
  859. uint64_t Offset, const DWARFUnit &Unit) {
  860. DataExtractor Data = Unit.getDebugInfoExtractor();
  861. for (unsigned I = 0; I < Idx; ++I)
  862. DWARFFormValue::skipValue(Abbrev->getFormByIndex(I), Data, &Offset,
  863. Unit.getFormParams());
  864. uint64_t End = Offset;
  865. DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End,
  866. Unit.getFormParams());
  867. return std::make_pair(Offset, End);
  868. }
  869. bool DwarfLinkerForBinary::AddressManager::isLiveVariable(
  870. const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
  871. const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
  872. std::optional<uint32_t> LocationIdx =
  873. Abbrev->findAttributeIndex(dwarf::DW_AT_location);
  874. if (!LocationIdx)
  875. return false;
  876. uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
  877. uint64_t LocationOffset, LocationEndOffset;
  878. std::tie(LocationOffset, LocationEndOffset) =
  879. getAttributeOffsets(Abbrev, *LocationIdx, Offset, *DIE.getDwarfUnit());
  880. // FIXME: Support relocations debug_addr.
  881. return hasValidRelocationAt(ValidDebugInfoRelocs, LocationOffset,
  882. LocationEndOffset, MyInfo);
  883. }
  884. bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram(
  885. const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
  886. const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
  887. std::optional<uint32_t> LowPcIdx =
  888. Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
  889. if (!LowPcIdx)
  890. return false;
  891. dwarf::Form Form = Abbrev->getFormByIndex(*LowPcIdx);
  892. if (Form == dwarf::DW_FORM_addr) {
  893. uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
  894. uint64_t LowPcOffset, LowPcEndOffset;
  895. std::tie(LowPcOffset, LowPcEndOffset) =
  896. getAttributeOffsets(Abbrev, *LowPcIdx, Offset, *DIE.getDwarfUnit());
  897. return hasValidRelocationAt(ValidDebugInfoRelocs, LowPcOffset,
  898. LowPcEndOffset, MyInfo);
  899. }
  900. if (Form == dwarf::DW_FORM_addrx) {
  901. std::optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
  902. if (std::optional<uint64_t> AddrOffsetSectionBase =
  903. DIE.getDwarfUnit()->getAddrOffsetSectionBase()) {
  904. uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue();
  905. uint64_t EndOffset =
  906. StartOffset + DIE.getDwarfUnit()->getAddressByteSize();
  907. return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset,
  908. MyInfo);
  909. } else
  910. Linker.reportWarning("no base offset for address table", SrcFileName);
  911. }
  912. return false;
  913. }
  914. uint64_t
  915. DwarfLinkerForBinary::AddressManager::relocate(const ValidReloc &Reloc) const {
  916. return Reloc.Mapping->getValue().BinaryAddress + Reloc.Addend;
  917. }
  918. /// Apply the valid relocations found by findValidRelocs() to
  919. /// the buffer \p Data, taking into account that Data is at \p BaseOffset
  920. /// in the debug_info section.
  921. ///
  922. /// Like for findValidRelocs(), this function must be called with
  923. /// monotonic \p BaseOffset values.
  924. ///
  925. /// \returns whether any reloc has been applied.
  926. bool DwarfLinkerForBinary::AddressManager::applyValidRelocs(
  927. MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
  928. std::vector<ValidReloc> Relocs = getRelocations(
  929. ValidDebugInfoRelocs, BaseOffset, BaseOffset + Data.size());
  930. for (const ValidReloc &CurReloc : Relocs) {
  931. assert(CurReloc.Offset - BaseOffset < Data.size());
  932. assert(CurReloc.Offset - BaseOffset + CurReloc.Size <= Data.size());
  933. char Buf[8];
  934. uint64_t Value = relocate(CurReloc);
  935. for (unsigned I = 0; I != CurReloc.Size; ++I) {
  936. unsigned Index = IsLittleEndian ? I : (CurReloc.Size - I - 1);
  937. Buf[I] = uint8_t(Value >> (Index * 8));
  938. }
  939. assert(CurReloc.Size <= sizeof(Buf));
  940. memcpy(&Data[CurReloc.Offset - BaseOffset], Buf, CurReloc.Size);
  941. }
  942. return Relocs.size() > 0;
  943. }
  944. llvm::Expected<uint64_t>
  945. DwarfLinkerForBinary::AddressManager::relocateIndexedAddr(uint64_t StartOffset,
  946. uint64_t EndOffset) {
  947. std::vector<ValidReloc> Relocs =
  948. getRelocations(ValidDebugAddrRelocs, StartOffset, EndOffset);
  949. if (Relocs.size() == 0)
  950. return createStringError(
  951. std::make_error_code(std::errc::invalid_argument),
  952. "no relocation for offset %llu in debug_addr section", StartOffset);
  953. return relocate(Relocs[0]);
  954. }
  955. bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
  956. const DebugMap &DM, LinkOptions Options) {
  957. DwarfLinkerForBinary Linker(OutFile, BinHolder, std::move(Options));
  958. return Linker.link(DM);
  959. }
  960. } // namespace dsymutil
  961. } // namespace llvm