DwarfLinkerForBinary.cpp 33 KB

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