[lld] r223359 - [ELF] Adjust ELF header entry symbol value if this symbol is microMIPS encoded

Simon Atanasyan simon at atanasyan.com
Thu Dec 4 05:43:35 PST 2014


Author: atanasyan
Date: Thu Dec  4 07:43:35 2014
New Revision: 223359

URL: http://llvm.org/viewvc/llvm-project?rev=223359&view=rev
Log:
[ELF] Adjust ELF header entry symbol value if this symbol is microMIPS encoded

To find an AtomLayout object for the given symbol I replace the
`Layout::findAtomAddrByName` method by `Layout::findAtomLayoutByName` method.

Added:
    lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test
    lld/trunk/test/elf/Mips/exe-fileheader-micro.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/Layout.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Dec  4 07:43:35 2014
@@ -236,12 +236,12 @@ public:
       si->doPreFlight();
   }
 
-  inline bool findAtomAddrByName(StringRef name, uint64_t &addr) override {
+  inline const AtomLayout *findAtomLayoutByName(StringRef name) const override {
     for (auto sec : _sections)
-      if (auto section = dyn_cast<Section<ELFT> >(sec))
-        if (section->findAtomAddrByName(name, addr))
-         return true;
-    return false;
+      if (auto section = dyn_cast<Section<ELFT>>(sec))
+        if (auto *al = section->findAtomLayoutByName(name))
+          return al;
+    return nullptr;
   }
 
   inline void setHeader(ELFHeader<ELFT> *elfHeader) { _elfHeader = elfHeader; }

Modified: lld/trunk/lib/ReaderWriter/ELF/Layout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Layout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Layout.h Thu Dec  4 07:43:35 2014
@@ -41,8 +41,8 @@ public:
   /// \returns A reference to the atom layout or an error. The atom layout will
   /// be updated as linking progresses.
   virtual ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) = 0;
-  /// find the Atom Address in the current layout
-  virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) = 0;
+  /// find the Atom in the current layout
+  virtual const AtomLayout *findAtomLayoutByName(StringRef name) const = 0;
   /// associates a section to a segment
   virtual void assignSectionsToSegments() = 0;
   /// associates a virtual address to the segment, section, and the atom

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Thu Dec  4 07:43:35 2014
@@ -32,12 +32,7 @@ protected:
   bool createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
 
   void finalizeDefaultAtomValues() override;
-
-  std::error_code setELFHeader() override {
-    ExecutableWriter<ELFT>::setELFHeader();
-    _writeHelper.setELFHeader(*this->_elfHeader);
-    return std::error_code();
-  }
+  std::error_code setELFHeader() override;
 
   LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) createSymbolTable() override;
   LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() override;
@@ -60,6 +55,25 @@ MipsExecutableWriter<ELFT>::MipsExecutab
       _mipsTargetLayout(layout) {}
 
 template <class ELFT>
+std::error_code MipsExecutableWriter<ELFT>::setELFHeader() {
+  std::error_code ec = ExecutableWriter<ELFT>::setELFHeader();
+  if (ec)
+    return ec;
+
+  StringRef entryName = _mipsContext.entrySymbolName();
+  if (const AtomLayout *al = this->_layout.findAtomLayoutByName(entryName)) {
+    const auto *ea = cast<DefinedAtom>(al->_atom);
+    if (ea->codeModel() == DefinedAtom::codeMipsMicro ||
+        ea->codeModel() == DefinedAtom::codeMipsMicroPIC)
+      // Adjust entry symbol value if this symbol is microMIPS encoded.
+      this->_elfHeader->e_entry(al->_virtualAddr + 1);
+  }
+
+  _writeHelper.setELFHeader(*this->_elfHeader);
+  return std::error_code();
+}
+
+template <class ELFT>
 void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
   // MIPS ABI requires to add to dynsym even undefined symbols
   // if they have a corresponding entries in a global part of GOT.

Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Thu Dec  4 07:43:35 2014
@@ -428,9 +428,10 @@ template <class ELFT> std::error_code Ou
   _elfHeader->e_shentsize(_shdrtab->entsize());
   _elfHeader->e_shnum(_shdrtab->numHeaders());
   _elfHeader->e_shstrndx(_shstrtab->ordinal());
-  uint64_t virtualAddr = 0;
-  _layout.findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
-  _elfHeader->e_entry(virtualAddr);
+  if (const auto *al = _layout.findAtomLayoutByName(_context.entrySymbolName()))
+    _elfHeader->e_entry(al->_virtualAddr);
+  else
+    _elfHeader->e_entry(0);
 
   return std::error_code();
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Dec  4 07:43:35 2014
@@ -95,7 +95,9 @@ public:
     this->_segmentType = segmentType;
   }
 
