[lld] r261838 - [ELF2] - Basic implementation of -r/--relocatable

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 00:23:38 PST 2016


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




More information about the llvm-commits mailing list