aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp264
1 files changed, 149 insertions, 115 deletions
diff --git a/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp
index 6fd2f7e7a718..531d29954c38 100644
--- a/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp
@@ -13,10 +13,11 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -28,28 +29,26 @@
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCFragment.h"
-#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/Alignment.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SMLoc.h"
-#include "llvm/Support/StringSaver.h"
-#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/Host.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -73,7 +72,7 @@ class ELFObjectWriter;
struct ELFWriter;
bool isDwoSection(const MCSectionELF &Sec) {
- return Sec.getName().endswith(".dwo");
+ return Sec.getName().ends_with(".dwo");
}
class SymbolTableWriter {
@@ -130,11 +129,11 @@ struct ELFWriter {
/// @}
// This holds the symbol table index of the last local symbol.
- unsigned LastLocalSymbolIndex;
+ unsigned LastLocalSymbolIndex = ~0u;
// This holds the .strtab section index.
- unsigned StringTableIndex;
+ unsigned StringTableIndex = ~0u;
// This holds the .symtab section index.
- unsigned SymbolTableIndex;
+ unsigned SymbolTableIndex = ~0u;
// Sections in the order they are to be output in the section table.
std::vector<const MCSectionELF *> SectionTable;
@@ -144,17 +143,18 @@ struct ELFWriter {
bool is64Bit() const;
bool usesRela(const MCSectionELF &Sec) const;
- uint64_t align(unsigned Alignment);
+ uint64_t align(Align Alignment);
- bool maybeWriteCompression(uint64_t Size,
- SmallVectorImpl<char> &CompressedContents,
- bool ZLibStyle, unsigned Alignment);
+ bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
+ SmallVectorImpl<uint8_t> &CompressedContents,
+ Align Alignment);
public:
ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
bool IsLittleEndian, DwoMode Mode)
- : OWriter(OWriter),
- W(OS, IsLittleEndian ? support::little : support::big), Mode(Mode) {}
+ : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
+ : llvm::endianness::big),
+ Mode(Mode) {}
void WriteWord(uint64_t Word) {
if (is64Bit())
@@ -194,6 +194,8 @@ public:
MCSectionELF *createRelocationSection(MCContext &Ctx,
const MCSectionELF &Sec);
+ void createMemtagRelocs(MCAssembler &Asm);
+
void writeSectionHeader(const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
const SectionOffsetsTy &SectionOffsets);
@@ -203,7 +205,7 @@ public:
void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset, uint64_t Size,
- uint32_t Link, uint32_t Info, uint64_t Alignment,
+ uint32_t Link, uint32_t Info, MaybeAlign Alignment,
uint64_t EntrySize);
void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
@@ -223,13 +225,12 @@ class ELFObjectWriter : public MCObjectWriter {
DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
bool SeenGnuAbi = false;
- bool EmitAddrsigSection = false;
- std::vector<const MCSymbol *> AddrsigSyms;
+
+ std::optional<uint8_t> OverrideABIVersion;
bool hasRelocationAddend() const;
- bool shouldRelocateWithSymbol(const MCAssembler &Asm,
- const MCSymbolRefExpr *RefA,
+ bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
const MCSymbolELF *Sym, uint64_t C,
unsigned Type) const;
@@ -239,6 +240,7 @@ public:
void reset() override {
SeenGnuAbi = false;
+ OverrideABIVersion.reset();
Relocations.clear();
Renames.clear();
MCObjectWriter::reset();
@@ -264,10 +266,10 @@ public:
void markGnuAbi() override { SeenGnuAbi = true; }
bool seenGnuAbi() const { return SeenGnuAbi; }
- void emitAddrsigSection() override { EmitAddrsigSection = true; }
- void addAddrsigSymbol(const MCSymbol *Sym) override {
- AddrsigSyms.push_back(Sym);
- }
+
+ bool seenOverrideABIVersion() const { return OverrideABIVersion.has_value(); }
+ uint8_t getOverrideABIVersion() const { return OverrideABIVersion.value(); }
+ void setOverrideABIVersion(uint8_t V) override { OverrideABIVersion = V; }
friend struct ELFWriter;
};
@@ -301,9 +303,8 @@ public:
: ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
IsLittleEndian(IsLittleEndian) {}
- virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
- const MCSectionELF *From,
- const MCSectionELF *To) override {
+ bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
+ const MCSectionELF *To) override {
if (isDwoSection(*From)) {
Ctx.reportError(Loc, "A dwo section may not contain relocations");
return false;
@@ -326,8 +327,9 @@ public:
} // end anonymous namespace
-uint64_t ELFWriter::align(unsigned Alignment) {
- uint64_t Offset = W.OS.tell(), NewOffset = alignTo(Offset, Alignment);
+uint64_t ELFWriter::align(Align Alignment) {
+ uint64_t Offset = W.OS.tell();
+ uint64_t NewOffset = alignTo(Offset, Alignment);
W.OS.write_zeros(NewOffset - Offset);
return NewOffset;
}
@@ -412,8 +414,8 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
// e_ident[EI_DATA]
- W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
- : ELF::ELFDATA2MSB);
+ W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB
+ : ELF::ELFDATA2MSB);
W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
// e_ident[EI_OSABI]
@@ -422,7 +424,9 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
? int(ELF::ELFOSABI_GNU)
: OSABI);
// e_ident[EI_ABIVERSION]
- W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
+ W.OS << char(OWriter.seenOverrideABIVersion()
+ ? OWriter.getOverrideABIVersion()
+ : OWriter.TargetObjectWriter->getABIVersion());
W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
@@ -460,7 +464,7 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
if (Sym.isCommon())
- return Sym.getCommonAlignment();
+ return Sym.getCommonAlignment()->value();
uint64_t Res;
if (!Layout.getSymbolOffset(Sym, Res))
@@ -549,9 +553,27 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
uint64_t Size = 0;
const MCExpr *ESize = MSD.Symbol->getSize();
- if (!ESize && Base)
+ if (!ESize && Base) {
+ // For expressions like .set y, x+1, if y's size is unset, inherit from x.
ESize = Base->getSize();
+ // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
+ // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
+ // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
+ // needs. MCBinaryExpr is not handled.
+ const MCSymbolELF *Sym = &Symbol;
+ while (Sym->isVariable()) {
+ if (auto *Expr =
+ dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
+ Sym = cast<MCSymbolELF>(&Expr->getSymbol());
+ if (!Sym->getSize())
+ continue;
+ ESize = Sym->getSize();
+ }
+ break;
+ }
+ }
+
if (ESize) {
int64_t Res;
if (!ESize->evaluateKnownAbsolute(Res, Layout))
@@ -599,6 +621,23 @@ bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
return true;
}
+void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
+ MCSectionELF *MemtagRelocs = nullptr;
+ for (const MCSymbol &Sym : Asm.symbols()) {
+ const auto &SymE = cast<MCSymbolELF>(Sym);
+ if (!SymE.isMemtag())
+ continue;
+ if (MemtagRelocs == nullptr) {
+ MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
+ if (MemtagRelocs == nullptr)
+ report_fatal_error("Tagged globals are not available on this architecture.");
+ Asm.registerSection(*MemtagRelocs);
+ }
+ ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
+ OWriter.Relocations[MemtagRelocs].push_back(Rec);
+ }
+}
+
void ELFWriter::computeSymbolTable(
MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
@@ -613,7 +652,7 @@ void ELFWriter::computeSymbolTable(
SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
SymbolTableIndex = addToSectionTable(SymtabSection);
- uint64_t SecStart = align(SymtabSection->getAlignment());
+ uint64_t SecStart = align(SymtabSection->getAlign());
// The first entry is the undefined symbol entry.
Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
@@ -777,7 +816,8 @@ void ELFWriter::computeSymbolTable(
void ELFWriter::writeAddrsigSection() {
for (const MCSymbol *Sym : OWriter.AddrsigSyms)
- encodeULEB128(Sym->getIndex(), W.OS);
+ if (Sym->getIndex() != 0)
+ encodeULEB128(Sym->getIndex(), W.OS);
}
MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
@@ -809,36 +849,25 @@ MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
// Include the debug info compression header.
bool ELFWriter::maybeWriteCompression(
- uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
- unsigned Alignment) {
- if (ZLibStyle) {
- uint64_t HdrSize =
- is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
- if (Size <= HdrSize + CompressedContents.size())
- return false;
- // Platform specific header is followed by compressed data.
- if (is64Bit()) {
- // Write Elf64_Chdr header.
- write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB));
- write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
- write(static_cast<ELF::Elf64_Xword>(Size));
- write(static_cast<ELF::Elf64_Xword>(Alignment));
- } else {
- // Write Elf32_Chdr header otherwise.
- write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB));
- write(static_cast<ELF::Elf32_Word>(Size));
- write(static_cast<ELF::Elf32_Word>(Alignment));
- }
- return true;
- }
-
- // "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
- // useful for consumers to preallocate a buffer to decompress into.
- const StringRef Magic = "ZLIB";
- if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
+ uint32_t ChType, uint64_t Size,
+ SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
+ uint64_t HdrSize =
+ is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
+ if (Size <= HdrSize + CompressedContents.size())
return false;
- W.OS << Magic;
- support::endian::write(W.OS, Size, support::big);
+ // Platform specific header is followed by compressed data.
+ if (is64Bit()) {
+ // Write Elf64_Chdr header.
+ write(static_cast<ELF::Elf64_Word>(ChType));
+ write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
+ write(static_cast<ELF::Elf64_Xword>(Size));
+ write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
+ } else {
+ // Write Elf32_Chdr header otherwise.
+ write(static_cast<ELF::Elf32_Word>(ChType));
+ write(static_cast<ELF::Elf32_Word>(Size));
+ write(static_cast<ELF::Elf32_Word>(Alignment.value()));
+ }
return true;
}
@@ -850,58 +879,51 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
auto &MC = Asm.getContext();
const auto &MAI = MC.getAsmInfo();
- // Compressing debug_frame requires handling alignment fragments which is
- // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
- // for writing to arbitrary buffers) for little benefit.
- bool CompressionEnabled =
- MAI->compressDebugSections() != DebugCompressionType::None;
- if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
- SectionName == ".debug_frame") {
+ const DebugCompressionType CompressionType = MAI->compressDebugSections();
+ if (CompressionType == DebugCompressionType::None ||
+ !SectionName.starts_with(".debug_")) {
Asm.writeSectionData(W.OS, &Section, Layout);
return;
}
- assert((MAI->compressDebugSections() == DebugCompressionType::Z ||
- MAI->compressDebugSections() == DebugCompressionType::GNU) &&
- "expected zlib or zlib-gnu style compression");
-
SmallVector<char, 128> UncompressedData;
raw_svector_ostream VecOS(UncompressedData);
Asm.writeSectionData(VecOS, &Section, Layout);
-
- SmallVector<char, 128> CompressedContents;
- if (Error E = zlib::compress(
- StringRef(UncompressedData.data(), UncompressedData.size()),
- CompressedContents)) {
- consumeError(std::move(E));
- W.OS << UncompressedData;
- return;
+ ArrayRef<uint8_t> Uncompressed =
+ ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
+ UncompressedData.size());
+
+ SmallVector<uint8_t, 128> Compressed;
+ uint32_t ChType;
+ switch (CompressionType) {
+ case DebugCompressionType::None:
+ llvm_unreachable("has been handled");
+ case DebugCompressionType::Zlib:
+ ChType = ELF::ELFCOMPRESS_ZLIB;
+ break;
+ case DebugCompressionType::Zstd:
+ ChType = ELF::ELFCOMPRESS_ZSTD;
+ break;
}
-
- bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
- if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
- ZlibStyle, Sec.getAlignment())) {
+ compression::compress(compression::Params(CompressionType), Uncompressed,
+ Compressed);
+ if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
+ Sec.getAlign())) {
W.OS << UncompressedData;
return;
}
- if (ZlibStyle) {
- // Set the compressed flag. That is zlib style.
- Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
- // Alignment field should reflect the requirements of
- // the compressed section header.
- Section.setAlignment(is64Bit() ? Align(8) : Align(4));
- } else {
- // Add "z" prefix to section name. This is zlib-gnu style.
- MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str());
- }
- W.OS << CompressedContents;
+ Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
+ // Alignment field should reflect the requirements of
+ // the compressed section header.
+ Section.setAlignment(is64Bit() ? Align(8) : Align(4));
+ W.OS << toStringRef(Compressed);
}
void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset,
uint64_t Size, uint32_t Link, uint32_t Info,
- uint64_t Alignment, uint64_t EntrySize) {
+ MaybeAlign Alignment, uint64_t EntrySize) {
W.write<uint32_t>(Name); // sh_name: index into string table
W.write<uint32_t>(Type); // sh_type
WriteWord(Flags); // sh_flags
@@ -910,7 +932,7 @@ void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
WriteWord(Size); // sh_size
W.write<uint32_t>(Link); // sh_link
W.write<uint32_t>(Info); // sh_info
- WriteWord(Alignment); // sh_addralign
+ WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
WriteWord(EntrySize); // sh_entsize
}
@@ -1032,7 +1054,7 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
Section.getType(), Section.getFlags(), 0, Offset, Size,
- sh_link, sh_info, Section.getAlignment(),
+ sh_link, sh_info, Section.getAlign(),
Section.getEntrySize());
}
@@ -1044,7 +1066,7 @@ void ELFWriter::writeSectionHeader(
// Null section first.
uint64_t FirstSectionSize =
(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
- WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
+ WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
for (const MCSectionELF *Section : SectionTable) {
uint32_t GroupSymbolIndex;
@@ -1075,6 +1097,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
StringTableIndex = addToSectionTable(StrtabSection);
+ createMemtagRelocs(Asm);
+
RevGroupMapTy RevGroupMap;
SectionIndexMapTy SectionIndexMap;
@@ -1095,7 +1119,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
continue;
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(Section.getAlignment());
+ const uint64_t SecStart = align(Section.getAlign());
const MCSymbolELF *SignatureSymbol = Section.getGroup();
writeSectionData(Asm, Section, Layout);
@@ -1132,7 +1156,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
for (MCSectionELF *Group : Groups) {
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(Group->getAlignment());
+ const uint64_t SecStart = align(Group->getAlign());
const MCSymbol *SignatureSymbol = Group->getGroup();
assert(SignatureSymbol);
@@ -1164,7 +1188,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
for (MCSectionELF *RelSection : Relocations) {
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(RelSection->getAlignment());
+ const uint64_t SecStart = align(RelSection->getAlign());
writeRelocations(Asm,
cast<MCSectionELF>(*RelSection->getLinkedToSection()));
@@ -1187,7 +1211,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
}
- const uint64_t SectionHeaderOffset = align(is64Bit() ? 8 : 4);
+ const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
// ... then the section header table ...
writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
@@ -1235,7 +1259,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
StringRef Prefix = AliasName.substr(0, Pos);
StringRef Rest = AliasName.substr(Pos);
StringRef Tail = Rest;
- if (Rest.startswith("@@@"))
+ if (Rest.starts_with("@@@"))
Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
auto *Alias =
@@ -1253,8 +1277,8 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
if (!Symbol.isUndefined() && S.KeepOriginalSym)
continue;
- if (Symbol.isUndefined() && Rest.startswith("@@") &&
- !Rest.startswith("@@@")) {
+ if (Symbol.isUndefined() && Rest.starts_with("@@") &&
+ !Rest.starts_with("@@@")) {
Asm.getContext().reportError(S.Loc, "default version symbol " +
AliasName + " must be defined");
continue;
@@ -1272,7 +1296,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
for (const MCSymbol *&Sym : AddrsigSyms) {
if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
Sym = R;
- if (Sym->isInSection() && Sym->getName().startswith(".L"))
+ if (Sym->isInSection() && Sym->getName().starts_with(".L"))
Sym = Sym->getSection().getBeginSymbol();
Sym->setUsedInReloc();
}
@@ -1282,10 +1306,11 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
// to use a relocation with a section if that is possible. Using the section
// allows us to omit some local symbols from the symbol table.
bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
- const MCSymbolRefExpr *RefA,
+ const MCValue &Val,
const MCSymbolELF *Sym,
uint64_t C,
unsigned Type) const {
+ const MCSymbolRefExpr *RefA = Val.getSymA();
// A PCRel relocation to an absolute value has no symbol (or section). We
// represent that with a relocation to a null section.
if (!RefA)
@@ -1324,6 +1349,15 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
if (Sym->isUndefined())
return true;
+ // For memory-tagged symbols, ensure that the relocation uses the symbol. For
+ // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
+ // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
+ // this global needs to be tagged. In addition, the linker needs to know
+ // whether to emit a special addend when relocating `end` symbols, and this
+ // can only be determined by the attributes of the symbol itself.
+ if (Sym->isMemtag())
+ return true;
+
unsigned Binding = Sym->getBinding();
switch(Binding) {
default:
@@ -1395,7 +1429,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
if (Asm.isThumbFunc(Sym))
return true;
- if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
+ if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
return true;
return false;
}
@@ -1460,7 +1494,7 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
// Emiting relocation with sybmol for CG Profile to help with --cg-profile.
bool RelocateWithSymbol =
- shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type) ||
+ shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
(Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
uint64_t Addend = 0;