[lld] r229442 - [Mips] Read GP0 value from .MIPS.options section

Simon Atanasyan simon at atanasyan.com
Mon Feb 16 13:52:44 PST 2015


Author: atanasyan
Date: Mon Feb 16 15:52:43 2015
New Revision: 229442

URL: http://llvm.org/viewvc/llvm-project?rev=229442&view=rev
Log:
[Mips] Read GP0 value from .MIPS.options section

Added:
    lld/trunk/test/elf/Mips/mips-options-gp0.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=229442&r1=229441&r2=229442&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Mon Feb 16 15:52:43 2015
@@ -24,15 +24,26 @@ struct Elf_RegInfo<ELFType<TargetEndiann
   LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
   Elf_Word ri_gprmask;     // bit-mask of used general registers
   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
-  Elf_Sword ri_gp_value;   // gp register value
+  Elf_Addr ri_gp_value;    // gp register value
 };
 
 template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign>
 struct Elf_RegInfo<ELFType<TargetEndianness, MaxAlign, true>> {
   LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
   Elf_Word ri_gprmask;     // bit-mask of used general registers
+  Elf_Word ri_pad;         // unused padding field
   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
-  Elf_Sword ri_gp_value;   // gp register value
+  Elf_Addr ri_gp_value;    // gp register value
+};
+
+template <class ELFT> struct Elf_Mips_Options {
+  LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment,
+                        ELFT::Is64Bits)
+  uint8_t kind;     // Determines interpretation of variable part of descriptor
+  uint8_t size;     // Byte size of descriptor, including this header
+  Elf_Half section; // Section header index of section affected,
+                    // or 0 for global options
+  Elf_Word info;    // Kind-specific information
 };
 
 } // end namespace object.
@@ -146,13 +157,34 @@ private:
   }
 
   std::error_code readAuxData() {
-    if (const Elf_Shdr *sec = findSectionByFlags(llvm::ELF::SHF_TLS)) {
+    using namespace llvm::ELF;
+    if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
       _tpOff = sec->sh_addr + TP_OFFSET;
       _dtpOff = sec->sh_addr + DTP_OFFSET;
     }
-    if (const Elf_Shdr *sec = findSectionByType(llvm::ELF::SHT_MIPS_REGINFO)) {
-      typedef llvm::object::Elf_RegInfo<ELFT> Elf_RegInfo;
 
+    typedef llvm::object::Elf_RegInfo<ELFT> Elf_RegInfo;
+    typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
+
+    if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
+      auto contents = this->getSectionContents(sec);
+      if (std::error_code ec = contents.getError())
+        return ec;
+
+      ArrayRef<uint8_t> raw = contents.get();
+      while (!raw.empty()) {
+        if (raw.size() < sizeof(Elf_Mips_Options))
+          return make_dynamic_error_code(
+              StringRef("Invalid size of MIPS_OPTIONS section"));
+
+        const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
+        if (opt->kind == 1/*ODK_REGINFO*/) {
+          _gp0 = reinterpret_cast<const Elf_RegInfo *>(opt + 1)->ri_gp_value;
+          break;
+        }
+        raw = raw.slice(opt->size);
+      }
+    } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
       auto contents = this->getSectionContents(sec);
       if (std::error_code ec = contents.getError())
         return ec;

Added: lld/trunk/test/elf/Mips/mips-options-gp0.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/mips-options-gp0.test?rev=229442&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/mips-options-gp0.test (added)
+++ lld/trunk/test/elf/Mips/mips-options-gp0.test Mon Feb 16 15:52:43 2015
@@ -0,0 +1,78 @@
+# Check reading GP0 value from .MIPS.options section
+#
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -e G1 -shared -o %t.so %t.o
+# RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=SEC %s
+
+# SYM:      Name: L1 (1)
+# SYM-NEXT: Value: 0xCC
+# SYM-NEXT: Size: 4
+# SYM-NEXT: Binding: Local (0x0)
+# SYM-NEXT: Type: Function (0x2)
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: .text (0x4)
+
+# SYM:      Name: _gp (34)
+# SYM-NEXT: Value: 0x8FF0
+# SYM-NEXT: Size: 0
+# SYM-NEXT: Binding: Global (0x1)
+# SYM-NEXT: Type: Object (0x1)
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: Absolute (0xFFF1)
+
+# 0xffff80dc == 0x0 (addend) + 0x00cc (L1) + 0x1000 (GP0) - 0x8ff0 (_gp)
+# SEC:      Contents of section .rodata:
+# SEC-NEXT:  00d4 dc80ffff 00000000 00000000 00000000  ................
+
+!ELF
+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 ]
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+  AddressAlign: 0x04
+  Size:         0x08
+
+- Name:         .rodata
+  Type:         SHT_PROGBITS
+  Flags:        [ SHF_ALLOC ]
+  AddressAlign: 0x04
+  Size:         16
+
+- Name:         .rel.rodata
+  Type:         SHT_REL
+  Link:         .symtab
+  Info:         .rodata
+  AddressAlign: 0x04
+  Relocations:
+    - Offset:      0
+      Symbol:      L1
+      Type:        R_MIPS_GPREL32
+
+- Name:         .MIPS.options
+  Type:         SHT_MIPS_OPTIONS
+  Flags:        [ SHF_ALLOC ]
+  AddressAlign: 0x01
+  Content:      "0128000000000000000000000000000000000000000000000000000000100000"
+
+Symbols:
+  Local:
+    - Name:     L1
+      Section:  .text
+      Value:    0x00
+      Size:     0x04
+    - Name:     .rodata
+      Type:     STT_SECTION
+      Section:  .rodata
+  Global:
+    - Name:     G1
+      Section:  .text
+      Value:    0x04
+      Size:     0x04





More information about the llvm-commits mailing list