LLVM 20.0.0git
MCELFObjectWriter.h
Go to the documentation of this file.
1//===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- 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#ifndef LLVM_MC_MCELFOBJECTWRITER_H
10#define LLVM_MC_MCELFOBJECTWRITER_H
11
12#include "llvm/ADT/DenseMap.h"
20#include <cstdint>
21#include <memory>
22#include <optional>
23#include <vector>
24
25namespace llvm {
26
27class MCAssembler;
28class MCContext;
29class MCFixup;
30class MCSymbol;
31class MCSymbolELF;
32class MCTargetOptions;
33class MCValue;
34
36 uint64_t Offset; // Where is the relocation.
37 const MCSymbolELF *Symbol; // The symbol to relocate with.
38 unsigned Type; // The type of the relocation.
39 uint64_t Addend; // The addend to use.
40 const MCSymbolELF *OriginalSymbol; // The original value of Symbol if we changed it.
41 uint64_t OriginalAddend; // The original value of addend.
42
48
49 void print(raw_ostream &Out) const {
50 Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type
51 << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol
52 << ", OriginalAddend=" << OriginalAddend;
53 }
54
55 LLVM_DUMP_METHOD void dump() const { print(errs()); }
56};
57
59 const uint8_t OSABI;
60 const uint8_t ABIVersion;
61 const uint16_t EMachine;
62 const unsigned HasRelocationAddend : 1;
63 const unsigned Is64Bit : 1;
64
65protected:
66 MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
67 bool HasRelocationAddend_, uint8_t ABIVersion_ = 0);
68
69public:
70 virtual ~MCELFObjectTargetWriter() = default;
71
72 Triple::ObjectFormatType getFormat() const override { return Triple::ELF; }
73 static bool classof(const MCObjectTargetWriter *W) {
74 return W->getFormat() == Triple::ELF;
75 }
76
77 static uint8_t getOSABI(Triple::OSType OSType) {
78 switch (OSType) {
81 case Triple::PS4:
82 case Triple::FreeBSD:
84 case Triple::Solaris:
86 case Triple::OpenBSD:
88 default:
89 return ELF::ELFOSABI_NONE;
90 }
91 }
92
93 virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
94 const MCFixup &Fixup, bool IsPCRel) const = 0;
95
96 virtual bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
97 unsigned Type) const;
98
99 virtual void sortRelocs(const MCAssembler &Asm,
100 std::vector<ELFRelocationEntry> &Relocs);
101
102 /// \name Accessors
103 /// @{
104 uint8_t getOSABI() const { return OSABI; }
105 uint8_t getABIVersion() const { return ABIVersion; }
106 uint16_t getEMachine() const { return EMachine; }
107 bool hasRelocationAddend() const { return HasRelocationAddend; }
108 bool is64Bit() const { return Is64Bit; }
109 /// @}
110
111 // Instead of changing everyone's API we pack the N64 Type fields
112 // into the existing 32 bit data unsigned.
113#define R_TYPE_SHIFT 0
114#define R_TYPE_MASK 0xffffff00
115#define R_TYPE2_SHIFT 8
116#define R_TYPE2_MASK 0xffff00ff
117#define R_TYPE3_SHIFT 16
118#define R_TYPE3_MASK 0xff00ffff
119#define R_SSYM_SHIFT 24
120#define R_SSYM_MASK 0x00ffffff
121
122 // N64 relocation type accessors
123 uint8_t getRType(uint32_t Type) const {
124 return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
125 }
126 uint8_t getRType2(uint32_t Type) const {
127 return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
128 }
129 uint8_t getRType3(uint32_t Type) const {
130 return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
131 }
132 uint8_t getRSsym(uint32_t Type) const {
133 return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
134 }
135
136 // N64 relocation type setting
137 static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
138 return ((Value1 & 0xff) << R_TYPE_SHIFT) |
139 ((Value2 & 0xff) << R_TYPE2_SHIFT) |
140 ((Value3 & 0xff) << R_TYPE3_SHIFT);
141 }
142 unsigned setRSsym(unsigned Value, unsigned Type) const {
143 return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
144 }
145
146 // On AArch64, return a new section to be added to the ELF object that
147 // contains relocations used to describe every symbol that should have memory
148 // tags applied. Returns nullptr if no such section is necessary (i.e. there's
149 // no tagged globals).
151 return nullptr;
152 }
153};
154
155class ELFObjectWriter final : public MCObjectWriter {
156 unsigned ELFHeaderEFlags = 0;
157
158public:
159 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
162
165 bool IsLittleEndian = false;
166 bool SeenGnuAbi = false;
167 std::optional<uint8_t> OverrideABIVersion;
168
169 struct Symver {
171 const MCSymbol *Sym;
173 // True if .symver *, *@@@* or .symver *, *, remove.
175 };
177
178 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
180 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
182 bool IsLittleEndian);
183
184 void reset() override;
185 void executePostLayoutBinding(MCAssembler &Asm) override;
186 void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
187 const MCFixup &Fixup, MCValue Target,
188 uint64_t &FixedValue) override;
190 const MCSymbol &SymA,
191 const MCFragment &FB, bool InSet,
192 bool IsPCRel) const override;
193 uint64_t writeObject(MCAssembler &Asm) override;
194
195 bool hasRelocationAddend() const;
196 bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const;
197
198 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
199 const MCSymbolELF *Sym, uint64_t C,
200 unsigned Type) const;
201
202 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
203 const MCSectionELF *To);
204
205 unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; }
206 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
207
208 // Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN, STB_GNU_UNIQUE).
209 void markGnuAbi() { SeenGnuAbi = true; }
210 bool seenGnuAbi() const { return SeenGnuAbi; }
211
212 // Override the default e_ident[EI_ABIVERSION] in the ELF header.
214};
215} // end namespace llvm
216
217#endif // LLVM_MC_MCELFOBJECTWRITER_H
BlockVerifier::State From
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:537
This file defines the DenseMap class.
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define R_TYPE2_SHIFT
#define R_SSYM_MASK
#define R_TYPE_SHIFT
#define R_TYPE3_SHIFT
#define R_SSYM_SHIFT
PowerPC TLS Dynamic Call Fixup
This file defines the SmallVector class.
std::unique_ptr< MCELFObjectTargetWriter > TargetObjectWriter
unsigned getELFHeaderEFlags() const
bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val, const MCSymbolELF *Sym, uint64_t C, unsigned Type) const
uint64_t writeObject(MCAssembler &Asm) override
Write the object file and returns the number of bytes written.
void executePostLayoutBinding(MCAssembler &Asm) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
void reset() override
lifetime management
void setELFHeaderEFlags(unsigned Flags)
void setOverrideABIVersion(uint8_t V)
std::optional< uint8_t > OverrideABIVersion
void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
DenseMap< const MCSectionELF *, std::vector< ELFRelocationEntry > > Relocations
SmallVector< Symver, 0 > Symvers
raw_pwrite_stream & OS
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
bool hasRelocationAddend() const
bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From, const MCSectionELF *To)
raw_pwrite_stream * DwoOS
bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const
DenseMap< const MCSymbolELF *, const MCSymbolELF * > Renames
Context object for machine code objects.
Definition: MCContext.h:83
static bool classof(const MCObjectTargetWriter *W)
virtual void sortRelocs(const MCAssembler &Asm, std::vector< ELFRelocationEntry > &Relocs)
virtual bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const
Triple::ObjectFormatType getFormat() const override
virtual MCSectionELF * getMemtagRelocsSection(MCContext &Ctx) const
static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3)
uint8_t getRType(uint32_t Type) const
virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const =0
uint8_t getRSsym(uint32_t Type) const
virtual ~MCELFObjectTargetWriter()=default
static uint8_t getOSABI(Triple::OSType OSType)
unsigned setRSsym(unsigned Value, unsigned Type) const
uint8_t getRType2(uint32_t Type) const
uint8_t getRType3(uint32_t Type) const
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
Base class for classes that define behaviour that is specific to both the target and the object forma...
Defines the object file and target independent interfaces used by the assembler backend to write nati...
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
This represents an "assembler immediate".
Definition: MCValue.h:36
Represents a location in source code.
Definition: SMLoc.h:23
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1210
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Target - Wrapper for Target specific information.
@ HermitCore
Definition: Triple.h:232
ObjectFormatType
Definition: Triple.h:297
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:434
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ELFOSABI_OPENBSD
Definition: ELF.h:354
@ ELFOSABI_SOLARIS
Definition: ELF.h:348
@ ELFOSABI_FREEBSD
Definition: ELF.h:351
@ ELFOSABI_STANDALONE
Definition: ELF.h:369
@ ELFOSABI_NONE
Definition: ELF.h:342
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, uint64_t Addend, const MCSymbolELF *OriginalSymbol, uint64_t OriginalAddend)
const MCSymbolELF * OriginalSymbol
const MCSymbolELF * Symbol
void print(raw_ostream &Out) const
LLVM_DUMP_METHOD void dump() const