1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===// 2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// The LLVM Linker 4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file is distributed under the University of Illinois Open Source 6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// License. See LICENSE.TXT for details. 7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "DebugMap.h" 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "BinaryHolder.h" 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "DebugMap.h" 12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "dsymutil.h" 134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/IntervalMap.h" 144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/StringMap.h" 154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h" 164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/CodeGen/AsmPrinter.h" 174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/CodeGen/DIE.h" 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFContext.h" 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCAsmBackend.h" 224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCAsmInfo.h" 234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCContext.h" 244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCCodeEmitter.h" 254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCDwarf.h" 264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCInstrInfo.h" 274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCObjectFileInfo.h" 284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCRegisterInfo.h" 294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCStreamer.h" 30ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Object/MachO.h" 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Dwarf.h" 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/LEB128.h" 334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/TargetRegistry.h" 344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Target/TargetMachine.h" 354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Target/TargetOptions.h" 36ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include <string> 374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include <tuple> 38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 39ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace llvm { 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace dsymutil { 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid warn(const Twine &Warning, const Twine &Context) { 454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << Twine("while processing ") + Context + ":\n"; 464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << Twine("warning: ") + Warning + "\n"; 474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool error(const Twine &Error, const Twine &Context) { 504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << Twine("while processing ") + Context + ":\n"; 514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << Twine("error: ") + Error + "\n"; 524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainartemplate <typename KeyT, typename ValT> 564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarusing HalfOpenIntervalMap = 574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, 584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntervalMapHalfOpenInfo<KeyT>>; 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainartypedef HalfOpenIntervalMap<uint64_t, int64_t> FunctionIntervals; 614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Stores all information relating to a compile unit, be it in 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// its original instance in the object file to its brand new cloned 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// and linked DIE tree. 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass CompileUnit { 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Information gathered about a DIE in the object file. 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines struct DIEInfo { 694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t AddrAdjust; ///< Address offset to apply to the described entity. 704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *Clone; ///< Cloned version of that DIE. 71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t ParentIdx; ///< The index of this DIE's parent. 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Keep; ///< Is the DIE part of the linked output? 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool InDebugMap; ///< Was this DIE's entity found in the map? 74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit(DWARFUnit &OrigUnit, unsigned ID) 774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : OrigUnit(OrigUnit), ID(ID), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(), 784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges(RangeAlloc), UnitRangeAttribute(nullptr) { 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Info.resize(OrigUnit.getNumDIEs()); 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit(CompileUnit &&RHS) 834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : OrigUnit(RHS.OrigUnit), Info(std::move(RHS.Info)), 844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CUDie(std::move(RHS.CUDie)), StartOffset(RHS.StartOffset), 854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NextUnitOffset(RHS.NextUnitOffset), RangeAlloc(), Ranges(RangeAlloc) { 864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The CompileUnit container has been 'reserve()'d with the right 874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // size. We cannot move the IntervalMap anyway. 884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar llvm_unreachable("CompileUnits should not be moved."); 894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFUnit &getOrigUnit() const { return OrigUnit; } 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned getUniqueID() const { return ID; } 944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *getOutputUnitDIE() const { return CUDie.get(); } 964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void setOutputUnitDIE(DIE *Die) { CUDie.reset(Die); } 974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; } 99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; } 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getStartOffset() const { return StartOffset; } 1024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getNextUnitOffset() const { return NextUnitOffset; } 1034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; } 1044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getLowPc() const { return LowPc; } 1064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getHighPc() const { return HighPc; } 1074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *getUnitRangesAttribute() const { return UnitRangeAttribute; } 1094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const FunctionIntervals &getFunctionRanges() const { return Ranges; } 1104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<DIEInteger *> &getRangesAttributes() const { 1114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return RangeAttributes; 1124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<std::pair<DIEInteger *, int64_t>> & 1154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar getLocationAttributes() const { 1164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return LocationAttributes; 1174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Compute the end offset for this unit. Must be 1204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// called after the CU's DIEs have been cloned. 1214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \returns the next unit offset (which is also the current 1224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug_info section size). 1234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t computeNextUnitOffset(); 1244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Keep track of a forward reference to DIE \p Die in \p 1264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// RefUnit by \p Attr. The attribute should be fixed up later to 1274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// point to the absolute offset of \p Die in the debug_info section. 1284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void noteForwardReference(DIE *Die, const CompileUnit *RefUnit, 1294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr); 1304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Apply all fixups recored by noteForwardReference(). 1324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void fixupForwardReferences(); 1334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Add a function range [\p LowPC, \p HighPC) that is 1354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// relocatad by applying offset \p PCOffset. 1364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); 1374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Keep track of a DW_AT_range attribute that we will need to 1394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// patch up later. 1404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void noteRangeAttribute(const DIE &Die, DIEInteger *Attr); 1414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Keep track of a location attribute pointing to a location 1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// list in the debug_loc section. 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void noteLocationAttribute(DIEInteger *Attr, int64_t PcOffset); 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Add a name accelerator entry for \p Die with \p Name 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// which is stored in the string table at \p Offset. 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void addNameAccelerator(const DIE *Die, const char *Name, uint32_t Offset, 1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool SkipPubnamesSection = false); 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Add a type accelerator entry for \p Die with \p Name 1524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// which is stored in the string table at \p Offset. 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void addTypeAccelerator(const DIE *Die, const char *Name, uint32_t Offset); 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar struct AccelInfo { 1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef Name; ///< Name of the entry. 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DIE *Die; ///< DIE this entry describes. 1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t NameOffset; ///< Offset of Name in the string pool. 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool SkipPubSection; ///< Emit this entry only in the apple_* sections. 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AccelInfo(StringRef Name, const DIE *Die, uint32_t NameOffset, 1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool SkipPubSection = false) 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : Name(Name), Die(Die), NameOffset(NameOffset), 1644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SkipPubSection(SkipPubSection) {} 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar }; 1664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<AccelInfo> &getPubnames() const { return Pubnames; } 1684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; } 1694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesprivate: 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFUnit &OrigUnit; 1724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned ID; 1734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. 1744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<DIE> CUDie; ///< Root of the linked DIE tree. 1754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t StartOffset; 1774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t NextUnitOffset; 1784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t LowPc; 1804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t HighPc; 1814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief A list of attributes to fixup with the absolute offset of 1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// a DIE in the debug_info section. 1844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// The offsets for the attributes in this array couldn't be set while 1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// cloning because for cross-cu forward refences the target DIE's 1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// offset isn't known you emit the reference attribute. 1884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<std::tuple<DIE *, const CompileUnit *, DIEInteger *>> 1894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ForwardDIEReferences; 1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionIntervals::Allocator RangeAlloc; 1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief The ranges in that interval map are the PC ranges for 1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// functions in this unit, associated with the PC offset to apply 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// to the addresses to get the linked address. 1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionIntervals Ranges; 1964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief DW_AT_ranges attributes to patch after we have gathered 1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// all the unit's function addresses. 1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @{ 2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DIEInteger *> RangeAttributes; 2014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *UnitRangeAttribute; 2024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @} 2034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Location attributes that need to be transfered from th 2054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// original debug_loc section to the liked one. They are stored 2064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// along with the PC offset that is to be applied to their 2074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// function's address. 2084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<std::pair<DIEInteger *, int64_t>> LocationAttributes; 2094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Accelerator entries for the unit, both for the pub* 2114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// sections and the apple* ones. 2124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @{ 2134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<AccelInfo> Pubnames; 2144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<AccelInfo> Pubtypes; 2154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @} 2164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}; 2174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainaruint64_t CompileUnit::computeNextUnitOffset() { 2194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NextUnitOffset = StartOffset + 11 /* Header size */; 2204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The root DIE might be null, meaning that the Unit had nothing to 2214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // contribute to the linked output. In that case, we will emit the 2224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // unit header without any actual DIE. 2234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CUDie) 2244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NextUnitOffset += CUDie->getSize(); 2254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return NextUnitOffset; 2264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Keep track of a forward cross-cu reference from this unit 2294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// to \p Die that lives in \p RefUnit. 2304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit, 2314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr) { 2324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ForwardDIEReferences.emplace_back(Die, RefUnit, Attr); 2334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Apply all fixups recorded by noteForwardReference(). 2364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::fixupForwardReferences() { 2374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Ref : ForwardDIEReferences) { 2384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *RefDie; 2394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const CompileUnit *RefUnit; 2404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr; 2414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::tie(RefDie, RefUnit, Attr) = Ref; 2424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr->setValue(RefDie->getOffset() + RefUnit->getStartOffset()); 2434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 2444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, 2474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t PcOffset) { 2484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges.insert(FuncLowPc, FuncHighPc, PcOffset); 2494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar this->LowPc = std::min(LowPc, FuncLowPc + PcOffset); 2504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); 2514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::noteRangeAttribute(const DIE &Die, DIEInteger *Attr) { 2544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Die.getTag() != dwarf::DW_TAG_compile_unit) 2554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangeAttributes.push_back(Attr); 2564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 2574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar UnitRangeAttribute = Attr; 2584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::noteLocationAttribute(DIEInteger *Attr, int64_t PcOffset) { 2614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LocationAttributes.emplace_back(Attr, PcOffset); 2624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Add a name accelerator entry for \p Die with \p Name 2654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// which is stored in the string table at \p Offset. 2664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::addNameAccelerator(const DIE *Die, const char *Name, 2674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Offset, bool SkipPubSection) { 2684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Pubnames.emplace_back(Name, Die, Offset, SkipPubSection); 2694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Add a type accelerator entry for \p Die with \p Name 2724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// which is stored in the string table at \p Offset. 2734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid CompileUnit::addTypeAccelerator(const DIE *Die, const char *Name, 2744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Offset) { 2754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Pubtypes.emplace_back(Name, Die, Offset, false); 2764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief A string table that doesn't need relocations. 2794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 2804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// We are doing a final link, no need for a string table that 2814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// has relocation entries for every reference to it. This class 2824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// provides this ablitity by just associating offsets with 2834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// strings. 2844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarclass NonRelocatableStringpool { 2854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarpublic: 2864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Entries are stored into the StringMap and simply linked 2874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// together through the second element of this pair in order to 2884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// keep track of insertion order. 2894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef StringMap<std::pair<uint32_t, StringMapEntryBase *>, BumpPtrAllocator> 2904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MapTy; 2914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NonRelocatableStringpool() 2934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : CurrentEndOffset(0), Sentinel(0), Last(&Sentinel) { 2944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Legacy dsymutil puts an empty string at the start of the line 2954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // table. 2964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar getStringOffset(""); 2974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 2984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Get the offset of string \p S in the string table. This 3004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// can insert a new element or return the offset of a preexisitng 3014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// one. 3024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t getStringOffset(StringRef S); 3034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Get permanent storage for \p S (but do not necessarily 3054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// emit \p S in the output section). 3064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \returns The StringRef that points to permanent storage to use 3074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// in place of \p S. 3084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef internString(StringRef S); 3094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // \brief Return the first entry of the string table. 3114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const MapTy::MapEntryTy *getFirstEntry() const { 3124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return getNextEntry(&Sentinel); 3134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 3144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // \brief Get the entry following \p E in the string table or null 3164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // if \p E was the last entry. 3174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const MapTy::MapEntryTy *getNextEntry(const MapTy::MapEntryTy *E) const { 3184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return static_cast<const MapTy::MapEntryTy *>(E->getValue().second); 3194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 3204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getSize() { return CurrentEndOffset; } 3224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarprivate: 3244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MapTy Strings; 3254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t CurrentEndOffset; 3264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MapTy::MapEntryTy Sentinel, *Last; 3274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}; 3284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Get the offset of string \p S in the string table. This 3304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// can insert a new element or return the offset of a preexisitng 3314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// one. 3324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainaruint32_t NonRelocatableStringpool::getStringOffset(StringRef S) { 3334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (S.empty() && !Strings.empty()) 3344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 3354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr); 3374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MapTy::iterator It; 3384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool Inserted; 3394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A non-empty string can't be at offset 0, so if we have an entry 3414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // with a 0 offset, it must be a previously interned string. 3424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::tie(It, Inserted) = Strings.insert(std::make_pair(S, Entry)); 3434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Inserted || It->getValue().first == 0) { 3444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Set offset and chain at the end of the entries list. 3454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar It->getValue().first = CurrentEndOffset; 3464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrentEndOffset += S.size() + 1; // +1 for the '\0'. 3474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Last->getValue().second = &*It; 3484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Last = &*It; 3494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 3504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return It->getValue().first; 3514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 3524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Put \p S into the StringMap so that it gets permanent 3544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// storage, but do not actually link it in the chain of elements 3554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// that go into the output section. A latter call to 3564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// getStringOffset() with the same string will chain it though. 3574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarStringRef NonRelocatableStringpool::internString(StringRef S) { 3584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr); 3594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto InsertResult = Strings.insert(std::make_pair(S, Entry)); 3604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return InsertResult.first->getKey(); 3614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 3624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief The Dwarf streaming logic 3644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 3654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// All interactions with the MC layer that is used to build the debug 3664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// information binary representation are handled in this class. 3674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarclass DwarfStreamer { 3684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \defgroup MCObjects MC layer objects constructed by the streamer 3694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @{ 3704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCRegisterInfo> MRI; 3714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCAsmInfo> MAI; 3724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCObjectFileInfo> MOFI; 3734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCContext> MC; 3744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCAsmBackend *MAB; // Owned by MCStreamer 3754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCInstrInfo> MII; 3764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<MCSubtargetInfo> MSTI; 3774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCCodeEmitter *MCE; // Owned by MCStreamer 3784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCStreamer *MS; // Owned by AsmPrinter 3794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<TargetMachine> TM; 3804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<AsmPrinter> Asm; 3814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @} 3824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief the file we stream the linked Dwarf to. 3844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<raw_fd_ostream> OutFile; 3854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t RangesSectionSize; 3874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t LocSectionSize; 3884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t LineSectionSize; 3894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the pubnames or pubtypes section contribution for \p 3914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// Unit into \p Sec. The data is provided in \p Names. 3924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitPubSectionForUnit(const MCSection *Sec, StringRef Name, 3934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const CompileUnit &Unit, 3944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<CompileUnit::AccelInfo> &Names); 3954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 3964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarpublic: 3974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Actually create the streamer and the ouptut file. 3984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 3994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// This could be done directly in the constructor, but it feels 4004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// more natural to handle errors through return value. 4014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool init(Triple TheTriple, StringRef OutputFilename); 4024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Dump the file to the disk. 4044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool finish(); 4054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsmPrinter &getAsmPrinter() const { return *Asm; } 4074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Set the current output section to debug_info and change 4094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// the MC Dwarf version to \p DwarfVersion. 4104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void switchToDebugInfoSection(unsigned DwarfVersion); 4114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the compilation unit header for \p Unit in the 4134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug_info section. 4144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 4154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// As a side effect, this also switches the current Dwarf version 4164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// of the MC layer to the one of U.getOrigUnit(). 4174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitCompileUnitHeader(CompileUnit &Unit); 4184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Recursively emit the DIE tree rooted at \p Die. 4204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitDIE(DIE &Die); 4214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the abbreviation table \p Abbrevs to the 4234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug_abbrev section. 4244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitAbbrevs(const std::vector<DIEAbbrev *> &Abbrevs); 4254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the string table described by \p Pool. 4274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitStrings(const NonRelocatableStringpool &Pool); 4284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit debug_ranges for \p FuncRange by translating the 4304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// original \p Entries. 4314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitRangesEntries( 4324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t UnitPcOffset, uint64_t OrigLowPc, 4334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionIntervals::const_iterator FuncRange, 4344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, 4354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AddressSize); 4364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit debug_aranges entries for \p Unit and if \p 4384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// DoRangesSection is true, also emit the debug_ranges entries for 4394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// the DW_TAG_compile_unit's DW_AT_ranges attribute. 4404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection); 4414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t getRangesSectionSize() const { return RangesSectionSize; } 4434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the debug_loc contribution for \p Unit by copying 4454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// the entries from \p Dwarf and offseting them. Update the 4464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// location attributes to point to the new entries. 4474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitLocationsForUnit(const CompileUnit &Unit, DWARFContext &Dwarf); 4484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the line table described in \p Rows into the 4504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug_line section. 4514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitLineTableForUnit(StringRef PrologueBytes, unsigned MinInstLength, 4524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DWARFDebugLine::Row> &Rows, 4534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AdddressSize); 4544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t getLineSectionSize() const { return LineSectionSize; } 4564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the .debug_pubnames contribution for \p Unit. 4584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitPubNamesForUnit(const CompileUnit &Unit); 4594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the .debug_pubtypes contribution for \p Unit. 4614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitPubTypesForUnit(const CompileUnit &Unit); 462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 4644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) { 4654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string ErrorStr; 4664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string TripleName; 4674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef Context = "dwarf streamer init"; 4684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Get the target. 4704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const Target *TheTarget = 4714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); 4724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!TheTarget) 4734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error(ErrorStr, Context); 4744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TripleName = TheTriple.getTriple(); 4754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Create all the MC Objects. 4774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MRI.reset(TheTarget->createMCRegInfo(TripleName)); 4784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MRI) 4794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error(Twine("no register info for target ") + TripleName, Context); 4804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName)); 4824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MAI) 4834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no asm info for target " + TripleName, Context); 4844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MOFI.reset(new MCObjectFileInfo); 4864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get())); 4874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MOFI->InitMCObjectFileInfo(TripleName, Reloc::Default, CodeModel::Default, 4884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *MC); 4894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, ""); 4914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MAB) 4924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no asm backend for target " + TripleName, Context); 4934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MII.reset(TheTarget->createMCInstrInfo()); 4954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MII) 4964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no instr info info for target " + TripleName, Context); 4974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 4984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); 4994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MSTI) 5004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no subtarget info for target " + TripleName, Context); 5014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC); 5034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MCE) 5044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no code emitter for target " + TripleName, Context); 5054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Create the output file. 5074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::error_code EC; 5084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutFile = 5094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar llvm::make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::F_None); 5104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (EC) 5114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error(Twine(OutputFilename) + ": " + EC.message(), Context); 5124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS = TheTarget->createMCObjectStreamer(TheTriple, *MC, *MAB, *OutFile, MCE, 5144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *MSTI, false, 5154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /*DWARFMustBeAtTheEnd*/ false); 5164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MS) 5174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no object streamer for target " + TripleName, Context); 5184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Finally create the AsmPrinter we'll use to emit the DIEs. 5204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions())); 5214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!TM) 5224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no target machine for target " + TripleName, Context); 5234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); 5254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Asm) 5264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return error("no asm printer for target " + TripleName, Context); 5274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangesSectionSize = 0; 5294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LocSectionSize = 0; 5304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize = 0; 5314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return true; 5334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool DwarfStreamer::finish() { 5364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->Finish(); 5374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return true; 5384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Set the current output section to debug_info and change 5414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// the MC Dwarf version to \p DwarfVersion. 5424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { 5434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MOFI->getDwarfInfoSection()); 5444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MC->setDwarfVersion(DwarfVersion); 5454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the compilation unit header for \p Unit in the 5484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// debug_info section. 5494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 5504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// A Dwarf scetion header is encoded as: 5514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// uint32_t Unit length (omiting this field) 5524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// uint16_t Version 5534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// uint32_t Abbreviation table offset 5544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// uint8_t Address size 5554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 5564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Leading to a total of 11 bytes. 5574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) { 5584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Version = Unit.getOrigUnit().getVersion(); 5594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar switchToDebugInfoSection(Version); 5604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit size of content not including length itself. The size has 5624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // already been computed in CompileUnit::computeOffsets(). Substract 5634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // 4 to that size to account for the length field. 5644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4); 5654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt16(Version); 5664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We share one abbreviations table across all units so it's always at the 5674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // start of the section. 5684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(0); 5694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt8(Unit.getOrigUnit().getAddressByteSize()); 5704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the \p Abbrevs array as the shared abbreviation table 5734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// for the linked Dwarf file. 5744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitAbbrevs(const std::vector<DIEAbbrev *> &Abbrevs) { 5754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MOFI->getDwarfAbbrevSection()); 5764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->emitDwarfAbbrevs(Abbrevs); 5774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Recursively emit the DIE tree rooted at \p Die. 5804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitDIE(DIE &Die) { 5814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MOFI->getDwarfInfoSection()); 5824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->emitDwarfDIE(Die); 5834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the debug_str section stored in \p Pool. 5864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) { 5874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.SwitchSection(MOFI->getDwarfStrSection()); 5884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto *Entry = Pool.getFirstEntry(); Entry; 5894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Entry = Pool.getNextEntry(Entry)) 5904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitBytes( 5914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef(Entry->getKey().data(), Entry->getKey().size() + 1)); 5924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 5934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 5944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the debug_range section contents for \p FuncRange by 5954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// translating the original \p Entries. The debug_range section 5964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// format is totally trivial, consisting just of pairs of address 5974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// sized addresses describing the ranges. 5984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitRangesEntries( 5994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t UnitPcOffset, uint64_t OrigLowPc, 6004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionIntervals::const_iterator FuncRange, 6014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, 6024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AddressSize) { 6034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); 6044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Offset each range by the right amount. 6064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t PcOffset = FuncRange.value() + UnitPcOffset; 6074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Range : Entries) { 6084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Range.isBaseAddressSelectionEntry(AddressSize)) { 6094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar warn("unsupported base address selection operation", 6104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "emitting debug_ranges"); 6114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 6124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 6134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Do not emit empty ranges. 6144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Range.StartAddress == Range.EndAddress) 6154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 6164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // All range entries should lie in the function range. 6184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() && 6194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Range.EndAddress + OrigLowPc <= FuncRange.stop())) 6204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar warn("inconsistent range data.", "emitting debug_ranges"); 6214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Range.StartAddress + PcOffset, AddressSize); 6224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Range.EndAddress + PcOffset, AddressSize); 6234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangesSectionSize += 2 * AddressSize; 6244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 6254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Add the terminator entry. 6274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(0, AddressSize); 6284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(0, AddressSize); 6294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangesSectionSize += 2 * AddressSize; 6304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 6314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the debug_aranges contribution of a unit and 6334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// if \p DoDebugRanges is true the debug_range contents for a 6344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// compile_unit level DW_AT_ranges attribute (Which are basically the 6354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// same thing with a different base address). 6364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Just aggregate all the ranges gathered inside that unit. 6374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit, 6384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool DoDebugRanges) { 6394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 6404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Gather the ranges in a vector, so that we can simplify them. The 6414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // IntervalMap will have coalesced the non-linked ranges, but here 6424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // we want to coalesce the linked addresses. 6434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<std::pair<uint64_t, uint64_t>> Ranges; 6444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &FunctionRanges = Unit.getFunctionRanges(); 6454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end(); 6464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Range != End; ++Range) 6474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges.push_back(std::make_pair(Range.start() + Range.value(), 6484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Range.stop() + Range.value())); 6494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The object addresses where sorted, but again, the linked 6514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // addresses might end up in a different order. 6524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::sort(Ranges.begin(), Ranges.end()); 6534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Ranges.empty()) { 6554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); 6564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *BeginLabel = Asm->createTempSymbol("Barange"); 6584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *EndLabel = Asm->createTempSymbol("Earange"); 6594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned HeaderSize = 6614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar sizeof(int32_t) + // Size of contents (w/o this field 6624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar sizeof(int16_t) + // DWARF ARange version number 6634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar sizeof(int32_t) + // Offset of CU in the .debug_info section 6644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar sizeof(int8_t) + // Pointer Size (in bytes) 6654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar sizeof(int8_t); // Segment Size (in bytes) 6664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned TupleSize = AddressSize * 2; 6684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize); 6694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length 6714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitLabel(BeginLabel); 6724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); // Version number 6734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(Unit.getStartOffset()); // Corresponding unit's offset 6744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt8(AddressSize); // Address size 6754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt8(0); // Segment size 6764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitFill(Padding, 0x0); 6784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; 6804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ++Range) { 6814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t RangeStart = Range->first; 6824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(RangeStart, AddressSize); 6834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar while ((Range + 1) != End && Range->second == (Range + 1)->first) 6844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ++Range; 6854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Range->second - RangeStart, AddressSize); 6864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 6874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit terminator 6894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(0, AddressSize); 6904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(0, AddressSize); 6914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitLabel(EndLabel); 6924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 6934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!DoDebugRanges) 6954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 6964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); 6984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Offset each range by the right amount. 6994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t PcOffset = -Unit.getLowPc(); 7004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit coalesced ranges. 7014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) { 7024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Range->first + PcOffset, AddressSize); 7034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar while (Range + 1 != End && Range->second == (Range + 1)->first) 7044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ++Range; 7054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Range->second + PcOffset, AddressSize); 7064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangesSectionSize += 2 * AddressSize; 7074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 7084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Add the terminator entry. 7104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(0, AddressSize); 7114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(0, AddressSize); 7124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangesSectionSize += 2 * AddressSize; 7134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 7144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit location lists for \p Unit and update attribtues to 7164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// point to the new entries. 7174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitLocationsForUnit(const CompileUnit &Unit, 7184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFContext &Dwarf) { 7194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<std::pair<DIEInteger *, int64_t>> &Attributes = 7204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.getLocationAttributes(); 7214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Attributes.empty()) 7234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 7244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection()); 7264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 7284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFSection &InputSec = Dwarf.getLocSection(); 7294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize); 7304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFUnit &OrigUnit = Unit.getOrigUnit(); 7314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false); 7324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t UnitPcOffset = 0; 7334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress( 7344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &OrigUnit, dwarf::DW_AT_low_pc, -1ULL); 7354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (OrigLowPc != -1ULL) 7364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc(); 7374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Attr : Attributes) { 7394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Offset = Attr.first->getValue(); 7404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr.first->setValue(LocSectionSize); 7414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This is the quantity to add to the old location address to get 7424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the correct address for the new one. 7434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t LocPcOffset = Attr.second + UnitPcOffset; 7444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar while (Data.isValidOffset(Offset)) { 7454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Low = Data.getUnsigned(&Offset, AddressSize); 7464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t High = Data.getUnsigned(&Offset, AddressSize); 7474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LocSectionSize += 2 * AddressSize; 7484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Low == 0 && High == 0) { 7494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(0, AddressSize); 7504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(0, AddressSize); 7514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 7524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 7534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(Low + LocPcOffset, AddressSize); 7544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(High + LocPcOffset, AddressSize); 7554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Length = Data.getU16(&Offset); 7564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitIntValue(Length, 2); 7574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Just copy the bytes over. 7584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitBytes( 7594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef(InputSec.Data.substr(Offset, Length))); 7604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Offset += Length; 7614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LocSectionSize += Length + 2; 7624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 7634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 7644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 7654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitLineTableForUnit(StringRef PrologueBytes, 7674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned MinInstLength, 7684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DWARFDebugLine::Row> &Rows, 7694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned PointerSize) { 7704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Switch to the section where the table will be emitted into. 7714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection()); 7724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *LineStartSym = MC->CreateTempSymbol(); 7734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *LineEndSym = MC->CreateTempSymbol(); 7744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The first 4 bytes is the total length of the information for this 7764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // compilation unit (not including these 4 bytes for the length). 7774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitLabelDifference(LineEndSym, LineStartSym, 4); 7784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitLabel(LineStartSym); 7794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Copy Prologue. 7804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitBytes(PrologueBytes); 7814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += PrologueBytes.size() + 4; 7824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallString<128> EncodingBuffer; 7844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar raw_svector_ostream EncodingOS(EncodingBuffer); 7854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Rows.empty()) { 7874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We only have the dummy entry, dsymutil emits an entry with a 0 7884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // address in that case. 7894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS); 7904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitBytes(EncodingOS.str()); 7914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += EncodingBuffer.size(); 7924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitLabel(LineEndSym); 7934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 7944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 7954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 7964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Line table state machine fields 7974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned FileNum = 1; 7984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned LastLine = 1; 7994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Column = 0; 8004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned IsStatement = 1; 8014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Isa = 0; 8024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Address = -1ULL; 8034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned RowsSinceLastSequence = 0; 8054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (unsigned Idx = 0; Idx < Rows.size(); ++Idx) { 8074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto &Row = Rows[Idx]; 8084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t AddressDelta; 8104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Address == -1ULL) { 8114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); 8124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitULEB128IntValue(PointerSize + 1); 8134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNE_set_address, 1); 8144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(Row.Address, PointerSize); 8154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1); 8164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressDelta = 0; 8174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 8184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressDelta = (Row.Address - Address) / MinInstLength; 8194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: code copied and transfromed from 8224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share 8234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // this code, but the current compatibility requirement with 8244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // classic dsymutil makes it hard. Revisit that once this 8254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // requirement is dropped. 8264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (FileNum != Row.File) { 8284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FileNum = Row.File; 8294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_file, 1); 8304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitULEB128IntValue(FileNum); 8314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1 + getULEB128Size(FileNum); 8324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Column != Row.Column) { 8344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Column = Row.Column; 8354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_column, 1); 8364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitULEB128IntValue(Column); 8374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1 + getULEB128Size(Column); 8384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: We should handle the discriminator here, but dsymutil 8414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // doesn' consider it, thus ignore it for now. 8424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Isa != Row.Isa) { 8444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Isa = Row.Isa; 8454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_isa, 1); 8464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitULEB128IntValue(Isa); 8474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1 + getULEB128Size(Isa); 8484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (IsStatement != Row.IsStmt) { 8504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IsStatement = Row.IsStmt; 8514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1); 8524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1; 8534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Row.BasicBlock) { 8554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1); 8564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1; 8574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Row.PrologueEnd) { 8604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1); 8614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1; 8624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Row.EpilogueBegin) { 8654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1); 8664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1; 8674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t LineDelta = int64_t(Row.Line) - LastLine; 8704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Row.EndSequence) { 8714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCDwarfLineAddr::Encode(*MC, LineDelta, AddressDelta, EncodingOS); 8724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitBytes(EncodingOS.str()); 8734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += EncodingBuffer.size(); 8744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingBuffer.resize(0); 8754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingOS.resync(); 8764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Address = Row.Address; 8774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LastLine = Row.Line; 8784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RowsSinceLastSequence++; 8794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 8804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (LineDelta) { 8814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_advance_line, 1); 8824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitSLEB128IntValue(LineDelta); 8834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1 + getSLEB128Size(LineDelta); 8844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AddressDelta) { 8864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitIntValue(dwarf::DW_LNS_advance_pc, 1); 8874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitULEB128IntValue(AddressDelta); 8884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += 1 + getULEB128Size(AddressDelta); 8894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS); 8914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitBytes(EncodingOS.str()); 8924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += EncodingBuffer.size(); 8934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingBuffer.resize(0); 8944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingOS.resync(); 8954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Address = -1ULL; 8964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LastLine = FileNum = IsStatement = 1; 8974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RowsSinceLastSequence = Column = Isa = 0; 8984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 8994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (RowsSinceLastSequence) { 9024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS); 9034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitBytes(EncodingOS.str()); 9044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineSectionSize += EncodingBuffer.size(); 9054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingBuffer.resize(0); 9064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EncodingOS.resync(); 9074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MS->EmitLabel(LineEndSym); 9104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 9114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit the pubnames or pubtypes section contribution for \p 9134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Unit into \p Sec. The data is provided in \p Names. 9144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitPubSectionForUnit( 9154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const MCSection *Sec, StringRef SecName, const CompileUnit &Unit, 9164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::vector<CompileUnit::AccelInfo> &Names) { 9174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Names.empty()) 9184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 9194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Start the dwarf pubnames section. 9214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.SwitchSection(Sec); 9224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin"); 9234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end"); 9244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool HeaderEmitted = false; 9264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit the pubnames for this compilation unit. 9274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Name : Names) { 9284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Name.SkipPubSection) 9294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 9304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!HeaderEmitted) { 9324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit the header. 9334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Length 9344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitLabel(BeginLabel); 9354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); // Version 9364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(Unit.getStartOffset()); // Unit offset 9374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size 9384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar HeaderEmitted = true; 9394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(Name.Die->getOffset()); 9414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitBytes( 9424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef(Name.Name.data(), Name.Name.size() + 1)); 9434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!HeaderEmitted) 9464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 9474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->EmitInt32(0); // End marker. 9484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Asm->OutStreamer.EmitLabel(EndLabel); 9494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 9504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit .debug_pubnames for \p Unit. 9524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { 9534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(), 9544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "names", Unit, Unit.getPubnames()); 9554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 9564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Emit .debug_pubtypes for \p Unit. 9584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) { 9594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(), 9604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "types", Unit, Unit.getPubtypes()); 9614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 9624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief The core of the Dwarf linking logic. 964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// The link of the dwarf information from the object files will be 966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// driven by the selection of 'root DIEs', which are DIEs that 967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// describe variables or functions that are present in the linked 968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// binary (and thus have entries in the debug map). All the debug 969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// information that will be linked (the DIEs, but also the line 970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// tables, ranges, ...) is derived from that set of root DIEs. 971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// The root DIEs are identified because they contain relocations that 973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// correspond to a debug map entry at specific places (the low_pc for 974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// a function, the location for a variable). These relocations are 975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// called ValidRelocs in the DwarfLinker and are gathered as a very 976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// first step when we start processing a DebugMapObject. 977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass DwarfLinker { 978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 9794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DwarfLinker(StringRef OutputFilename, const LinkOptions &Options) 9804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : OutputFilename(OutputFilename), Options(Options), 9814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar BinHolder(Options.Verbose) {} 9824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ~DwarfLinker() { 9844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto *Abbrev : Abbreviations) 9854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar delete Abbrev; 9864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Link the contents of the DebugMap. 989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool link(const DebugMap &); 990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 991ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesprivate: 992ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Called at the start of a debug object link. 9934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void startDebugObject(DWARFContext &, DebugMapObject &); 994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Called at the end of a debug object link. 996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void endDebugObject(); 997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \defgroup FindValidRelocations Translate debug map into a list 999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// of relevant relocations 1000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// 1001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @{ 1002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines struct ValidReloc { 1003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Offset; 1004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Size; 1005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t Addend; 1006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject::DebugMapEntry *Mapping; 1007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidReloc(uint32_t Offset, uint32_t Size, uint64_t Addend, 1009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject::DebugMapEntry *Mapping) 1010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {} 1011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator<(const ValidReloc &RHS) const { return Offset < RHS.Offset; } 1013ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 1014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1015ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief The valid relocations for the current DebugMapObject. 1016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// This vector is sorted by relocation offset. 1017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<ValidReloc> ValidRelocs; 1018ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Index into ValidRelocs of the next relocation to 1020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// consider. As we walk the DIEs in acsending file offset and as 1021ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// ValidRelocs is sorted by file offset, keeping this index 1022ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// uptodate is all we have to do to have a cheap lookup during the 10234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// root DIE selection and during DIE cloning. 1024ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned NextValidReloc; 1025ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1026ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj, 1027ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO); 1028ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1029ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool findValidRelocs(const object::SectionRef &Section, 1030ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const object::ObjectFile &Obj, 1031ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO); 1032ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1033ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void findValidRelocsMachO(const object::SectionRef &Section, 1034ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const object::MachOObjectFile &Obj, 1035ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO); 1036ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @} 1037ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1038ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries. 1039ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// 1040ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @{ 1041ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Recursively walk the \p DIE tree and look for DIEs to 1042ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// keep. Store that information in \p CU's DIEInfo. 1043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void lookForDIEsToKeep(const DWARFDebugInfoEntryMinimal &DIE, 1044ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO, CompileUnit &CU, 1045ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags); 1046ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1047ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Flags passed to DwarfLinker::lookForDIEsToKeep 1048ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines enum TravesalFlags { 1049ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept. 1050ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope. 1051ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE. 1052ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE. 1053ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 1054ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1055ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Mark the passed DIE as well as all the ones it depends on 1056ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// as kept. 1057ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE, 1058ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, 1059ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO, CompileUnit &CU, 1060ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags); 1061ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1062ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned shouldKeepDIE(const DWARFDebugInfoEntryMinimal &DIE, 1063ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, 1064ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags); 1065ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1066ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned shouldKeepVariableDIE(const DWARFDebugInfoEntryMinimal &DIE, 1067ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit &Unit, 1068ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, unsigned Flags); 1069ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1070ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned shouldKeepSubprogramDIE(const DWARFDebugInfoEntryMinimal &DIE, 1071ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit &Unit, 1072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, 1073ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags); 1074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1075ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, 1076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &Info); 1077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @} 1078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 10794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \defgroup Linking Methods used to link the debug information 10804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 10814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @{ 10824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Recursively clone \p InputDIE into an tree of DIE objects 10834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// where useless (as decided by lookForDIEsToKeep()) bits have been 10844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// stripped out and addresses have been rewritten according to the 10854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug map. 10864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 10874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \param OutOffset is the offset the cloned DIE in the output 10884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// compile unit. 10894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \param PCOffset (while cloning a function scope) is the offset 10904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// applied to the entry point of the function to get the linked address. 10914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 10924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \returns the root of the cloned tree. 10934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &U, 10944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t PCOffset, uint32_t OutOffset); 10954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 10964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec; 10974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 10984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Information gathered and exchanged between the various 10994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// clone*Attributes helpers about the attributes of a particular DIE. 11004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar struct AttributesInfo { 11014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *Name, *MangledName; ///< Names. 11024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool. 11034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE 11054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t PCOffset; ///< Offset to apply to PC addresses inside a function. 11064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool HasLowPc; ///< Does the DIE have a low_pc attribute? 11084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool IsDeclaration; ///< Is this DIE only a declaration? 11094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo() 11114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : Name(nullptr), MangledName(nullptr), NameOffset(0), 11124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MangledNameOffset(0), OrigHighPc(0), PCOffset(0), HasLowPc(false), 11134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IsDeclaration(false) {} 11144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar }; 11154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned cloneAttribute(DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, 11184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit &U, const DWARFFormValue &Val, 11194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const AttributeSpec AttrSpec, unsigned AttrSize, 11204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo &AttrInfo); 11214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, 11244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, const DWARFUnit &U); 11254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned 11284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cloneDieReferenceAttribute(DIE &Die, 11294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal &InputDIE, 11304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributeSpec AttrSpec, unsigned AttrSize, 11314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, CompileUnit &Unit); 11324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, 11354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, unsigned AttrSize); 11364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, 11394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, 11404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const CompileUnit &Unit, AttributesInfo &Info); 11414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned cloneScalarAttribute(DIE &Die, 11444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal &InputDIE, 11454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit &U, AttributeSpec AttrSpec, 11464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, unsigned AttrSize, 11474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo &Info); 11484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Helper for cloneDIE. 11504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset, 11514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool isLittleEndian); 11524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Assign an abbreviation number to \p Abbrev 11544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void AssignAbbrev(DIEAbbrev &Abbrev); 11554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief FoldingSet that uniques the abbreviations. 11574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FoldingSet<DIEAbbrev> AbbreviationsSet; 11584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Storage for the unique Abbreviations. 11594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot 11604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// be changed to a vecot of unique_ptrs. 11614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DIEAbbrev *> Abbreviations; 11624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Compute and emit debug_ranges section for \p Unit, and 11644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// patch the attributes referencing it. 11654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf) const; 11664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Generate and emit the DW_AT_ranges attribute for a 11684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// compile_unit if it had one. 11694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void generateUnitRanges(CompileUnit &Unit) const; 11704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Extract the line tables fromt he original dwarf, extract 11724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// the relevant parts according to the linked function ranges and 11734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// emit the result in the debug_line section. 11744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf); 11754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Emit the accelerator entries for \p Unit. 11774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void emitAcceleratorEntriesForUnit(CompileUnit &Unit); 11784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief DIELoc objects that need to be destructed (but not freed!). 11804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DIELoc *> DIELocs; 11814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief DIEBlock objects that need to be destructed (but not freed!). 11824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DIEBlock *> DIEBlocks; 11834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief Allocator used for all the DIEValue objects. 11844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar BumpPtrAllocator DIEAlloc; 11854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// @} 11864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \defgroup Helpers Various helper methods. 1188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// 1189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @{ 1190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFDebugInfoEntryMinimal * 1191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines resolveDIEReference(DWARFFormValue &RefValue, const DWARFUnit &Unit, 1192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFDebugInfoEntryMinimal &DIE, 1193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit *&ReferencedCU); 1194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit *getUnitForOffset(unsigned Offset); 1196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 11974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool getDIENames(const DWARFDebugInfoEntryMinimal &Die, DWARFUnit &U, 11984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo &Info); 11994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr, 12014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal *DIE = nullptr) const; 12024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool createStreamer(Triple TheTriple, StringRef OutputFilename); 1204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// @} 1205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesprivate: 1207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string OutputFilename; 12084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LinkOptions Options; 1209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BinaryHolder BinHolder; 12104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<DwarfStreamer> Streamer; 1211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// The units of the current debug map object. 1213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<CompileUnit> Units; 1214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// The debug map object curently under consideration. 1216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DebugMapObject *CurrentDebugObject; 12174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief The Dwarf string pool 12194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NonRelocatableStringpool StringPool; 12204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// \brief This map is keyed by the entry PC of functions in that 12224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// debug object and the associated value is a pair storing the 12234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// corresponding end PC and the offset to apply to get the linked 12244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// address. 12254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// 12264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// See startDebugObject() for a more complete description of its use. 12274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::map<uint64_t, std::pair<uint64_t, int64_t>> Ranges; 1228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 1229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Similar to DWARFUnitSection::getUnitForOffset(), but 1231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// returning our CompileUnit object instead. 1232ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCompileUnit *DwarfLinker::getUnitForOffset(unsigned Offset) { 1233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto CU = 1234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::upper_bound(Units.begin(), Units.end(), Offset, 1235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines [](uint32_t LHS, const CompileUnit &RHS) { 1236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return LHS < RHS.getOrigUnit().getNextUnitOffset(); 1237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }); 1238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return CU != Units.end() ? &*CU : nullptr; 1239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Resolve the DIE attribute reference that has been 1242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// extracted in \p RefValue. The resulting DIE migh be in another 1243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// CompileUnit which is stored into \p ReferencedCU. 1244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns null if resolving fails for any reason. 1245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesconst DWARFDebugInfoEntryMinimal *DwarfLinker::resolveDIEReference( 1246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFFormValue &RefValue, const DWARFUnit &Unit, 1247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) { 1248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(RefValue.isFormClass(DWARFFormValue::FC_Reference)); 1249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t RefOffset = *RefValue.getAsReference(&Unit); 1250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if ((RefCU = getUnitForOffset(RefOffset))) 1252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const auto *RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) 1253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return RefDie; 1254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines reportWarning("could not find referenced DIE", &Unit, &DIE); 1256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 1257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Get the potential name and mangled name for the entity 12604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// described by \p Die and store them in \Info if they are not 12614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// already there. 12624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns is a name was found. 12634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool DwarfLinker::getDIENames(const DWARFDebugInfoEntryMinimal &Die, 12644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFUnit &U, AttributesInfo &Info) { 12654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: a bit wastefull as the first getName might return the 12664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // short name. 12674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Info.MangledName && 12684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar (Info.MangledName = Die.getName(&U, DINameKind::LinkageName))) 12694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info.MangledNameOffset = StringPool.getStringOffset(Info.MangledName); 12704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Info.Name && (Info.Name = Die.getName(&U, DINameKind::ShortName))) 12724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info.NameOffset = StringPool.getStringOffset(Info.Name); 12734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Info.Name || Info.MangledName; 12754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 12764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Report a warning to the user, optionaly including 1278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// information about a specific \p DIE related to the warning. 1279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DwarfLinker::reportWarning(const Twine &Warning, const DWARFUnit *Unit, 12804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal *DIE) const { 12814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef Context = "<debug map>"; 1282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CurrentDebugObject) 12834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Context = CurrentDebugObject->getObjectFilename(); 12844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar warn(Warning, Context); 1285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Options.Verbose || !DIE) 1287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 1288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines errs() << " in DIE:\n"; 1290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIE->dump(errs(), const_cast<DWARFUnit *>(Unit), 0 /* RecurseDepth */, 1291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 6 /* Indent */); 1292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool DwarfLinker::createStreamer(Triple TheTriple, StringRef OutputFilename) { 12954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.NoOutput) 12964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return true; 12974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 12984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer = llvm::make_unique<DwarfStreamer>(); 12994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Streamer->init(TheTriple, OutputFilename); 13004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 13014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Recursive helper to gather the child->parent relationships in the 1303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// original compile unit. 1304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void gatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE, 1305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned ParentIdx, CompileUnit &CU) { 1306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE); 1307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CU.getInfo(MyIdx).ParentIdx = ParentIdx; 1308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (DIE->hasChildren()) 1310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto *Child = DIE->getFirstChild(); Child && !Child->isNULL(); 1311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Child = Child->getSibling()) 1312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines gatherDIEParents(Child, MyIdx, CU); 1313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) { 1316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (Tag) { 1317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 1318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_subprogram: 1320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_lexical_block: 1321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_subroutine_type: 1322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_structure_type: 1323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_class_type: 1324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_union_type: 1325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 1326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines llvm_unreachable("Invalid Tag"); 1328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 13304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) { 1331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Units.reserve(Dwarf.getNumCompileUnits()); 1332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NextValidReloc = 0; 13334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Iterate over the debug map entries and put all the ones that are 13344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // functions (because they have a size) into the Ranges map. This 13354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // map is very similar to the FunctionRanges that are stored in each 13364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // unit, with 2 notable differences: 13374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // - obviously this one is global, while the other ones are per-unit. 13384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // - this one contains not only the functions described in the DIE 13394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // tree, but also the ones that are only in the debug map. 13404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The latter information is required to reproduce dsymutil's logic 13414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // while linking line tables. The cases where this information 13424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // matters look like bugs that need to be investigated, but for now 13434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // we need to reproduce dsymutil's behavior. 13444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: Once we understood exactly if that information is needed, 13454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // maybe totally remove this (or try to use it to do a real 13464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // -gline-tables-only on Darwin. 13474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Entry : Obj.symbols()) { 13484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &Mapping = Entry.getValue(); 13494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Mapping.Size) 13504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges[Mapping.ObjectAddress] = std::make_pair( 13514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mapping.ObjectAddress + Mapping.Size, 13524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t(Mapping.BinaryAddress) - Mapping.ObjectAddress); 13534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DwarfLinker::endDebugObject() { 1357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Units.clear(); 1358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidRelocs.clear(); 13594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges.clear(); 13604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 13614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto *Block : DIEBlocks) 13624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Block->~DIEBlock(); 13634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto *Loc : DIELocs) 13644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Loc->~DIELoc(); 13654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 13664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEBlocks.clear(); 13674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIELocs.clear(); 13684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEAlloc.Reset(); 1369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Iterate over the relocations of the given \p Section and 1372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// store the ones that correspond to debug map entries into the 1373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ValidRelocs array. 1374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DwarfLinker::findValidRelocsMachO(const object::SectionRef &Section, 1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const object::MachOObjectFile &Obj, 1376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO) { 1377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef Contents; 1378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Section.getContents(Contents); 1379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DataExtractor Data(Contents, Obj.isLittleEndian(), 0); 1380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const object::RelocationRef &Reloc : Section.relocations()) { 1382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl(); 1383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef); 1384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc); 1385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t Offset64; 1386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if ((RelocSize != 4 && RelocSize != 8) || Reloc.getOffset(Offset64)) { 1387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines reportWarning(" unsupported relocation in debug_info section."); 1388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 1389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Offset = Offset64; 1391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Mach-o uses REL relocations, the addend is at the relocation offset. 1392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t Addend = Data.getUnsigned(&Offset, RelocSize); 1393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto Sym = Reloc.getSymbol(); 1395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Sym != Obj.symbol_end()) { 1396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef SymbolName; 1397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Sym->getName(SymbolName)) { 1398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines reportWarning("error getting relocation symbol name."); 1399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 1400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const auto *Mapping = DMO.lookupSymbol(SymbolName)) 1402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping); 1403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (const auto *Mapping = DMO.lookupObjectAddress(Addend)) { 1404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Do not store the addend. The addend was the address of the 1405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // symbol in the object file, the address in the binary that is 1406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // stored in the debug map doesn't need to be offseted. 1407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidRelocs.emplace_back(Offset64, RelocSize, 0, Mapping); 1408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Dispatch the valid relocation finding logic to the 1413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// appropriate handler depending on the object file format. 1414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool DwarfLinker::findValidRelocs(const object::SectionRef &Section, 1415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const object::ObjectFile &Obj, 1416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO) { 1417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Dispatch to the right handler depending on the file type. 1418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj)) 1419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines findValidRelocsMachO(Section, *MachOObj, DMO); 1420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 1421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines reportWarning(Twine("unsupported object file type: ") + Obj.getFileName()); 1422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ValidRelocs.empty()) 1424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Sort the relocations by offset. We will walk the DIEs linearly in 1427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the file, this allows us to just keep an index in the relocation 1428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // array that we advance during our walk, rather than resorting to 1429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // some associative container. See DwarfLinker::NextValidReloc. 1430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::sort(ValidRelocs.begin(), ValidRelocs.end()); 1431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 1432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Look for relocations in the debug_info section that match 1435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// entries in the debug map. These relocations will drive the Dwarf 1436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// link by indicating which DIEs refer to symbols present in the 1437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// linked binary. 1438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns wether there are any valid relocations in the debug info. 1439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool DwarfLinker::findValidRelocsInDebugInfo(const object::ObjectFile &Obj, 1440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO) { 1441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Find the debug_info section. 1442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const object::SectionRef &Section : Obj.sections()) { 1443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef SectionName; 1444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Section.getName(SectionName); 1445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SectionName = SectionName.substr(SectionName.find_first_not_of("._")); 1446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (SectionName != "debug_info") 1447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 1448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return findValidRelocs(Section, Obj, DMO); 1449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Checks that there is a relocation against an actual debug 1454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// map entry between \p StartOffset and \p NextOffset. 1455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 1456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// This function must be called with offsets in strictly ascending 1457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// order because it never looks back at relocations it already 'went past'. 1458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns true and sets Info.InDebugMap if it is the case. 1459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool DwarfLinker::hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, 1460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &Info) { 1461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(NextValidReloc == 0 || 1462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StartOffset > ValidRelocs[NextValidReloc - 1].Offset); 1463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (NextValidReloc >= ValidRelocs.size()) 1464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t RelocOffset = ValidRelocs[NextValidReloc].Offset; 1467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We might need to skip some relocs that we didn't consider. For 1469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // example the high_pc of a discarded DIE might contain a reloc that 1470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is in the list because it actually corresponds to the start of a 1471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // function that is in the debug map. 1472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (RelocOffset < StartOffset && NextValidReloc < ValidRelocs.size() - 1) 1473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RelocOffset = ValidRelocs[++NextValidReloc].Offset; 1474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (RelocOffset < StartOffset || RelocOffset >= EndOffset) 1476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const auto &ValidReloc = ValidRelocs[NextValidReloc++]; 14794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) 1480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey() 1481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " " << format("\t%016" PRIx64 " => %016" PRIx64, 1482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidReloc.Mapping->getValue().ObjectAddress, 1483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValidReloc.Mapping->getValue().BinaryAddress); 1484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 14854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info.AddrAdjust = int64_t(ValidReloc.Mapping->getValue().BinaryAddress) + 14864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ValidReloc.Addend - 14874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ValidReloc.Mapping->getValue().ObjectAddress; 1488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Info.InDebugMap = true; 1489ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 1490ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Get the starting and ending (exclusive) offset for the 1493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// attribute with index \p Idx descibed by \p Abbrev. \p Offset is 1494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// supposed to point to the position of the first attribute described 1495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// by \p Abbrev. 1496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \return [StartOffset, EndOffset) as a pair. 1497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic std::pair<uint32_t, uint32_t> 1498ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesgetAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx, 1499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Offset, const DWARFUnit &Unit) { 1500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DataExtractor Data = Unit.getDebugInfoExtractor(); 1501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0; i < Idx; ++i) 1503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, &Unit); 1504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t End = Offset; 1506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, &Unit); 1507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return std::make_pair(Offset, End); 1509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Check if a variable describing DIE should be kept. 1512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns updated TraversalFlags. 1513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesunsigned DwarfLinker::shouldKeepVariableDIE( 1514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFDebugInfoEntryMinimal &DIE, CompileUnit &Unit, 1515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, unsigned Flags) { 1516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); 1517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Global variables with constant value can always be kept. 1519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!(Flags & TF_InFunctionScope) && 1520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Abbrev->findAttributeIndex(dwarf::DW_AT_const_value) != -1U) { 1521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MyInfo.InDebugMap = true; 1522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags | TF_Keep; 1523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t LocationIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_location); 1526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LocationIdx == -1U) 1527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags; 1528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); 1530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFUnit &OrigUnit = Unit.getOrigUnit(); 1531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t LocationOffset, LocationEndOffset; 1532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::tie(LocationOffset, LocationEndOffset) = 1533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getAttributeOffsets(Abbrev, LocationIdx, Offset, OrigUnit); 1534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See if there is a relocation to a valid debug map entry inside 1536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // this variable's location. The order is important here. We want to 1537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // always check in the variable has a valid relocation, so that the 1538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // DIEInfo is filled. However, we don't want a static variable in a 1539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // function to force us to keep the enclosing function. 1540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) || 1541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (Flags & TF_InFunctionScope)) 1542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags; 1543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 15444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) 1545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */); 1546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags | TF_Keep; 1548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Check if a function describing DIE should be kept. 1551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns updated TraversalFlags. 1552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesunsigned DwarfLinker::shouldKeepSubprogramDIE( 1553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFDebugInfoEntryMinimal &DIE, CompileUnit &Unit, 1554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, unsigned Flags) { 1555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); 1556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Flags |= TF_InFunctionScope; 1558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc); 1560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LowPcIdx == -1U) 1561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags; 1562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); 1564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFUnit &OrigUnit = Unit.getOrigUnit(); 1565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t LowPcOffset, LowPcEndOffset; 1566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::tie(LowPcOffset, LowPcEndOffset) = 1567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getAttributeOffsets(Abbrev, LowPcIdx, Offset, OrigUnit); 1568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t LowPc = 1570ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIE.getAttributeValueAsAddress(&OrigUnit, dwarf::DW_AT_low_pc, -1ULL); 1571ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(LowPc != -1ULL && "low_pc attribute is not an address."); 1572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (LowPc == -1ULL || 1573ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines !hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo)) 1574ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags; 1575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 15764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) 1577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */); 1578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 15794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Flags |= TF_Keep; 15804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 15814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFFormValue HighPcValue; 15824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!DIE.getAttributeValue(&OrigUnit, dwarf::DW_AT_high_pc, HighPcValue)) { 15834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning("Function without high_pc. Range will be discarded.\n", 15844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &OrigUnit, &DIE); 15854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Flags; 15864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 15874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 15884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t HighPc; 15894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (HighPcValue.isFormClass(DWARFFormValue::FC_Address)) { 15904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar HighPc = *HighPcValue.getAsAddress(&OrigUnit); 15914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 15924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(HighPcValue.isFormClass(DWARFFormValue::FC_Constant)); 15934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar HighPc = LowPc + *HighPcValue.getAsUnsignedConstant(); 15944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 15954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 15964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Replace the debug map range with a more accurate one. 15974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Ranges[LowPc] = std::make_pair(HighPc, MyInfo.AddrAdjust); 15984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.addFunctionRange(LowPc, HighPc, MyInfo.AddrAdjust); 15994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Flags; 1600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Check if a DIE should be kept. 1603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \returns updated TraversalFlags. 1604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesunsigned DwarfLinker::shouldKeepDIE(const DWARFDebugInfoEntryMinimal &DIE, 1605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit &Unit, 1606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, 1607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags) { 1608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (DIE.getTag()) { 1609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_constant: 1610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_variable: 1611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return shouldKeepVariableDIE(DIE, Unit, MyInfo, Flags); 1612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_subprogram: 1613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return shouldKeepSubprogramDIE(DIE, Unit, MyInfo, Flags); 1614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_module: 1615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_imported_module: 1616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_imported_declaration: 1617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case dwarf::DW_TAG_imported_unit: 1618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We always want to keep these. 1619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags | TF_Keep; 1620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Flags; 1623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Mark the passed DIE as well as all the ones it depends on 1626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// as kept. 1627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 1628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// This function is called by lookForDIEsToKeep on DIEs that are 1629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// newly discovered to be needed in the link. It recursively calls 1630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// back to lookForDIEsToKeep while adding TF_DependencyWalk to the 1631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// TraversalFlags to inform it that it's not doing the primary DIE 1632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// tree walk. 1633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DwarfLinker::keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE, 1634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo, 1635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO, 1636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit &CU, unsigned Flags) { 1637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DWARFUnit &Unit = CU.getOrigUnit(); 1638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MyInfo.Keep = true; 1639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // First mark all the parent chain as kept. 1641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned AncestorIdx = MyInfo.ParentIdx; 1642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (!CU.getInfo(AncestorIdx).Keep) { 1643ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines lookForDIEsToKeep(*Unit.getDIEAtIndex(AncestorIdx), DMO, CU, 1644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_ParentWalk | TF_Keep | TF_DependencyWalk); 1645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx; 1646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Then we need to mark all the DIEs referenced by this DIE's 1649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // attributes as kept. 1650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DataExtractor Data = Unit.getDebugInfoExtractor(); 1651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); 1652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); 1653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Mark all DIEs referenced through atttributes as kept. 1655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &AttrSpec : Abbrev->attributes()) { 1656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFFormValue Val(AttrSpec.Form); 1657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Val.isFormClass(DWARFFormValue::FC_Reference)) { 1659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &Unit); 1660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 1661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val.extractValue(Data, &Offset, &Unit); 1664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit *ReferencedCU; 1665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const auto *RefDIE = resolveDIEReference(Val, Unit, DIE, ReferencedCU)) 1666ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines lookForDIEsToKeep(*RefDIE, DMO, *ReferencedCU, 1667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TF_Keep | TF_DependencyWalk); 1668ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Recursively walk the \p DIE tree and look for DIEs to 1672ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// keep. Store that information in \p CU's DIEInfo. 1673ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 1674ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// This function is the entry point of the DIE selection 1675ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// algorithm. It is expected to walk the DIE tree in file order and 1676ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// (though the mediation of its helper) call hasValidRelocation() on 1677ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// each DIE that might be a 'root DIE' (See DwarfLinker class 1678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// comment). 1679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// While walking the dependencies of root DIEs, this function is 1680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// also called, but during these dependency walks the file order is 1681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// not respected. The TF_DependencyWalk flag tells us which kind of 1682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// traversal we are currently doing. 1683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid DwarfLinker::lookForDIEsToKeep(const DWARFDebugInfoEntryMinimal &DIE, 1684ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const DebugMapObject &DMO, CompileUnit &CU, 1685ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags) { 1686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Idx = CU.getOrigUnit().getDIEIndex(&DIE); 1687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx); 1688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool AlreadyKept = MyInfo.Keep; 1689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1690ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If the Keep flag is set, we are marking a required DIE's 1691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // dependencies. If our target is already marked as kept, we're all 1692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // set. 1693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if ((Flags & TF_DependencyWalk) && AlreadyKept) 1694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 1695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We must not call shouldKeepDIE while called from keepDIEAndDenpendencies, 1697ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // because it would screw up the relocation finding logic. 1698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!(Flags & TF_DependencyWalk)) 1699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Flags = shouldKeepDIE(DIE, CU, MyInfo, Flags); 1700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If it is a newly kept DIE mark it as well as all its dependencies as kept. 1702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!AlreadyKept && (Flags & TF_Keep)) 1703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines keepDIEAndDenpendencies(DIE, MyInfo, DMO, CU, Flags); 1704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The TF_ParentWalk flag tells us that we are currently walking up 1706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the parent chain of a required DIE, and we don't want to mark all 1707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the children of the parents as kept (consider for example a 1708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // DW_TAG_namespace node in the parent chain). There are however a 1709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // set of DIE types for which we want to ignore that directive and still 1710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // walk their children. 1711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (dieNeedsChildrenToBeMeaningful(DIE.getTag())) 1712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Flags &= ~TF_ParentWalk; 1713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!DIE.hasChildren() || (Flags & TF_ParentWalk)) 1715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 1716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto *Child = DIE.getFirstChild(); Child && !Child->isNULL(); 1718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Child = Child->getSibling()) 1719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines lookForDIEsToKeep(*Child, DMO, CU, Flags); 1720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 17224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Assign an abbreviation numer to \p Abbrev. 17234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 17244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Our DIEs get freed after every DebugMapObject has been processed, 17254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to 17264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// the instances hold by the DIEs. When we encounter an abbreviation 17274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// that we don't know, we create a permanent copy of it. 17284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) { 17294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Check the set for priors. 17304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FoldingSetNodeID ID; 17314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbrev.Profile(ID); 17324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void *InsertToken; 17334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); 17344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If it's newly added. 17364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (InSet) { 17374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Assign existing abbreviation number. 17384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbrev.setNumber(InSet->getNumber()); 17394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 17404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Add to abbreviation list. 17414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbreviations.push_back( 17424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new DIEAbbrev(Abbrev.getTag(), Abbrev.hasChildren())); 17434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Attr : Abbrev.getData()) 17444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbreviations.back()->AddAttribute(Attr.getAttribute(), Attr.getForm()); 17454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AbbreviationsSet.InsertNode(Abbreviations.back(), InsertToken); 17464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Assign the unique abbreviation number. 17474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbrev.setNumber(Abbreviations.size()); 17484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbreviations.back()->setNumber(Abbreviations.size()); 17494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 17504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 17514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone a string attribute described by \p AttrSpec and add 17534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// it to \p Die. 17544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the new attribute. 17554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, 17564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, 17574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFUnit &U) { 17584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Switch everything to out of line strings. 17594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *String = *Val.getAsCString(&U); 17604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Offset = StringPool.getStringOffset(String); 17614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp, 17624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new (DIEAlloc) DIEInteger(Offset)); 17634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 4; 17644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 17654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone an attribute referencing another DIE and add 17674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// it to \p Die. 17684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the new attribute. 17694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneDieReferenceAttribute( 17704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, 17714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val, 17724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit &Unit) { 17734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Ref = *Val.getAsReference(&Unit.getOrigUnit()); 17744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *NewRefDie = nullptr; 17754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit *RefUnit = nullptr; 17764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal *RefDie = nullptr; 17774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!(RefUnit = getUnitForOffset(Ref)) || 17794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar !(RefDie = RefUnit->getOrigUnit().getDIEForOffset(Ref))) { 17804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *AttributeString = dwarf::AttributeString(AttrSpec.Attr); 17814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!AttributeString) 17824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributeString = "DW_AT_???"; 17834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning(Twine("Missing DIE for ref in attribute ") + AttributeString + 17844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ". Dropping.", 17854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &Unit.getOrigUnit(), &InputDIE); 17864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 17874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 17884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie); 17904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(Idx); 17914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!RefInfo.Clone) { 17924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(Ref > InputDIE.getOffset()); 17934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We haven't cloned this DIE yet. Just create an empty one and 17944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // store it. It'll get really cloned when we process it. 17954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RefInfo.Clone = new DIE(dwarf::Tag(RefDie->getTag())); 17964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 17974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NewRefDie = RefInfo.Clone; 17984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 17994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrSpec.Form == dwarf::DW_FORM_ref_addr) { 18004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We cannot currently rely on a DIEEntry to emit ref_addr 18014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // references, because the implementation calls back to DwarfDebug 18024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // to find the unit offset. (We don't have a DwarfDebug) 18034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: we should be able to design DIEEntry reliance on 18044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // DwarfDebug away. 18054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr; 18064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Ref < InputDIE.getOffset()) { 18074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We must have already cloned that DIE. 18084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t NewRefOffset = 18094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RefUnit->getStartOffset() + NewRefDie->getOffset(); 18104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr = new (DIEAlloc) DIEInteger(NewRefOffset); 18114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 18124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A forward reference. Note and fixup later. 18134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr = new (DIEAlloc) DIEInteger(0xBADDEF); 18144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.noteForwardReference(NewRefDie, RefUnit, Attr); 18154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_ref_addr, 18174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr); 18184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return AttrSize; 18194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 18214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), 18224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new (DIEAlloc) DIEEntry(*NewRefDie)); 18234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return AttrSize; 18244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 18254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 18264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone an attribute of block form (locations, constants) and add 18274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// it to \p Die. 18284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the new attribute. 18294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, 18304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, 18314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AttrSize) { 18324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *Attr; 18334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEValue *Value; 18344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIELoc *Loc = nullptr; 18354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEBlock *Block = nullptr; 18364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Just copy the block data over. 18374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrSpec.Form == dwarf::DW_FORM_exprloc) { 18384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Loc = new (DIEAlloc) DIELoc(); 18394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIELocs.push_back(Loc); 18404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 18414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Block = new (DIEAlloc) DIEBlock(); 18424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEBlocks.push_back(Block); 18434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr = Loc ? static_cast<DIE *>(Loc) : static_cast<DIE *>(Block); 18454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value = Loc ? static_cast<DIEValue *>(Loc) : static_cast<DIEValue *>(Block); 18464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ArrayRef<uint8_t> Bytes = *Val.getAsBlock(); 18474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto Byte : Bytes) 18484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr->addValue(static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1, 18494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new (DIEAlloc) DIEInteger(Byte)); 18504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: If DIEBlock and DIELoc just reuses the Size field of 18514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the DIE class, this if could be replaced by 18524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Attr->setSize(Bytes.size()). 18534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Streamer) { 18544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Loc) 18554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Loc->ComputeSize(&Streamer->getAsmPrinter()); 18564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 18574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Block->ComputeSize(&Streamer->getAsmPrinter()); 18584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), 18604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value); 18614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return AttrSize; 18624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 18634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 18644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone an address attribute and add it to \p Die. 18654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the new attribute. 18664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, 18674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, 18684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const CompileUnit &Unit, 18694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo &Info) { 18704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Addr = *Val.getAsAddress(&Unit.getOrigUnit()); 18714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrSpec.Attr == dwarf::DW_AT_low_pc) { 18724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine || 18734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.getTag() == dwarf::DW_TAG_lexical_block) 18744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr += Info.PCOffset; 18754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else if (Die.getTag() == dwarf::DW_TAG_compile_unit) { 18764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr = Unit.getLowPc(); 18774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Addr == UINT64_MAX) 18784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 18794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info.HasLowPc = true; 18814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) { 18824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Die.getTag() == dwarf::DW_TAG_compile_unit) { 18834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (uint64_t HighPc = Unit.getHighPc()) 18844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr = HighPc; 18854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 18864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 18874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else 18884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If we have a high_pc recorded for the input DIE, use 18894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // it. Otherwise (when no relocations where applied) just use the 18904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // one we just decoded. 18914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset; 18924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 18934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 18944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(static_cast<dwarf::Attribute>(AttrSpec.Attr), 18954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar static_cast<dwarf::Form>(AttrSpec.Form), 18964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new (DIEAlloc) DIEInteger(Addr)); 18974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Unit.getOrigUnit().getAddressByteSize(); 18984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 18994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone a scalar attribute and add it to \p Die. 19014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the new attribute. 19024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneScalarAttribute( 19034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit, 19044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, 19054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo &Info) { 19064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Value; 19074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrSpec.Attr == dwarf::DW_AT_high_pc && 19084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.getTag() == dwarf::DW_TAG_compile_unit) { 19094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Unit.getLowPc() == -1ULL) 19104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 19114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Dwarf >= 4 high_pc is an size, not an address. 19124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value = Unit.getHighPc() - Unit.getLowPc(); 19134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset) 19144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value = *Val.getAsSectionOffset(); 19154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else if (AttrSpec.Form == dwarf::DW_FORM_sdata) 19164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value = *Val.getAsSignedConstant(); 19174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else if (auto OptionalValue = Val.getAsUnsignedConstant()) 19184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value = *OptionalValue; 19194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else { 19204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning("Unsupported scalar attribute form. Dropping attribute.", 19214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &Unit.getOrigUnit(), &InputDIE); 19224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 19234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 19244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr = new (DIEAlloc) DIEInteger(Value); 19254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrSpec.Attr == dwarf::DW_AT_ranges) 19264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.noteRangeAttribute(Die, Attr); 19274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A more generic way to check for location attributes would be 19284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // nice, but it's very unlikely that any other attribute needs a 19294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // location list. 19304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else if (AttrSpec.Attr == dwarf::DW_AT_location || 19314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttrSpec.Attr == dwarf::DW_AT_frame_base) 19324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.noteLocationAttribute(Attr, Info.PCOffset); 19334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) 19344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info.IsDeclaration = true; 19354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), 19374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr); 19384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return AttrSize; 19394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 19404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Clone \p InputDIE's attribute described by \p AttrSpec with 19424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// value \p Val, and add it to \p Die. 19434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the size of the cloned attribute. 19444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarunsigned DwarfLinker::cloneAttribute(DIE &Die, 19454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal &InputDIE, 19464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit &Unit, 19474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFFormValue &Val, 19484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const AttributeSpec AttrSpec, 19494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AttrSize, AttributesInfo &Info) { 19504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFUnit &U = Unit.getOrigUnit(); 19514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar switch (AttrSpec.Form) { 19534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_strp: 19544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_string: 19554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return cloneStringAttribute(Die, AttrSpec, Val, U); 19564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_ref_addr: 19574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_ref1: 19584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_ref2: 19594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_ref4: 19604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_ref8: 19614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, 19624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit); 19634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_block: 19644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_block1: 19654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_block2: 19664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_block4: 19674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_exprloc: 19684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return cloneBlockAttribute(Die, AttrSpec, Val, AttrSize); 19694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_addr: 19704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info); 19714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_data1: 19724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_data2: 19734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_data4: 19744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_data8: 19754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_udata: 19764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_sdata: 19774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_sec_offset: 19784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_flag: 19794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_FORM_flag_present: 19804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return cloneScalarAttribute(Die, InputDIE, Unit, AttrSpec, Val, AttrSize, 19814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Info); 19824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar default: 19834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning("Unsupported attribute form in cloneAttribute. Dropping.", &U, 19844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &InputDIE); 19854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 19864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 0; 19884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 19894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Apply the valid relocations found by findValidRelocs() to 19914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// the buffer \p Data, taking into account that Data is at \p BaseOffset 19924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// in the debug_info section. 19934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 19944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Like for findValidRelocs(), this function must be called with 19954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// monotonic \p BaseOffset values. 19964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 19974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns wether any reloc has been applied. 19984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool DwarfLinker::applyValidRelocs(MutableArrayRef<char> Data, 19994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t BaseOffset, bool isLittleEndian) { 20004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert((NextValidReloc == 0 || 20014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) && 20024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "BaseOffset should only be increasing."); 20034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (NextValidReloc >= ValidRelocs.size()) 20044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 20054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Skip relocs that haven't been applied. 20074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar while (NextValidReloc < ValidRelocs.size() && 20084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ValidRelocs[NextValidReloc].Offset < BaseOffset) 20094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ++NextValidReloc; 20104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool Applied = false; 20124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t EndOffset = BaseOffset + Data.size(); 20134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar while (NextValidReloc < ValidRelocs.size() && 20144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ValidRelocs[NextValidReloc].Offset >= BaseOffset && 20154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ValidRelocs[NextValidReloc].Offset < EndOffset) { 20164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &ValidReloc = ValidRelocs[NextValidReloc++]; 20174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(ValidReloc.Offset - BaseOffset < Data.size()); 20184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <= Data.size()); 20194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar char Buf[8]; 20204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress; 20214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value += ValidReloc.Addend; 20224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (unsigned i = 0; i != ValidReloc.Size; ++i) { 20234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Index = isLittleEndian ? i : (ValidReloc.Size - i - 1); 20244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Buf[i] = uint8_t(Value >> (Index * 8)); 20254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 20264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(ValidReloc.Size <= sizeof(Buf)); 20274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar memcpy(&Data[ValidReloc.Offset - BaseOffset], Buf, ValidReloc.Size); 20284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Applied = true; 20294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 20304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Applied; 20324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 20334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic bool isTypeTag(uint16_t Tag) { 20354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar switch (Tag) { 20364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_array_type: 20374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_class_type: 20384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_enumeration_type: 20394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_pointer_type: 20404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_reference_type: 20414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_string_type: 20424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_structure_type: 20434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_subroutine_type: 20444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_typedef: 20454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_union_type: 20464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_ptr_to_member_type: 20474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_set_type: 20484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_subrange_type: 20494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_base_type: 20504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_const_type: 20514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_constant: 20524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_file_type: 20534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_namelist: 20544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_packed_type: 20554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_volatile_type: 20564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_restrict_type: 20574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_interface_type: 20584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_unspecified_type: 20594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case dwarf::DW_TAG_shared_type: 20604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return true; 20614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar default: 20624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 20634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 20644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 20654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 20664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Recursively clone \p InputDIE's subtrees that have been 20684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// selected to appear in the linked output. 20694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 20704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \param OutOffset is the Offset where the newly created DIE will 20714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// lie in the linked compile unit. 20724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// 20734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \returns the cloned DIE object or null if nothing was selected. 20744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarDIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, 20754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit &Unit, int64_t PCOffset, 20764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t OutOffset) { 20774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFUnit &U = Unit.getOrigUnit(); 20784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Idx = U.getDIEIndex(&InputDIE); 20794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileUnit::DIEInfo &Info = Unit.getInfo(Idx); 20804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Should the DIE appear in the output? 20824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Unit.getInfo(Idx).Keep) 20834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return nullptr; 20844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Offset = InputDIE.getOffset(); 20864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The DIE might have been already created by a forward reference 20874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (see cloneDieReferenceAttribute()). 20884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *Die = Info.Clone; 20894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Die) 20904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die = Info.Clone = new DIE(dwarf::Tag(InputDIE.getTag())); 20914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(Die->getTag() == InputDIE.getTag()); 20924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die->setOffset(OutOffset); 20934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Extract and clone every attribute. 20954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DataExtractor Data = U.getDebugInfoExtractor(); 20964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t NextOffset = U.getDIEAtIndex(Idx + 1)->getOffset(); 20974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttributesInfo AttrInfo; 20984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 20994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We could copy the data only if we need to aply a relocation to 21004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // it. After testing, it seems there is no performance downside to 21014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // doing the copy unconditionally, and it makes the code simpler. 21024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset)); 21034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Data = DataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize()); 21044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Modify the copy with relocated addresses. 21054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) { 21064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If we applied relocations, we store the value of high_pc that was 21074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // potentially stored in the input DIE. If high_pc is an address 21084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (Dwarf version == 2), then it might have been relocated to a 21094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // totally unrelated value (because the end address in the object 21104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // file might be start address of another function which got moved 21114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // independantly by the linker). The computation of the actual 21124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // high_pc value is done in cloneAddressAttribute(). 21134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttrInfo.OrigHighPc = 21144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar InputDIE.getAttributeValueAsAddress(&U, dwarf::DW_AT_high_pc, 0); 21154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Reset the Offset to 0 as we will be working on the local copy of 21184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the data. 21194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Offset = 0; 21204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto *Abbrev = InputDIE.getAbbreviationDeclarationPtr(); 21224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Offset += getULEB128Size(Abbrev->getCode()); 21234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We are entering a subprogram. Get and propagate the PCOffset. 21254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Die->getTag() == dwarf::DW_TAG_subprogram) 21264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PCOffset = Info.AddrAdjust; 21274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttrInfo.PCOffset = PCOffset; 21284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &AttrSpec : Abbrev->attributes()) { 21304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFFormValue Val(AttrSpec.Form); 21314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t AttrSize = Offset; 21324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Val.extractValue(Data, &Offset, &U); 21334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttrSize = Offset - AttrSize; 21344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutOffset += 21364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo); 21374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Look for accelerator entries. 21404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint16_t Tag = InputDIE.getTag(); 21414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: This is slightly wrong. An inline_subroutine without a 21424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // low_pc, but with AT_ranges might be interesting to get into the 21434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // accelerator tables too. For now stick with dsymutil's behavior. 21444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if ((Info.InDebugMap || AttrInfo.HasLowPc) && 21454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Tag != dwarf::DW_TAG_compile_unit && 21464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) { 21474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name) 21484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.addNameAccelerator(Die, AttrInfo.MangledName, 21494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AttrInfo.MangledNameOffset, 21504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Tag == dwarf::DW_TAG_inlined_subroutine); 21514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AttrInfo.Name) 21524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.addNameAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset, 21534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Tag == dwarf::DW_TAG_inlined_subroutine); 21544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration && 21554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) { 21564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset); 21574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEAbbrev &NewAbbrev = Die->getAbbrev(); 21604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If a scope DIE is kept, we must have kept at least one child. If 21614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // it's not the case, we'll just be emitting one wasteful end of 21624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // children marker, but things won't break. 21634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (InputDIE.hasChildren()) 21644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); 21654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Assign a permanent abbrev number 21664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AssignAbbrev(Die->getAbbrev()); 21674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Add the size of the abbreviation number to the output offset. 21694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutOffset += getULEB128Size(Die->getAbbrevNumber()); 21704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Abbrev->hasChildren()) { 21724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Update our size. 21734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die->setSize(OutOffset - Die->getOffset()); 21744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Die; 21754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Recursively clone children. 21784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL(); 21794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Child = Child->getSibling()) { 21804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (DIE *Clone = cloneDIE(*Child, Unit, PCOffset, OutOffset)) { 21814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die->addChild(std::unique_ptr<DIE>(Clone)); 21824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutOffset = Clone->getOffset() + Clone->getSize(); 21834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 21854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Account for the end of children marker. 21874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutOffset += sizeof(int8_t); 21884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Update our size. 21894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Die->setSize(OutOffset - Die->getOffset()); 21904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Die; 21914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 21924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Patch the input object file relevant debug_ranges entries 21944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// and emit them in the output file. Update the relevant attributes 21954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// to point at the new entries. 21964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::patchRangesForUnit(const CompileUnit &Unit, 21974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFContext &OrigDwarf) const { 21984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFDebugRangeList RangeList; 21994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &FunctionRanges = Unit.getFunctionRanges(); 22004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 22014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DataExtractor RangeExtractor(OrigDwarf.getRangeSection(), 22024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OrigDwarf.isLittleEndian(), AddressSize); 22034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; 22044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFUnit &OrigUnit = Unit.getOrigUnit(); 22054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false); 22064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress( 22074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &OrigUnit, dwarf::DW_AT_low_pc, -1ULL); 22084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Ranges addresses are based on the unit's low_pc. Compute the 22094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // offset we need to apply to adapt to the the new unit's low_pc. 22104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t UnitPcOffset = 0; 22114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (OrigLowPc != -1ULL) 22124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc(); 22134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &RangeAttribute : Unit.getRangesAttributes()) { 22154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Offset = RangeAttribute->getValue(); 22164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangeAttribute->setValue(Streamer->getRangesSectionSize()); 22174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RangeList.extract(RangeExtractor, &Offset); 22184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &Entries = RangeList.getEntries(); 22194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugRangeList::RangeListEntry &First = Entries.front(); 22204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CurrRange == InvalidRange || First.StartAddress < CurrRange.start() || 22224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar First.StartAddress >= CurrRange.stop()) { 22234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc); 22244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CurrRange == InvalidRange || 22254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrRange.start() > First.StartAddress + OrigLowPc) { 22264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning("no mapping for range."); 22274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 22284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitRangesEntries(UnitPcOffset, OrigLowPc, CurrRange, Entries, 22324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSize); 22334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 22354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Generate the debug_aranges entries for \p Unit and if the 22374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// unit has a DW_AT_ranges attribute, also emit the debug_ranges 22384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// contribution for this attribute. 22394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// FIXME: this could actually be done right in patchRangesForUnit, 22404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// but for the sake of initial bit-for-bit compatibility with legacy 22414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// dsymutil, we have to do it in a delayed pass. 22424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::generateUnitRanges(CompileUnit &Unit) const { 22434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *Attr = Unit.getUnitRangesAttribute(); 22444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Attr) 22454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Attr->setValue(Streamer->getRangesSectionSize()); 22464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitUnitRangesEntries(Unit, Attr != nullptr); 22474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 22484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Insert the new line info sequence \p Seq into the current 22504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// set of already linked line info \p Rows. 22514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq, 22524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DWARFDebugLine::Row> &Rows) { 22534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Seq.empty()) 22544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 22554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Rows.empty() && Rows.back().Address < Seq.front().Address) { 22574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Rows.insert(Rows.end(), Seq.begin(), Seq.end()); 22584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.clear(); 22594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 22604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto InsertPoint = std::lower_bound( 22634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Rows.begin(), Rows.end(), Seq.front(), 22644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar [](const DWARFDebugLine::Row &LHS, const DWARFDebugLine::Row &RHS) { 22654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return LHS.Address < RHS.Address; 22664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar }); 22674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: this only removes the unneeded end_sequence if the 22694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // sequences have been inserted in order. using a global sort like 22704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // described in patchLineTableForUnit() and delaying the end_sequene 22714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // elimination to emitLineTableForUnit() we can get rid of all of them. 22724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (InsertPoint != Rows.end() && 22734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar InsertPoint->Address == Seq.front().Address && InsertPoint->EndSequence) { 22744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *InsertPoint = Seq.front(); 22754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end()); 22764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 22774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Rows.insert(InsertPoint, Seq.begin(), Seq.end()); 22784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.clear(); 22814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 22824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Extract the line table for \p Unit from \p OrigDwarf, and 22844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// recreate a relocated version of these for the address ranges that 22854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// are present in the binary. 22864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, 22874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFContext &OrigDwarf) { 22884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DWARFDebugInfoEntryMinimal *CUDie = 22894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.getOrigUnit().getCompileUnitDIE(); 22904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t StmtList = CUDie->getAttributeValueAsSectionOffset( 22914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &Unit.getOrigUnit(), dwarf::DW_AT_stmt_list, -1ULL); 22924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (StmtList == -1ULL) 22934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 22944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 22954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Update the cloned DW_AT_stmt_list with the correct debug_line offset. 22964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (auto *OutputDIE = Unit.getOutputUnitDIE()) { 22974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &Abbrev = OutputDIE->getAbbrev().getData(); 22984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto Stmt = std::find_if( 22994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Abbrev.begin(), Abbrev.end(), [](const DIEAbbrevData &AbbrevData) { 23004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return AbbrevData.getAttribute() == dwarf::DW_AT_stmt_list; 23014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar }); 23024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(Stmt < Abbrev.end() && "Didn't find DW_AT_stmt_list in cloned DIE!"); 23034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIEInteger *StmtAttr = 23044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cast<DIEInteger>(OutputDIE->getValues()[Stmt - Abbrev.begin()]); 23054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StmtAttr->setValue(Streamer->getLineSectionSize()); 23064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Parse the original line info for the unit. 23094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DWARFDebugLine::LineTable LineTable; 23104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t StmtOffset = StmtList; 23114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef LineData = OrigDwarf.getLineSection().Data; 23124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DataExtractor LineExtractor(LineData, OrigDwarf.isLittleEndian(), 23134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.getOrigUnit().getAddressByteSize()); 23144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineTable.parse(LineExtractor, &OrigDwarf.getLineSection().Relocs, 23154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &StmtOffset); 23164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This vector is the output line table. 23184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DWARFDebugLine::Row> NewRows; 23194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NewRows.reserve(LineTable.Rows.size()); 23204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Current sequence of rows being extracted, before being inserted 23224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // in NewRows. 23234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<DWARFDebugLine::Row> Seq; 23244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto &FunctionRanges = Unit.getFunctionRanges(); 23254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; 23264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: This logic is meant to generate exactly the same output as 23284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Darwin's classic dsynutil. There is a nicer way to implement this 23294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // by simply putting all the relocated line info in NewRows and simply 23304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // sorting NewRows before passing it to emitLineTableForUnit. This 23314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // should be correct as sequences for a function should stay 23324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // together in the sorted output. There are a few corner cases that 23334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // look suspicious though, and that required to implement the logic 23344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // this way. Revisit that once initial validation is finished. 23354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Iterate over the object file line info and extract the sequences 23374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // that correspond to linked functions. 23384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto &Row : LineTable.Rows) { 23394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Check wether we stepped out of the range. The range is 23404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // half-open, but consider accept the end address of the range if 23414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // it is marked as end_sequence in the input (because in that 23424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // case, the relocation offset is accurate and that entry won't 23434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // serve as the start of another function). 23444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CurrRange == InvalidRange || Row.Address < CurrRange.start() || 23454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Row.Address > CurrRange.stop() || 23464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar (Row.Address == CurrRange.stop() && !Row.EndSequence)) { 23474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // We just stepped out of a known range. Insert a end_sequence 23484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // corresponding to the end of the range. 23494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t StopAddress = CurrRange != InvalidRange 23504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ? CurrRange.stop() + CurrRange.value() 23514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : -1ULL; 23524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrRange = FunctionRanges.find(Row.Address); 23534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool CurrRangeValid = 23544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrRange != InvalidRange && CurrRange.start() <= Row.Address; 23554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!CurrRangeValid) { 23564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrRange = InvalidRange; 23574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (StopAddress != -1ULL) { 23584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Try harder by looking in the DebugMapObject function 23594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // ranges map. There are corner cases where this finds a 23604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // valid entry. It's unclear if this is right or wrong, but 23614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // for now do as dsymutil. 23624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: Understand exactly what cases this addresses and 23634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // potentially remove it along with the Ranges map. 23644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto Range = Ranges.lower_bound(Row.Address); 23654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Range != Ranges.begin() && Range != Ranges.end()) 23664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar --Range; 23674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Range != Ranges.end() && Range->first <= Row.Address && 23694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Range->second.first >= Row.Address) { 23704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StopAddress = Row.Address + Range->second.second; 23714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (StopAddress != -1ULL && !Seq.empty()) { 23754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Insert end sequence row with the computed end address, but 23764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the same line as the previous one. 23774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.emplace_back(Seq.back()); 23784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.back().Address = StopAddress; 23794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.back().EndSequence = 1; 23804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.back().PrologueEnd = 0; 23814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.back().BasicBlock = 0; 23824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.back().EpilogueBegin = 0; 23834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar insertLineSequence(Seq, NewRows); 23844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!CurrRangeValid) 23874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 23884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 23894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Ignore empty sequences. 23914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Row.EndSequence && Seq.empty()) 23924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 23934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Relocate row address and add it to the current sequence. 23954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Row.Address += CurrRange.value(); 23964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Seq.emplace_back(Row); 23974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Row.EndSequence) 23994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar insertLineSequence(Seq, NewRows); 24004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 24014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 24024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Finished extracting, now emit the line tables. 24034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t PrologueEnd = StmtList + 10 + LineTable.Prologue.PrologueLength; 24044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: LLVM hardcodes it's prologue values. We just copy the 24054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // prologue over and that works because we act as both producer and 24064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // consumer. It would be nicer to have a real configurable line 24074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // table emitter. 24084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (LineTable.Prologue.Version != 2 || 24094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT || 24104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineTable.Prologue.LineBase != -5 || LineTable.Prologue.LineRange != 14 || 24114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineTable.Prologue.OpcodeBase != 13) 24124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar reportWarning("line table paramters mismatch. Cannot emit."); 24134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 24144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitLineTableForUnit(LineData.slice(StmtList + 4, PrologueEnd), 24154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LineTable.Prologue.MinInstLength, NewRows, 24164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Unit.getOrigUnit().getAddressByteSize()); 24174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 24184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 24194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) { 24204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitPubNamesForUnit(Unit); 24214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitPubTypesForUnit(Unit); 24224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 24234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool DwarfLinker::link(const DebugMap &Map) { 2425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Map.begin() == Map.end()) { 2427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines errs() << "Empty debug map.\n"; 2428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 2429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 24314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!createStreamer(Map.getTriple(), OutputFilename)) 24324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 24334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 24344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Size of the DIEs (and headers) generated for the linked output. 24354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t OutputDebugInfoSize = 0; 24364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A unique ID that identifies each compile unit. 24374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned UnitID = 0; 2438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Obj : Map.objects()) { 2439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CurrentDebugObject = Obj.get(); 2440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 24414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) 2442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n"; 2443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto ErrOrObj = BinHolder.GetObjectFile(Obj->getObjectFilename()); 2444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (std::error_code EC = ErrOrObj.getError()) { 2445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines reportWarning(Twine(Obj->getObjectFilename()) + ": " + EC.message()); 2446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 2447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Look for relocations that correspond to debug map entries. 2450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) { 24514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) 2452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << "No valid relocations found. Skipping.\n"; 2453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 2454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Setup access to the debug info. 2457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DWARFContextInMemory DwarfContext(*ErrOrObj); 24584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar startDebugObject(DwarfContext, *Obj); 2459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // In a first phase, just read in the debug info and store the DIE 2461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // parent links that we will use during the next phase. 2462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &CU : DwarfContext.compile_units()) { 2463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *CUDie = CU->getCompileUnitDIE(false); 24644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.Verbose) { 2465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << "Input compilation unit:"; 2466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CUDie->dump(outs(), CU.get(), 0); 2467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 24684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Units.emplace_back(*CU, UnitID++); 2469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines gatherDIEParents(CUDie, 0, Units.back()); 2470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Then mark all the DIEs that need to be present in the linked 2473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // output and collect some information about them. Note that this 2474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // loop can not be merged with the previous one becaue cross-cu 2475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // references require the ParentIdx to be setup for every CU in 2476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the object file before calling this. 2477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &CurrentUnit : Units) 2478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getCompileUnitDIE(), *Obj, 2479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CurrentUnit, 0); 2480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 24814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The calls to applyValidRelocs inside cloneDIE will walk the 24824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // reloc array again (in the same way findValidRelocsInDebugInfo() 24834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // did). We need to reset the NextValidReloc index to the beginning. 24844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NextValidReloc = 0; 24854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 24864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Construct the output DIE tree by cloning the DIEs we chose to 24874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // keep above. If there are no valid relocs, then there's nothing 24884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // to clone/emit. 24894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ValidRelocs.empty()) 24904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto &CurrentUnit : Units) { 24914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const auto *InputDIE = CurrentUnit.getOrigUnit().getCompileUnitDIE(); 24924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrentUnit.setStartOffset(OutputDebugInfoSize); 24934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIE *OutputDIE = cloneDIE(*InputDIE, CurrentUnit, 0 /* PCOffset */, 24944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 11 /* Unit Header size */); 24954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrentUnit.setOutputUnitDIE(OutputDIE); 24964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OutputDebugInfoSize = CurrentUnit.computeNextUnitOffset(); 24974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Options.NoOutput) 24984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 24994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // FIXME: for compatibility with the classic dsymutil, we emit 25004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // an empty line table for the unit, even if the unit doesn't 25014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // actually exist in the DIE tree. 25024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar patchLineTableForUnit(CurrentUnit, DwarfContext); 25034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!OutputDIE) 25044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 25054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar patchRangesForUnit(CurrentUnit, DwarfContext); 25064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitLocationsForUnit(CurrentUnit, DwarfContext); 25074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar emitAcceleratorEntriesForUnit(CurrentUnit); 25084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 25094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 25104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit all the compile unit's debug information. 25114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ValidRelocs.empty() && !Options.NoOutput) 25124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto &CurrentUnit : Units) { 25134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar generateUnitRanges(CurrentUnit); 25144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CurrentUnit.fixupForwardReferences(); 25154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitCompileUnitHeader(CurrentUnit); 25164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!CurrentUnit.getOutputUnitDIE()) 25174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar continue; 25184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitDIE(*CurrentUnit.getOutputUnitDIE()); 25194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 25204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 2521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Clean-up before starting working on the next object. 2522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines endDebugObject(); 2523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 25254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Emit everything that's global. 25264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Options.NoOutput) { 25274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitAbbrevs(Abbreviations); 25284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Streamer->emitStrings(StringPool); 25294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 25304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 25314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Options.NoOutput ? true : Streamer->finish(); 2532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 25354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool linkDwarf(StringRef OutputFilename, const DebugMap &DM, 25364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const LinkOptions &Options) { 25374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DwarfLinker Linker(OutputFilename, Options); 2538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Linker.link(DM); 2539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2542