-  virtual bool findAtomAddrByName(StringRef, uint64_t &) { return false; }
+  virtual const AtomLayout *findAtomLayoutByName(StringRef) const {
+    return nullptr;
+  }
 
   void setOutputSection(OutputSection<ELFT> *os, bool isFirst = false) {
     _outputSection = os;
@@ -237,14 +239,11 @@ public:
   /// \brief Find the Atom address given a name, this is needed to properly
   ///  apply relocation. The section class calls this to find the atom address
   ///  to fix the relocation
-  virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
-    for (auto ai : _atoms) {
-      if (ai->_atom->name() == name) {
-        addr = ai->_virtualAddr;
-        return true;
-      }
-    }
-    return false;
+  const AtomLayout *findAtomLayoutByName(StringRef name) const override {
+    for (auto ai : _atoms)
+      if (ai->_atom->name() == name)
+        return ai;
+    return nullptr;
   }
 
   /// \brief Return the raw flags, we need this to sort segments

Added: lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test?rev=223359&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test (added)
+++ lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test Thu Dec  4 07:43:35 2014
@@ -0,0 +1,82 @@
+# Check ELF Header for shared library in case of microMIPS symbols.
+
+# Build shared library
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o
+# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
+
+# CHECK:      Format: ELF32-mips
+# CHECK-NEXT: Arch: mipsel
+# CHECK-NEXT: AddressSize: 32bit
+# CHECK-NEXT: LoadName:
+# CHECK-NEXT: ElfHeader {
+# CHECK-NEXT:   Ident {
+# CHECK-NEXT:    Magic: (7F 45 4C 46)
+# CHECK-NEXT:    Class: 32-bit (0x1)
+# CHECK-NEXT:    DataEncoding: LittleEndian (0x1)
+# CHECK-NEXT:    FileVersion: 1
+# CHECK-NEXT:    OS/ABI: SystemV (0x0)
+# CHECK-NEXT:    ABIVersion: 0
+# CHECK-NEXT:    Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Type: SharedObject (0x3)
+# CHECK-NEXT:  Machine: EM_MIPS (0x8)
+# CHECK-NEXT:  Version: 1
+# CHECK-NEXT:  Entry: 0x100
+# CHECK-NEXT:  ProgramHeaderOffset: 0x34
+# CHECK-NEXT:  SectionHeaderOffset: 0x2100
+# CHECK-NEXT:  Flags [ (0x72001007)
+# CHECK-NEXT:    EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:    EF_MIPS_ARCH_32R2 (0x70000000)
+# CHECK-NEXT:    EF_MIPS_CPIC (0x4)
+# CHECK-NEXT:    EF_MIPS_MICROMIPS (0x2000000)
+# CHECK-NEXT:    EF_MIPS_NOREORDER (0x1)
+# CHECK-NEXT:    EF_MIPS_PIC (0x2)
+# CHECK-NEXT:  ]
+# CHECK-NEXT:  HeaderSize: 52
+# CHECK-NEXT:  ProgramHeaderEntrySize: 32
+# CHECK-NEXT:  ProgramHeaderCount: 4
+# CHECK-NEXT:  SectionHeaderEntrySize: 40
+# CHECK-NEXT:  SectionHeaderCount: 11
+# CHECK-NEXT:  StringTableSectionIndex: 8
+# CHECK-NEXT:}
+
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x04
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Size:            0x00
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Size:            0x00
+  - Name:            .reginfo
+    Type:            SHT_MIPS_REGINFO
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x01
+    Size:            0x18
+  - Name:            .MIPS.abiflags
+    Type:            SHT_MIPS_ABIFLAGS
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x08
+    Size:            0x18
+
+Symbols:
+  Global:
+    - Name:            glob
+      Section:         .text
+      Other:           [ STO_MIPS_MICROMIPS ]

Added: lld/trunk/test/elf/Mips/exe-fileheader-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-fileheader-micro.test?rev=223359&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/exe-fileheader-micro.test (added)
+++ lld/trunk/test/elf/Mips/exe-fileheader-micro.test Thu Dec  4 07:43:35 2014
@@ -0,0 +1,69 @@
+# Check ELF Header for non-pic executable file in case
+# of microMIPS entry symbol.
+
+# Build executable
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe %t-o.o
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# CHECK:      Format: ELF32-mips
+# CHECK-NEXT: Arch: mipsel
+# CHECK-NEXT: AddressSize: 32bit
+# CHECK-NEXT: LoadName:
+# CHECK-NEXT: ElfHeader {
+# CHECK-NEXT:   Ident {
+# CHECK-NEXT:     Magic: (7F 45 4C 46)
+# CHECK-NEXT:     Class: 32-bit (0x1)
+# CHECK-NEXT:     DataEncoding: LittleEndian (0x1)
+# CHECK-NEXT:     FileVersion: 1
+# CHECK-NEXT:     OS/ABI: SystemV (0x0)
+# CHECK-NEXT:     ABIVersion: 0
+# CHECK-NEXT:     Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Type: Executable (0x2)
+# CHECK-NEXT:   Machine: EM_MIPS (0x8)
+# CHECK-NEXT:   Version: 1
+# CHECK-NEXT:   Entry: 0x400109
+# CHECK-NEXT:   ProgramHeaderOffset: 0x34
+# CHECK-NEXT:   SectionHeaderOffset: 0x1268
+# CHECK-NEXT:   Flags [ (0x72001005)
+# CHECK-NEXT:     EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:     EF_MIPS_ARCH_32R2 (0x70000000)
+# CHECK-NEXT:     EF_MIPS_CPIC (0x4)
+# CHECK-NEXT:     EF_MIPS_MICROMIPS (0x2000000)
+# CHECK-NEXT:     EF_MIPS_NOREORDER (0x1)
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   HeaderSize: 52
+# CHECK-NEXT:   ProgramHeaderEntrySize: 32
+# CHECK-NEXT:   ProgramHeaderCount: 5
+# CHECK-NEXT:   SectionHeaderEntrySize: 40
+# CHECK-NEXT:   SectionHeaderCount: 11
+# CHECK-NEXT:   StringTableSectionIndex: 8
+# CHECK-NEXT: }
+
+# o.o
+---
+FileHeader:
+  Class:          ELFCLASS32
+  Data:           ELFDATA2LSB
+  Type:           ET_REL
+  Machine:        EM_MIPS
+  Flags:          [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                    EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
+Sections:
+  - Name:         .text
+    Type:         SHT_PROGBITS
+    Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign: 0x04
+    Size:         0x08
+
+Symbols:
+  Local:
+    - Name:       .text
+      Type:       STT_SECTION
+      Section:    .text
+  Global:
+    - Name:       glob
+      Section:    .text
+      Other:      [ STO_MIPS_MICROMIPS ]
+...





More information about the llvm-commits mailing list