1356843Sdim//===- DWARFLinker.h --------------------------------------------*- C++ -*-===//
2356843Sdim//
3356843Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4356843Sdim// See https://llvm.org/LICENSE.txt for license information.
5356843Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6356843Sdim//
7356843Sdim//===----------------------------------------------------------------------===//
8356843Sdim
9356843Sdim#ifndef LLVM_DWARFLINKER_DWARFLINKER_H
10356843Sdim#define LLVM_DWARFLINKER_DWARFLINKER_H
11356843Sdim
12356843Sdim#include "llvm/CodeGen/AccelTable.h"
13356843Sdim#include "llvm/CodeGen/NonRelocatableStringpool.h"
14356843Sdim#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
15356843Sdim#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
16356843Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h"
17356843Sdim#include "llvm/MC/MCDwarf.h"
18356843Sdim#include <map>
19356843Sdim
20356843Sdimnamespace llvm {
21356843Sdim
22356843Sdimenum class DwarfLinkerClient { Dsymutil, LLD, General };
23356843Sdim
24356843Sdim/// Partial address range. Besides an offset, only the
25356843Sdim/// HighPC is stored. The structure is stored in a map where the LowPC is the
26356843Sdim/// key.
27356843Sdimstruct ObjFileAddressRange {
28356843Sdim  /// Function HighPC.
29356843Sdim  uint64_t HighPC;
30356843Sdim  /// Offset to apply to the linked address.
31356843Sdim  /// should be 0 for not-linked object file.
32356843Sdim  int64_t Offset;
33356843Sdim
34356843Sdim  ObjFileAddressRange(uint64_t EndPC, int64_t Offset)
35356843Sdim      : HighPC(EndPC), Offset(Offset) {}
36356843Sdim
37356843Sdim  ObjFileAddressRange() : HighPC(0), Offset(0) {}
38356843Sdim};
39356843Sdim
40356843Sdim/// Map LowPC to ObjFileAddressRange.
41356843Sdimusing RangesTy = std::map<uint64_t, ObjFileAddressRange>;
42356843Sdim
43356843Sdim/// AddressesMap represents information about valid addresses used
44356843Sdim/// by debug information. Valid addresses are those which points to
45356843Sdim/// live code sections. i.e. relocations for these addresses point
46356843Sdim/// into sections which would be/are placed into resulting binary.
47356843Sdimclass AddressesMap {
48356843Sdimpublic:
49356843Sdim  virtual ~AddressesMap();
50356843Sdim
51356843Sdim  /// Returns true if represented addresses are from linked file.
52356843Sdim  /// Returns false if represented addresses are from not-linked
53356843Sdim  /// object file.
54356843Sdim  virtual bool areRelocationsResolved() const = 0;
55356843Sdim
56356843Sdim  /// Checks that there are valid relocations against a .debug_info
57356843Sdim  /// section. Reset current relocation pointer if neccessary.
58356843Sdim  virtual bool hasValidRelocs(bool ResetRelocsPtr = true) = 0;
59356843Sdim
60356843Sdim  /// Checks that there is a relocation against .debug_info
61356843Sdim  /// table between \p StartOffset and \p NextOffset.
62356843Sdim  ///
63356843Sdim  /// This function must be called with offsets in strictly ascending
64356843Sdim  /// order because it never looks back at relocations it already 'went past'.
65356843Sdim  /// \returns true and sets Info.InDebugMap if it is the case.
66356843Sdim  virtual bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
67356843Sdim                                    CompileUnit::DIEInfo &Info) = 0;
68356843Sdim
69356843Sdim  /// Apply the valid relocations to the buffer \p Data, taking into
70356843Sdim  /// account that Data is at \p BaseOffset in the debug_info section.
71356843Sdim  ///
72356843Sdim  /// This function must be called with monotonic \p BaseOffset values.
73356843Sdim  ///
74356843Sdim  /// \returns true whether any reloc has been applied.
75356843Sdim  virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
76356843Sdim                                bool IsLittleEndian) = 0;
77356843Sdim
78356843Sdim  /// Returns all valid functions address ranges(i.e., those ranges
79356843Sdim  /// which points to sections with code).
80356843Sdim  virtual RangesTy &getValidAddressRanges() = 0;
81356843Sdim
82356843Sdim  /// Erases all data.
83356843Sdim  virtual void clear() = 0;
84356843Sdim};
85356843Sdim
86356843Sdim/// DwarfEmitter presents interface to generate all debug info tables.
87356843Sdimclass DwarfEmitter {
88356843Sdimpublic:
89356843Sdim  virtual ~DwarfEmitter();
90356843Sdim
91356843Sdim  /// Emit DIE containing warnings.
92356843Sdim  virtual void emitPaperTrailWarningsDie(const Triple &Triple, DIE &Die) = 0;
93356843Sdim
94356843Sdim  /// Emit section named SecName with content equals to
95356843Sdim  /// corresponding section in Obj.
96356843Sdim  virtual void emitSectionContents(const object::ObjectFile &Obj,
97356843Sdim                                   StringRef SecName) = 0;
98356843Sdim
99356843Sdim  /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
100356843Sdim  virtual void
101356843Sdim  emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
102356843Sdim              unsigned DwarfVersion) = 0;
103356843Sdim
104356843Sdim  /// Emit the string table described by \p Pool.
105356843Sdim  virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
106356843Sdim
107356843Sdim  /// Emit DWARF debug names.
108356843Sdim  virtual void
109356843Sdim  emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0;
110356843Sdim
111356843Sdim  /// Emit Apple namespaces accelerator table.
112356843Sdim  virtual void
113356843Sdim  emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
114356843Sdim
115356843Sdim  /// Emit Apple names accelerator table.
116356843Sdim  virtual void
117356843Sdim  emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
118356843Sdim
119356843Sdim  /// Emit Apple Objective-C accelerator table.
120356843Sdim  virtual void
121356843Sdim  emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
122356843Sdim
123356843Sdim  /// Emit Apple type accelerator table.
124356843Sdim  virtual void
125356843Sdim  emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
126356843Sdim
127356843Sdim  /// Emit debug_ranges for \p FuncRange by translating the
128356843Sdim  /// original \p Entries.
129356843Sdim  virtual void emitRangesEntries(
130356843Sdim      int64_t UnitPcOffset, uint64_t OrigLowPc,
131356843Sdim      const FunctionIntervals::const_iterator &FuncRange,
132356843Sdim      const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
133356843Sdim      unsigned AddressSize) = 0;
134356843Sdim
135356843Sdim  /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
136356843Sdim  /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
137356843Sdim  /// DW_AT_ranges attribute.
138356843Sdim  virtual void emitUnitRangesEntries(CompileUnit &Unit,
139356843Sdim                                     bool DoRangesSection) = 0;
140356843Sdim
141356843Sdim  /// Copy the debug_line over to the updated binary while unobfuscating the
142356843Sdim  /// file names and directories.
143356843Sdim  virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0;
144356843Sdim
145356843Sdim  /// Emit the line table described in \p Rows into the debug_line section.
146356843Sdim  virtual void emitLineTableForUnit(MCDwarfLineTableParams Params,
147356843Sdim                                    StringRef PrologueBytes,
148356843Sdim                                    unsigned MinInstLength,
149356843Sdim                                    std::vector<DWARFDebugLine::Row> &Rows,
150356843Sdim                                    unsigned AdddressSize) = 0;
151356843Sdim
152356843Sdim  /// Emit the .debug_pubnames contribution for \p Unit.
153356843Sdim  virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
154356843Sdim
155356843Sdim  /// Emit the .debug_pubtypes contribution for \p Unit.
156356843Sdim  virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
157356843Sdim
158356843Sdim  /// Emit a CIE.
159356843Sdim  virtual void emitCIE(StringRef CIEBytes) = 0;
160356843Sdim
161356843Sdim  /// Emit an FDE with data \p Bytes.
162356843Sdim  virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
163356843Sdim                       StringRef Bytes) = 0;
164356843Sdim
165356843Sdim  /// Emit the debug_loc contribution for \p Unit by copying the entries from
166356843Sdim  /// \p Dwarf and offsetting them. Update the location attributes to point to
167356843Sdim  /// the new entries.
168356843Sdim  virtual void emitLocationsForUnit(
169356843Sdim      const CompileUnit &Unit, DWARFContext &Dwarf,
170356843Sdim      std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
171356843Sdim          ProcessExpr) = 0;
172356843Sdim
173356843Sdim  /// Emit the compilation unit header for \p Unit in the
174356843Sdim  /// debug_info section.
175356843Sdim  ///
176356843Sdim  /// As a side effect, this also switches the current Dwarf version
177356843Sdim  /// of the MC layer to the one of U.getOrigUnit().
178356843Sdim  virtual void emitCompileUnitHeader(CompileUnit &Unit) = 0;
179356843Sdim
180356843Sdim  /// Recursively emit the DIE tree rooted at \p Die.
181356843Sdim  virtual void emitDIE(DIE &Die) = 0;
182356843Sdim
183356843Sdim  /// Returns size of generated .debug_line section.
184356843Sdim  virtual uint64_t getLineSectionSize() const = 0;
185356843Sdim
186356843Sdim  /// Returns size of generated .debug_frame section.
187356843Sdim  virtual uint64_t getFrameSectionSize() const = 0;
188356843Sdim
189356843Sdim  /// Returns size of generated .debug_ranges section.
190356843Sdim  virtual uint64_t getRangesSectionSize() const = 0;
191356843Sdim
192356843Sdim  /// Returns size of generated .debug_info section.
193356843Sdim  virtual uint64_t getDebugInfoSectionSize() const = 0;
194356843Sdim};
195356843Sdim
196356843Sdim} // end namespace llvm
197356843Sdim
198356843Sdim#endif // LLVM_DWARFLINKER_DWARFLINKER_H
199