[lld] r251914 - Two small fixes to copy relocation processing.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 3 06:13:40 PST 2015


Author: rafael
Date: Tue Nov  3 08:13:40 2015
New Revision: 251914

URL: http://llvm.org/viewvc/llvm-project?rev=251914&view=rev
Log:
Two small fixes to copy relocation processing.

* We can determine the alignment requirement.
* We have to update the bss alignment with it.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/Inputs/relocation-copy.s
    lld/trunk/test/elf2/relocation-copy.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Nov  3 08:13:40 2015
@@ -51,6 +51,20 @@ ELFFileBase<ELFT>::getSymbolsHelper(bool
   return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
 }
 
+template <class ELFT>
+uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
+  uint32_t Index = Sym.st_shndx;
+  if (Index == ELF::SHN_XINDEX)
+    Index = this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab,
+                                                     SymtabSHNDX);
+  else if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
+    return 0;
+
+  if (!Index)
+    error("Invalid section index");
+  return Index;
+}
+
 template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
   if (!Symtab)
     return;
@@ -176,7 +190,7 @@ void elf2::ObjectFile<ELFT>::initializeS
     case SHT_SYMTAB_SHNDX: {
       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
       error(ErrorOrTable);
-      SymtabSHNDX = *ErrorOrTable;
+      this->SymtabSHNDX = *ErrorOrTable;
       break;
     }
     case SHT_STRTAB:
@@ -219,14 +233,10 @@ template <class ELFT> void elf2::ObjectF
 template <class ELFT>
 InputSectionBase<ELFT> *
 elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
-  uint32_t Index = Sym.st_shndx;
-  if (Index == ELF::SHN_XINDEX)
-    Index = this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab,
-                                                     SymtabSHNDX);
-  else if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
+  uint32_t Index = this->getSectionIndex(Sym);
+  if (Index == 0)
     return nullptr;
-
-  if (Index >= Sections.size() || !Index || !Sections[Index])
+  if (Index >= Sections.size() || !Sections[Index])
     error("Invalid section index");
   return Sections[Index];
 }
@@ -313,6 +323,17 @@ SharedFile<ELFT>::SharedFile(MemoryBuffe
   AsNeeded = Config->AsNeeded;
 }
 
