aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/MC/ELFObjectWriter.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp50
1 files changed, 26 insertions, 24 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 883735fcc293..eda495693595 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -13,10 +13,10 @@
#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/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,18 +28,18 @@
#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"
@@ -47,8 +47,6 @@
#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 <algorithm>
#include <cassert>
@@ -223,8 +221,6 @@ class ELFObjectWriter : public MCObjectWriter {
DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
bool SeenGnuAbi = false;
- bool EmitAddrsigSection = false;
- std::vector<const MCSymbol *> AddrsigSyms;
bool hasRelocationAddend() const;
@@ -264,10 +260,6 @@ 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);
- }
friend struct ELFWriter;
};
@@ -549,9 +541,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))
@@ -850,13 +860,9 @@ 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") {
+ if (!CompressionEnabled || !SectionName.startswith(".debug_")) {
Asm.writeSectionData(W.OS, &Section, Layout);
return;
}
@@ -870,13 +876,8 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
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;
- }
+ zlib::compress(StringRef(UncompressedData.data(), UncompressedData.size()),
+ CompressedContents);
bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
@@ -1336,6 +1337,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
// can update it.
return true;
case ELF::STB_GLOBAL:
+ case ELF::STB_GNU_UNIQUE:
// Global ELF symbols can be preempted by the dynamic linker. The relocation
// has to point to the symbol for a reason analogous to the STB_WEAK case.
return true;