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 virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec);
103
104 /// \name Accessors
105 /// @{
106 uint8_t getOSABI() const { return OSABI; }
107 uint8_t getABIVersion() const { return ABIVersion; }
108 uint16_t getEMachine() const { return EMachine; }
109 bool hasRelocationAddend() const { return HasRelocationAddend; }
110 bool is64Bit() const { return Is64Bit; }
111 /// @}
112
113 // Instead of changing everyone's API we pack the N64 Type fields
114 // into the existing 32 bit data unsigned.
115#define R_TYPE_SHIFT 0
116#define R_TYPE_MASK 0xffffff00
117#define R_TYPE2_SHIFT 8
118#define R_TYPE2_MASK 0xffff00ff
119#define R_TYPE3_SHIFT 16
120#define R_TYPE3_MASK 0xff00ffff
121#define R_SSYM_SHIFT 24
122#define R_SSYM_MASK 0x00ffffff
123
124 // N64 relocation type accessors
125 uint8_t getRType(uint32_t Type) const {
126 return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
127 }
128 uint8_t getRType2(uint32_t Type) const {
129 return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
130 }
131 uint8_t getRType3(uint32_t Type) const {
132 return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
133 }
134 uint8_t getRSsym(uint32_t Type) const {
135 return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
136 }
137
138 // N64 relocation type setting
139 static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
140 return ((Value1 & 0xff) << R_TYPE_SHIFT) |
141 ((Value2 & 0xff) << R_TYPE2_SHIFT) |
142 ((Value3 & 0xff) << R_TYPE3_SHIFT);
143 }
144 unsigned setRSsym(unsigned Value, unsigned Type) const {
145 return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
146 }
147
148 // On AArch64, return a new section to be added to the ELF object that
149 // contains relocations used to describe every symbol that should have memory
150 // tags applied. Returns nullptr if no such section is necessary (i.e. there's
151 // no tagged globals).
153 return nullptr;
154 }
155};
156
157class ELFObjectWriter final : public MCObjectWriter {
158 unsigned ELFHeaderEFlags = 0;
159
160public:
161 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
164
167 bool IsLittleEndian = false;
168 bool SeenGnuAbi = false;
169 std::optional<uint8_t> OverrideABIVersion;
170
171 struct Symver {
173 const MCSymbol *Sym;
175 // True if .symver *, *@@@* or .symver *, *, remove.
177 };
179
180 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
182 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
184 bool IsLittleEndian);
185
186 void reset() override;
187 void executePostLayoutBinding(MCAssembler &Asm) override;
188 void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
189 const MCFixup &Fixup, MCValue Target,
190 uint64_t &FixedValue) override;
192 const MCSymbol &SymA,
193 const MCFragment &FB, bool InSet,
194 bool IsPCRel) const override;
195 uint64_t writeObject(MCAssembler &Asm) override;
196
197 bool hasRelocationAddend() const;
198 bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const;
199
200 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
201 const MCSymbolELF *Sym, uint64_t C,
202 unsigned Type) const;
203
204 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
205 const MCSectionELF *To);
206
207 unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; }
208 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
209
210 // Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN, STB_GNU_UNIQUE).
211 void markGnuAbi() { SeenGnuAbi = true; }
212 bool seenGnuAbi() const { return SeenGnuAbi; }
213
214 // Override the default e_ident[EI_ABIVERSION] in the ELF header.
216};
217} // end namespace llvm
218
219#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
virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec)
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:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Target - Wrapper for Target specific information.
@ HermitCore
Definition: Triple.h:234
ObjectFormatType
Definition: Triple.h:299
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