LLVM 20.0.0git
COFFLinkGraphBuilder.h
Go to the documentation of this file.
1//===----- COFFLinkGraphBuilder.h - COFF LinkGraph builder ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Generic COFF LinkGraph building code.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LIB_EXECUTIONENGINE_JITLINK_COFFLINKGRAPHBUILDER_H
14#define LIB_EXECUTIONENGINE_JITLINK_COFFLINKGRAPHBUILDER_H
15
16#include "llvm/ADT/DenseMap.h"
18#include "llvm/Object/COFF.h"
19
20#include "COFFDirectiveParser.h"
21#include "EHFrameSupportImpl.h"
22#include "JITLinkGeneric.h"
23
24#define DEBUG_TYPE "jitlink"
25
26#include <list>
27
28namespace llvm {
29namespace jitlink {
30
32public:
35
36protected:
37 using COFFSectionIndex = int32_t;
38 using COFFSymbolIndex = int32_t;
39
41 std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
42 SubtargetFeatures Features,
44
45 LinkGraph &getGraph() const { return *G; }
46
47 const object::COFFObjectFile &getObject() const { return Obj; }
48
49 virtual Error addRelocations() = 0;
50
53
55 Symbol &Sym) {
56 assert(!GraphSymbols[SymIndex] && "Duplicate symbol at index");
57 GraphSymbols[SymIndex] = &Sym;
58 if (!COFF::isReservedSectionNumber(SecIndex))
59 SymbolSets[SecIndex].insert({Sym.getOffset(), &Sym});
60 }
61
63 if (SymIndex < 0 ||
64 SymIndex >= static_cast<COFFSymbolIndex>(GraphSymbols.size()))
65 return nullptr;
66 return GraphSymbols[SymIndex];
67 }
68
70 assert(!GraphBlocks[SecIndex] && "Duplicate section at index");
71 assert(!COFF::isReservedSectionNumber(SecIndex) && "Invalid section index");
72 GraphBlocks[SecIndex] = B;
73 }
74
76 if (SecIndex <= 0 ||
77 SecIndex >= static_cast<COFFSectionIndex>(GraphSymbols.size()))
78 return nullptr;
79 return GraphBlocks[SecIndex];
80 }
81
83 return Obj.sections();
84 }
85
86 /// Traverse all matching relocation records in the given section. The handler
87 /// function Func should be callable with this signature:
88 /// Error(const object::RelocationRef&,
89 /// const object::SectionRef&, Section &)
90 ///
91 template <typename RelocHandlerFunction>
93 RelocHandlerFunction &&Func,
94 bool ProcessDebugSections = false);
95
96 /// Traverse all matching relocation records in the given section. Convenience
97 /// wrapper to allow passing a member function for the handler.
98 ///
99 template <typename ClassT, typename RelocHandlerMethod>
100 Error forEachRelocation(const object::SectionRef &RelSec, ClassT *Instance,
101 RelocHandlerMethod &&Method,
102 bool ProcessDebugSections = false) {
103 return forEachRelocation(
104 RelSec,
105 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
106 return (Instance->*Method)(Rel, Target, GS);
107 },
108 ProcessDebugSections);
109 }
110
111private:
112 // Pending comdat symbol export that is initiated by the first symbol of
113 // COMDAT sequence.
114 struct ComdatExportRequest {
115 COFFSymbolIndex SymbolIndex;
118 };
119 std::vector<std::optional<ComdatExportRequest>> PendingComdatExports;
120
121 // This represents a pending request to create a weak external symbol with a
122 // name.
123 struct WeakExternalRequest {
124 COFFSymbolIndex Alias;
126 uint32_t Characteristics;
127 StringRef SymbolName;
128 };
129 std::vector<WeakExternalRequest> WeakExternalRequests;
130
131 // Per COFF section jitlink symbol set sorted by offset.
132 // Used for calculating implicit size of defined symbols.
133 using SymbolSet = std::set<std::pair<orc::ExecutorAddrDiff, Symbol *>>;
134 std::vector<SymbolSet> SymbolSets;
135
136 Section &getCommonSection();
137
138 Symbol *createExternalSymbol(COFFSymbolIndex SymIndex,
139 orc::SymbolStringPtr SymbolName,
140 object::COFFSymbolRef Symbol,
141 const object::coff_section *Section);
142 Expected<Symbol *> createAliasSymbol(orc::SymbolStringPtr SymbolName,
143 Linkage L, Scope S, Symbol &Target);
144 Expected<Symbol *> createDefinedSymbol(COFFSymbolIndex SymIndex,
145 orc::SymbolStringPtr SymbolName,
146 object::COFFSymbolRef Symbol,
147 const object::coff_section *Section);
148 Expected<Symbol *> createCOMDATExportRequest(
149 COFFSymbolIndex SymIndex, object::COFFSymbolRef Symbol,
150 const object::coff_aux_section_definition *Definition);
151 Expected<Symbol *> exportCOMDATSymbol(COFFSymbolIndex SymIndex,
152 orc::SymbolStringPtr SymbolName,
153 object::COFFSymbolRef Symbol);
154
155 Error handleDirectiveSection(StringRef Str);
156 Error flushWeakAliasRequests();
157 Error handleAlternateNames();
158 Error calculateImplicitSizeOfSymbols();
159
160 static uint64_t getSectionAddress(const object::COFFObjectFile &Obj,
161 const object::coff_section *Section);
162 static uint64_t getSectionSize(const object::COFFObjectFile &Obj,
163 const object::coff_section *Section);
164 static bool isComdatSection(const object::coff_section *Section);
165 static unsigned getPointerSize(const object::COFFObjectFile &Obj);
166 static llvm::endianness getEndianness(const object::COFFObjectFile &Obj);
167 static StringRef getDLLImportStubPrefix() { return "__imp_"; }
168 static StringRef getDirectiveSectionName() { return ".drectve"; }
169 StringRef getCOFFSectionName(COFFSectionIndex SectionIndex,
170 const object::coff_section *Sec,
171 object::COFFSymbolRef Sym);
172
173 const object::COFFObjectFile &Obj;
174 std::unique_ptr<LinkGraph> G;
175 COFFDirectiveParser DirectiveParser;
176
177 Section *CommonSection = nullptr;
178 std::vector<Block *> GraphBlocks;
179 std::vector<Symbol *> GraphSymbols;
180
181 DenseMap<orc::SymbolStringPtr, orc::SymbolStringPtr> AlternateNames;
182 DenseMap<orc::SymbolStringPtr, Symbol *> ExternalSymbols;
183 DenseMap<orc::SymbolStringPtr, Symbol *> DefinedSymbols;
184};
185
186template <typename RelocHandlerFunction>
188 RelocHandlerFunction &&Func,
189 bool ProcessDebugSections) {
190
191 auto COFFRelSect = Obj.getCOFFSection(RelSec);
192
193 // Target sections have names in valid COFF object files.
194 Expected<StringRef> Name = Obj.getSectionName(COFFRelSect);
195 if (!Name)
196 return Name.takeError();
197
198 // Skip the unhandled metadata sections.
199 if (*Name == ".voltbl")
200 return Error::success();
201 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
202
203 // Lookup the link-graph node corresponding to the target section name.
204 auto *BlockToFix = getGraphBlock(RelSec.getIndex() + 1);
205 if (!BlockToFix)
206 return make_error<StringError>(
207 "Referencing a section that wasn't added to the graph: " + *Name,
209
210 // Let the callee process relocation entries one by one.
211 for (const auto &R : RelSec.relocations())
212 if (Error Err = Func(R, RelSec, *BlockToFix))
213 return Err;
214
215 LLVM_DEBUG(dbgs() << "\n");
216 return Error::success();
217}
218
219} // end namespace jitlink
220} // end namespace llvm
221
222#endif // LIB_EXECUTIONENGINE_JITLINK_COFFLINKGRAPHBUILDER_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DEBUG(...)
Definition: Debug.h:106
This file defines the DenseMap class.
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A range adaptor for a pair of iterators.
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
const coff_section * getCOFFSection(const SectionRef &Section) const
section_iterator_range sections() const
Definition: ObjectFile.h:329
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
uint64_t getIndex() const
Definition: ObjectFile.h:525
iterator_range< relocation_iterator > relocations() const
Definition: ObjectFile.h:133
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: COFF.h:848
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
endianness
Definition: bit.h:70