28#define DEBUG_TYPE "jitlink"
35 std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT,
47 return "C_FILE (File name)";
49 return "C_BINCL (Beginning of include file)";
51 return "C_EINCL (Ending of include file)";
53 return "C_GSYM (Global variable)";
55 return "C_STSYM (Statically allocated symbol)";
57 return "C_BCOMM (Beginning of common block)";
59 return "C_ECOMM (End of common block)";
61 return "C_ENTRY (Alternate entry)";
63 return "C_BSTAT (Beginning of static block)";
65 return "C_ESTAT (End of static block)";
67 return "C_GTLS (Global thread-local variable)";
69 return "C_STTLS (Static thread-local variable)";
71 return "C_DWARF (DWARF section symbol)";
73 return "C_LSYM (Automatic variable allocated on stack)";
75 return "C_PSYM (Argument to subroutine allocated on stack)";
77 return "C_RSYM (Register variable)";
79 return "C_RPSYM (Argument to function stored in register)";
81 return "C_ECOML (Local member of common block)";
83 return "C_FUN (Function or procedure)";
85 return "C_EXT (External symbol)";
87 return "C_WEAKEXT (Weak external symbol)";
91 return "C_STAT (Static)";
93 return "C_BLOCK (\".bb\" or \".eb\")";
95 return "C_FCN (\".bf\" or \".ef\")";
97 return "C_HIDEXT (Un-named external symbol)";
99 return "C_INFO (Comment string in .info section)";
101 return "C_DECL (Declaration of object)";
103 return "C_AUTO (Automatic variable)";
105 return "C_REG (Register variable)";
107 return "C_EXTDEF (External definition)";
109 return "C_LABEL (Label)";
111 return "C_ULABEL (Undefined label)";
113 return "C_MOS (Member of structure)";
115 return "C_ARG (Function argument)";
117 return "C_STRTAG (Structure tag)";
119 return "C_MOU (Member of union)";
121 return "C_UNTAG (Union tag)";
123 return "C_TPDEF (Type definition)";
125 return "C_USTATIC (Undefined static)";
127 return "C_ENTAG (Enumeration tag)";
129 return "C_MOE (Member of enumeration)";
131 return "C_REGPARM (Register parameter)";
133 return "C_FIELD (Bit field)";
135 return "C_EOS (End of structure)";
139 return "C_ALIAS (Duplicate tag)";
141 return "C_HIDDEN (Special storage class for external)";
143 return "C_EFCN (Physical end of function)";
145 return "C_TCSYM (Reserved)";
151Error XCOFFLinkGraphBuilder::processSections() {
163 <<
", idx = " << Section.getIndex()
165 <<
", vma = " <<
format_hex(Section.getAddress(), 16) <<
"\n";
169 if (Section.isDebugSection() || *
SectionName ==
"pad")
174 if (Section.isText())
176 if (Section.isData() || Section.isBSS())
183 "Section with same index already exists");
184 SectionTable[Section.getIndex()] = {GraphSec, Section};
190static std::optional<object::XCOFFSymbolRef>
200 if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.
get().isLabel())
203 static_cast<uint32_t>(CsectAuxEntOrErr.
get().getSectionOrLength());
215 if (
Sym.isCsectSymbol()) {
216 auto CsectAuxEntry =
cantFail(
Sym.getXCOFFCsectAuxRef());
217 if (!CsectAuxEntry.isLabel()) {
227 OS <<
" " <<
Sym.getSectionNumber();
230 if (
Sym.isCsectSymbol()) {
232 OS <<
" (csect idx: "
240Error XCOFFLinkGraphBuilder::processCsectsAndSymbols() {
243 for ([[maybe_unused]]
auto [K, V] : SectionTable) {
245 <<
" section: " << V.Section->getName() <<
")\n");
253 return Flags.takeError();
266 SymbolIndexTable[SymbolIndex] =
267 &G->addExternalSymbol(*SymbolName,
Symbol.getSize(),
Weak);
271 if (!
Symbol.isCsectSymbol()) {
282 bool IsUndefinedSection = !SectionTable.contains(ParentSectionNumber);
283 Section *ParentSection = !IsUndefinedSection
284 ? SectionTable[ParentSectionNumber].Section
289 if (!CsectTable.contains(CsectSymbolIndex) && !IsUndefinedSection) {
291 SectionTable[ParentSectionNumber].SectionData;
294 return Data.takeError();
295 auto CsectSymbolAddr = CsectSymbol.
getAddress();
296 if (!CsectSymbolAddr)
297 return CsectSymbolAddr.takeError();
303 <<
", size = " << CsectSymbol.
getSize()
304 <<
", storage class = "
308 B = &G->createContentBlock(
309 *ParentSection, SectionBuffer.slice(
Offset, CsectSymbol.
getSize()),
312 CsectTable[CsectSymbolIndex] =
B;
314 B = CsectTable[CsectSymbolIndex];
326 auto SymbolAddr =
Symbol.getAddress();
328 return SymbolAddr.takeError();
329 auto IsCallableOrErr =
Symbol.isFunction();
330 if (!IsCallableOrErr)
331 return IsCallableOrErr.takeError();
333 auto BlockOffset = *SymbolAddr -
B->getAddress().getValue();
337 <<
format_hex(
B->getAddress().getValue(), 16) <<
"\n");
339 SymbolIndexTable[SymbolIndex] =
340 &G->addDefinedSymbol(*
B, BlockOffset, *SymbolName,
Symbol.getSize(), L,
341 S, *IsCallableOrErr,
true);
347Error XCOFFLinkGraphBuilder::processRelocations() {
360 Relocation.getTypeName(RelocName);
363 auto TargetSymbol =
Symbol.getName();
365 return TargetSymbol.takeError();
370 <<
" (idx: " << SymbolIndex <<
")"
371 <<
" " << RelocName <<
" " << *TargetSymbol <<
"\n";);
373 assert(SymbolIndexTable.contains(SymbolIndex) &&
374 "Relocation needs a record in the symbol table");
375 auto *S = SymbolIndexTable[SymbolIndex];
378 Relocation.getOffset())](
379 const Block *
B) ->
bool {
380 return B->getRange().contains(Target);
382 assert(It != G->blocks().end() &&
383 "Cannot find the target relocation block");
386 auto TargetBlockOffset =
Section.getAddress() + Relocation.getOffset() -
387 B->getAddress().getValue();
388 switch (Relocation.getType()) {
394 Relocation.getTypeName(RelocType);
395 return make_error<StringError>(
396 "Unsupported Relocation Type: " + RelocType, std::error_code());
409 if (
auto Err = processSections())
411 if (
auto Err = processCsectsAndSymbols())
413 if (
auto Err = processRelocations())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
reference get()
Returns a reference to the stored T value.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
const char *(*)(Edge::Kind) GetEdgeKindNameFunction
Represents an object file section.
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
orc::ExecutorAddrDiff getSize() const
Returns the size of this symbol.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
XCOFFLinkGraphBuilder(const object::XCOFFObjectFile &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
section_iterator_range sections() const
This is a value type class that represents a single relocation in the list of relocations in the obje...
This is a value type class that represents a single section in the list of sections in the object fil...
Expected< StringRef > getContents() const
uint64_t getAddress() const
This is a value type class that represents a single symbol in the list of symbols in the object file.
uint32_t getAlignment() const
Get the alignment of this symbol as the actual value (not log 2).
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const
XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const
uintptr_t getSymbolByIndex(uint32_t Idx) const
xcoff_symbol_iterator_range symbols() const
LLVM_ABI Expected< XCOFFCsectAuxRef > getXCOFFCsectAuxRef() const
int16_t getSectionNumber() const
LLVM_ABI bool isCsectSymbol() const
uintptr_t getEntryAddress() const
XCOFF::StorageClass getStorageClass() const
Represents an address in the executor process.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI StringRef getMappingClassString(XCOFF::StorageMappingClass SMC)
@ R_POS
Positive relocation.
LLVM_ABI const char * getLinkageName(Linkage L)
For errors and debugging output.
static llvm::StringRef getStorageClassString(XCOFF::StorageClass SC)
static void printSymbolEntry(raw_ostream &OS, const object::XCOFFObjectFile &Obj, const object::XCOFFSymbolRef &Sym)
LLVM_ABI const char * getScopeName(Scope S)
For debugging output.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
static std::optional< object::XCOFFSymbolRef > getXCOFFSymbolContainingSymbolRef(const object::XCOFFObjectFile &Obj, const object::SymbolRef &Sym)
MemProt
Describes Read/Write/Exec permissions for memory.
NodeAddr< BlockNode * > Block
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
@ Global
Append to llvm.global_dtors.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.