+template <class ELFT>
+const typename ELFFile<ELFT>::Elf_Shdr *
+SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
+  uint32_t Index = this->getSectionIndex(Sym);
+  if (Index == 0)
+    return nullptr;
+  ErrorOr<const Elf_Shdr *> Ret = this->ELFObj.getSection(Index);
+  error(Ret);
+  return *Ret;
+}
+
 template <class ELFT> void SharedFile<ELFT>::parseSoName() {
   typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
@@ -320,11 +341,22 @@ template <class ELFT> void SharedFile<EL
 
   const ELFFile<ELFT> Obj = this->ELFObj;
   for (const Elf_Shdr &Sec : Obj.sections()) {
-    uint32_t Type = Sec.sh_type;
-    if (Type == SHT_DYNSYM)
+    switch (Sec.sh_type) {
+    default:
+      continue;
+    case SHT_DYNSYM:
       this->Symtab = &Sec;
-    else if (Type == SHT_DYNAMIC)
+      break;
+    case SHT_DYNAMIC:
       DynamicSec = &Sec;
+      break;
+    case SHT_SYMTAB_SHNDX: {
+      ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
+      error(ErrorOrTable);
+      this->SymtabSHNDX = *ErrorOrTable;
+      break;
+    }
+    }
   }
 
   this->initStringTable();

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Tue Nov  3 08:13:40 2015
@@ -49,6 +49,8 @@ private:
 template <typename ELFT> class ELFFileBase : public InputFile {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
 
   ELFFileBase(Kind K, MemoryBufferRef M);
@@ -78,9 +80,12 @@ public:
 
   StringRef getStringTable() const { return StringTable; }
 
+  uint32_t getSectionIndex(const Elf_Sym &Sym) const;
+
 protected:
   llvm::object::ELFFile<ELFT> ELFObj;
   const Elf_Shdr *Symtab = nullptr;
+  ArrayRef<Elf_Word> SymtabSHNDX;
   StringRef StringTable;
   void initStringTable();
   Elf_Sym_Range getNonLocalSymbols();
@@ -135,8 +140,6 @@ private:
   // List of all sections defined by this file.
   std::vector<InputSectionBase<ELFT> *> Sections;
 
-  ArrayRef<Elf_Word> SymtabSHNDX;
-
   // List of all symbols referenced or defined by this file.
   std::vector<SymbolBody *> SymbolBodies;
 
@@ -168,6 +171,7 @@ template <class ELFT> class SharedFile :
   typedef ELFFileBase<ELFT> Base;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
 
   std::vector<SharedSymbol<ELFT>> SymbolBodies;
@@ -179,7 +183,7 @@ public:
   llvm::MutableArrayRef<SharedSymbol<ELFT>> getSharedSymbols() {
     return SymbolBodies;
   }
-
+  const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
   llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
 
   static bool classof(const InputFile *F) {

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Nov  3 08:13:40 2015
@@ -93,6 +93,10 @@ public:
     return std::max<uintX_t>(Header.sh_addralign, 1);
   }
   uint32_t getType() { return Header.sh_type; }
+  void updateAlign(uintX_t Align) {
+    if (Align > Header.sh_addralign)
+      Header.sh_addralign = Align;
+  }
 
   virtual void finalize() {}
   virtual void writeTo(uint8_t *Buf) = 0;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov  3 08:13:40 2015
@@ -404,14 +404,18 @@ template <class ELFT>
 static void addSharedCopySymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
+  typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
 
   uintX_t Off = Out<ELFT>::Bss->getSize();
   for (SharedSymbol<ELFT> *C : Syms) {
     const Elf_Sym &Sym = C->Sym;
-    // We don't know the exact alignment requirement for the data copied by a
-    // copy relocation, so align that to 16 byte boundaries that should be large
-    // enough unconditionally.
-    Off = RoundUpToAlignment(Off, 16);
+    const Elf_Shdr *Sec = C->File->getSection(Sym);
+    uintX_t SecAlign = Sec->sh_addralign;
+    uintX_t Align = Sym.st_value % SecAlign;
+    if (Align == 0)
+      Align = SecAlign;
+    Out<ELFT>::Bss->updateAlign(Align);
+    Off = RoundUpToAlignment(Off, Align);
     C->OffsetInBSS = Off;
     Off += Sym.st_size;
   }

Modified: lld/trunk/test/elf2/Inputs/relocation-copy.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/relocation-copy.s?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/test/elf2/Inputs/relocation-copy.s (original)
+++ lld/trunk/test/elf2/Inputs/relocation-copy.s Tue Nov  3 08:13:40 2015
@@ -2,14 +2,21 @@
 
 .type x, at object
 .globl x
-.align 4
+.align 16
 x:
 .long 0
 .size x, 4
 
 .type y, at object
 .globl y
-.align 4
+.align 16
 y:
 .long 0
 .size y, 4
+
+.type z, at object
+.globl z
+.align 4
+z:
+.long 0
+.size z, 4

Modified: lld/trunk/test/elf2/relocation-copy.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relocation-copy.s?rev=251914&r1=251913&r2=251914&view=diff
==============================================================================
--- lld/trunk/test/elf2/relocation-copy.s (original)
+++ lld/trunk/test/elf2/relocation-copy.s Tue Nov  3 08:13:40 2015
@@ -13,6 +13,7 @@
 main:
 movl $5, x
 movl $7, y
+movl $9, z
 
 // CHECK:      Name: .bss
 // CHECK-NEXT:  Type: SHT_NOBITS (0x8)
@@ -22,10 +23,10 @@ movl $7, y
 // CHECK-NEXT:  ]
 // CHECK-NEXT:  Address: 0x120A0
 // CHECK-NEXT:  Offset: 0x20A0
-// CHECK-NEXT:  Size: 20
+// CHECK-NEXT:  Size: 24
 // CHECK-NEXT:  Link: 0
 // CHECK-NEXT:  Info: 0
-// CHECK-NEXT:  AddressAlignment: 4
+// CHECK-NEXT:  AddressAlignment: 16
 // CHECK-NEXT:  EntrySize: 0
 
 // CHECK:      Relocations [
@@ -42,13 +43,21 @@ movl $7, y
 // CHECK-NEXT:       Symbol: y
 // CHECK-NEXT:       Addend: 0x0
 // CHECK-NEXT:     }
+// CHECK-NEXT:     Relocation {
+// CHECK-NEXT:       Offset:
+// CHECK-NEXT:       Type: R_X86_64_COPY
+// CHECK-NEXT:       Symbol: z
+// CHECK-NEXT:       Addend: 0x0
+// CHECK-NEXT:     }
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 // 73888 = 0x120A0
 // 16 is alignment here
 // 73904 = 0x120A0 + 16
+// 73908 = 0x120A0 + 16 + 4
 // CODE: Disassembly of section .text:
 // CODE-NEXT: main:
 // CODE-NEXT: 11000: c7 04 25 a0 20 01 00 05 00 00 00 movl $5, 73888
 // CODE-NEXT: 1100b: c7 04 25 b0 20 01 00 07 00 00 00 movl $7, 73904
+// CODE-NEXT: 11016: c7 04 25 b4 20 01 00 09 00 00 00 movl $9, 73908




More information about the llvm-commits mailing list