aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/ELFObjectWriter.cpp')
-rw-r--r--lib/MC/ELFObjectWriter.cpp59
1 files changed, 42 insertions, 17 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 89f3b30cddd6..2c68723a12f8 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -1,9 +1,8 @@
//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -426,7 +425,8 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
// e_ident[EI_OSABI]
W.OS << char(OWriter.TargetObjectWriter->getOSABI());
- W.OS << char(0); // e_ident[EI_ABIVERSION]
+ // e_ident[EI_ABIVERSION]
+ W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
@@ -463,7 +463,7 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
- if (Sym.isCommon() && Sym.isExternal())
+ if (Sym.isCommon() && (Sym.isTargetCommon() || Sym.isExternal()))
return Sym.getCommonAlignment();
uint64_t Res;
@@ -577,6 +577,10 @@ bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
bool Used, bool Renamed) {
if (Symbol.isVariable()) {
const MCExpr *Expr = Symbol.getVariableValue();
+ // Target Expressions that are always inlined do not appear in the symtab
+ if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
+ if (T->inlineAssignedExpr())
+ return false;
if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
return false;
@@ -656,8 +660,12 @@ void ELFWriter::computeSymbolTable(
if (Symbol.isAbsolute()) {
MSD.SectionIndex = ELF::SHN_ABS;
} else if (Symbol.isCommon()) {
- assert(!Local);
- MSD.SectionIndex = ELF::SHN_COMMON;
+ if (Symbol.isTargetCommon()) {
+ MSD.SectionIndex = Symbol.getIndex();
+ } else {
+ assert(!Local);
+ MSD.SectionIndex = ELF::SHN_COMMON;
+ }
} else if (Symbol.isUndefined()) {
if (isSignature && !Used) {
MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
@@ -710,7 +718,7 @@ void ELFWriter::computeSymbolTable(
if (HasLargeSectionIndex) {
MCSectionELF *SymtabShndxSection =
- Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
+ Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
SymtabShndxSection->setAlignment(4);
}
@@ -882,12 +890,16 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
return;
}
- if (ZlibStyle)
+ if (ZlibStyle) {
// Set the compressed flag. That is zlib style.
Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
- else
+ // Alignment field should reflect the requirements of
+ // the compressed section header.
+ Section.setAlignment(is64Bit() ? 8 : 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;
}
@@ -1271,18 +1283,25 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
// This is the first place we are able to copy this information.
Alias->setExternal(Symbol.isExternal());
Alias->setBinding(Symbol.getBinding());
+ Alias->setOther(Symbol.getOther());
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
continue;
- // FIXME: produce a better error message.
+ // FIXME: Get source locations for these errors or diagnose them earlier.
if (Symbol.isUndefined() && Rest.startswith("@@") &&
- !Rest.startswith("@@@"))
- report_fatal_error("A @@ version cannot be undefined");
+ !Rest.startswith("@@@")) {
+ Asm.getContext().reportError(SMLoc(), "versioned symbol " + AliasName +
+ " must be defined");
+ continue;
+ }
- if (Renames.count(&Symbol) && Renames[&Symbol] != Alias)
- report_fatal_error(llvm::Twine("Multiple symbol versions defined for ") +
- Symbol.getName());
+ if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
+ Asm.getContext().reportError(
+ SMLoc(), llvm::Twine("multiple symbol versions defined for ") +
+ Symbol.getName());
+ continue;
+ }
Renames.insert(std::make_pair(&Symbol, Alias));
}
@@ -1358,6 +1377,12 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
return true;
}
+ // Keep symbol type for a local ifunc because it may result in an IRELATIVE
+ // reloc that the dynamic loader will use to resolve the address at startup
+ // time.
+ if (Sym->getType() == ELF::STT_GNU_IFUNC)
+ return true;
+
// If a relocation points to a mergeable section, we have to be careful.
// If the offset is zero, a relocation with the section will encode the
// same information. With a non-zero offset, the situation is different.