aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-01-06 20:07:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-01-06 20:07:13 +0000
commitfba2c04f31e119eacf142fcbbaabd5a9e63a39ed (patch)
tree59eba88ea527759edb2c98d294ae369f95f57e33
parent5a5c549fe9a3fef595297bd21d36bed8409dc37d (diff)
downloadsrc-fba2c04f31e119eacf142fcbbaabd5a9e63a39ed.tar.gz
src-fba2c04f31e119eacf142fcbbaabd5a9e63a39ed.zip
Vendor import of lld trunk r256945:vendor/lld/lld-trunk-r256945
Notes
Notes: svn path=/vendor/lld/dist/; revision=293258 svn path=/vendor/lld/lld-trunk-r256945/; revision=293259; tag=vendor/lld/lld-trunk-r256945
-rw-r--r--ELF/Config.h5
-rw-r--r--ELF/Driver.cpp28
-rw-r--r--ELF/Driver.h1
-rw-r--r--ELF/InputFiles.cpp112
-rw-r--r--ELF/InputFiles.h15
-rw-r--r--ELF/InputSection.h8
-rw-r--r--ELF/MarkLive.cpp6
-rw-r--r--ELF/OutputSections.cpp31
-rw-r--r--ELF/SymbolTable.cpp56
-rw-r--r--ELF/SymbolTable.h9
-rw-r--r--ELF/Symbols.cpp3
-rw-r--r--ELF/Symbols.h6
-rw-r--r--ELF/Target.cpp2
-rw-r--r--ELF/Writer.cpp45
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_arm64.cpp17
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp24
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp210
-rw-r--r--test/ELF/dt_tags.s18
-rw-r--r--test/ELF/dynamic-reloc.s1
-rw-r--r--test/ELF/got.s18
-rw-r--r--test/ELF/local-got.s12
-rw-r--r--test/ELF/relocation-i686.s4
-rw-r--r--test/ELF/relocation.s6
-rw-r--r--test/ELF/relro.s20
-rw-r--r--test/ELF/shared-be.s1
-rw-r--r--test/ELF/shared.s1
-rw-r--r--test/ELF/tls-got.s16
-rw-r--r--test/ELF/tls-opt-gdie.s16
-rw-r--r--test/ELF/tls-opt-gdiele-i686.s4
-rw-r--r--test/ELF/tls-opt-iele-i686-nopic.s16
-rw-r--r--test/mach-o/arm64-reloc-negDelta32-fixup.yaml10
-rw-r--r--test/mach-o/arm64-section-order.yaml67
-rw-r--r--test/mach-o/parse-data-relocs-x86_64.yaml2
33 files changed, 446 insertions, 344 deletions
diff --git a/ELF/Config.h b/ELF/Config.h
index 7b820f18b8c7..c279b99b43c1 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -30,6 +30,10 @@ enum ELFKind {
ELF64BEKind
};
+// This struct contains the global configuration for the linker.
+// Most fields are direct mapping from the command line options
+// and such fields have the same name as the corresponding options.
+// Most fields are initialized by the driver.
struct Configuration {
SymbolBody *EntrySym = nullptr;
SymbolBody *MipsGpDisp = nullptr;
@@ -76,6 +80,7 @@ struct Configuration {
unsigned Optimize = 0;
};
+// The only instance of Configuration struct.
extern Configuration *Config;
} // namespace elf2
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 6d881373b303..2a3ecfa61586 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -57,6 +57,24 @@ static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
error("Unknown emulation: " + S);
}
+// Returns slices of MB by parsing MB as an archive file.
+// Each slice consists of a member file in the archive.
+static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB) {
+ ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
+ error(FileOrErr, "Failed to parse archive");
+ std::unique_ptr<Archive> File = std::move(*FileOrErr);
+
+ std::vector<MemoryBufferRef> V;
+ for (const ErrorOr<Archive::Child> &C : File->children()) {
+ error(C, "Could not get the child of the archive " + File->getFileName());
+ ErrorOr<MemoryBufferRef> MbOrErr = C->getMemoryBufferRef();
+ error(MbOrErr, "Could not get the buffer for a child of the archive " +
+ File->getFileName());
+ V.push_back(*MbOrErr);
+ }
+ return V;
+}
+
// Opens and parses a file. Path has to be resolved already.
// Newly created memory buffers are owned by this driver.
void LinkerDriver::addFile(StringRef Path) {
@@ -75,19 +93,17 @@ void LinkerDriver::addFile(StringRef Path) {
return;
case file_magic::archive:
if (WholeArchive) {
- auto File = make_unique<ArchiveFile>(MBRef);
- for (MemoryBufferRef &MB : File->getMembers())
- Files.push_back(createELFFile<ObjectFile>(MB));
- OwningArchives.emplace_back(std::move(File));
+ for (MemoryBufferRef MB : getArchiveMembers(MBRef))
+ Files.push_back(createObjectFile(MB));
return;
}
Files.push_back(make_unique<ArchiveFile>(MBRef));
return;
case file_magic::elf_shared_object:
- Files.push_back(createELFFile<SharedFile>(MBRef));
+ Files.push_back(createSharedFile(MBRef));
return;
default:
- Files.push_back(createELFFile<ObjectFile>(MBRef));
+ Files.push_back(createObjectFile(MBRef));
}
}
diff --git a/ELF/Driver.h b/ELF/Driver.h
index 2641155104dc..bfae2b3f4dfa 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -38,7 +38,6 @@ private:
llvm::BumpPtrAllocator Alloc;
bool WholeArchive = false;
std::vector<std::unique_ptr<InputFile>> Files;
- std::vector<std::unique_ptr<ArchiveFile>> OwningArchives;
std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
};
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index e0827a3ee43d..d9df6abbf233 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -37,10 +37,9 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef M)
template <class ELFT>
ELFKind ELFFileBase<ELFT>::getELFKind() {
- using llvm::support::little;
- if (ELFT::Is64Bits)
- return ELFT::TargetEndianness == little ? ELF64LEKind : ELF64BEKind;
- return ELFT::TargetEndianness == little ? ELF32LEKind : ELF32BEKind;
+ if (ELFT::TargetEndianness == support::little)
+ return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
+ return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
}
template <class ELFT>
@@ -63,8 +62,7 @@ template <class ELFT>
uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
uint32_t I = Sym.st_shndx;
if (I == ELF::SHN_XINDEX)
- return this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab,
- SymtabSHNDX);
+ return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX);
if (I >= ELF::SHN_LORESERVE || I == ELF::SHN_ABS)
return 0;
return I;
@@ -74,7 +72,7 @@ template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
if (!Symtab)
return;
ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
- error(StringTableOrErr.getError());
+ error(StringTableOrErr);
StringTable = *StringTableOrErr;
}
@@ -108,9 +106,9 @@ ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
}
template <class ELFT>
-void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) {
+void ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) {
// Read section and symbol tables.
- initializeSections(Comdats);
+ initializeSections(ComdatGroups);
initializeSymbols();
}
@@ -139,7 +137,7 @@ ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
const ELFFile<ELFT> &Obj = this->ELFObj;
ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr =
Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec);
- error(EntriesOrErr.getError());
+ error(EntriesOrErr);
ArrayRef<GroupEntryType> Entries = *EntriesOrErr;
if (Entries.empty() || Entries[0] != GRP_COMDAT)
error("Unsupported SHT_GROUP format");
@@ -174,7 +172,7 @@ static bool shouldMerge(const typename ELFFile<ELFT>::Elf_Shdr &Sec) {
}
template <class ELFT>
-void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
+void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) {
uint64_t Size = this->ELFObj.getNumSections();
Sections.resize(Size);
unsigned I = -1;
@@ -187,7 +185,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
switch (Sec.sh_type) {
case SHT_GROUP:
Sections[I] = &InputSection<ELFT>::Discarded;
- if (Comdats.insert(getShtGroupSignature(Sec)).second)
+ if (ComdatGroups.insert(getShtGroupSignature(Sec)).second)
continue;
for (GroupEntryType E : getShtGroupEntries(Sec)) {
uint32_t SecIndex = E;
@@ -235,7 +233,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
}
template <class ELFT> InputSectionBase<ELFT> *
-elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
+ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
error(NameOrErr);
StringRef Name = *NameOrErr;
@@ -250,29 +248,29 @@ elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// A MIPS object file has a special section that contains register
// usage info, which needs to be handled by the linker specially.
if (Config->EMachine == EM_MIPS && Name == ".reginfo") {
- MipsReginfo = new (this->Alloc) MipsReginfoInputSection<ELFT>(this, &Sec);
+ MipsReginfo = new (Alloc) MipsReginfoInputSection<ELFT>(this, &Sec);
return MipsReginfo;
}
if (Name == ".eh_frame")
- return new (this->EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);
+ return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);
if (shouldMerge<ELFT>(Sec))
- return new (this->MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);
- return new (this->Alloc) InputSection<ELFT>(this, &Sec);
+ return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);
+ return new (Alloc) InputSection<ELFT>(this, &Sec);
}
-template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
+template <class ELFT> void ObjectFile<ELFT>::initializeSymbols() {
this->initStringTable();
Elf_Sym_Range Syms = this->getNonLocalSymbols();
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
- this->SymbolBodies.reserve(NumSymbols);
+ SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms)
- this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
+ SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
}
template <class ELFT>
InputSectionBase<ELFT> *
-elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
+ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
uint32_t Index = this->getSectionIndex(Sym);
if (Index == 0)
return nullptr;
@@ -282,19 +280,19 @@ elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
}
template <class ELFT>
-SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
+SymbolBody *ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
const Elf_Sym *Sym) {
ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
- error(NameOrErr.getError());
+ error(NameOrErr);
StringRef Name = *NameOrErr;
switch (Sym->st_shndx) {
case SHN_UNDEF:
- return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym);
+ return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
case SHN_COMMON:
- return new (this->Alloc) DefinedCommon(
- Name, Sym->st_size, Sym->st_value,
- Sym->getBinding() == llvm::ELF::STB_WEAK, Sym->getVisibility());
+ return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value,
+ Sym->getBinding() == llvm::ELF::STB_WEAK,
+ Sym->getVisibility());
}
switch (Sym->getBinding()) {
@@ -305,20 +303,16 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
case STB_GNU_UNIQUE: {
InputSectionBase<ELFT> *Sec = getSection(*Sym);
if (Sec == &InputSection<ELFT>::Discarded)
- return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym);
- return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
+ return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
+ return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
}
}
}
-static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) {
- ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
- error(ArchiveOrErr, "Failed to parse archive");
- return std::move(*ArchiveOrErr);
-}
-
void ArchiveFile::parse() {
- File = openArchive(MB);
+ ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
+ error(FileOrErr, "Failed to parse archive");
+ File = std::move(*FileOrErr);
// Allocate a buffer for Lazy objects.
size_t NumSyms = File->getNumberOfSymbols();
@@ -345,28 +339,9 @@ MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
return *RefOrErr;
}
-std::vector<MemoryBufferRef> ArchiveFile::getMembers() {
- File = openArchive(MB);
-
- std::vector<MemoryBufferRef> Result;
- for (auto &ChildOrErr : File->children()) {
- error(ChildOrErr,
- "Could not get the child of the archive " + File->getFileName());
- const Archive::Child Child(*ChildOrErr);
- ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef();
- if (!MbOrErr)
- error(MbOrErr, "Could not get the buffer for a child of the archive " +
- File->getFileName());
- Result.push_back(MbOrErr.get());
- }
- return Result;
-}
-
template <class ELFT>
SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
- : ELFFileBase<ELFT>(Base::SharedKind, M) {
- AsNeeded = Config->AsNeeded;
-}
+ : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {}
template <class ELFT>
const typename ELFFile<ELFT>::Elf_Shdr *
@@ -379,6 +354,8 @@ SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
return *Ret;
}
+// Partially parse the shared object file so that we can call
+// getSoName on this object.
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
@@ -405,7 +382,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
}
this->initStringTable();
- this->SoName = this->getName();
+ SoName = this->getName();
if (!DynamicSec)
return;
@@ -418,13 +395,14 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
uintX_t Val = Dyn.getVal();
if (Val >= this->StringTable.size())
error("Invalid DT_SONAME entry");
- this->SoName = StringRef(this->StringTable.data() + Val);
+ SoName = StringRef(this->StringTable.data() + Val);
return;
}
}
}
-template <class ELFT> void SharedFile<ELFT>::parse() {
+// Fully parse the shared object file. This must be called after parseSoName().
+template <class ELFT> void SharedFile<ELFT>::parseRest() {
Elf_Sym_Range Syms = this->getNonLocalSymbols();
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
SymbolBodies.reserve(NumSymbols);
@@ -456,7 +434,7 @@ static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) {
}
template <template <class> class T>
-std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) {
+static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer());
if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB)
error("Invalid data encoding: " + MB.getBufferIdentifier());
@@ -474,6 +452,14 @@ std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) {
error("Invalid file class: " + MB.getBufferIdentifier());
}
+std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) {
+ return createELFFile<ObjectFile>(MB);
+}
+
+std::unique_ptr<InputFile> elf2::createSharedFile(MemoryBufferRef MB) {
+ return createELFFile<SharedFile>(MB);
+}
+
template class elf2::ELFFileBase<ELF32LE>;
template class elf2::ELFFileBase<ELF32BE>;
template class elf2::ELFFileBase<ELF64LE>;
@@ -488,9 +474,3 @@ template class elf2::SharedFile<ELF32LE>;
template class elf2::SharedFile<ELF32BE>;
template class elf2::SharedFile<ELF64LE>;
template class elf2::SharedFile<ELF64BE>;
-
-template std::unique_ptr<InputFile>
-elf2::createELFFile<ObjectFile>(MemoryBufferRef);
-
-template std::unique_ptr<InputFile>
-elf2::createELFFile<SharedFile>(MemoryBufferRef);
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 4e529c558cf5..9c54a9328f80 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -101,10 +101,10 @@ public:
return F->kind() == Base::ObjectKind;
}
- ArrayRef<SymbolBody *> getSymbols() { return this->SymbolBodies; }
+ ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
explicit ObjectFile(MemoryBufferRef M);
- void parse(llvm::DenseSet<StringRef> &Comdats);
+ void parse(llvm::DenseSet<StringRef> &ComdatGroups);
ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; }
InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const;
@@ -113,7 +113,7 @@ public:
uint32_t FirstNonLocal = this->Symtab->sh_info;
if (SymbolIndex < FirstNonLocal)
return nullptr;
- return this->SymbolBodies[SymbolIndex - FirstNonLocal];
+ return SymbolBodies[SymbolIndex - FirstNonLocal];
}
Elf_Sym_Range getLocalSymbols();
@@ -127,7 +127,7 @@ public:
uint32_t getMipsGp0() const;
private:
- void initializeSections(llvm::DenseSet<StringRef> &Comdats);
+ void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups);
void initializeSymbols();
InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec);
@@ -159,7 +159,6 @@ public:
MemoryBufferRef getMember(const Archive::Symbol *Sym);
llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; }
- std::vector<MemoryBufferRef> getMembers();
private:
std::unique_ptr<Archive> File;
@@ -194,7 +193,7 @@ public:
explicit SharedFile(MemoryBufferRef M);
void parseSoName();
- void parse();
+ void parseRest();
// Used for --as-needed
bool AsNeeded = false;
@@ -202,8 +201,8 @@ public:
bool isNeeded() const { return !AsNeeded || IsUsed; }
};
-template <template <class> class T>
-std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB);
+std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB);
+std::unique_ptr<InputFile> createSharedFile(MemoryBufferRef MB);
} // namespace elf2
} // namespace lld
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index d4dc9864ae91..24491a2e17c0 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -93,6 +93,10 @@ InputSectionBase<ELFT>
InputSectionBase<ELFT>::Discarded(nullptr, nullptr,
InputSectionBase<ELFT>::Regular);
+// Usually sections are copied to the output as atomic chunks of data,
+// but some special types of sections are split into small pieces of data
+// and each piece is copied to a different place in the output.
+// This class represents such special sections.
template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
@@ -100,7 +104,11 @@ template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> {
public:
SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
typename InputSectionBase<ELFT>::Kind SectionKind);
+
+ // For each piece of data, we maintain the offsets in the input section and
+ // in the output section. The latter may be -1 if it is not assigned yet.
std::vector<std::pair<uintX_t, uintX_t>> Offsets;
+
std::pair<std::pair<uintX_t, uintX_t> *, uintX_t>
getRangeAndSize(uintX_t Offset);
};
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index 1ad9b01af4e8..b719b1a09c25 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -16,7 +16,7 @@
// by default. Starting with GC-root symbols or sections, markLive function
// defined in this file visits all reachable sections to set their Live
// bits. Writer will then ignore sections whose Live bits are off, so that
-// such sections are removed from output.
+// such sections are not included into output.
//
//===----------------------------------------------------------------------===//
@@ -37,7 +37,7 @@ using namespace llvm::object;
using namespace lld;
using namespace lld::elf2;
-// Calls Fn for each section that Sec refers to.
+// Calls Fn for each section that Sec refers to via relocations.
template <class ELFT>
static void forEachSuccessor(InputSection<ELFT> *Sec,
std::function<void(InputSectionBase<ELFT> *)> Fn) {
@@ -104,7 +104,7 @@ template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) {
MarkSymbol(Symtab->find(S));
// Preserve externally-visible symbols if the symbols defined by this
- // file could override other ELF file's symbols at runtime.
+ // file can interrupt other ELF file's symbols at runtime.
if (Config->Shared || Config->ExportDynamic) {
for (const std::pair<StringRef, Symbol *> &P : Symtab->getSymbols()) {
SymbolBody *B = P.second->Body;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index 8bdc2b0e5c4f..30ec83f4d3b1 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -239,14 +239,13 @@ bool RelocationSection<ELFT>::applyTlsDynamicReloc(SymbolBody *Body,
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
- const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
for (const DynamicReloc<ELFT> &Rel : Relocs) {
auto *P = reinterpret_cast<Elf_Rel *>(Buf);
- Buf += EntrySize;
+ Buf += IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
// Skip placeholder for global dynamic TLS relocation pair. It was already
// handled by the previous relocation.
- if (!Rel.C || !Rel.RI)
+ if (!Rel.C)
continue;
InputSectionBase<ELFT> &C = *Rel.C;
@@ -262,16 +261,16 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
continue;
bool NeedsCopy = Body && Target->needsCopyRel(Type, *Body);
bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body);
- bool CanBePreempted = canBePreempted(Body, NeedsGot);
+ bool CBP = canBePreempted(Body, NeedsGot);
bool LazyReloc = Body && Target->supportsLazyRelocations() &&
Target->relocNeedsPlt(Type, *Body);
bool IsDynRelative = Type == Target->getRelativeReloc();
- unsigned Sym = CanBePreempted ? Body->DynamicSymbolTableIndex : 0;
+ unsigned Sym = CBP ? Body->DynamicSymbolTableIndex : 0;
unsigned Reloc;
- if (!CanBePreempted && Body && isGnuIFunc<ELFT>(*Body))
+ if (!CBP && Body && isGnuIFunc<ELFT>(*Body))
Reloc = Target->getIRelativeReloc();
- else if (!CanBePreempted || IsDynRelative)
+ else if (!CBP || IsDynRelative)
Reloc = Target->getRelativeReloc();
else if (LazyReloc)
Reloc = Target->getPltReloc();
@@ -289,7 +288,7 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
else if (NeedsCopy)
P->r_offset = Out<ELFT>::Bss->getVA() +
- dyn_cast<SharedSymbol<ELFT>>(Body)->OffsetInBSS;
+ cast<SharedSymbol<ELFT>>(Body)->OffsetInBss;
else
P->r_offset = C.getOffset(RI.r_offset) + C.OutSec->getVA();
@@ -300,7 +299,7 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
uintX_t Addend;
if (NeedsCopy)
Addend = 0;
- else if (CanBePreempted || IsDynRelative)
+ else if (CBP || IsDynRelative)
Addend = OrigAddend;
else if (Body)
Addend = getSymVA<ELFT>(*Body) + OrigAddend;
@@ -640,6 +639,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (DtFlags1)
++NumEntries; // DT_FLAGS_1
+ if (!Config->Entry.empty())
+ ++NumEntries; // DT_DEBUG
+
if (Config->EMachine == EM_MIPS) {
++NumEntries; // DT_MIPS_RLD_VERSION
++NumEntries; // DT_MIPS_FLAGS
@@ -738,6 +740,8 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
WriteVal(DT_FLAGS, DtFlags);
if (DtFlags1)
WriteVal(DT_FLAGS_1, DtFlags1);
+ if (!Config->Entry.empty())
+ WriteVal(DT_DEBUG, 0);
// See "Dynamic Section" in Chapter 5 in the following document
// for detailed description:
@@ -799,11 +803,11 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
return SC->OutSec->getVA() + SC->getOffset(DR.Sym);
}
case SymbolBody::DefinedCommonKind:
- return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBSS;
+ return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBss;
case SymbolBody::SharedKind: {
auto &SS = cast<SharedSymbol<ELFT>>(S);
if (SS.NeedsCopy)
- return Out<ELFT>::Bss->getVA() + SS.OffsetInBSS;
+ return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
return 0;
}
case SymbolBody::UndefinedElfKind:
@@ -1119,9 +1123,9 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
ArrayRef<uint8_t> D = S->getSectionData();
StringRef Data((const char *)D.data(), D.size());
uintX_t EntSize = S->getSectionHdr()->sh_entsize;
- uintX_t Offset = 0;
if (this->Header.sh_flags & SHF_STRINGS) {
+ uintX_t Offset = 0;
while (!Data.empty()) {
size_t End = findNull(Data, EntSize);
if (End == StringRef::npos)
@@ -1139,8 +1143,7 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) {
StringRef Entry = Data.substr(I, EntSize);
size_t OutputOffset = Builder.add(Entry);
- S->Offsets.push_back(std::make_pair(Offset, OutputOffset));
- Offset += EntSize;
+ S->Offsets.push_back(std::make_pair(I, OutputOffset));
}
}
}
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index e022ecd2e90d..74951bad410f 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// Symbol table is a bag of all known symbols. We put all symbols of
-// all input files to the symbol table. The symbol Table is basically
+// all input files to the symbol table. The symbol table is basically
// a hash table with the logic to resolve symbol name conflicts using
// the symbol types.
//
@@ -28,6 +28,9 @@ using namespace lld::elf2;
template <class ELFT> SymbolTable<ELFT>::SymbolTable() {}
+// All input object files must be for the same architecture
+// (e.g. it does not make sense to link x86 object files with
+// MIPS object files.) This function checks for that error.
template <class ELFT>
static void checkCompatibility(InputFile *FileP) {
auto *F = dyn_cast<ELFFileBase<ELFT>>(FileP);
@@ -42,6 +45,7 @@ static void checkCompatibility(InputFile *FileP) {
error(A + " is incompatible with " + B);
}
+// Add symbols in File to the symbol table.
template <class ELFT>
void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
InputFile *FileP = File.get();
@@ -64,7 +68,7 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
return;
SharedFiles.emplace_back(cast<SharedFile<ELFT>>(File.release()));
- F->parse();
+ F->parseRest();
for (SharedSymbol<ELFT> &B : F->getSharedSymbols())
resolve(&B);
return;
@@ -73,7 +77,7 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
// .o file
auto *F = cast<ObjectFile<ELFT>>(FileP);
ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(File.release()));
- F->parse(Comdats);
+ F->parse(ComdatGroups);
for (SymbolBody *B : F->getSymbols())
resolve(B);
}
@@ -109,6 +113,9 @@ void SymbolTable<ELFT>::addSynthetic(StringRef Name,
resolve(Sym);
}
+// Add Name as an "ignored" symbol. An ignored symbol is a regular
+// linker-synthesized defined symbol, but it is not recorded to the output
+// file's symbol table. Such symbols are useful for some linker-defined symbols.
template <class ELFT>
SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {
auto *Sym = new (Alloc)
@@ -117,18 +124,10 @@ SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {
return Sym;
}
-template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name) {
- if (SymbolBody *Sym = find(Name))
- return Sym->isUndefined();
- return false;
-}
-
// Returns a file from which symbol B was created.
-// If B does not belong to any file in ObjectFiles, returns a nullptr.
+// If B does not belong to any file, returns a nullptr.
template <class ELFT>
-ELFFileBase<ELFT> *
-elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles,
- const SymbolBody *B) {
+ELFFileBase<ELFT> *SymbolTable<ELFT>::findFile(SymbolBody *B) {
for (const std::unique_ptr<ObjectFile<ELFT>> &F : ObjectFiles) {
ArrayRef<SymbolBody *> Syms = F->getSymbols();
if (std::find(Syms.begin(), Syms.end(), B) != Syms.end())
@@ -139,8 +138,8 @@ elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles,
template <class ELFT>
std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Old, SymbolBody *New) {
- ELFFileBase<ELFT> *OldFile = findFile<ELFT>(ObjectFiles, Old);
- ELFFileBase<ELFT> *NewFile = findFile<ELFT>(ObjectFiles, New);
+ ELFFileBase<ELFT> *OldFile = findFile(Old);
+ ELFFileBase<ELFT> *NewFile = findFile(New);
StringRef Sym = Old->getName();
StringRef F1 = OldFile ? OldFile->getName() : "(internal)";
@@ -173,15 +172,15 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
// compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
// equivalent (conflicting), or more preferable, respectively.
- int comp = Existing->compare<ELFT>(New);
- if (comp == 0) {
+ int Comp = Existing->compare<ELFT>(New);
+ if (Comp == 0) {
std::string S = "duplicate symbol: " + conflictMsg(Existing, New);
if (!Config->AllowMultipleDefinition)
error(S);
warning(S);
return;
}
- if (comp < 0)
+ if (Comp < 0)
Sym->Body = New;
}
@@ -248,20 +247,7 @@ template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() {
Sym->setUsedInDynamicReloc();
}
-template class lld::elf2::SymbolTable<ELF32LE>;
-template class lld::elf2::SymbolTable<ELF32BE>;
-template class lld::elf2::SymbolTable<ELF64LE>;
-template class lld::elf2::SymbolTable<ELF64BE>;
-
-template ELFFileBase<ELF32LE> *
-lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF32LE>>>,
- const SymbolBody *);
-template ELFFileBase<ELF32BE> *
-lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF32BE>>>,
- const SymbolBody *);
-template ELFFileBase<ELF64LE> *
-lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF64LE>>>,
- const SymbolBody *);
-template ELFFileBase<ELF64BE> *
-lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF64BE>>>,
- const SymbolBody *);
+template class elf2::SymbolTable<ELF32LE>;
+template class elf2::SymbolTable<ELF32BE>;
+template class elf2::SymbolTable<ELF64LE>;
+template class elf2::SymbolTable<ELF64BE>;
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index aa905e027d48..4f8f5afa420a 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -55,9 +55,9 @@ public:
void addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section,
typename llvm::object::ELFFile<ELFT>::uintX_t Value);
SymbolBody *addIgnored(StringRef Name);
- bool isUndefined(StringRef Name);
void scanShlibUndefined();
SymbolBody *find(StringRef Name);
+ ELFFileBase<ELFT> *findFile(SymbolBody *B);
private:
Symbol *insert(SymbolBody *New);
@@ -78,7 +78,7 @@ private:
llvm::MapVector<StringRef, Symbol *> Symtab;
llvm::BumpPtrAllocator Alloc;
- llvm::DenseSet<StringRef> Comdats;
+ llvm::DenseSet<StringRef> ComdatGroups;
// The writer needs to infer the machine type from the object files.
std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles;
@@ -87,11 +87,6 @@ private:
llvm::DenseSet<StringRef> IncludedSoNames;
};
-template <class ELFT>
-ELFFileBase<ELFT> *
-findFile(ArrayRef<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles,
- const SymbolBody *B);
-
} // namespace elf2
} // namespace lld
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index f8d585242a86..4af1b88e79ad 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -115,8 +115,7 @@ std::unique_ptr<InputFile> Lazy::getMember() {
// read from the library.
if (MBRef.getBuffer().empty())
return std::unique_ptr<InputFile>(nullptr);
-
- return createELFFile<ObjectFile>(MBRef);
+ return createObjectFile(MBRef);
}
template <class ELFT> static void doInitSymbols() {
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index 8556452dbb13..16a3b338b3cd 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -173,7 +173,7 @@ public:
// The output offset of this common symbol in the output bss. Computed by the
// writer.
- uint64_t OffsetInBSS;
+ uint64_t OffsetInBss;
// The maximum alignment we have seen for this symbol.
uint64_t MaxAlignment;
@@ -262,9 +262,9 @@ public:
SharedFile<ELFT> *File;
// True if the linker has to generate a copy relocation for this shared
- // symbol. OffsetInBSS is significant only when NeedsCopy is true.
+ // symbol. OffsetInBss is significant only when NeedsCopy is true.
bool NeedsCopy = false;
- uintX_t OffsetInBSS = 0;
+ uintX_t OffsetInBss = 0;
};
// This class represents a symbol defined in an archive file. It is
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index 8d848d040c61..8d54c93570fa 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -320,7 +320,7 @@ void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
// separate procedure linkage tables.
if (Config->Shared) {
const uint8_t V[] = {
- 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx
+ 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx)
0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
0x90, 0x90, 0x90, 0x90 // nop;nop;nop;nop
};
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index bdcb720a8a48..2437a435657c 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -69,7 +69,7 @@ private:
}
int getPhdrsNum() const;
- OutputSection<ELFT> *getBSS();
+ OutputSection<ELFT> *getBss();
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
@@ -330,18 +330,17 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &S,
}
template <class ELFT>
-static void reportUndefined(const SymbolTable<ELFT> &S, const SymbolBody &Sym) {
+static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
if (Config->Shared && !Config->NoUndefined)
return;
- ELFFileBase<ELFT> *SymFile = findFile<ELFT>(S.getObjectFiles(), &Sym);
- std::string Message = "undefined symbol: " + Sym.getName().str();
- if (SymFile)
- Message += " in " + SymFile->getName().str();
+ std::string Msg = "undefined symbol: " + Sym->getName().str();
+ if (ELFFileBase<ELFT> *File = Symtab.findFile(Sym))
+ Msg += " in " + File->getName().str();
if (Config->NoInhibitExec)
- warning(Message);
+ warning(Msg);
else
- error(Message);
+ error(Msg);
}
// Local symbols are not in the linker's symbol table. This function scans
@@ -466,7 +465,7 @@ static bool compareOutputSections(OutputSectionBase<ELFT> *A,
return false;
}
-template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBSS() {
+template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBss() {
if (!Out<ELFT>::Bss) {
Out<ELFT>::Bss =
new OutputSection<ELFT>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
@@ -480,8 +479,6 @@ template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBSS() {
// This function adds them to end of BSS section.
template <class ELFT>
void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
- typedef typename ELFFile<ELFT>::uintX_t uintX_t;
-
if (Syms.empty())
return;
@@ -491,11 +488,11 @@ void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
return A->MaxAlignment > B->MaxAlignment;
});
- uintX_t Off = getBSS()->getSize();
+ uintX_t Off = getBss()->getSize();
for (DefinedCommon *C : Syms) {
uintX_t Align = C->MaxAlignment;
Off = RoundUpToAlignment(Off, Align);
- C->OffsetInBSS = Off;
+ C->OffsetInBss = Off;
Off += C->Size;
}
@@ -507,7 +504,7 @@ template <class ELFT>
void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
if (Syms.empty())
return;
- uintX_t Off = getBSS()->getSize();
+ uintX_t Off = getBss()->getSize();
for (SharedSymbol<ELFT> *C : Syms) {
const Elf_Sym &Sym = C->Sym;
const Elf_Shdr *Sec = C->File->getSection(Sym);
@@ -518,7 +515,7 @@ void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
uintX_t Align = 1 << TrailingZeros;
Out<ELFT>::Bss->updateAlign(Align);
Off = RoundUpToAlignment(Off, Align);
- C->OffsetInBSS = Off;
+ C->OffsetInBss = Off;
Off += Sym.st_size;
}
Out<ELFT>::Bss->setSize(Off);
@@ -803,7 +800,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
SymbolBody *Body = P.second->Body;
if (auto *U = dyn_cast<Undefined>(Body))
if (!U->isWeak() && !U->canKeepUndefined())
- reportUndefined<ELFT>(Symtab, *Body);
+ reportUndefined<ELFT>(Symtab, Body);
if (auto *C = dyn_cast<DefinedCommon>(Body))
CommonSymbols.push_back(C);
@@ -958,10 +955,12 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
StringSaver Saver(Alloc);
StringRef Start = Saver.save("__start_" + S);
StringRef Stop = Saver.save("__stop_" + S);
- if (Symtab.isUndefined(Start))
- Symtab.addSynthetic(Start, *Sec, 0);
- if (Symtab.isUndefined(Stop))
- Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
+ if (SymbolBody *B = Symtab.find(Start))
+ if (B->isUndefined())
+ Symtab.addSynthetic(Start, *Sec, 0);
+ if (SymbolBody *B = Symtab.find(Stop))
+ if (B->isUndefined())
+ Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
}
template <class ELFT> static bool needsPhdr(OutputSectionBase<ELFT> *Sec) {
@@ -1016,7 +1015,7 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
Elf_Phdr GnuRelroPhdr = {};
Elf_Phdr TlsPhdr{};
bool RelroAligned = false;
- uintX_t ThreadBSSOffset = 0;
+ uintX_t ThreadBssOffset = 0;
// Create phdrs as we assign VAs and file offsets to all output sections.
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
Elf_Phdr *PH = &Phdrs[PhdrIdx];
@@ -1042,11 +1041,11 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
if (Sec->getType() != SHT_NOBITS)
VA = RoundUpToAlignment(VA, Sec->getAlign());
- uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign());
+ uintX_t TVA = RoundUpToAlignment(VA + ThreadBssOffset, Sec->getAlign());
Sec->setVA(TVA);
TlsPhdr.p_memsz += Sec->getSize();
if (Sec->getType() == SHT_NOBITS) {
- ThreadBSSOffset = TVA - VA + Sec->getSize();
+ ThreadBssOffset = TVA - VA + Sec->getSize();
} else {
TlsPhdr.p_filesz += Sec->getSize();
VA += Sec->getSize();
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index 5e5a426b310b..0ba590cc6422 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -507,6 +507,23 @@ void ArchHandler_arm64::generateAtomContent(
// Copy raw bytes.
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
// Apply fix-ups.
+#ifndef NDEBUG
+ if (atom.begin() != atom.end()) {
+ DEBUG_WITH_TYPE("atom-content", llvm::dbgs()
+ << "Applying fixups to atom:\n"
+ << " address="
+ << llvm::format(" 0x%09lX", &atom)
+ << ", file=#"
+ << atom.file().ordinal()
+ << ", atom=#"
+ << atom.ordinal()
+ << ", name="
+ << atom.name()
+ << ", type="
+ << atom.contentType()
+ << "\n");
+ }
+#endif
for (const Reference *ref : atom) {
uint32_t offset = ref->offsetInAtom();
const Atom *target = ref->target();
diff --git a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
index c57a00359e33..8b4d1cf38cba 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -647,13 +647,33 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
*loc32 = ref.addend() + inAtomAddress - fixupAddress;
return;
case delta32Anon:
- *loc32 = (targetAddress - fixupAddress) + ref.addend();
+ // The value we write here should be the the delta to the target
+ // after taking in to account the difference from the fixup back to the
+ // last defined label
+ // ie, if we have:
+ // _base: ...
+ // Lfixup: .quad Ltarget - .
+ // ...
+ // Ltarget:
+ //
+ // Then we want to encode the value (Ltarget + addend) - (LFixup - _base)
+ *loc32 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress);
return;
case delta64:
*loc64 = ref.addend() + inAtomAddress - fixupAddress;
return;
case delta64Anon:
- *loc64 = (targetAddress - fixupAddress) + ref.addend();
+ // The value we write here should be the the delta to the target
+ // after taking in to account the difference from the fixup back to the
+ // last defined label
+ // ie, if we have:
+ // _base: ...
+ // Lfixup: .quad Ltarget - .
+ // ...
+ // Ltarget:
+ //
+ // Then we want to encode the value (Ltarget + addend) - (LFixup - _base)
+ *loc64 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress);
return;
case negDelta32:
*loc32 = fixupAddress - targetAddress + ref.addend();
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index f80e2ac467fc..e830db9fcc7b 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -406,14 +406,8 @@ bool Util::TextSectionSorter::operator()(const SectionInfo *left,
}
void Util::organizeSections() {
- if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT) {
- // Leave sections ordered as normalized file specified.
- uint32_t sectionIndex = 1;
- for (SectionInfo *si : _sectionInfos) {
- si->finalSectionIndex = sectionIndex++;
- }
- } else {
- switch (_ctx.outputMachOType()) {
+ // NOTE!: Keep this in sync with assignAddressesToSections.
+ switch (_ctx.outputMachOType()) {
case llvm::MachO::MH_EXECUTE:
// Main executables, need a zero-page segment
segmentForName("__PAGEZERO");
@@ -425,32 +419,30 @@ void Util::organizeSections() {
break;
default:
break;
+ }
+ // Group sections into segments.
+ for (SectionInfo *si : _sectionInfos) {
+ SegmentInfo *seg = segmentForName(si->segmentName);
+ seg->sections.push_back(si);
+ }
+ // Sort segments.
+ std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
+
+ // Sort sections within segments.
+ for (SegmentInfo *seg : _segmentInfos) {
+ if (seg->name.equals("__TEXT")) {
+ std::sort(seg->sections.begin(), seg->sections.end(),
+ TextSectionSorter());
}
- // Group sections into segments.
- for (SectionInfo *si : _sectionInfos) {
- SegmentInfo *seg = segmentForName(si->segmentName);
- seg->sections.push_back(si);
- }
- // Sort segments.
- std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
-
- // Sort sections within segments.
- for (SegmentInfo *seg : _segmentInfos) {
- if (seg->name.equals("__TEXT")) {
- std::sort(seg->sections.begin(), seg->sections.end(),
- TextSectionSorter());
- }
- }
+ }
- // Record final section indexes.
- uint32_t segmentIndex = 0;
- uint32_t sectionIndex = 1;
- for (SegmentInfo *seg : _segmentInfos) {
- seg->normalizedSegmentIndex = segmentIndex++;
- for (SectionInfo *sect : seg->sections) {
- sect->finalSectionIndex = sectionIndex++;
- }
- }
+ // Record final section indexes.
+ uint32_t segmentIndex = 0;
+ uint32_t sectionIndex = 1;
+ for (SegmentInfo *seg : _segmentInfos) {
+ seg->normalizedSegmentIndex = segmentIndex++;
+ for (SectionInfo *sect : seg->sections)
+ sect->finalSectionIndex = sectionIndex++;
}
}
@@ -487,54 +479,39 @@ void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
}
void Util::assignAddressesToSections(const NormalizedFile &file) {
+ // NOTE!: Keep this in sync with organizeSections.
size_t hlcSize = headerAndLoadCommandsSize(file);
uint64_t address = 0;
- if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
- for (SegmentInfo *seg : _segmentInfos) {
- if (seg->name.equals("__PAGEZERO")) {
- seg->size = _ctx.pageZeroSize();
- address += seg->size;
- }
- else if (seg->name.equals("__TEXT")) {
- // _ctx.baseAddress() == 0 implies it was either unspecified or
- // pageZeroSize is also 0. In either case resetting address is safe.
- address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
- layoutSectionsInTextSegment(hlcSize, seg, address);
- } else
- layoutSectionsInSegment(seg, address);
-
- address = llvm::RoundUpToAlignment(address, _ctx.pageSize());
+ for (SegmentInfo *seg : _segmentInfos) {
+ if (seg->name.equals("__PAGEZERO")) {
+ seg->size = _ctx.pageZeroSize();
+ address += seg->size;
}
- DEBUG_WITH_TYPE("WriterMachO-norm",
- llvm::dbgs() << "assignAddressesToSections()\n";
- for (SegmentInfo *sgi : _segmentInfos) {
- llvm::dbgs() << " address=" << llvm::format("0x%08llX", sgi->address)
- << ", size=" << llvm::format("0x%08llX", sgi->size)
- << ", segment-name='" << sgi->name
- << "'\n";
- for (SectionInfo *si : sgi->sections) {
- llvm::dbgs()<< " addr=" << llvm::format("0x%08llX", si->address)
- << ", size=" << llvm::format("0x%08llX", si->size)
- << ", section-name='" << si->sectionName
- << "\n";
- }
+ else if (seg->name.equals("__TEXT")) {
+ // _ctx.baseAddress() == 0 implies it was either unspecified or
+ // pageZeroSize is also 0. In either case resetting address is safe.
+ address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
+ layoutSectionsInTextSegment(hlcSize, seg, address);
+ } else
+ layoutSectionsInSegment(seg, address);
+
+ address = llvm::RoundUpToAlignment(address, _ctx.pageSize());
+ }
+ DEBUG_WITH_TYPE("WriterMachO-norm",
+ llvm::dbgs() << "assignAddressesToSections()\n";
+ for (SegmentInfo *sgi : _segmentInfos) {
+ llvm::dbgs() << " address=" << llvm::format("0x%08llX", sgi->address)
+ << ", size=" << llvm::format("0x%08llX", sgi->size)
+ << ", segment-name='" << sgi->name
+ << "'\n";
+ for (SectionInfo *si : sgi->sections) {
+ llvm::dbgs()<< " addr=" << llvm::format("0x%08llX", si->address)
+ << ", size=" << llvm::format("0x%08llX", si->size)
+ << ", section-name='" << si->sectionName
+ << "\n";
}
- );
- } else {
- for (SectionInfo *sect : _sectionInfos) {
- sect->address = llvm::RoundUpToAlignment(address, sect->alignment);
- address = sect->address + sect->size;
}
- DEBUG_WITH_TYPE("WriterMachO-norm",
- llvm::dbgs() << "assignAddressesToSections()\n";
- for (SectionInfo *si : _sectionInfos) {
- llvm::dbgs() << " section=" << si->sectionName
- << " address= " << llvm::format("0x%08X", si->address)
- << " size= " << llvm::format("0x%08X", si->size)
- << "\n";
- }
- );
- }
+ );
}
void Util::copySegmentInfo(NormalizedFile &file) {
@@ -604,16 +581,9 @@ void Util::copySectionContent(NormalizedFile &file) {
void Util::copySectionInfo(NormalizedFile &file) {
file.sections.reserve(_sectionInfos.size());
- // For final linked images, write sections grouped by segment.
- if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
- for (SegmentInfo *sgi : _segmentInfos) {
- for (SectionInfo *si : sgi->sections) {
- appendSection(si, file);
- }
- }
- } else {
- // Object files write sections in default order.
- for (SectionInfo *si : _sectionInfos) {
+ // Write sections grouped by segment.
+ for (SegmentInfo *sgi : _segmentInfos) {
+ for (SectionInfo *si : sgi->sections) {
appendSection(si, file);
}
}
@@ -621,20 +591,12 @@ void Util::copySectionInfo(NormalizedFile &file) {
void Util::updateSectionInfo(NormalizedFile &file) {
file.sections.reserve(_sectionInfos.size());
- if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
- // For final linked images, sections grouped by segment.
- for (SegmentInfo *sgi : _segmentInfos) {
- Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
- normSeg->address = sgi->address;
- normSeg->size = sgi->size;
- for (SectionInfo *si : sgi->sections) {
- Section *normSect = &file.sections[si->normalizedSectionIndex];
- normSect->address = si->address;
- }
- }
- } else {
- // Object files write sections in default order.
- for (SectionInfo *si : _sectionInfos) {
+ // sections grouped by segment.
+ for (SegmentInfo *sgi : _segmentInfos) {
+ Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
+ normSeg->address = sgi->address;
+ normSeg->size = sgi->size;
+ for (SectionInfo *si : sgi->sections) {
Section *normSect = &file.sections[si->normalizedSectionIndex];
normSect->address = si->address;
}
@@ -663,19 +625,47 @@ void Util::buildAtomToAddressMap() {
_entryAtom = info.atom;
}
DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
- << " address="
- << llvm::format("0x%016X", _atomToAddress[info.atom])
- << " atom=" << info.atom
- << " name=" << info.atom->name() << "\n");
+ << " address="
+ << llvm::format("0x%016X", _atomToAddress[info.atom])
+ << llvm::format(" 0x%09lX", info.atom)
+ << ", file=#"
+ << info.atom->file().ordinal()
+ << ", atom=#"
+ << info.atom->ordinal()
+ << ", name="
+ << info.atom->name()
+ << ", type="
+ << info.atom->contentType()
+ << "\n");
}
}
+ DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
+ << "assign header alias atom addresses:\n");
for (const Atom *atom : _machHeaderAliasAtoms) {
_atomToAddress[atom] = _ctx.baseAddress();
- DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
- << " address="
- << llvm::format("0x%016X", _atomToAddress[atom])
- << " atom=" << atom
- << " name=" << atom->name() << "\n");
+#ifndef NDEBUG
+ if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
+ DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
+ << " address="
+ << llvm::format("0x%016X", _atomToAddress[atom])
+ << llvm::format(" 0x%09lX", atom)
+ << ", file=#"
+ << definedAtom->file().ordinal()
+ << ", atom=#"
+ << definedAtom->ordinal()
+ << ", name="
+ << definedAtom->name()
+ << ", type="
+ << definedAtom->contentType()
+ << "\n");
+ } else {
+ DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
+ << " address="
+ << llvm::format("0x%016X", _atomToAddress[atom])
+ << " atom=" << atom
+ << " name=" << atom->name() << "\n");
+ }
+#endif
}
}
@@ -999,11 +989,9 @@ void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
uint32_t Util::sectionIndexForAtom(const Atom *atom) {
uint64_t address = _atomToAddress[atom];
- uint32_t index = 1;
for (const SectionInfo *si : _sectionInfos) {
if ((si->address <= address) && (address < si->address+si->size))
- return index;
- ++index;
+ return si->finalSectionIndex;
}
llvm_unreachable("atom not in any section");
}
diff --git a/test/ELF/dt_tags.s b/test/ELF/dt_tags.s
new file mode 100644
index 000000000000..f2759d6ef204
--- /dev/null
+++ b/test/ELF/dt_tags.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
+# RUN: ld.lld -shared %t -o %t.so
+# RUN: ld.lld %t %t.so -o %t.exe
+# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DSO %s
+# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=EXE %s
+
+# EXE: DynamicSection [
+# EXE: 0x0000000000000015 DEBUG 0x0
+# EXE: ]
+
+# DSO: DynamicSection [
+# DSO-NOT: 0x0000000000000015 DEBUG 0x0
+# DSO: ]
+
+.globl _start
+_start:
diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s
index ab2a2405726b..295396006543 100644
--- a/test/ELF/dynamic-reloc.s
+++ b/test/ELF/dynamic-reloc.s
@@ -53,6 +53,7 @@
// CHECK-NEXT: 0x000000000000000A STRSZ
// CHECK-NEXT: 0x0000000000000004 HASH
// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/got.s b/test/ELF/got.s
index 5fa1c2a7251f..600377ded2f7 100644
--- a/test/ELF/got.s
+++ b/test/ELF/got.s
@@ -12,7 +12,7 @@
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x120A0
+// CHECK-NEXT: Address: 0x120B0
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 16
// CHECK-NEXT: Link: 0
@@ -21,22 +21,22 @@
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT: 0x120A0 R_X86_64_GLOB_DAT bar 0x0
-// CHECK-NEXT: 0x120A8 R_X86_64_GLOB_DAT zed 0x0
+// CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT bar 0x0
+// CHECK-NEXT: 0x120B8 R_X86_64_GLOB_DAT zed 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
// Unfortunately FileCheck can't do math, so we have to check for explicit
// values:
-// 0x120A0 - (0x11000 + 2) - 4 = 4250
-// 0x120A0 - (0x11006 + 2) - 4 = 4244
-// 0x120A8 - (0x1100c + 2) - 4 = 4246
+// 0x120B0 - (0x11000 + 2) - 4 = 4266
+// 0x120B0 - (0x11006 + 2) - 4 = 4260
+// 0x120A8 - (0x1100c + 2) - 4 = 4262
// DISASM: _start:
-// DISASM-NEXT: 11000: {{.*}} jmpq *4250(%rip)
-// DISASM-NEXT: 11006: {{.*}} jmpq *4244(%rip)
-// DISASM-NEXT: 1100c: {{.*}} jmpq *4246(%rip)
+// DISASM-NEXT: 11000: {{.*}} jmpq *4266(%rip)
+// DISASM-NEXT: 11006: {{.*}} jmpq *4260(%rip)
+// DISASM-NEXT: 1100c: {{.*}} jmpq *4262(%rip)
.global _start
_start:
diff --git a/test/ELF/local-got.s b/test/ELF/local-got.s
index 015c058e2eb9..1a8fa0dfd253 100644
--- a/test/ELF/local-got.s
+++ b/test/ELF/local-got.s
@@ -14,11 +14,11 @@ _start:
foo:
nop
-// 0x120A0 - 0x11000 - 5 = 4251
-// 0x120A8 - 0x11005 - 5 = 4254
+// 0x120B0 - 0x11000 - 5 = 4251
+// 0x120B8 - 0x11005 - 5 = 4254
// DISASM: _start:
-// DISASM-NEXT: 11000: {{.*}} callq 4251
-// DISASM-NEXT: 11005: {{.*}} callq 4254
+// DISASM-NEXT: 11000: {{.*}} callq 4267
+// DISASM-NEXT: 11005: {{.*}} callq 4270
// DISASM: foo:
// DISASM-NEXT: 1100a: {{.*}} nop
@@ -29,7 +29,7 @@ foo:
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x120A0
+// CHECK-NEXT: Address: 0x120B0
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 16
// CHECK-NEXT: Link: 0
@@ -43,6 +43,6 @@ foo:
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT: 0x120A0 R_X86_64_GLOB_DAT bar 0x0
+// CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT bar 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/test/ELF/relocation-i686.s b/test/ELF/relocation-i686.s
index f66cad20a074..529a35765f9e 100644
--- a/test/ELF/relocation-i686.s
+++ b/test/ELF/relocation-i686.s
@@ -55,7 +55,7 @@ movl bar@GOT, %eax
// ADDR-NEXT: SHF_ALLOC
// ADDR-NEXT: SHF_WRITE
// ADDR-NEXT: ]
-// ADDR-NEXT: Address: 0x12070
+// ADDR-NEXT: Address: 0x12078
.section .R_386_GOTPC,"ax",@progbits
R_386_GOTPC:
@@ -65,7 +65,7 @@ R_386_GOTPC:
// CHECK: Disassembly of section .R_386_GOTPC:
// CHECK-NEXT: R_386_GOTPC:
-// CHECK-NEXT: 11014: {{.*}} movl $4188, %eax
+// CHECK-NEXT: 11014: {{.*}} movl $4196, %eax
.section .dynamic_reloc, "ax",@progbits
call bar
diff --git a/test/ELF/relocation.s b/test/ELF/relocation.s
index a6dd1d1ef5d6..33b0e23ee972 100644
--- a/test/ELF/relocation.s
+++ b/test/ELF/relocation.s
@@ -22,7 +22,7 @@
// SEC-NEXT: SHF_ALLOC
// SEC-NEXT: SHF_WRITE
// SEC-NEXT: ]
-// SEC-NEXT: Address: 0x120E0
+// SEC-NEXT: Address: 0x120F0
// SEC-NEXT: Offset:
// SEC-NEXT: Size: 8
// SEC-NEXT: Link: 0
@@ -111,7 +111,7 @@ R_X86_64_64:
R_X86_64_GOTPCREL:
.long zed@gotpcrel
-// 0x120E8 - 0x101D8 = 7952
+// 0x120F8 - 0x101D8 = 7952
// 7952 = 0x101f0000 in little endian
// CHECK: Contents of section .R_X86_64_GOTPCREL
-// CHECK-NEXT: 101d0 101f0000
+// CHECK-NEXT: 101d0 201f0000
diff --git a/test/ELF/relro.s b/test/ELF/relro.s
index 7a225a269075..692d6b271cf8 100644
--- a/test/ELF/relro.s
+++ b/test/ELF/relro.s
@@ -17,8 +17,8 @@
// FULLRELRO-NEXT: SHF_ALLOC
// FULLRELRO-NEXT: SHF_WRITE
// FULLRELRO-NEXT: ]
-// FULLRELRO-NEXT: Address: 0x12100
-// FULLRELRO-NEXT: Offset: 0x2100
+// FULLRELRO-NEXT: Address: 0x12110
+// FULLRELRO-NEXT: Offset: 0x2110
// FULLRELRO-NEXT: Size: 8
// FULLRELRO-NEXT: Link: 0
// FULLRELRO-NEXT: Info: 0
@@ -36,8 +36,8 @@
// FULLRELRO-NEXT: SHF_ALLOC
// FULLRELRO-NEXT: SHF_WRITE
// FULLRELRO-NEXT: ]
-// FULLRELRO-NEXT: Address: 0x12108
-// FULLRELRO-NEXT: Offset: 0x2108
+// FULLRELRO-NEXT: Address: 0x12118
+// FULLRELRO-NEXT: Offset: 0x2118
// FULLRELRO-NEXT: Size: 32
// FULLRELRO-NEXT: Link: 0
// FULLRELRO-NEXT: Info: 0
@@ -103,8 +103,8 @@
// FULLRELRO-NEXT: Offset: 0x
// FULLRELRO-NEXT: VirtualAddress: [[RWADDR]]
// FULLRELRO-NEXT: PhysicalAddress:
-// FULLRELRO-NEXT: FileSize: 296
-// FULLRELRO-NEXT: MemSize: 296
+// FULLRELRO-NEXT: FileSize: 312
+// FULLRELRO-NEXT: MemSize: 312
// FULLRELRO-NEXT: Flags [
// FULLRELRO-NEXT: PF_R
// FULLRELRO-NEXT: ]
@@ -119,8 +119,8 @@
// PARTRELRO-NEXT: SHF_ALLOC
// PARTRELRO-NEXT: SHF_WRITE
// PARTRELRO-NEXT: ]
-// PARTRELRO-NEXT: Address: 0x120E0
-// PARTRELRO-NEXT: Offset: 0x20E0
+// PARTRELRO-NEXT: Address: 0x120F0
+// PARTRELRO-NEXT: Offset: 0x20F0
// PARTRELRO-NEXT: Size: 8
// PARTRELRO-NEXT: Link: 0
// PARTRELRO-NEXT: Info: 0
@@ -219,8 +219,8 @@
// PARTRELRO-NEXT: Offset: 0x2000
// PARTRELRO-NEXT: VirtualAddress: [[RWADDR]]
// PARTRELRO-NEXT: PhysicalAddress:
-// PARTRELRO-NEXT: FileSize: 232
-// PARTRELRO-NEXT: MemSize: 232
+// PARTRELRO-NEXT: FileSize: 248
+// PARTRELRO-NEXT: MemSize: 248
// PARTRELRO-NEXT: Flags [
// PARTRELRO-NEXT: PF_R
// PARTRELRO-NEXT: ]
diff --git a/test/ELF/shared-be.s b/test/ELF/shared-be.s
index 1524d48b2ed6..0f57a4b7f0c3 100644
--- a/test/ELF/shared-be.s
+++ b/test/ELF/shared-be.s
@@ -25,6 +25,7 @@
// CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes)
// CHECK: 0x000000000000001D RUNPATH foo:bar
// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index f76495d960af..1bf5bd1795bc 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -253,6 +253,7 @@
// CHECK-NEXT: 0x00000004 HASH [[HASHADDR]]
// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s
index 10b9cf994579..aa024519a64a 100644
--- a/test/ELF/tls-got.s
+++ b/test/ELF/tls-got.s
@@ -14,7 +14,7 @@
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
// CHECK-NEXT: Address: [[ADDR:.*]]
-// CHECK-NEXT: Offset: 0x20A0
+// CHECK-NEXT: Offset: 0x20B0
// CHECK-NEXT: Size: 16
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
@@ -25,20 +25,20 @@
// CHECK: Relocations [
// CHECK-NEXT: Section (4) .rela.dyn {
// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
-// CHECK-NEXT: 0x120A8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT: 0x120B8 R_X86_64_TPOFF64 tls0 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
-//0x11000 + 4249 + 7 = 0x120A0
-//0x1100A + 4247 + 7 = 0x120A8
-//0x11014 + 4237 + 7 = 0x120A8
+//0x11000 + 4249 + 7 = 0x120B0
+//0x1100A + 4247 + 7 = 0x120B8
+//0x11014 + 4237 + 7 = 0x120B8
//DISASM: Disassembly of section .text:
//DISASM-NEXT: main:
-//DISASM-NEXT: 11000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
+//DISASM-NEXT: 11000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
//DISASM-NEXT: 11007: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 1100a: 48 8b 05 97 10 00 00 movq 4247(%rip), %rax
+//DISASM-NEXT: 1100a: 48 8b 05 a7 10 00 00 movq 4263(%rip), %rax
//DISASM-NEXT: 11011: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 11014: 48 8b 05 8d 10 00 00 movq 4237(%rip), %rax
+//DISASM-NEXT: 11014: 48 8b 05 9d 10 00 00 movq 4253(%rip), %rax
//DISASM-NEXT: 1101b: 64 8b 00 movl %fs:(%rax), %eax
//DISASM-NEXT: 1101e: c3 retq
diff --git a/test/ELF/tls-opt-gdie.s b/test/ELF/tls-opt-gdie.s
index a6c68686c57b..3f83157086e7 100644
--- a/test/ELF/tls-opt-gdie.s
+++ b/test/ELF/tls-opt-gdie.s
@@ -13,8 +13,8 @@
//RELOC-NEXT: SHF_ALLOC
//RELOC-NEXT: SHF_WRITE
//RELOC-NEXT: ]
-//RELOC-NEXT: Address: 0x120E0
-//RELOC-NEXT: Offset: 0x20E0
+//RELOC-NEXT: Address: 0x120F0
+//RELOC-NEXT: Offset: 0x20F0
//RELOC-NEXT: Size: 16
//RELOC-NEXT: Link: 0
//RELOC-NEXT: Info: 0
@@ -23,22 +23,22 @@
//RELOC-NEXT: }
//RELOC: Relocations [
//RELOC-NEXT: Section (4) .rela.dyn {
-//RELOC-NEXT: 0x120E0 R_X86_64_TPOFF64 tlsshared0 0x0
-//RELOC-NEXT: 0x120E8 R_X86_64_TPOFF64 tlsshared1 0x0
+//RELOC-NEXT: 0x120F0 R_X86_64_TPOFF64 tlsshared0 0x0
+//RELOC-NEXT: 0x120F8 R_X86_64_TPOFF64 tlsshared1 0x0
//RELOC-NEXT: }
//RELOC-NEXT: Section (5) .rela.plt {
//RELOC-NEXT: 0x13018 R_X86_64_JUMP_SLOT __tls_get_addr 0x0
//RELOC-NEXT: }
//RELOC-NEXT: ]
-//0x11009 + (4304 + 7) = 0x120E0
-//0x11019 + (4296 + 7) = 0x120E8
+//0x11009 + (4304 + 7) = 0x120F0
+//0x11019 + (4296 + 7) = 0x120F8
// DISASM: Disassembly of section .text:
// DISASM-NEXT: _start:
// DISASM-NEXT: 11000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 11009: 48 03 05 d0 10 00 00 addq 4304(%rip), %rax
+// DISASM-NEXT: 11009: 48 03 05 e0 10 00 00 addq 4320(%rip), %rax
// DISASM-NEXT: 11010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 11019: 48 03 05 c8 10 00 00 addq 4296(%rip), %rax
+// DISASM-NEXT: 11019: 48 03 05 d8 10 00 00 addq 4312(%rip), %rax
.section .text
.globl _start
diff --git a/test/ELF/tls-opt-gdiele-i686.s b/test/ELF/tls-opt-gdiele-i686.s
index 94630bbc0df2..1432a9607da9 100644
--- a/test/ELF/tls-opt-gdiele-i686.s
+++ b/test/ELF/tls-opt-gdiele-i686.s
@@ -7,8 +7,8 @@
// NORELOC: Relocations [
// NORELOC-NEXT: Section ({{.*}}) .rel.dyn {
-// NORELOC-NEXT: 0x12050 R_386_TLS_TPOFF tlsshared0 0x0
-// NORELOC-NEXT: 0x12054 R_386_TLS_TPOFF tlsshared1 0x0
+// NORELOC-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
+// NORELOC-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
// NORELOC-NEXT: }
// NORELOC-NEXT: ]
diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s
index bc6c6bed7b44..50ade0fc76cc 100644
--- a/test/ELF/tls-opt-iele-i686-nopic.s
+++ b/test/ELF/tls-opt-iele-i686-nopic.s
@@ -16,8 +16,8 @@
// GOTREL-NEXT: SHF_ALLOC
// GOTREL-NEXT: SHF_WRITE
// GOTREL-NEXT: ]
-// GOTREL-NEXT: Address: 0x12050
-// GOTREL-NEXT: Offset: 0x2050
+// GOTREL-NEXT: Address: 0x12058
+// GOTREL-NEXT: Offset: 0x2058
// GOTREL-NEXT: Size: 8
// GOTREL-NEXT: Link: 0
// GOTREL-NEXT: Info: 0
@@ -26,8 +26,8 @@
// GOTREL-NEXT: }
// GOTREL: Relocations [
// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
-// GOTREL-NEXT: 0x12050 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTREL-NEXT: 0x12054 R_386_TLS_TPOFF tlsshared1 0x0
+// GOTREL-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTREL-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
// GOTREL-NEXT: }
// GOTREL-NEXT: ]
@@ -35,8 +35,8 @@
// DISASM-NEXT: _start:
// 4294967288 = 0xFFFFFFF8
// 4294967292 = 0xFFFFFFFC
-// 73808 = (.got)[0] = 0x12050
-// 73812 = (.got)[1] = 0x12054
+// 73808 = (.got)[0] = 0x12058
+// 73812 = (.got)[1] = 0x1205C
// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
// DISASM-NEXT: 11006: 65 8b 01 movl %gs:(%ecx), %eax
// DISASM-NEXT: 11009: b8 f8 ff ff ff movl $4294967288, %eax
@@ -49,9 +49,9 @@
// DISASM-NEXT: 11028: 65 8b 00 movl %gs:(%eax), %eax
// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
// DISASM-NEXT: 11031: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 11034: 8b 0d 50 20 01 00 movl 73808, %ecx
+// DISASM-NEXT: 11034: 8b 0d 58 20 01 00 movl 73816, %ecx
// DISASM-NEXT: 1103a: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 1103d: 03 0d 54 20 01 00 addl 73812, %ecx
+// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx
// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax
// GOTRELSHARED: Section {
diff --git a/test/mach-o/arm64-reloc-negDelta32-fixup.yaml b/test/mach-o/arm64-reloc-negDelta32-fixup.yaml
index 87708a0db12b..8beab2841dc3 100644
--- a/test/mach-o/arm64-reloc-negDelta32-fixup.yaml
+++ b/test/mach-o/arm64-reloc-negDelta32-fixup.yaml
@@ -6,12 +6,12 @@
# The reference from FDE->CIE is implicitly created as a negDelta32.
# We don't emit these in to the binary as relocations, so we need to
# make sure that the offset in the FDE to the CIE is the correct value.
-# CHECK: 0010 10000000 00000000 017a5200 01781e01
-# CHECK: 0020 100c1f00 20000000 18000000 e4ffffff
-# Note, this one that matters ^~~~~~~~
+# CHECK: {{[0-9abcdef]*}} 10000000 00000000 017a5200 01781e01
+# CHECK: {{[0-9abcdef]*}} 100c1f00 20000000 18000000 e4ffffff
+# Note, this one that matters ^~~~~~~~
# It needs to be 0x18 as that is the offset back to 0 where the CIE is.
-# CHECK: 0030 ffffffff 20000000 00000000 00480e10
-# CHECK: 0040 9e019d02 00000000
+# CHECK: {{[0-9abcdef]*}} ffffffff 20000000 00000000 00480e10
+# CHECK: {{[0-9abcdef]*}} 9e019d02 00000000
--- !mach-o
arch: arm64
diff --git a/test/mach-o/arm64-section-order.yaml b/test/mach-o/arm64-section-order.yaml
new file mode 100644
index 000000000000..50d684668a52
--- /dev/null
+++ b/test/mach-o/arm64-section-order.yaml
@@ -0,0 +1,67 @@
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2
+# RUN: llvm-objdump -section-headers %t | FileCheck %s
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
+
+# Make sure that the sections are sorted. Currently we want this order:
+# __text, __unwind_info
+
+# CHECK: Sections:
+# CHECK: 0 __text {{.*}} TEXT
+# CHECK: 1 __compact_unwind {{.*}}
+
+
+--- !mach-o
+arch: arm64
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+compat-version: 0.0
+current-version: 0.0
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 8
+ address: 0x0000000000000000
+ content: [ 0xC0, 0x03, 0x5F, 0xD6, 0xC0, 0x03, 0x5F, 0xD6 ]
+ - segment: __LD
+ section: __compact_unwind
+ type: S_REGULAR
+ attributes: [ ]
+ alignment: 8
+ address: 0x0000000000000008
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000020
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+global-symbols:
+ - name: __Z3fooi
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+ - name: __Z4foo2i
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000004
diff --git a/test/mach-o/parse-data-relocs-x86_64.yaml b/test/mach-o/parse-data-relocs-x86_64.yaml
index b6f38f5d10e4..6b05e26372b8 100644
--- a/test/mach-o/parse-data-relocs-x86_64.yaml
+++ b/test/mach-o/parse-data-relocs-x86_64.yaml
@@ -268,7 +268,7 @@ page-size: 0x00000000
# CHECK: type: data
# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
# CHECK: 00, 00, 00, 00, F0, FF, FF, FF, FF, FF, FF, FF,
-# CHECK: {{..}}, 00, 00, 00, 00, 00, 00, 00, {{..}}, 00, 00, 00,
+# CHECK: {{..}}, {{..}}, 00, 00, 00, 00, 00, 00, {{..}}, {{..}}, 00, 00,
# CHECK: 00, 00, 00, 00, D8, FF, FF, FF, FF, FF, FF, FF,
# CHECK: D4, FF, FF, FF, FF, FF, FF, FF, {{..}}, {{..}}, {{..}}, {{..}},
# CHECK: {{..}}, {{..}}, {{..}}, {{..}}, C0, FF, FF, FF, C0, FF, FF, FF,