Vendor import of lld trunk r338536:
https://llvm.org/svn/llvm-project/lld/trunk@338536
This commit is contained in:
parent
20d35e67e6
commit
84c4061b34
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/lld/dist/; revision=337145 svn path=/vendor/lld/lld-release_70-r338892/; revision=337307; tag=vendor/lld/lld-release_70-r338892
10
COFF/ICF.cpp
10
COFF/ICF.cpp
@ -27,6 +27,7 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Parallel.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/xxhash.h"
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
@ -65,13 +66,6 @@ class ICF {
|
||||
std::atomic<bool> Repeat = {false};
|
||||
};
|
||||
|
||||
// Returns a hash value for S.
|
||||
uint32_t ICF::getHash(SectionChunk *C) {
|
||||
return hash_combine(C->getOutputCharacteristics(), C->SectionName,
|
||||
C->Relocs.size(), uint32_t(C->Header->SizeOfRawData),
|
||||
C->Checksum, C->getContents());
|
||||
}
|
||||
|
||||
// Returns true if section S is subject of ICF.
|
||||
//
|
||||
// Microsoft's documentation
|
||||
@ -265,7 +259,7 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
|
||||
// Initially, we use hash values to partition sections.
|
||||
for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) {
|
||||
// Set MSB to 1 to avoid collisions with non-hash classs.
|
||||
SC->Class[0] = getHash(SC) | (1 << 31);
|
||||
SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31);
|
||||
});
|
||||
|
||||
// From now on, sections in Chunks are ordered so that sections in
|
||||
|
@ -97,10 +97,19 @@ ARM::ARM() {
|
||||
}
|
||||
|
||||
uint32_t ARM::calcEFlags() const {
|
||||
// The ABIFloatType is used by loaders to detect the floating point calling
|
||||
// convention.
|
||||
uint32_t ABIFloatType = 0;
|
||||
if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
|
||||
Config->ARMVFPArgs == ARMVFPArgKind::Default)
|
||||
ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
|
||||
else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
|
||||
ABIFloatType = EF_ARM_ABI_FLOAT_HARD;
|
||||
|
||||
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
|
||||
// but we don't have any firm guarantees of conformance. Linux AArch64
|
||||
// kernels (as of 2016) require an EABI version to be set.
|
||||
return EF_ARM_EABI_VER5;
|
||||
return EF_ARM_EABI_VER5 | ABIFloatType;
|
||||
}
|
||||
|
||||
RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
|
||||
|
@ -70,6 +70,12 @@ void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
switch (Type) {
|
||||
case R_HEX_NONE:
|
||||
break;
|
||||
case R_HEX_12_X:
|
||||
or32le(Loc, applyMask(0x000007e0, Val));
|
||||
break;
|
||||
case R_HEX_32_6_X:
|
||||
or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
|
||||
break;
|
||||
case R_HEX_B15_PCREL:
|
||||
or32le(Loc, applyMask(0x00df20fe, Val >> 2));
|
||||
break;
|
||||
|
@ -58,6 +58,9 @@ enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
|
||||
// For --target2
|
||||
enum class Target2Policy { Abs, Rel, GotRel };
|
||||
|
||||
// For tracking ARM Float Argument PCS
|
||||
enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
|
||||
|
||||
struct SymbolVersion {
|
||||
llvm::StringRef Name;
|
||||
bool IsExternCpp;
|
||||
@ -133,6 +136,7 @@ struct Configuration {
|
||||
bool EhFrameHdr;
|
||||
bool EmitRelocs;
|
||||
bool EnableNewDtags;
|
||||
bool ExecuteOnly;
|
||||
bool ExportDynamic;
|
||||
bool FixCortexA53Errata843419;
|
||||
bool GcSections;
|
||||
@ -195,6 +199,7 @@ struct Configuration {
|
||||
StripPolicy Strip;
|
||||
UnresolvedPolicy UnresolvedSymbols;
|
||||
Target2Policy Target2;
|
||||
ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
|
||||
BuildIdKind BuildId = BuildIdKind::None;
|
||||
ELFKind EKind = ELFNoneKind;
|
||||
uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
|
||||
|
@ -302,6 +302,14 @@ static void checkOptions(opt::InputArgList &Args) {
|
||||
if (Config->Pie)
|
||||
error("-r and -pie may not be used together");
|
||||
}
|
||||
|
||||
if (Config->ExecuteOnly) {
|
||||
if (Config->EMachine != EM_AARCH64)
|
||||
error("-execute-only is only supported on AArch64 targets");
|
||||
|
||||
if (Config->SingleRoRx && !Script->HasSectionsCommand)
|
||||
error("-execute-only and -no-rosegment cannot be used together");
|
||||
}
|
||||
}
|
||||
|
||||
static const char *getReproduceOption(opt::InputArgList &Args) {
|
||||
@ -493,6 +501,8 @@ static bool isOutputFormatBinary(opt::InputArgList &Args) {
|
||||
StringRef S = Arg->getValue();
|
||||
if (S == "binary")
|
||||
return true;
|
||||
if (S.startswith("elf"))
|
||||
return false;
|
||||
error("unknown --oformat value: " + S);
|
||||
}
|
||||
return false;
|
||||
@ -747,6 +757,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
||||
Config->EnableNewDtags =
|
||||
Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
|
||||
Config->Entry = Args.getLastArgValue(OPT_entry);
|
||||
Config->ExecuteOnly =
|
||||
Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
|
||||
Config->ExportDynamic =
|
||||
Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
|
||||
Config->FilterList = args::getStrings(Args, OPT_filter);
|
||||
@ -1303,6 +1315,12 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char *LibcallRoutineNames[] = {
|
||||
#define HANDLE_LIBCALL(code, name) name,
|
||||
#include "llvm/IR/RuntimeLibcalls.def"
|
||||
#undef HANDLE_LIBCALL
|
||||
};
|
||||
|
||||
// Do actual linking. Note that when this function is called,
|
||||
// all linker scripts have already been parsed.
|
||||
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
@ -1369,11 +1387,21 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
for (StringRef S : Config->Undefined)
|
||||
handleUndefined<ELFT>(S);
|
||||
|
||||
// If an entry symbol is in a static archive, pull out that file now
|
||||
// to complete the symbol table. After this, no new names except a
|
||||
// few linker-synthesized ones will be added to the symbol table.
|
||||
// If an entry symbol is in a static archive, pull out that file now.
|
||||
handleUndefined<ELFT>(Config->Entry);
|
||||
|
||||
// If any of our inputs are bitcode files, the LTO code generator may create
|
||||
// references to certain library functions that might not be explicit in the
|
||||
// bitcode file's symbol table. If any of those library functions are defined
|
||||
// in a bitcode file in an archive member, we need to arrange to use LTO to
|
||||
// compile those archive members by adding them to the link beforehand.
|
||||
//
|
||||
// With this the symbol table should be complete. After this, no new names
|
||||
// except a few linker-synthesized ones will be added to the symbol table.
|
||||
if (!BitcodeFiles.empty())
|
||||
for (const char *S : LibcallRoutineNames)
|
||||
handleUndefined<ELFT>(S);
|
||||
|
||||
// Return if there were name resolution errors.
|
||||
if (errorCount())
|
||||
return;
|
||||
|
11
ELF/ICF.cpp
11
ELF/ICF.cpp
@ -80,9 +80,10 @@
|
||||
#include "SyntheticSections.h"
|
||||
#include "Writer.h"
|
||||
#include "lld/Common/Threads.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/Object/ELF.h"
|
||||
#include "llvm/Support/xxhash.h"
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
|
||||
@ -155,12 +156,6 @@ template <class ELFT> class ICF {
|
||||
};
|
||||
}
|
||||
|
||||
// Returns a hash value for S. Note that the information about
|
||||
// relocation targets is not included in the hash value.
|
||||
template <class ELFT> static uint32_t getHash(InputSection *S) {
|
||||
return hash_combine(S->Flags, S->getSize(), S->NumRelocations, S->Data);
|
||||
}
|
||||
|
||||
// Returns true if section S is subject of ICF.
|
||||
static bool isEligible(InputSection *S) {
|
||||
if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC))
|
||||
@ -441,7 +436,7 @@ template <class ELFT> void ICF<ELFT>::run() {
|
||||
// Initially, we use hash values to partition sections.
|
||||
parallelForEach(Sections, [&](InputSection *S) {
|
||||
// Set MSB to 1 to avoid collisions with non-hash IDs.
|
||||
S->Class[0] = getHash<ELFT>(S) | (1U << 31);
|
||||
S->Class[0] = xxHash64(S->Data) | (1U << 31);
|
||||
});
|
||||
|
||||
// From now on, sections in Sections vector are ordered so that sections
|
||||
|
@ -494,6 +494,46 @@ void ObjFile<ELFT>::initializeSections(
|
||||
}
|
||||
}
|
||||
|
||||
// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
|
||||
// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
|
||||
// the input objects have been compiled.
|
||||
static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
|
||||
const InputFile *F) {
|
||||
if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
|
||||
// If an ABI tag isn't present then it is implicitly given the value of 0
|
||||
// which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
|
||||
// including some in glibc that don't use FP args (and should have value 3)
|
||||
// don't have the attribute so we do not consider an implicit value of 0
|
||||
// as a clash.
|
||||
return;
|
||||
|
||||
unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
|
||||
ARMVFPArgKind Arg;
|
||||
switch (VFPArgs) {
|
||||
case ARMBuildAttrs::BaseAAPCS:
|
||||
Arg = ARMVFPArgKind::Base;
|
||||
break;
|
||||
case ARMBuildAttrs::HardFPAAPCS:
|
||||
Arg = ARMVFPArgKind::VFP;
|
||||
break;
|
||||
case ARMBuildAttrs::ToolChainFPPCS:
|
||||
// Tool chain specific convention that conforms to neither AAPCS variant.
|
||||
Arg = ARMVFPArgKind::ToolChain;
|
||||
break;
|
||||
case ARMBuildAttrs::CompatibleFPAAPCS:
|
||||
// Object compatible with all conventions.
|
||||
return;
|
||||
default:
|
||||
error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
|
||||
return;
|
||||
}
|
||||
// Follow ld.bfd and error if there is a mix of calling conventions.
|
||||
if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
|
||||
error(toString(F) + ": incompatible Tag_ABI_VFP_args");
|
||||
else
|
||||
Config->ARMVFPArgs = Arg;
|
||||
}
|
||||
|
||||
// The ARM support in lld makes some use of instructions that are not available
|
||||
// on all ARM architectures. Namely:
|
||||
// - Use of BLX instruction for interworking between ARM and Thumb state.
|
||||
@ -573,6 +613,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
|
||||
ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
|
||||
Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
|
||||
updateSupportedARMFeatures(Attributes);
|
||||
updateARMVFPArgs(Attributes, this);
|
||||
|
||||
// FIXME: Retain the first attribute section we see. The eglibc ARM
|
||||
// dynamic loaders require the presence of an attribute section for dlopen
|
||||
// to work. In a full implementation we would merge all attribute sections.
|
||||
|
@ -221,8 +221,8 @@ template <class ELFT>
|
||||
Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
|
||||
for (Symbol *B : File->getSymbols())
|
||||
if (Defined *D = dyn_cast<Defined>(B))
|
||||
if (D->Section == this && D->Type == STT_FUNC &&
|
||||
D->Value <= Offset && Offset < D->Value + D->Size)
|
||||
if (D->Section == this && D->Type == STT_FUNC && D->Value <= Offset &&
|
||||
Offset < D->Value + D->Size)
|
||||
return D;
|
||||
return nullptr;
|
||||
}
|
||||
@ -671,7 +671,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
|
||||
case R_TLSLD_GOT_FROM_END:
|
||||
return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
|
||||
case R_TLSLD_GOT:
|
||||
return InX::Got->getTlsIndexOff() + A;
|
||||
return InX::Got->getTlsIndexOff() + A;
|
||||
case R_TLSLD_PC:
|
||||
return InX::Got->getTlsIndexVA() + A - P;
|
||||
}
|
||||
@ -842,8 +842,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
|
||||
// For each function-defining prologue, find any calls to __morestack,
|
||||
// and replace them with calls to __morestack_non_split.
|
||||
static void switchMorestackCallsToMorestackNonSplit(
|
||||
llvm::DenseSet<Defined *>& Prologues,
|
||||
std::vector<Relocation *>& MorestackCalls) {
|
||||
DenseSet<Defined *> &Prologues, std::vector<Relocation *> &MorestackCalls) {
|
||||
|
||||
// If the target adjusted a function's prologue, all calls to
|
||||
// __morestack inside that function should be switched to
|
||||
@ -873,9 +872,8 @@ static void switchMorestackCallsToMorestackNonSplit(
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
enclosingPrologueAdjusted(uint64_t Offset,
|
||||
const llvm::DenseSet<Defined *> &Prologues) {
|
||||
static bool enclosingPrologueAdjusted(uint64_t Offset,
|
||||
const DenseSet<Defined *> &Prologues) {
|
||||
for (Defined *F : Prologues)
|
||||
if (F->Value <= Offset && Offset < F->Value + F->Size)
|
||||
return true;
|
||||
@ -891,7 +889,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
|
||||
uint8_t *End) {
|
||||
if (!getFile<ELFT>()->SplitStack)
|
||||
return;
|
||||
llvm::DenseSet<Defined *> AdjustedPrologues;
|
||||
DenseSet<Defined *> AdjustedPrologues;
|
||||
std::vector<Relocation *> MorestackCalls;
|
||||
|
||||
for (Relocation &Rel : Relocations) {
|
||||
@ -1071,8 +1069,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
|
||||
bool IsAlloc = Flags & SHF_ALLOC;
|
||||
|
||||
for (size_t I = 0; I != Size; I += EntSize)
|
||||
Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))),
|
||||
!IsAlloc);
|
||||
Pieces.emplace_back(I, xxHash64(Data.slice(I, EntSize)), !IsAlloc);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -58,8 +58,8 @@ defm allow_multiple_definition: B<"allow-multiple-definition",
|
||||
"Do not allow multiple definitions (default)">;
|
||||
|
||||
defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
|
||||
"Apply dynamic relocations to place",
|
||||
"Do not apply dynamic relocations to place">;
|
||||
"Apply link-time values for dynamic relocations",
|
||||
"Do not apply link-time values for dynamic relocations (default)">;
|
||||
|
||||
defm as_needed: B<"as-needed",
|
||||
"Only set DT_NEEDED for shared libraries if used",
|
||||
@ -131,6 +131,10 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">,
|
||||
|
||||
defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
|
||||
|
||||
defm execute_only: B<"execute-only",
|
||||
"Do not mark executable sections readable",
|
||||
"Mark executable sections readable (default)">;
|
||||
|
||||
defm export_dynamic: B<"export-dynamic",
|
||||
"Put symbols in the dynamic symbol table",
|
||||
"Do not put symbols in the dynamic symbol table (default)">;
|
||||
|
@ -335,7 +335,7 @@ void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||
switch (Config->BuildId) {
|
||||
case BuildIdKind::Fast:
|
||||
computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
|
||||
write64le(Dest, xxHash64(toStringRef(Arr)));
|
||||
write64le(Dest, xxHash64(Arr));
|
||||
});
|
||||
break;
|
||||
case BuildIdKind::Md5:
|
||||
@ -1935,6 +1935,23 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
|
||||
this->Entsize = sizeof(Elf_Sym);
|
||||
}
|
||||
|
||||
static BssSection *getCommonSec(Symbol *Sym) {
|
||||
if (!Config->DefineCommon)
|
||||
if (auto *D = dyn_cast<Defined>(Sym))
|
||||
return dyn_cast_or_null<BssSection>(D->Section);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static uint32_t getSymSectionIndex(Symbol *Sym) {
|
||||
if (getCommonSec(Sym))
|
||||
return SHN_COMMON;
|
||||
if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
|
||||
return SHN_UNDEF;
|
||||
if (const OutputSection *OS = Sym->getOutputSection())
|
||||
return OS->SectionIndex >= SHN_LORESERVE ? SHN_XINDEX : OS->SectionIndex;
|
||||
return SHN_ABS;
|
||||
}
|
||||
|
||||
// Write the internal symbol table contents to the output symbol table.
|
||||
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
// The first entry is a null entry as per the ELF spec.
|
||||
@ -1956,22 +1973,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
}
|
||||
|
||||
ESym->st_name = Ent.StrTabOffset;
|
||||
|
||||
// Set a section index.
|
||||
BssSection *CommonSec = nullptr;
|
||||
if (!Config->DefineCommon)
|
||||
if (auto *D = dyn_cast<Defined>(Sym))
|
||||
CommonSec = dyn_cast_or_null<BssSection>(D->Section);
|
||||
if (CommonSec)
|
||||
ESym->st_shndx = SHN_COMMON;
|
||||
else if (Sym->NeedsPltAddr)
|
||||
ESym->st_shndx = SHN_UNDEF;
|
||||
else if (const OutputSection *OutSec = Sym->getOutputSection())
|
||||
ESym->st_shndx = OutSec->SectionIndex;
|
||||
else if (isa<Defined>(Sym))
|
||||
ESym->st_shndx = SHN_ABS;
|
||||
else
|
||||
ESym->st_shndx = SHN_UNDEF;
|
||||
ESym->st_shndx = getSymSectionIndex(Ent.Sym);
|
||||
|
||||
// Copy symbol size if it is a defined symbol. st_size is not significant
|
||||
// for undefined symbols, so whether copying it or not is up to us if that's
|
||||
@ -1986,7 +1988,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
// st_value is usually an address of a symbol, but that has a
|
||||
// special meaining for uninstantiated common symbols (this can
|
||||
// occur if -r is given).
|
||||
if (CommonSec)
|
||||
if (BssSection *CommonSec = getCommonSec(Ent.Sym))
|
||||
ESym->st_value = CommonSec->Alignment;
|
||||
else
|
||||
ESym->st_value = Sym->getVA();
|
||||
@ -2026,6 +2028,44 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
}
|
||||
}
|
||||
|
||||
SymtabShndxSection::SymtabShndxSection()
|
||||
: SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndxr") {
|
||||
this->Entsize = 4;
|
||||
}
|
||||
|
||||
void SymtabShndxSection::writeTo(uint8_t *Buf) {
|
||||
// We write an array of 32 bit values, where each value has 1:1 association
|
||||
// with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
|
||||
// we need to write actual index, otherwise, we must write SHN_UNDEF(0).
|
||||
Buf += 4; // Ignore .symtab[0] entry.
|
||||
for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) {
|
||||
if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
|
||||
write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
|
||||
Buf += 4;
|
||||
}
|
||||
}
|
||||
|
||||
bool SymtabShndxSection::empty() const {
|
||||
// SHT_SYMTAB can hold symbols with section indices values up to
|
||||
// SHN_LORESERVE. If we need more, we want to use extension SHT_SYMTAB_SHNDX
|
||||
// section. Problem is that we reveal the final section indices a bit too
|
||||
// late, and we do not know them here. For simplicity, we just always create
|
||||
// a .symtab_shndxr section when the amount of output sections is huge.
|
||||
size_t Size = 0;
|
||||
for (BaseCommand *Base : Script->SectionCommands)
|
||||
if (isa<OutputSection>(Base))
|
||||
++Size;
|
||||
return Size < SHN_LORESERVE;
|
||||
}
|
||||
|
||||
void SymtabShndxSection::finalizeContents() {
|
||||
getParent()->Link = InX::SymTab->getParent()->SectionIndex;
|
||||
}
|
||||
|
||||
size_t SymtabShndxSection::getSize() const {
|
||||
return InX::SymTab->getNumSymbols() * 4;
|
||||
}
|
||||
|
||||
// .hash and .gnu.hash sections contain on-disk hash tables that map
|
||||
// symbol names to their dynamic symbol table indices. Their purpose
|
||||
// is to help the dynamic linker resolve symbols quickly. If ELF files
|
||||
@ -3025,6 +3065,7 @@ RelocationBaseSection *InX::RelaIplt;
|
||||
StringTableSection *InX::ShStrTab;
|
||||
StringTableSection *InX::StrTab;
|
||||
SymbolTableBaseSection *InX::SymTab;
|
||||
SymtabShndxSection *InX::SymTabShndx;
|
||||
|
||||
template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
|
||||
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
|
||||
|
@ -588,6 +588,16 @@ class SymbolTableSection final : public SymbolTableBaseSection {
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
};
|
||||
|
||||
class SymtabShndxSection final : public SyntheticSection {
|
||||
public:
|
||||
SymtabShndxSection();
|
||||
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
size_t getSize() const override;
|
||||
bool empty() const override;
|
||||
void finalizeContents() override;
|
||||
};
|
||||
|
||||
// Outputs GNU Hash section. For detailed explanation see:
|
||||
// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
|
||||
class GnuHashTableSection final : public SyntheticSection {
|
||||
@ -992,6 +1002,7 @@ struct InX {
|
||||
static StringTableSection *ShStrTab;
|
||||
static StringTableSection *StrTab;
|
||||
static SymbolTableBaseSection *SymTab;
|
||||
static SymtabShndxSection* SymTabShndx;
|
||||
};
|
||||
|
||||
template <class ELFT> struct In {
|
||||
|
@ -287,6 +287,7 @@ template <class ELFT> static void createSyntheticSections() {
|
||||
if (Config->Strip != StripPolicy::All) {
|
||||
InX::StrTab = make<StringTableSection>(".strtab", false);
|
||||
InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
|
||||
InX::SymTabShndx = make<SymtabShndxSection>();
|
||||
}
|
||||
|
||||
if (Config->BuildId != BuildIdKind::None) {
|
||||
@ -409,6 +410,8 @@ template <class ELFT> static void createSyntheticSections() {
|
||||
|
||||
if (InX::SymTab)
|
||||
Add(InX::SymTab);
|
||||
if (InX::SymTabShndx)
|
||||
Add(InX::SymTabShndx);
|
||||
Add(InX::ShStrTab);
|
||||
if (InX::StrTab)
|
||||
Add(InX::StrTab);
|
||||
@ -518,7 +521,6 @@ static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
|
||||
if (B.isSection())
|
||||
return false;
|
||||
|
||||
|
||||
if (Config->Discard == DiscardPolicy::None)
|
||||
return true;
|
||||
|
||||
@ -1605,6 +1607,15 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
||||
OutputSections.push_back(Sec);
|
||||
|
||||
// Ensure data sections are not mixed with executable sections when
|
||||
// -execute-only is used.
|
||||
if (Config->ExecuteOnly)
|
||||
for (OutputSection *OS : OutputSections)
|
||||
if (OS->Flags & SHF_EXECINSTR)
|
||||
for (InputSection *IS : getInputSections(OS))
|
||||
if (!(IS->Flags & SHF_EXECINSTR))
|
||||
error("-execute-only does not support intermingling data and code");
|
||||
|
||||
// Prefer command line supplied address over other constraints.
|
||||
for (OutputSection *Sec : OutputSections) {
|
||||
auto I = Config->SectionStartMap.find(Sec->Name);
|
||||
@ -1639,12 +1650,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
// Dynamic section must be the last one in this list and dynamic
|
||||
// symbol table section (DynSymTab) must be the first one.
|
||||
applySynthetic(
|
||||
{InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab,
|
||||
InX::HashTab, InX::SymTab, InX::ShStrTab, InX::StrTab,
|
||||
In<ELFT>::VerDef, InX::DynStrTab, InX::Got, InX::MipsGot,
|
||||
InX::IgotPlt, InX::GotPlt, InX::RelaDyn, InX::RelrDyn,
|
||||
InX::RelaIplt, InX::RelaPlt, InX::Plt, InX::Iplt,
|
||||
InX::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic},
|
||||
{InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab,
|
||||
InX::HashTab, InX::SymTab, InX::SymTabShndx, InX::ShStrTab,
|
||||
InX::StrTab, In<ELFT>::VerDef, InX::DynStrTab, InX::Got,
|
||||
InX::MipsGot, InX::IgotPlt, InX::GotPlt, InX::RelaDyn,
|
||||
InX::RelrDyn, InX::RelaIplt, InX::RelaPlt, InX::Plt,
|
||||
InX::Iplt, InX::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed,
|
||||
InX::Dynamic},
|
||||
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
||||
|
||||
if (!Script->HasSectionsCommand && !Config->Relocatable)
|
||||
@ -1763,6 +1775,8 @@ static bool needsPtLoad(OutputSection *Sec) {
|
||||
static uint64_t computeFlags(uint64_t Flags) {
|
||||
if (Config->Omagic)
|
||||
return PF_R | PF_W | PF_X;
|
||||
if (Config->ExecuteOnly && (Flags & PF_X))
|
||||
return Flags & ~PF_R;
|
||||
if (Config->SingleRoRx && !(Flags & PF_W))
|
||||
return Flags | PF_X;
|
||||
return Flags;
|
||||
|
@ -8,7 +8,7 @@ features that are useful for toolchain developers.
|
||||
The linker supports ELF (Unix), PE/COFF (Windows), Mach-O (macOS) and
|
||||
WebAssembly in descending order of completeness. Internally, LLD consists of
|
||||
several different linkers. The ELF port is the one that will be described in
|
||||
this document. The PE/COFF port is almost complete except the lack of the
|
||||
this document. The PE/COFF port is complete, including
|
||||
Windows debug info (PDB) support. The WebAssembly port is still a work in
|
||||
progress (See :doc:`WebAssembly`). The Mach-O port is built based on a
|
||||
different architecture than the others. For the details about Mach-O, please
|
||||
|
142
docs/ld.lld.1
142
docs/ld.lld.1
@ -3,7 +3,7 @@
|
||||
.\"
|
||||
.\" This man page documents only lld's ELF linking support, obtained originally
|
||||
.\" from FreeBSD.
|
||||
.Dd April 28, 2018
|
||||
.Dd July 30, 2018
|
||||
.Dt LD.LLD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -30,6 +30,8 @@ These options are available:
|
||||
.It Fl -allow-multiple-definition
|
||||
Do not error if a symbol is defined multiple times.
|
||||
The first definition will be used.
|
||||
.It Fl -apply-dynamic-relocs
|
||||
Apply link-time values for dynamic relocations.
|
||||
.It Fl -as-needed
|
||||
Only set
|
||||
.Dv DT_NEEDED
|
||||
@ -38,14 +40,14 @@ for shared libraries if used.
|
||||
Set the
|
||||
.Dv DT_AUXILIARY
|
||||
field to the specified name.
|
||||
.It Fl -Bdynamic
|
||||
.It Fl -Bdynamic , Fl -dy
|
||||
Link against shared libraries.
|
||||
.It Fl -Bstatic
|
||||
.It Fl -Bstatic , Fl -static , Fl -dn
|
||||
Do not link against shared libraries.
|
||||
.It Fl -Bsymbolic-functions
|
||||
Bind defined function symbols locally.
|
||||
.It Fl -Bsymbolic
|
||||
Bind defined symbols locally.
|
||||
.It Fl -Bsymbolic-functions
|
||||
Bind defined function symbols locally.
|
||||
.It Fl -build-id Ns = Ns Ar value
|
||||
Generate a build ID note.
|
||||
.Ar value
|
||||
@ -93,7 +95,9 @@ may be
|
||||
.Cm none
|
||||
or
|
||||
.Cm zlib .
|
||||
.It Fl -define-common
|
||||
.It Fl -cref
|
||||
Output cross reference table.
|
||||
.It Fl -define-common , Fl d
|
||||
Assign space to common symbols.
|
||||
.It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression
|
||||
Define a symbol alias.
|
||||
@ -107,9 +111,9 @@ or
|
||||
Demangle symbol names.
|
||||
.It Fl -disable-new-dtags
|
||||
Disable new dynamic tags.
|
||||
.It Fl -discard-all
|
||||
.It Fl -discard-all , Fl x
|
||||
Delete all local symbols.
|
||||
.It Fl -discard-locals
|
||||
.It Fl -discard-locals , Fl X
|
||||
Delete temporary local symbols.
|
||||
.It Fl -discard-none
|
||||
Keep all symbols in the symbol table.
|
||||
@ -126,7 +130,7 @@ Request creation of
|
||||
section and
|
||||
.Dv PT_GNU_EH_FRAME
|
||||
segment header.
|
||||
.It Fl -emit-relocs
|
||||
.It Fl -emit-relocs , Fl q
|
||||
Generate relocations in the output.
|
||||
.It Fl -enable-new-dtags
|
||||
Enable new dynamic tags.
|
||||
@ -142,21 +146,21 @@ A value of zero indicates that there is no limit.
|
||||
Report unresolved symbols as errors.
|
||||
.It Fl -exclude-libs Ns = Ns Ar value
|
||||
Exclude static libraries from automatic export.
|
||||
.It Fl -export-dynamic , Fl E
|
||||
Put symbols in the dynamic symbol table.
|
||||
.It Fl -export-dynamic-symbol Ns = Ns Ar symbol
|
||||
Include
|
||||
.Ar symbol
|
||||
in the dynamic symbol table.
|
||||
.It Fl -export-dynamic
|
||||
Put symbols in the dynamic symbol table.
|
||||
.It Fl -fatal-warnings
|
||||
Treat warnings as errors.
|
||||
.It Fl -filter Ns = Ns Ar value
|
||||
.It Fl -filter Ns = Ns Ar value , Fl F Ar value
|
||||
Set the
|
||||
.Dv DT_FILTER
|
||||
field to the specified value.
|
||||
.It Fl -fini Ns = Ns Ar symbol
|
||||
Specify a finalizer function.
|
||||
.It Fl -format Ns = Ns Ar input-format
|
||||
.It Fl -format Ns = Ns Ar input-format , Fl b Ar input-format
|
||||
Specify the format of the inputs following this option.
|
||||
.Ar input-format
|
||||
may be one of
|
||||
@ -196,6 +200,14 @@ Set the base address to
|
||||
.Ar value .
|
||||
.It Fl -init Ns = Ns Ar symbol
|
||||
Specify an initializer function.
|
||||
.It Fl -keep-unique Ns = Ns Ar symbol
|
||||
Do not fold
|
||||
.Ar symbol
|
||||
during ICF.
|
||||
.It Fl l Ar libName, Fl -library Ns = Ns Ar libName
|
||||
Root name of library to use.
|
||||
.It Fl L Ar dir , Fl -library-path Ns = Ns Ar dir
|
||||
Add a directory to the library search path.
|
||||
.It Fl -lto-aa-pipeline Ns = Ns Ar value
|
||||
AA pipeline to run during LTO.
|
||||
Used in conjunction with
|
||||
@ -206,15 +218,11 @@ Passes to run during LTO.
|
||||
Optimization level for LTO.
|
||||
.It Fl -lto-partitions Ns = Ns Ar value
|
||||
Number of LTO codegen partitions.
|
||||
.It Fl L Ar dir
|
||||
Add a directory to the library search path.
|
||||
.It Fl l Ar libName
|
||||
Root name of library to use.
|
||||
.It Fl -Map Ns = Ns Ar file
|
||||
Print a link map to
|
||||
.Ar file .
|
||||
.It Fl m Ar value
|
||||
Set target emulation.
|
||||
.It Fl -Map Ns = Ns Ar file , Fl M Ar file
|
||||
Print a link map to
|
||||
.Ar file .
|
||||
.It Fl -no-as-needed
|
||||
Always set
|
||||
.Dv DT_NEEDED
|
||||
@ -243,26 +251,18 @@ Report version scripts that refer undefined symbols.
|
||||
Report unresolved symbols even if the linker is creating a shared library.
|
||||
.It Fl -no-whole-archive
|
||||
Restores the default behavior of loading archive members.
|
||||
.It Fl -noinhibit-exec
|
||||
Retain the executable output file whenever it is still usable.
|
||||
.It Fl -no-pie
|
||||
Do not create a position independent executable.
|
||||
.It Fl -noinhibit-exec
|
||||
Retain the executable output file whenever it is still usable.
|
||||
.It Fl -nostdlib
|
||||
Only search directories specified on the command line.
|
||||
.It Fl -oformat Ns = Ns Ar format
|
||||
Specify the format for the output object file.
|
||||
The only supported
|
||||
.Ar format
|
||||
is
|
||||
.Cm binary ,
|
||||
which produces output with no ELF header.
|
||||
.It Fl -omagic
|
||||
Set the text and data sections to be readable and writable.
|
||||
.It Fl -opt-remarks-filename Ar file
|
||||
Write optimization remarks in YAML format to
|
||||
.Ar file .
|
||||
.It Fl -opt-remarks-with-hotness
|
||||
Include hotness information in the optimization remarks file.
|
||||
.It Fl o Ar path
|
||||
Write the output executable, library, or object to
|
||||
.Ar path .
|
||||
If not specified,
|
||||
.Dv a.out
|
||||
is used as a default.
|
||||
.It Fl O Ns Ar value
|
||||
Optimize output file size.
|
||||
.Ar value
|
||||
@ -279,12 +279,20 @@ Enable string tail merging.
|
||||
.Pp
|
||||
.Fl O Ns Cm 1
|
||||
is the default.
|
||||
.It Fl o Ar path
|
||||
Write the output executable, library, or object to
|
||||
.Ar path .
|
||||
If not specified,
|
||||
.Dv a.out
|
||||
is used as a default.
|
||||
.It Fl -oformat Ns = Ns Ar format
|
||||
Specify the format for the output object file.
|
||||
The only supported
|
||||
.Ar format
|
||||
is
|
||||
.Cm binary ,
|
||||
which produces output with no ELF header.
|
||||
.It Fl -omagic , Fl N
|
||||
Set the text and data sections to be readable and writable.
|
||||
.It Fl -opt-remarks-filename Ar file
|
||||
Write optimization remarks in YAML format to
|
||||
.Ar file .
|
||||
.It Fl -opt-remarks-with-hotness
|
||||
Include hotness information in the optimization remarks file.
|
||||
.It Fl -pie
|
||||
Create a position independent executable.
|
||||
.It Fl -print-gc-sections
|
||||
@ -300,13 +308,13 @@ and
|
||||
.It Fl -pop-state
|
||||
Undo the effect of
|
||||
.Fl -push-state.
|
||||
.It Fl -relocatable
|
||||
.It Fl -relocatable , Fl r
|
||||
Create relocatable object file.
|
||||
.It Fl -reproduce Ns = Ns Ar value
|
||||
Dump linker invocation and input files for debugging.
|
||||
.It Fl -retain-symbols-file Ns = Ns Ar file
|
||||
Retain only the symbols listed in the file.
|
||||
.It Fl -rpath Ns = Ns Ar value
|
||||
.It Fl -rpath Ns = Ns Ar value , Fl R Ar value
|
||||
Add a
|
||||
.Dv DT_RUNPATH
|
||||
to the output.
|
||||
@ -316,14 +324,14 @@ The supported values are
|
||||
.Cm windows
|
||||
and
|
||||
.Cm posix .
|
||||
.It Fl -script Ns = Ns Ar file
|
||||
.It Fl -script Ns = Ns Ar file , Fl T Ar file
|
||||
Read linker script from
|
||||
.Ar file .
|
||||
.It Fl -section-start Ns = Ar section Ns = Ns Ar address
|
||||
.It Fl -section-start Ns = Ns Ar section Ns = Ns Ar address
|
||||
Set address of section.
|
||||
.It Fl -shared
|
||||
.It Fl -shared , Fl -Bsharable
|
||||
Build a shared object.
|
||||
.It Fl -soname Ns = Ns Ar value
|
||||
.It Fl -soname Ns = Ns Ar value , Fl h Ar value
|
||||
Set
|
||||
.Dv DT_SONAME
|
||||
to
|
||||
@ -333,9 +341,9 @@ Specifies sections sorting rule when linkerscript is used.
|
||||
.It Fl -start-lib
|
||||
Start a grouping of objects that should be treated as if they were together
|
||||
in an archive.
|
||||
.It Fl -strip-all
|
||||
.It Fl -strip-all , Fl s
|
||||
Strip all symbols.
|
||||
.It Fl -strip-debug
|
||||
.It Fl -strip-debug , Fl S
|
||||
Strip debugging information.
|
||||
.It Fl -symbol-ordering-file Ns = Ns Ar file
|
||||
Lay out sections in the order specified by
|
||||
@ -376,6 +384,12 @@ Same as
|
||||
with
|
||||
.Li .data
|
||||
as the sectionname.
|
||||
.It Fl -Ttext Ns = Ns Ar value
|
||||
Same as
|
||||
.Fl -section-start
|
||||
with
|
||||
.Li .text
|
||||
as the sectionname.
|
||||
.It Fl -thinlto-cache-dir Ns = Ns Ar value
|
||||
Path to ThinLTO cached object file directory.
|
||||
.It Fl -thinlto-cache-policy Ns = Ns Ar value
|
||||
@ -385,33 +399,27 @@ Number of ThinLTO jobs.
|
||||
.It Fl -threads
|
||||
Run the linker multi-threaded.
|
||||
This option is enabled by default.
|
||||
.It Fl -trace-symbol Ns = Ns Ar symbol
|
||||
Trace references to
|
||||
.Ar symbol .
|
||||
.It Fl -trace
|
||||
Print the names of the input files.
|
||||
.It Fl -Ttext Ns = Ns Ar value
|
||||
Same as
|
||||
.Fl -section-start
|
||||
with
|
||||
.Li .text
|
||||
as the sectionname.
|
||||
.It Fl -undefined Ns = Ns Ar symbol
|
||||
.It Fl -trace-symbol Ns = Ns Ar symbol , Fl y Ar symbol
|
||||
Trace references to
|
||||
.Ar symbol .
|
||||
.It Fl -undefined Ns = Ns Ar symbol , Fl u Ar symbol
|
||||
Force
|
||||
.Ar symbol
|
||||
to be an undefined symbol during linking.
|
||||
.It Fl -unresolved-symbols Ns = Ns Ar value
|
||||
Determine how to handle unresolved symbols.
|
||||
.It Fl v
|
||||
Display the version number and proceed with linking if object files are
|
||||
specified.
|
||||
.It Fl V , Fl -version
|
||||
Display the version number and exit.
|
||||
.It Fl -verbose
|
||||
Verbose mode.
|
||||
.It Fl -version-script Ns = Ns Ar file
|
||||
Read version script from
|
||||
.Ar file .
|
||||
.It Fl V , Fl -version
|
||||
Display the version number and exit.
|
||||
.It Fl v
|
||||
Display the version number and proceed with linking if object files are
|
||||
specified.
|
||||
.It Fl -warn-backrefs
|
||||
Warn about reverse or cyclic dependencies to or between static archives.
|
||||
This can be used to ensure linker invocation remains compatible with
|
||||
@ -432,6 +440,10 @@ Make the main stack executable.
|
||||
Stack permissions are recorded in the
|
||||
.Dv PT_GNU_STACK
|
||||
segment.
|
||||
.It Cm initfirst
|
||||
Sets the
|
||||
.Dv DF_1_INITFIRST
|
||||
flag to indicate the module should be initialized first.
|
||||
.It Cm muldefs
|
||||
Do not error if a symbol is defined multiple times.
|
||||
The first definition will be used.
|
||||
|
@ -60,6 +60,13 @@ Debug info
|
||||
link.exe. However, LLD does not support /DEBUG:FASTLINK.
|
||||
|
||||
|
||||
Downloading LLD
|
||||
===============
|
||||
|
||||
The Windows version of LLD is included in the `pre-built binaries of LLVM's
|
||||
releases <https://releases.llvm.org/download.html>`_ and in the `LLVM Snapshot
|
||||
Builds <https://llvm.org/builds/>`_.
|
||||
|
||||
Building LLD
|
||||
============
|
||||
|
||||
|
16
test/ELF/Inputs/arm-vfp-arg-base.s
Normal file
16
test/ELF/Inputs/arm-vfp-arg-base.s
Normal file
@ -0,0 +1,16 @@
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 0 // Tag_ABI_VFP_args = 0 (AAPCS, Base variant)
|
||||
|
||||
.syntax unified
|
||||
.global f0
|
||||
.type f0, %function
|
||||
f0: bx lr
|
16
test/ELF/Inputs/arm-vfp-arg-compat.s
Normal file
16
test/ELF/Inputs/arm-vfp-arg-compat.s
Normal file
@ -0,0 +1,16 @@
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all)
|
||||
|
||||
.syntax unified
|
||||
.global f3
|
||||
.type f3, %function
|
||||
f3: bx lr
|
15
test/ELF/Inputs/arm-vfp-arg-toolchain.s
Normal file
15
test/ELF/Inputs/arm-vfp-arg-toolchain.s
Normal file
@ -0,0 +1,15 @@
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 2 // Tag_ABI_VFP_args = 2 (Toolchain specific)
|
||||
.syntax unified
|
||||
.global f2
|
||||
.type f1, %function
|
||||
f2: bx lr
|
15
test/ELF/Inputs/arm-vfp-arg-vfp.s
Normal file
15
test/ELF/Inputs/arm-vfp-arg-vfp.s
Normal file
@ -0,0 +1,15 @@
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 1 // Tag_ABI_VFP_args = 1 (AAPCS, VFP variant)
|
||||
.syntax unified
|
||||
.global f1
|
||||
.type f1, %function
|
||||
f1: bx lr
|
3
test/ELF/Inputs/icf-absolute2.s
Normal file
3
test/ELF/Inputs/icf-absolute2.s
Normal file
@ -0,0 +1,3 @@
|
||||
.globl a1, a2
|
||||
a1 = 1
|
||||
a2 = 2
|
@ -9,6 +9,7 @@ _start:
|
||||
bx lr
|
||||
|
||||
// CHECK: Flags [
|
||||
// CHECK-NEXT: 0x200
|
||||
// CHECK-NEXT: 0x1000000
|
||||
// CHECK-NEXT: 0x4000000
|
||||
// CHECK-NEXT: ]
|
||||
|
29
test/ELF/arm-tag-vfp-args-errs.s
Normal file
29
test/ELF/arm-tag-vfp-args-errs.s
Normal file
@ -0,0 +1,29 @@
|
||||
// REQUIRES:arm
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
|
||||
// RUN: not ld.lld %t.o %tbase.o %tvfp.o -o%t 2>&1 | FileCheck %s
|
||||
// RUN: not ld.lld %t.o %tbase.o %ttoolchain.o -o%t 2>&1 | FileCheck %s
|
||||
// RUN: not ld.lld %t.o %tvfp.o %tbase.o -o%t 2>&1 | FileCheck %s
|
||||
// RUN: not ld.lld %t.o %tvfp.o %ttoolchain.o -o%t 2>&1 | FileCheck %s
|
||||
// RUN: not ld.lld %t.o %ttoolchain.o %tbase.o -o%t 2>&1 | FileCheck %s
|
||||
// RUN: not ld.lld %t.o %ttoolchain.o %tvfp.o -o%t 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: incompatible Tag_ABI_VFP_args
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all)
|
||||
|
||||
.syntax unified
|
||||
.globl _start
|
||||
.type _start, %function
|
||||
_start: bx lr
|
21
test/ELF/arm-tag-vfp-args-illegal.s
Normal file
21
test/ELF/arm-tag-vfp-args-illegal.s
Normal file
@ -0,0 +1,21 @@
|
||||
// REQUIRES:arm
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
|
||||
// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: arm-tag-vfp-args-illegal.s.tmp.o: unknown Tag_ABI_VFP_args value: 5
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
.eabi_attribute 28, 5 // Tag_ABI_VFP_args = 5 (Illegal value)
|
||||
|
||||
.syntax unified
|
||||
.globl _start
|
||||
.type _start, %function
|
||||
_start: bx lr
|
72
test/ELF/arm-tag-vfp-args.s
Normal file
72
test/ELF/arm-tag-vfp-args.s
Normal file
@ -0,0 +1,72 @@
|
||||
// REQUIRES:arm
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-compat.s -o %tcompat.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
|
||||
|
||||
// The default for this file is 0 (Base AAPCS)
|
||||
// RUN: ld.lld %t.o -o %tdefault
|
||||
// RUN: llvm-readobj -file-headers %tdefault | FileCheck -check-prefix=CHECK-BASE %s
|
||||
|
||||
// Expect explicit Base AAPCS.
|
||||
// RUN: ld.lld %t.o %tbase.o -o %tbase
|
||||
// RUN: llvm-readobj -file-headers %tbase | FileCheck -check-prefix=CHECK-BASE %s
|
||||
|
||||
// Expect explicit Base AAPCS when linking Base and Compatible.
|
||||
// RUN: ld.lld %t.o %tbase.o %tcompat.o -o %tbasecompat
|
||||
// RUN: llvm-readobj -file-headers %tbasecompat | FileCheck -check-prefix=CHECK-BASE %s
|
||||
|
||||
// CHECK-BASE: Flags [ (0x5000200)
|
||||
// CHECK-BASE-NEXT: 0x200
|
||||
// CHECK-BASE-NEXT: 0x1000000
|
||||
// CHECK-BASE-NEXT: 0x4000000
|
||||
// CHECK-BASE-NEXT: ]
|
||||
|
||||
// Expect Hard float VFP AAPCS
|
||||
// RUN: ld.lld %t.o %tvfp.o -o %tvfp
|
||||
// RUN: llvm-readobj -file-headers %tvfp | FileCheck -check-prefix=CHECK-VFP %s
|
||||
|
||||
// Expect Hard float VFP AAPCS when linking VFP and Compatible
|
||||
// RUN: ld.lld %t.o %tvfp.o %tcompat.o -o %tvfpcompat
|
||||
// RUN: llvm-readobj -file-headers %tvfpcompat | FileCheck -check-prefix=CHECK-VFP %s
|
||||
|
||||
// CHECK-VFP: Flags [ (0x5000400)
|
||||
// CHECK-VFP-NEXT: 0x400
|
||||
// CHECK-VFP-NEXT: 0x1000000
|
||||
// CHECK-VFP-NEXT: 0x4000000
|
||||
// CHECK-VFP-NEXT: ]
|
||||
|
||||
// Expect Toolchain specifc to not use either Base or VFP AAPCS
|
||||
// RUN: ld.lld %t.o %ttoolchain.o -o %ttoolchain
|
||||
// RUN: llvm-readobj -file-headers %ttoolchain | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
|
||||
|
||||
// Expect Toolchain and Compatible to have same affect as Toolchain.
|
||||
// RUN: ld.lld %t.o %ttoolchain.o %tcompat.o -o %ttoolchaincompat
|
||||
// RUN: llvm-readobj -file-headers %ttoolchaincompat | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
|
||||
|
||||
// CHECK-TOOLCHAIN: Flags [ (0x5000000)
|
||||
// CHECK-TOOLCHAIN-NEXT: 0x1000000
|
||||
// CHECK-TOOLCHAIN-NEXT: 0x4000000
|
||||
// CHECK-TOOLCHAIN-NEXT: ]
|
||||
|
||||
.arch armv7-a
|
||||
.eabi_attribute 20, 1
|
||||
.eabi_attribute 21, 1
|
||||
.eabi_attribute 23, 3
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.eabi_attribute 26, 2
|
||||
.eabi_attribute 30, 6
|
||||
.eabi_attribute 34, 1
|
||||
.eabi_attribute 18, 4
|
||||
// We do not specify Tag_ABI_VFP_args (.eabi_attribute 28) in this file.
|
||||
// When omitted the value of the tag defaults to 0, however if there
|
||||
// are other files with explicit Tag_ABI_VFP_args we use that in
|
||||
// preference.
|
||||
|
||||
|
||||
.syntax unified
|
||||
.globl _start
|
||||
.type _start, %function
|
||||
_start: bx lr
|
26
test/ELF/execute-only-mixed-data.s
Normal file
26
test/ELF/execute-only-mixed-data.s
Normal file
@ -0,0 +1,26 @@
|
||||
// REQUIRES: aarch64
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
|
||||
|
||||
// RUN: echo "SECTIONS \
|
||||
// RUN: { \
|
||||
// RUN: .text : { *(.text) *(.rodata.foo) } \
|
||||
// RUN: .rodata : { *(.rodata.bar) } \
|
||||
// RUN: }" > %t.lds
|
||||
// RUN: not ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: echo "SECTIONS \
|
||||
// RUN: { \
|
||||
// RUN: .text : { *(.text) } \
|
||||
// RUN: .rodata : { *(.rodata.bar) *(.rodata.foo) } \
|
||||
// RUN: }" > %t.lds
|
||||
// RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1
|
||||
|
||||
// CHECK: -execute-only does not support intermingling data and code
|
||||
|
||||
br lr
|
||||
|
||||
.section .rodata.foo
|
||||
.word 0x1
|
||||
.section .rodata.bar
|
||||
.word 0x2
|
10
test/ELF/execute-only.s
Normal file
10
test/ELF/execute-only.s
Normal file
@ -0,0 +1,10 @@
|
||||
// REQUIRES: aarch64
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
|
||||
// RUN: ld.lld -Ttext=0xcafe0000 %t.o -o %t.so -shared -execute-only
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck %s
|
||||
|
||||
// CHECK: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 E 0x{{.*}}
|
||||
// CHECK-NOT: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 R E 0x{{.*}}
|
||||
|
||||
br lr
|
@ -4,6 +4,13 @@
|
||||
# RUN: ld.lld %t2 %t -o %t3
|
||||
# RUN: llvm-objdump -d %t3 | FileCheck %s
|
||||
|
||||
# Note: 69632 == 0x11000
|
||||
# R_HEX_32_6_X
|
||||
# R_HEX_12_X
|
||||
if (p0) r0 = ##_start
|
||||
# CHECK: immext(#69632)
|
||||
# CHECK: if (p0) r0 = ##69632
|
||||
|
||||
# R_HEX_B15_PCREL
|
||||
if (p0) jump:nt #_start
|
||||
# CHECK: if (p0) jump:nt 0x11000
|
||||
|
21
test/ELF/icf-absolute2.s
Normal file
21
test/ELF/icf-absolute2.s
Normal file
@ -0,0 +1,21 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute2.s -o %t2
|
||||
# RUN: ld.lld %t %t2 -o /dev/null --icf=all --print-icf-sections | FileCheck -allow-empty %s
|
||||
|
||||
## Test we do not crash and do not fold sections which relocations reffering to
|
||||
## absolute symbols with a different values.
|
||||
# CHECK-NOT: selected
|
||||
|
||||
.globl _start, f1, f2
|
||||
_start:
|
||||
ret
|
||||
|
||||
.section .text.f1, "ax"
|
||||
f1:
|
||||
.byte a1
|
||||
|
||||
.section .text.f2, "ax"
|
||||
f2:
|
||||
.byte a2
|
@ -10,10 +10,6 @@
|
||||
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s
|
||||
# RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s
|
||||
|
||||
# CHECK-NOT: selected section {{.*}}:(.rodata.l1)
|
||||
# CHECK: selected section {{.*}}:(.rodata.l3)
|
||||
# CHECK: removing identical section {{.*}}:(.rodata.l4)
|
||||
|
||||
# CHECK-NOT: selected section {{.*}}:(.text.f1)
|
||||
# CHECK: selected section {{.*}}:(.text.f3)
|
||||
# CHECK: removing identical section {{.*}}:(.text.f4)
|
||||
@ -22,6 +18,10 @@
|
||||
# CHECK: selected section {{.*}}:(.rodata.h3)
|
||||
# CHECK: removing identical section {{.*}}:(.rodata.h4)
|
||||
|
||||
# CHECK-NOT: selected section {{.*}}:(.rodata.l1)
|
||||
# CHECK: selected section {{.*}}:(.rodata.l3)
|
||||
# CHECK: removing identical section {{.*}}:(.rodata.l4)
|
||||
|
||||
# CHECK-NOT: selected section {{.*}}:(.rodata.g1)
|
||||
# CHECK: selected section {{.*}}:(.rodata.g3)
|
||||
# CHECK: removing identical section {{.*}}:(.rodata.g4)
|
||||
@ -30,26 +30,26 @@
|
||||
|
||||
# With --icf=all address-significance implies keep-unique only for rodata, not
|
||||
# text.
|
||||
# ALL-NOT: selected section {{.*}}:(.rodata.l1)
|
||||
# ALL: selected section {{.*}}:(.rodata.l3)
|
||||
# ALL: removing identical section {{.*}}:(.rodata.l4)
|
||||
|
||||
# ALL: selected section {{.*}}:(.text.f3)
|
||||
# ALL: removing identical section {{.*}}:(.text.f4)
|
||||
|
||||
# ALL: selected section {{.*}}:(.text.f1)
|
||||
# ALL: removing identical section {{.*}}:(.text.f2)
|
||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||
|
||||
# ALL-NOT: selected section {{.*}}:(.rodata.h1)
|
||||
# ALL: selected section {{.*}}:(.rodata.h3)
|
||||
# ALL: removing identical section {{.*}}:(.rodata.h4)
|
||||
|
||||
# ALL-NOT: selected section {{.*}}:(.rodata.l1)
|
||||
# ALL: selected section {{.*}}:(.rodata.l3)
|
||||
# ALL: removing identical section {{.*}}:(.rodata.l4)
|
||||
|
||||
# ALL-NOT: selected section {{.*}}:(.rodata.g1)
|
||||
# ALL: selected section {{.*}}:(.rodata.g3)
|
||||
# ALL: removing identical section {{.*}}:(.rodata.g4)
|
||||
|
||||
# ALL: selected section {{.*}}:(.text.f1)
|
||||
# ALL: removing identical section {{.*}}:(.text.f2)
|
||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||
|
||||
# llvm-mc normally emits an empty .text section into every object file. Since
|
||||
# nothing actually refers to it via a relocation, it doesn't have any associated
|
||||
# symbols (thus nor can anything refer to it via a relocation, making it safe to
|
||||
@ -58,36 +58,36 @@
|
||||
# STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented
|
||||
# anything else from being merged.
|
||||
# EXPORT-NOT: selected section
|
||||
# EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||
# EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||
# EXPORT-NOT: selected section
|
||||
# EXPORT: selected section {{.*}}:(.rodata.h3)
|
||||
# EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
||||
# EXPORT-NOT: selected section
|
||||
# EXPORT: selected section {{.*}}:(.text)
|
||||
# EXPORT: removing identical section {{.*}}:(.text)
|
||||
# EXPORT-NOT: selected section
|
||||
# EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||
# EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||
# EXPORT-NOT: selected section
|
||||
|
||||
# If --icf=all is specified when exporting we can also merge the exported text
|
||||
# sections, but not the exported rodata.
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.text.f3)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.f4)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.text.f1)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.f2)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.rodata.h3)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.text)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
# ALL-EXPORT: selected section {{.*}}:(.text.f1)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.f2)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||
# ALL-EXPORT-NOT: selected section
|
||||
|
||||
# OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r
|
||||
|
||||
|
15
test/ELF/icf17.s
Normal file
15
test/ELF/icf17.s
Normal file
@ -0,0 +1,15 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
|
||||
# RUN: ld.lld %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s
|
||||
|
||||
# CHECK-NOT: selected
|
||||
|
||||
.section .text
|
||||
.globl _start
|
||||
_start:
|
||||
ret
|
||||
|
||||
.section .aaa, "ax",%progbits,unique,1
|
||||
.quad _start
|
||||
|
||||
.section .aaa, "axS",%progbits,unique,2
|
||||
.quad _start
|
@ -36,6 +36,7 @@
|
||||
# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
|
||||
# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
|
||||
# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab'
|
||||
# REPORT-NEXT: <internal>:(.symtab_shndxr) is being placed in '.symtab_shndxr'
|
||||
# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
|
||||
# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab'
|
||||
|
||||
|
6
test/ELF/lto/Inputs/libcall-archive.ll
Normal file
6
test/ELF/lto/Inputs/libcall-archive.ll
Normal file
@ -0,0 +1,6 @@
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @memcpy() {
|
||||
ret void
|
||||
}
|
20
test/ELF/lto/libcall-archive.ll
Normal file
20
test/ELF/lto/libcall-archive.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: rm -f %t.a
|
||||
; RUN: llvm-as -o %t.o %s
|
||||
; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll
|
||||
; RUN: llvm-ar rcs %t.a %t2.o
|
||||
; RUN: ld.lld -o %t %t.o %t.a
|
||||
; RUN: llvm-nm %t | FileCheck %s
|
||||
|
||||
; CHECK: T _start
|
||||
; CHECK: T memcpy
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @_start(i8* %a, i8* %b) {
|
||||
entry:
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 1024, i1 false)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
|
@ -19,6 +19,8 @@
|
||||
# RUN: | FileCheck %s --check-prefix ERR
|
||||
# ERR: unknown --oformat value: foo
|
||||
|
||||
# RUN: ld.lld -o /dev/null %t --oformat elf
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl _start
|
||||
|
@ -1,20 +1,32 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
|
||||
# RUN: ld.lld -r %t.o -o %t
|
||||
# RUN: llvm-readobj -file-headers %t | FileCheck %s
|
||||
|
||||
## Check we are able to emit a valid ELF header when
|
||||
## Check we are able to link against relocatable file produced.
|
||||
# RUN: ld.lld %t -o %t.out
|
||||
|
||||
## Check we emit a valid ELF header when
|
||||
## sections amount is greater than SHN_LORESERVE.
|
||||
# CHECK: ElfHeader {
|
||||
# CHECK: SectionHeaderCount: 0 (65541)
|
||||
# CHECK-NEXT: StringTableSectionIndex: 65535 (65539)
|
||||
# RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR
|
||||
# HDR: ElfHeader {
|
||||
# HDR: SectionHeaderCount: 0 (65543)
|
||||
# HDR-NEXT: StringTableSectionIndex: 65535 (65541)
|
||||
|
||||
## Check that 65539 is really the index of .shstrtab section.
|
||||
# RUN: llvm-objdump -section-headers -section=.shstrtab %t \
|
||||
# RUN: | FileCheck %s --check-prefix=SHSTRTAB
|
||||
# SHSTRTAB: Sections:
|
||||
# SHSTRTAB-NEXT: Idx Name
|
||||
# SHSTRTAB-NEXT: 65539 .shstrtab
|
||||
## Check that:
|
||||
## 1) 65541 is the index of .shstrtab section.
|
||||
## 2) .symtab_shndxr is linked with .symtab.
|
||||
## 3) .symtab_shndxr entry size and alignment == 4.
|
||||
## 4) .symtab_shndxr has size equal to
|
||||
## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c
|
||||
# RUN: llvm-readelf -sections -symbols %t | FileCheck %s
|
||||
## [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CHECK: [65538] .bar
|
||||
# CHECK-NEXT: [65539] .symtab SYMTAB 0000000000000000 000040 180078 18 65542 65539 8
|
||||
# CHECK-NEXT: [65540] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65539 0 4
|
||||
# CHECK-NEXT: [65541] .shstrtab STRTAB 0000000000000000 1c00cc 0f0035 00 0 0 1
|
||||
# CHECK-NEXT: [65542] .strtab STRTAB 0000000000000000 2b0101 00000c 00
|
||||
# 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE).
|
||||
# CHECK: GLOBAL DEFAULT 65538 foo
|
||||
|
||||
.macro gen_sections4 x
|
||||
.section a\x
|
||||
@ -88,5 +100,10 @@ gen_sections16384 b
|
||||
gen_sections16384 c
|
||||
gen_sections16384 d
|
||||
|
||||
.section .bar
|
||||
.global foo
|
||||
foo:
|
||||
|
||||
.section .text, "ax"
|
||||
.global _start
|
||||
_start:
|
||||
|
Loading…
Reference in New Issue
Block a user