[lld] r261838 - [ELF2] - Basic implementation of -r/--relocatable
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 25 11:24:17 PST 2016
I believe that the resulting object files with this patch contains some
linker-synthesized symbols such as __init_array_start or
__start_<section-name>. Is this expected?
On Thu, Feb 25, 2016 at 12:23 AM, George Rimar via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: grimar
> Date: Thu Feb 25 02:23:37 2016
> New Revision: 261838
>
> URL: http://llvm.org/viewvc/llvm-project?rev=261838&view=rev
> Log:
> [ELF2] - Basic implementation of -r/--relocatable
>
> -r, -relocatable - Generate relocatable output
>
> Currently does not have support for files containing
> relocation sections with entries that refer to local
> symbols (like rel[a].eh_frame which refer to sections
> and not to symbols)
>
> Differential revision: http://reviews.llvm.org/D14382
>
> Added:
> lld/trunk/test/ELF/Inputs/relocatable.s
> lld/trunk/test/ELF/Inputs/relocatable2.s
> Modified:
> lld/trunk/ELF/Config.h
> lld/trunk/ELF/Driver.cpp
> lld/trunk/ELF/InputFiles.cpp
> lld/trunk/ELF/InputSection.cpp
> lld/trunk/ELF/InputSection.h
> lld/trunk/ELF/Options.td
> lld/trunk/ELF/OutputSections.cpp
> lld/trunk/ELF/OutputSections.h
> lld/trunk/ELF/Writer.cpp
> lld/trunk/test/ELF/relocatable.s
> lld/trunk/test/ELF/strip-all.s
>
> Modified: lld/trunk/ELF/Config.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Config.h (original)
> +++ lld/trunk/ELF/Config.h Thu Feb 25 02:23:37 2016
> @@ -67,6 +67,7 @@ struct Configuration {
> bool NoInhibitExec;
> bool NoUndefined;
> bool PrintGcSections;
> + bool Relocatable;
> bool Shared;
> bool Static = false;
> bool StripAll;
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Thu Feb 25 02:23:37 2016
> @@ -111,6 +111,10 @@ void LinkerDriver::addFile(StringRef Pat
> Files.push_back(make_unique<ArchiveFile>(MBRef));
> return;
> case file_magic::elf_shared_object:
> + if (Config->Relocatable) {
> + error("Attempted static link of dynamic object " + Path);
> + return;
> + }
> Files.push_back(createSharedFile(MBRef));
> return;
> default:
> @@ -130,12 +134,6 @@ void LinkerDriver::addLibrary(StringRef
> // Some command line options or some combinations of them are not allowed.
> // This function checks for such errors.
> static void checkOptions(opt::InputArgList &Args) {
> - // Traditional linkers can generate re-linkable object files instead
> - // of executables or DSOs. We don't support that since the feature
> - // does not seem to provide more value than the static archiver.
> - if (Args.hasArg(OPT_relocatable))
> - error("-r option is not supported. Use 'ar' command instead.");
> -
> // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
> // table which is a relatively new feature.
> if (Config->EMachine == EM_MIPS && Config->GnuHash)
> @@ -143,6 +141,9 @@ static void checkOptions(opt::InputArgLi
>
> if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
> error("-e option is not valid for AMDGPU.");
> +
> + if (Config->Relocatable && Config->Shared)
> + error("-r and -shared may not be used together");
> }
>
> static StringRef
> @@ -219,6 +220,7 @@ void LinkerDriver::readConfigs(opt::Inpu
> Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
> Config->NoUndefined = Args.hasArg(OPT_no_undefined);
> Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
> + Config->Relocatable = Args.hasArg(OPT_relocatable);
> Config->Shared = Args.hasArg(OPT_shared);
> Config->StripAll = Args.hasArg(OPT_strip_all);
> Config->Verbose = Args.hasArg(OPT_verbose);
> @@ -237,6 +239,9 @@ void LinkerDriver::readConfigs(opt::Inpu
> Config->ZOrigin = hasZOption(Args, "origin");
> Config->ZRelro = !hasZOption(Args, "norelro");
>
> + if (Config->Relocatable)
> + Config->StripAll = false;
> +
> if (auto *Arg = Args.getLastArg(OPT_O)) {
> StringRef Val = Arg->getValue();
> if (Val.getAsInteger(10, Config->Optimize))
> @@ -303,7 +308,7 @@ template <class ELFT> void LinkerDriver:
> std::unique_ptr<TargetInfo> TI(createTarget());
> Target = TI.get();
>
> - if (!Config->Shared) {
> + if (!Config->Shared && !Config->Relocatable) {
> // Add entry symbol.
> //
> // There is no entry symbol for AMDGPU binaries, so skip adding one
> to avoid
>
> Modified: lld/trunk/ELF/InputFiles.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.cpp (original)
> +++ lld/trunk/ELF/InputFiles.cpp Thu Feb 25 02:23:37 2016
> @@ -226,7 +226,10 @@ void elf2::ObjectFile<ELFT>::initializeS
> continue;
> if (!RelocatedSection)
> fatal("Unsupported relocation reference");
> - if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
> + if (Config->Relocatable) {
> + // For -r, relocation sections are handled as regular input
> sections.
> + Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec);
> + } else if (auto *S =
> dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
> S->RelocSections.push_back(&Sec);
> } else if (auto *S =
> dyn_cast<EHInputSection<ELFT>>(RelocatedSection)) {
> if (S->RelocSection)
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Thu Feb 25 02:23:37 2016
> @@ -105,6 +105,43 @@ bool InputSection<ELFT>::classof(const I
> }
>
> template <class ELFT>
> +InputSectionBase<ELFT> *InputSection<ELFT>::getRelocatedSection() {
> + assert(this->Header->sh_type == SHT_RELA || this->Header->sh_type ==
> SHT_REL);
> + ArrayRef<InputSectionBase<ELFT> *> Sections = this->File->getSections();
> + return Sections[this->Header->sh_info];
> +}
> +
> +// This is used for -r. We can't use memcpy to copy relocations because
> we need
> +// to update symbol table offset and section index for each relocation.
> So we
> +// copy relocations one by one.
> +template <class ELFT>
> +template <bool isRela>
> +void InputSection<ELFT>::copyRelocations(uint8_t *Buf,
> + RelIteratorRange<isRela> Rels) {
> + typedef Elf_Rel_Impl<ELFT, isRela> RelType;
> + InputSectionBase<ELFT> *RelocatedSection = getRelocatedSection();
> +
> + for (const RelType &Rel : Rels) {
> + uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
> + uint32_t Type = Rel.getType(Config->Mips64EL);
> + const Elf_Shdr *SymTab = this->File->getSymbolTable();
> +
> + RelType *P = reinterpret_cast<RelType *>(Buf);
> + Buf += sizeof(RelType);
> +
> + // Relocation for local symbol here means that it is probably
> + // rel[a].eh_frame section which has references to
> + // sections in r_info field. Also needs fix for addend.
> + if (SymIndex < SymTab->sh_info)
> + fatal("Relocation against local symbols is not supported yet");
> +
> + SymbolBody *Body = this->File->getSymbolBody(SymIndex)->repl();
> + P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
> + P->setSymbolAndType(Body->DynsymIndex, Type, Config->Mips64EL);
> + }
> +}
> +
> +template <class ELFT>
> template <bool isRela>
> uint8_t *
> InputSectionBase<ELFT>::findMipsPairedReloc(uint8_t *Buf, uint32_t
> SymIndex,
> @@ -256,9 +293,21 @@ template <class ELFT> void InputSection<
> return;
> // Copy section contents from source object file to output file.
> ArrayRef<uint8_t> Data = this->getSectionData();
> + ELFFile<ELFT> &EObj = this->File->getObj();
> +
> + // That happens with -r. In that case we need fix the relocation
> position and
> + // target. No relocations are applied.
> + if (this->Header->sh_type == SHT_RELA) {
> + this->copyRelocations(Buf + OutSecOff, EObj.relas(this->Header));
> + return;
> + }
> + if (this->Header->sh_type == SHT_REL) {
> + this->copyRelocations(Buf + OutSecOff, EObj.rels(this->Header));
> + return;
> + }
> +
> memcpy(Buf + OutSecOff, Data.data(), Data.size());
>
> - ELFFile<ELFT> &EObj = this->File->getObj();
> uint8_t *BufEnd = Buf + OutSecOff + Data.size();
> // Iterate over all relocation sections that apply to this section.
> for (const Elf_Shdr *RelSec : this->RelocSections) {
>
> Modified: lld/trunk/ELF/InputSection.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputSection.h (original)
> +++ lld/trunk/ELF/InputSection.h Thu Feb 25 02:23:37 2016
> @@ -158,6 +158,16 @@ public:
> uint64_t OutSecOff = 0;
>
> static bool classof(const InputSectionBase<ELFT> *S);
> +
> + InputSectionBase<ELFT> *getRelocatedSection();
> +
> +private:
> + template <bool isRela>
> + using RelIteratorRange =
> + llvm::iterator_range<const llvm::object::Elf_Rel_Impl<ELFT, isRela>
> *>;
> +
> + template <bool isRela>
> + void copyRelocations(uint8_t *Buf, RelIteratorRange<isRela> Rels);
> };
>
> // MIPS .reginfo section provides information on the registers used by
> the code
>
> Modified: lld/trunk/ELF/Options.td
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Options.td (original)
> +++ lld/trunk/ELF/Options.td Thu Feb 25 02:23:37 2016
> @@ -94,7 +94,8 @@ def print_gc_sections: Flag<["--"], "pri
> def rpath : Separate<["-"], "rpath">,
> HelpText<"Add a DT_RUNPATH to the output">;
>
> -def relocatable : Flag<["--"], "relocatable">;
> +def relocatable : Flag<["--"], "relocatable">,
> + HelpText<"Create relocatable object file">;
>
> def script : Separate<["--"], "script">, HelpText<"Read linker script">;
>
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Thu Feb 25 02:23:37 2016
> @@ -728,9 +728,24 @@ template <class ELFT> void EhFrameHeader
> }
>
> template <class ELFT>
> -OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type,
> - uintX_t Flags)
> - : OutputSectionBase<ELFT>(Name, Type, Flags) {}
> +OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t
> Flags)
> + : OutputSectionBase<ELFT>(Name, Type, Flags) {
> + if (Type == SHT_RELA)
> + this->Header.sh_entsize = sizeof(Elf_Rela);
> + else if (Type == SHT_REL)
> + this->Header.sh_entsize = sizeof(Elf_Rel);
> +}
> +
> +template <class ELFT> void OutputSection<ELFT>::finalize() {
> + uint32_t Type = this->Header.sh_type;
> + if (Type != SHT_RELA && Type != SHT_REL)
> + return;
> + this->Header.sh_link = Out<ELFT>::SymTab->SectionIndex;
> + // sh_info for SHT_REL[A] sections should contain the section header
> index of
> + // the section to which the relocation applies.
> + InputSectionBase<ELFT> *S = Sections[0]->getRelocatedSection();
> + this->Header.sh_info = S->OutSec->SectionIndex;
> +}
>
> template <class ELFT>
> void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
> @@ -1368,6 +1383,13 @@ template <class ELFT> void SymbolTableSe
> this->Header.sh_link = StrTabSec.SectionIndex;
> this->Header.sh_info = NumLocals + 1;
>
> + if (Config->Relocatable) {
> + size_t I = NumLocals;
> + for (const std::pair<SymbolBody *, size_t> &P : Symbols)
> + P.first->DynsymIndex = ++I;
> + return;
> + }
> +
> if (!StrTabSec.isDynamic()) {
> std::stable_sort(Symbols.begin(), Symbols.end(),
> [](const std::pair<SymbolBody *, unsigned> &L,
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Thu Feb 25 02:23:37 2016
> @@ -287,6 +287,7 @@ public:
> void sortInitFini();
> void sortCtorsDtors();
> void writeTo(uint8_t *Buf) override;
> + void finalize() override;
>
> private:
> void reassignOffsets();
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Thu Feb 25 02:23:37 2016
> @@ -69,6 +69,7 @@ private:
> void scanRelocs(InputSectionBase<ELFT> &S, const Elf_Shdr &RelSec);
> void createPhdrs();
> void assignAddresses();
> + void assignAddressesRelocatable();
> void fixAbsoluteSymbols();
> bool openFile();
> void writeHeader();
> @@ -93,13 +94,15 @@ private:
> std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
>
> // We create a section for the ELF header and one for the program
> headers.
> - const unsigned NumDummySections = 2;
> ArrayRef<OutputSectionBase<ELFT> *> getSections() const {
> - return makeArrayRef(OutputSections).slice(NumDummySections);
> + return makeArrayRef(OutputSections).slice(dummySectionsNum());
> }
> unsigned getNumSections() const {
> - return OutputSections.size() + 1 - NumDummySections;
> + return OutputSections.size() + 1 - dummySectionsNum();
> }
> + // Usually there are 2 dummies sections: ELF header and program header.
> + // Relocatable output does not require program headers to be created.
> + unsigned dummySectionsNum() const { return Config->Relocatable ? 1 : 2;
> }
>
> void addRelIpltSymbols();
> void addStartEndSymbols();
> @@ -193,8 +196,12 @@ template <class ELFT> void Writer<ELFT>:
> addReservedSymbols();
> if (!createSections())
> return;
> - createPhdrs();
> - assignAddresses();
> + if (!Config->Relocatable) {
> + createPhdrs();
> + assignAddresses();
> + } else {
> + assignAddressesRelocatable();
> + }
> fixAbsoluteSymbols();
> if (!openFile())
> return;
> @@ -495,7 +502,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
>
> template <class ELFT>
> static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
> - if (Config->Shared && !Config->NoUndefined)
> + if ((Config->Relocatable || Config->Shared) && !Config->NoUndefined)
> return;
>
> std::string Msg = "undefined symbol: " + Sym->getName().str();
> @@ -928,7 +935,8 @@ template <class ELFT> static void sortCt
> // Create output section objects and add them to OutputSections.
> template <class ELFT> bool Writer<ELFT>::createSections() {
> OutputSections.push_back(Out<ELFT>::ElfHeader);
> - OutputSections.push_back(Out<ELFT>::ProgramHeaders);
> + if (!Config->Relocatable)
> + OutputSections.push_back(Out<ELFT>::ProgramHeaders);
>
> // Add .interp first because some loaders want to see that section
> // on the first page of the executable file when loaded into memory.
> @@ -1040,8 +1048,8 @@ template <class ELFT> bool Writer<ELFT>:
> std::stable_sort(OutputSections.begin(), OutputSections.end(),
> compareSections<ELFT>);
>
> - for (unsigned I = NumDummySections, N = OutputSections.size(); I < N;
> ++I)
> - OutputSections[I]->SectionIndex = I + 1 - NumDummySections;
> + for (unsigned I = dummySectionsNum(), N = OutputSections.size(); I < N;
> ++I)
> + OutputSections[I]->SectionIndex = I + 1 - dummySectionsNum();
>
> for (OutputSectionBase<ELFT> *Sec : getSections())
> Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
> @@ -1304,6 +1312,21 @@ template <class ELFT> void Writer<ELFT>:
> AddHdr(PT_GNU_STACK, PF_R | PF_W);
> }
>
> +// Used for relocatable output (-r). In this case we create only ELF file
> +// header, do not create program headers. Also assign of section addresses
> +// is very straightforward: we just put all sections sequentually to the
> file.
> +template <class ELFT> void Writer<ELFT>::assignAddressesRelocatable() {
> + Out<ELFT>::ElfHeader->setSize(sizeof(Elf_Ehdr));
> + uintX_t FileOff = 0;
> + for (OutputSectionBase<ELFT> *Sec : OutputSections) {
> + FileOff = alignTo(FileOff, Sec->getAlign());
> + Sec->setFileOffset(FileOff);
> + FileOff += Sec->getSize();
> + }
> + SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t));
> + FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
> +}
> +
> // Visits all headers in PhdrTable and assigns the adresses to
> // the output sections. Also creates common and special headers.
> template <class ELFT> void Writer<ELFT>::assignAddresses() {
> @@ -1445,20 +1468,29 @@ template <class ELFT> void Writer<ELFT>:
> auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf);
> EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
>
> - EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC;
> + if (Config->Shared)
> + EHdr->e_type = ET_DYN;
> + else if (Config->Relocatable)
> + EHdr->e_type = ET_REL;
> + else
> + EHdr->e_type = ET_EXEC;
> +
> EHdr->e_machine = FirstObj.getEMachine();
> EHdr->e_version = EV_CURRENT;
> EHdr->e_entry = getEntryAddr<ELFT>();
> - EHdr->e_phoff = sizeof(Elf_Ehdr);
> EHdr->e_shoff = SectionHeaderOff;
> EHdr->e_flags = getELFFlags();
> EHdr->e_ehsize = sizeof(Elf_Ehdr);
> - EHdr->e_phentsize = sizeof(Elf_Phdr);
> EHdr->e_phnum = Phdrs.size();
> EHdr->e_shentsize = sizeof(Elf_Shdr);
> EHdr->e_shnum = getNumSections();
> EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
>
> + if (!Config->Relocatable) {
> + EHdr->e_phoff = sizeof(Elf_Ehdr);
> + EHdr->e_phentsize = sizeof(Elf_Phdr);
> + }
> +
> // Write the program header table.
> auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
> for (Phdr &P : Phdrs)
>
> Added: lld/trunk/test/ELF/Inputs/relocatable.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/relocatable.s?rev=261838&view=auto
>
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/relocatable.s (added)
> +++ lld/trunk/test/ELF/Inputs/relocatable.s Thu Feb 25 02:23:37 2016
> @@ -0,0 +1,22 @@
> +.text
> +.type xx, at object
> +.bss
> +.globl xx
> +.align 4
> +xx:
> +.long 0
> +.size xx, 4
> +.type yy, at object
> +.globl yy
> +.align 4
> +yy:
> +.long 0
> +.size yy, 4
> +
> +.text
> +.globl foo
> +.align 16, 0x90
> +.type foo, at function
> +foo:
> +movl $1, xx
> +movl $2, yy
>
> Added: lld/trunk/test/ELF/Inputs/relocatable2.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/relocatable2.s?rev=261838&view=auto
>
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/relocatable2.s (added)
> +++ lld/trunk/test/ELF/Inputs/relocatable2.s Thu Feb 25 02:23:37 2016
> @@ -0,0 +1,22 @@
> +.text
> +.type xxx, at object
> +.bss
> +.globl xxx
> +.align 4
> +xxx:
> +.long 0
> +.size xxx, 4
> +.type yyy, at object
> +.globl yyy
> +.align 4
> +yyy:
> +.long 0
> +.size yyy, 4
> +
> +.text
> +.globl bar
> +.align 16, 0x90
> +.type bar, at function
> +bar:
> +movl $8, xxx
> +movl $9, yyy
>
> Modified: lld/trunk/test/ELF/relocatable.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocatable.s?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/relocatable.s (original)
> +++ lld/trunk/test/ELF/relocatable.s Thu Feb 25 02:23:37 2016
> @@ -1,9 +1,129 @@
> # REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux
> %p/Inputs/relocatable.s -o %t2.o
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux
> %p/Inputs/relocatable2.s -o %t3.o
> +# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
> +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r
> %t | FileCheck %s
> +# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
>
> -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> -# RUN: not ld.lld -r %t -o %t2 2>&1 | FileCheck %s
> +## Test --relocatable alias
> +# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t
> +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r
> %t | FileCheck %s
> +# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
>
> -# CHECK: -r option is not supported. Use 'ar' command instead.
> +## Verify that we can use our relocation output as input to produce
> executable
> +# RUN: ld.lld -e main %t -o %texec
> +# RUN: llvm-readobj -file-headers %texec | FileCheck
> -check-prefix=CHECKEXE %s
>
> -.globl _start;
> -_start:
> +## Attempt to link DSO with -r
> +# RUN: ld.lld -shared %t1.o -o %t.so
> +# RUN: not ld.lld -r %t.so %t2.o -o %tfail 2>&1 | FileCheck
> -check-prefix=ERR %s
> +# ERR: Attempted static link of dynamic object
> +
> +## Attempt to use -r and shared together
> +# RUN: not ld.lld -r -shared %t2.o -o %tfail 2>&1 | FileCheck
> -check-prefix=ERR2 %s
> +# ERR2: -r and -shared may not be used together
> +
> +# CHECK: ElfHeader {
> +# CHECK-NEXT: Ident {
> +# CHECK-NEXT: Magic: (7F 45 4C 46)
> +# CHECK-NEXT: Class: 64-bit
> +# CHECK-NEXT: DataEncoding: LittleEndian
> +# CHECK-NEXT: FileVersion: 1
> +# CHECK-NEXT: OS/ABI: SystemV
> +# CHECK-NEXT: ABIVersion: 0
> +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
> +# CHECK-NEXT: }
> +# CHECK-NEXT: Type: Relocatable
> +# CHECK-NEXT: Machine: EM_X86_64
> +# CHECK-NEXT: Version: 1
> +# CHECK-NEXT: Entry: 0x0
> +# CHECK-NEXT: ProgramHeaderOffset: 0x0
> +# CHECK-NEXT: SectionHeaderOffset: 0x2D8
> +# CHECK-NEXT: Flags [
> +# CHECK-NEXT: ]
> +# CHECK-NEXT: HeaderSize: 64
> +# CHECK-NEXT: ProgramHeaderEntrySize: 0
> +# CHECK-NEXT: ProgramHeaderCount: 0
> +# CHECK-NEXT: SectionHeaderEntrySize: 64
> +# CHECK-NEXT: SectionHeaderCount: 7
> +# CHECK-NEXT: StringTableSectionIndex: 5
> +# CHECK-NEXT: }
> +
> +# CHECK: Relocations [
> +# CHECK-NEXT: Section (3) .rela.text {
> +# CHECK-NEXT: 0x3 R_X86_64_32S x 0x0
> +# CHECK-NEXT: 0xE R_X86_64_32S y 0x0
> +# CHECK-NEXT: 0x23 R_X86_64_32S xx 0x0
> +# CHECK-NEXT: 0x2E R_X86_64_32S yy 0x0
> +# CHECK-NEXT: 0x43 R_X86_64_32S xxx 0x0
> +# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0
> +# CHECK-NEXT: }
> +
> +# CHECKTEXT: Disassembly of section .text:
> +# CHECKTEXT-NEXT: main:
> +# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
> +# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0
> +# CHECKTEXT: foo:
> +# CHECKTEXT-NEXT: 20: c7 04 25 00 00 00 00 01 00 00 00 movl $1, 0
> +# CHECKTEXT-NEXT: 2b: c7 04 25 00 00 00 00 02 00 00 00 movl $2, 0
> +# CHECKTEXT: bar:
> +# CHECKTEXT-NEXT: 40: c7 04 25 00 00 00 00 08 00 00 00 movl $8, 0
> +# CHECKTEXT-NEXT: 4b: c7 04 25 00 00 00 00 09 00 00 00 movl $9, 0
> +
> +# CHECKEXE: Format: ELF64-x86-64
> +# CHECKEXE-NEXT: Arch: x86_64
> +# CHECKEXE-NEXT: AddressSize: 64bit
> +# CHECKEXE-NEXT: LoadName:
> +# CHECKEXE-NEXT: ElfHeader {
> +# CHECKEXE-NEXT: Ident {
> +# CHECKEXE-NEXT: Magic: (7F 45 4C 46)
> +# CHECKEXE-NEXT: Class: 64-bit
> +# CHECKEXE-NEXT: DataEncoding: LittleEndian
> +# CHECKEXE-NEXT: FileVersion: 1
> +# CHECKEXE-NEXT: OS/ABI: SystemV (0x0)
> +# CHECKEXE-NEXT: ABIVersion: 0
> +# CHECKEXE-NEXT: Unused: (00 00 00 00 00 00 00)
> +# CHECKEXE-NEXT: }
> +# CHECKEXE-NEXT: Type: Executable
> +# CHECKEXE-NEXT: Machine: EM_X86_64
> +# CHECKEXE-NEXT: Version: 1
> +# CHECKEXE-NEXT: Entry: 0x11000
> +# CHECKEXE-NEXT: ProgramHeaderOffset: 0x40
> +# CHECKEXE-NEXT: SectionHeaderOffset: 0x11E8
> +# CHECKEXE-NEXT: Flags [
> +# CHECKEXE-NEXT: ]
> +# CHECKEXE-NEXT: HeaderSize: 64
> +# CHECKEXE-NEXT: ProgramHeaderEntrySize: 56
> +# CHECKEXE-NEXT: ProgramHeaderCount: 5
> +# CHECKEXE-NEXT: SectionHeaderEntrySize: 64
> +# CHECKEXE-NEXT: SectionHeaderCount: 6
> +# CHECKEXE-NEXT: StringTableSectionIndex: 4
> +# CHECKEXE-NEXT: }
> +
> +.text
> +.type x, at object
> +.bss
> +.globl x
> +.align 4
> +x:
> +.long 0
> +.size x, 4
> +.type y, at object
> +.globl y
> +.align 4
> +y:
> +.long 0
> +.size y, 4
> +
> +.text
> +.globl main
> +.align 16, 0x90
> +.type main, at function
> +main:
> +movl $5, x
> +movl $7, y
> +
> +blah:
> +goo:
> +abs = 42
>
> Modified: lld/trunk/test/ELF/strip-all.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/strip-all.s?rev=261838&r1=261837&r2=261838&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/strip-all.s (original)
> +++ lld/trunk/test/ELF/strip-all.s Thu Feb 25 02:23:37 2016
> @@ -13,6 +13,10 @@
> #AFTER: .shstrtab
> #AFTER-NOT: .strtab
>
> +# Ignore --strip-all if -r is specified
> +#RUN: ld.lld %t.o --strip-all -r -o %t1
> +#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix
> BEFORE
> +
> # Test alias -s
> #RUN: ld.lld %t.o -s -o %t1
> #RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160225/9840e626/attachment.html>
More information about the llvm-commits
mailing list