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
46
47 void print(raw_ostream &Out) const {
48 Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type
49 << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol;
50 }
51
52 LLVM_DUMP_METHOD void dump() const { print(errs()); }
53};
54
56 const uint8_t OSABI;
57 const uint8_t ABIVersion;
58 const uint16_t EMachine;
59 const unsigned HasRelocationAddend : 1;
60 const unsigned Is64Bit : 1;
61
62protected:
63 MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
64 bool HasRelocationAddend_, uint8_t ABIVersion_ = 0);
65
66public:
67 virtual ~MCELFObjectTargetWriter() = default;
68
69 Triple::ObjectFormatType getFormat() const override { return Triple::ELF; }
70 static bool classof(const MCObjectTargetWriter *W) {
71 return W->getFormat() == Triple::ELF;
72 }
73
74 static uint8_t getOSABI(Triple::OSType OSType) {
75 switch (OSType) {
78 case Triple::PS4:
79 case Triple::FreeBSD:
81 case Triple::Solaris:
83 case Triple::OpenBSD:
85 default:
86 return ELF::ELFOSABI_NONE;
87 }
88 }
89
90 virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
91 const MCFixup &Fixup, bool IsPCRel) const = 0;
92
93 virtual bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
94 unsigned Type) const;
95
96 virtual void sortRelocs(const MCAssembler &Asm,
97 std::vector<ELFRelocationEntry> &Relocs);
98
99 /// \name Accessors
100 /// @{
101 uint8_t getOSABI() const { return OSABI; }
102 uint8_t getABIVersion() const { return ABIVersion; }
103 uint16_t getEMachine() const { return EMachine; }
104 bool hasRelocationAddend() const { return HasRelocationAddend; }
105 bool is64Bit() const { return Is64Bit; }
106 /// @}
107
108 // Instead of changing everyone's API we pack the N64 Type fields
109 // into the existing 32 bit data unsigned.
110#define R_TYPE_SHIFT 0
111#define R_TYPE_MASK 0xffffff00
112#define R_TYPE2_SHIFT 8
113#define R_TYPE2_MASK 0xffff00ff
114#define R_TYPE3_SHIFT 16
115#define R_TYPE3_MASK 0xff00ffff
116#define R_SSYM_SHIFT 24
117#define R_SSYM_MASK 0x00ffffff
118
119 // N64 relocation type accessors
120 uint8_t getRType(uint32_t Type) const {
121 return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
122 }
123 uint8_t getRType2(uint32_t Type) const {
124 return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
125 }
126 uint8_t getRType3(uint32_t Type) const {
127 return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
128 }
129 uint8_t getRSsym(uint32_t Type) const {
130 return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
131 }
132
133 // N64 relocation type setting
134 static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
135 return ((Value1 & 0xff) << R_TYPE_SHIFT) |
136 ((Value2 & 0xff) << R_TYPE2_SHIFT) |
137 ((Value3 & 0xff) << R_TYPE3_SHIFT);
138 }
139 unsigned setRSsym(unsigned Value, unsigned Type) const {
140 return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
141 }
142
143 // On AArch64, return a new section to be added to the ELF object that
144 // contains relocations used to describe every symbol that should have memory
145 // tags applied. Returns nullptr if no such section is necessary (i.e. there's
146 // no tagged globals).
148 return nullptr;
149 }
150};
151
152class ELFObjectWriter final : public MCObjectWriter {
153 unsigned ELFHeaderEFlags = 0;
154
155public:
156 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
159
162 bool IsLittleEndian = false;
163 bool SeenGnuAbi = false;
164 std::optional<uint8_t> OverrideABIVersion;
165
166 struct Symver {
168 const MCSymbol *Sym;
170 // True if .symver *, *@@@* or .symver *, *, remove.
172 };
174
175 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
177 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
179 bool IsLittleEndian);
180
181 void reset() override;
182 void executePostLayoutBinding(MCAssembler &Asm) override;
183 void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
184 const MCFixup &Fixup, MCValue Target,
185 uint64_t &FixedValue) override;
187 const MCSymbol &SymA,
188 const MCFragment &FB, bool InSet,
189 bool IsPCRel) const override;
190 uint64_t writeObject(MCAssembler &Asm) override;
191
192 bool hasRelocationAddend() const;
193 bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const;
194
195 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
196 const MCSymbolELF *Sym, uint64_t C,
197 unsigned Type) const;
198
199 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
200 const MCSectionELF *To);
201
202 unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; }
203 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
204
205 // Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN, STB_GNU_UNIQUE).
206 void markGnuAbi() { SeenGnuAbi = true; }
207 bool seenGnuAbi() const { return SeenGnuAbi; }
208
209 // Override the default e_ident[EI_ABIVERSION] in the ELF header.
211};
212} // end namespace llvm
213
214#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:533
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: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: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)
const MCSymbolELF * OriginalSymbol
const MCSymbolELF * Symbol
void print(raw_ostream &Out) const
LLVM_DUMP_METHOD void dump() const