[lld] r252275 - [ELF2] Add GOT section for MIPS target.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 5 23:43:04 PST 2015


Author: ikudrin
Date: Fri Nov  6 01:43:03 2015
New Revision: 252275

URL: http://llvm.org/viewvc/llvm-project?rev=252275&view=rev
Log:
[ELF2] Add GOT section for MIPS target.

This patch implements R_MIPS_GOT16 relocation for global symbols in order to
generate some entries in GOT. Only reserved and global entries are supported
for now. For the detailed description about GOT in MIPS, see "Global Offset
Table" in Chapter 5 in the followin document:
ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf

In addition, the platform specific symbol "_gp" is added, see "Global Data
Symbols" in Chapter 6 in the aforementioned document.

Differential revision: http://reviews.llvm.org/D14211

Added:
    lld/trunk/test/elf2/mips-got-relocs.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/basic-mips.s

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Nov  6 01:43:03 2015
@@ -251,6 +251,13 @@ template <class ELFT> void LinkerDriver:
     Symtab.addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
   }
 
+  // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
+  // so that it points to an absolute address which is relative to GOT.
+  // See "Global Data Symbols" in Chapter 6 in the following document:
+  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+  if (Config->EMachine == EM_MIPS)
+    Symtab.addAbsoluteSym("_gp", DefinedAbsolute<ELFT>::MipsGp);
+
   for (std::unique_ptr<InputFile> &F : Files)
     Symtab.addFile(std::move(F));
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Nov  6 01:43:03 2015
@@ -72,11 +72,13 @@ template <class ELFT>
 GotSection<ELFT>::GotSection()
     : OutputSectionBase<ELFT>(".got", llvm::ELF::SHT_PROGBITS,
                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) {
+  if (Config->EMachine == EM_MIPS)
+    this->Header.sh_flags |= llvm::ELF::SHF_MIPS_GPREL;
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
-  Sym->GotIndex = Entries.size();
+  Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
   Entries.push_back(Sym);
 }
 
@@ -86,11 +88,23 @@ GotSection<ELFT>::getEntryAddr(const Sym
   return this->getVA() + B.GotIndex * sizeof(uintX_t);
 }
 
+template <class ELFT> void GotSection<ELFT>::finalize() {
+  this->Header.sh_size =
+      (Target->getGotHeaderEntriesNum() + Entries.size()) * sizeof(uintX_t);
+}
+
 template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
+  Target->writeGotHeaderEntries(Buf);
+  Buf += Target->getGotHeaderEntriesNum() * sizeof(uintX_t);
   for (const SymbolBody *B : Entries) {
     uint8_t *Entry = Buf;
     Buf += sizeof(uintX_t);
-    if (canBePreempted(B, false))
+    // MIPS has special rules to fill up GOT entries.
+    // See "Global Offset Table" in Chapter 5 in the following document
+    // for detailed description:
+    // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+    // As the first approach, we can just store addresses for all symbols.
+    if (Config->EMachine != EM_MIPS && canBePreempted(B, false))
       continue; // The dynamic linker will take care of it.
     uintX_t VA = getSymVA<ELFT>(*B);
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Nov  6 01:43:03 2015
@@ -113,9 +113,7 @@ template <class ELFT> class GotSection f
 
 public:
   GotSection();
-  void finalize() override {
-    this->Header.sh_size = Entries.size() * sizeof(uintX_t);
-  }
+  void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const { return Entries.empty(); }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Nov  6 01:43:03 2015
@@ -71,6 +71,12 @@ SymbolBody *SymbolTable<ELFT>::addUndefi
 }
 
 template <class ELFT>
+void SymbolTable<ELFT>::addAbsoluteSym(StringRef Name,
+                                       typename ELFFile<ELFT>::Elf_Sym &ESym) {
+  resolve(new (Alloc) DefinedAbsolute<ELFT>(Name, ESym));
+}
+
+template <class ELFT>
 void SymbolTable<ELFT>::addSyntheticSym(StringRef Name,
                                         OutputSectionBase<ELFT> &Section,
                                         typename ELFFile<ELFT>::uintX_t Value) {

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Fri Nov  6 01:43:03 2015
@@ -50,6 +50,8 @@ public:
 
   SymbolBody *addUndefined(StringRef Name);
   SymbolBody *addUndefinedOpt(StringRef Name);
+  void addAbsoluteSym(StringRef Name,
+                      typename llvm::object::ELFFile<ELFT>::Elf_Sym &ESym);
   void addSyntheticSym(StringRef Name, OutputSectionBase<ELFT> &Section,
                        typename llvm::object::ELFFile<ELFT>::uintX_t Value);
   void addIgnoredSym(StringRef Name);

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Nov  6 01:43:03 2015
@@ -177,6 +177,11 @@ template <class ELFT> class DefinedAbsol
 public:
   static Elf_Sym IgnoreUndef;
 
+  // The content for _gp symbol for MIPS target.
+  // The symbol has to be added early to reserve a place in symbol tables.
+  // The value of the symbol is computed later by Writer.
+  static Elf_Sym MipsGp;
+
   DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
       : Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
 
@@ -188,6 +193,9 @@ public:
 template <class ELFT>
 typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::IgnoreUndef;
 
+template <class ELFT>
+typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::MipsGp;
+
 template <class ELFT> class DefinedCommon : public Defined<ELFT> {
   typedef ELFSymbolBody<ELFT> Base;
   typedef typename Base::Elf_Sym Elf_Sym;

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Nov  6 01:43:03 2015
@@ -35,6 +35,14 @@ namespace elf2 {
 
 std::unique_ptr<TargetInfo> Target;
 
+template <bool IsLE> static uint32_t read32(const uint8_t *L);
+template <> uint32_t read32<true>(const uint8_t *L) { return read32le(L); }
+template <> uint32_t read32<false>(const uint8_t *L) { return read32be(L); }
+
+template <bool IsLE> static void write32(uint8_t *L, uint32_t V);
+template <> void write32<true>(uint8_t *L, uint32_t V) { write32le(L, V); }
+template <> void write32<false>(uint8_t *L, uint32_t V) { write32be(L, V); }
+
 static void add32le(uint8_t *L, int32_t V) { write32le(L, read32le(L) + V); }
 static void add32be(uint8_t *L, int32_t V) { write32be(L, read32be(L) + V); }
 static void or32le(uint8_t *L, int32_t V) { write32le(L, read32le(L) | V); }
@@ -108,6 +116,7 @@ public:
 template <class ELFT> class MipsTargetInfo final : public TargetInfo {
 public:
   MipsTargetInfo();
+  void writeGotHeaderEntries(uint8_t *Buf) const override;
   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                          uint64_t PltEntryAddr) const override;
@@ -155,6 +164,8 @@ bool TargetInfo::relocPointsToGot(uint32
 
 bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
 
+void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {}
+
 X86TargetInfo::X86TargetInfo() {
   PCRelReloc = R_386_PC32;
   GotReloc = R_386_GLOB_DAT;
@@ -670,6 +681,16 @@ void AArch64TargetInfo::relocateOne(uint
 
 template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
   PageSize = 65536;
+  GotRefReloc = R_MIPS_GOT16;
+  GotHeaderEntriesNum = 2;
+}
+
+template <class ELFT>
+void MipsTargetInfo<ELFT>::writeGotHeaderEntries(uint8_t *Buf) const {
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Off Elf_Off;
+  auto *P = reinterpret_cast<Elf_Off *>(Buf);
+  // Module pointer
+  P[1] = ELFT::Is64Bits ? 0x8000000000000000 : 0x80000000;
 }
 
 template <class ELFT>
@@ -684,7 +705,7 @@ void MipsTargetInfo<ELFT>::writePltEntry
 template <class ELFT>
 bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,
                                          const SymbolBody &S) const {
-  return false;
+  return Type == R_MIPS_GOT16;
 }
 
 template <class ELFT>
@@ -702,9 +723,27 @@ void MipsTargetInfo<ELFT>::relocateOne(u
   case R_MIPS_32:
     add32<IsLE>(Loc, SA);
     break;
+  case R_MIPS_GOT16: {
+    int64_t V = SA - getMipsGpAddr<ELFT>();
+    if (!isInt<16>(V))
+      error("Relocation R_MIPS_GOT16 out of range");
+    write32<IsLE>(Loc, (read32<IsLE>(Loc) & 0xffff0000) | (V & 0xffff));
+    break;
+  }
   default:
     error("unrecognized reloc " + Twine(Type));
   }
 }
+
+template <class ELFT>
+typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr() {
+  const unsigned GPOffset = 0x7ff0;
+  return Out<ELFT>::Got->getVA() ? (Out<ELFT>::Got->getVA() + GPOffset) : 0;
+}
+
+template uint32_t getMipsGpAddr<ELF32LE>();
+template uint32_t getMipsGpAddr<ELF32BE>();
+template uint64_t getMipsGpAddr<ELF64LE>();
+template uint64_t getMipsGpAddr<ELF64BE>();
 }
 }

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Nov  6 01:43:03 2015
@@ -11,6 +11,7 @@
 #define LLD_ELF_TARGET_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ELF.h"
 
 #include <memory>
 
@@ -31,7 +32,9 @@ public:
   unsigned getPltZeroEntrySize() const { return PltZeroEntrySize; }
   unsigned getPltEntrySize() const { return PltEntrySize; }
   bool supportsLazyRelocations() const { return LazyRelocations; }
+  unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; }
   virtual unsigned getPLTRefReloc(unsigned Type) const;
+  virtual void writeGotHeaderEntries(uint8_t *Buf) const;
   virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0;
   virtual void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                                  uint64_t PltEntryAddr) const = 0;
@@ -66,11 +69,15 @@ protected:
   unsigned RelativeReloc;
   unsigned PltEntrySize = 8;
   unsigned PltZeroEntrySize = 0;
+  unsigned GotHeaderEntriesNum = 0;
   bool LazyRelocations = false;
 };
 
 uint64_t getPPC64TocBase();
 
+template <class ELFT>
+typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr();
+
 extern std::unique_ptr<TargetInfo> Target;
 TargetInfo *createTarget();
 }

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov  6 01:43:03 2015
@@ -225,6 +225,15 @@ void Writer<ELFT>::scanRelocs(
       }
     }
 
+    if (Config->EMachine == EM_MIPS && NeedsGot) {
+      // MIPS ABI has special rules to process GOT entries
+      // and doesn't require relocation entries for them.
+      // See "Global Offset Table" in Chapter 5 in the following document
+      // for detailed description:
+      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+      Body->setUsedInDynamicReloc();
+      continue;
+    }
     bool CBP = canBePreempted(Body, NeedsGot);
     if (!CBP && (!Config->Shared || Target->isRelRelative(Type)))
       continue;
@@ -762,6 +771,10 @@ template <class ELFT> void Writer<ELFT>:
   // Add space for section headers.
   SectionHeaderOff = RoundUpToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4);
   FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
+
+  // Update MIPS _gp absolute symbol so that it points to the static data.
+  if (Config->EMachine == EM_MIPS)
+    DefinedAbsolute<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
 }
 
 // Returns the number of PHDR entries.

Modified: lld/trunk/test/elf2/basic-mips.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic-mips.s?rev=252275&r1=252274&r2=252275&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic-mips.s (original)
+++ lld/trunk/test/elf2/basic-mips.s Fri Nov  6 01:43:03 2015
@@ -27,7 +27,7 @@ __start:
 # CHECK-NEXT:   Version: 1
 # CHECK-NEXT:   Entry: 0x20000
 # CHECK-NEXT:   ProgramHeaderOffset: 0x34
-# CHECK-NEXT:   SectionHeaderOffset: 0x20070
+# CHECK-NEXT:   SectionHeaderOffset: 0x20084
 # CHECK-NEXT:   Flags [ (0x0)
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   HeaderSize: 52
@@ -138,7 +138,7 @@ __start:
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
 # CHECK-NEXT:     Offset: 0x20000
-# CHECK-NEXT:     Size: 32
+# CHECK-NEXT:     Size: 48
 # CHECK-NEXT:     Link: 8
 # CHECK-NEXT:     Info: 1
 # CHECK-NEXT:     AddressAlignment: 4
@@ -151,7 +151,7 @@ __start:
 # CHECK-NEXT:     Flags [ (0x0)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x20020
+# CHECK-NEXT:     Offset: 0x20030
 # CHECK-NEXT:     Size: 68
 # CHECK-NEXT:     Link: 0
 # CHECK-NEXT:     Info: 0
@@ -165,8 +165,8 @@ __start:
 # CHECK-NEXT:     Flags [ (0x0)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x20064
-# CHECK-NEXT:     Size: 9
+# CHECK-NEXT:     Offset: 0x20074
+# CHECK-NEXT:     Size: 13
 # CHECK-NEXT:     Link: 0
 # CHECK-NEXT:     Info: 0
 # CHECK-NEXT:     AddressAlignment: 1
@@ -184,6 +184,15 @@ __start:
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: _gp
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local (0x0)
+# CHECK-NEXT:     Type: None (0x0)
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Absolute (0xFFF1)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: __start
 # CHECK-NEXT:     Value: 0x20000
 # CHECK-NEXT:     Size: 0

Added: lld/trunk/test/elf2/mips-got-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/mips-got-relocs.s?rev=252275&view=auto
==============================================================================
--- lld/trunk/test/elf2/mips-got-relocs.s (added)
+++ lld/trunk/test/elf2/mips-got-relocs.s Fri Nov  6 01:43:03 2015
@@ -0,0 +1,99 @@
+# Check R_MIPS_GOT16 relocation calculation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
+# RUN: ld.lld2 %t-be.o -o %t-be.exe
+# RUN: llvm-objdump -section-headers -t %t-be.exe | FileCheck -check-prefix=EXE_SYM %s
+# RUN: llvm-objdump -s -section=.got %t-be.exe | FileCheck -check-prefix=EXE_GOT_BE %s
+# RUN: llvm-objdump -d %t-be.exe | FileCheck -check-prefix=EXE_DIS_BE %s
+# RUN: llvm-readobj -relocations %t-be.exe | FileCheck -check-prefix=NORELOC %s
+# RUN: llvm-readobj -sections %t-be.exe | FileCheck -check-prefix=SHFLAGS %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
+# RUN: ld.lld2 %t-el.o -o %t-el.exe
+# RUN: llvm-objdump -section-headers -t %t-el.exe | FileCheck -check-prefix=EXE_SYM %s
+# RUN: llvm-objdump -s -section=.got %t-el.exe | FileCheck -check-prefix=EXE_GOT_EL %s
+# RUN: llvm-objdump -d %t-el.exe | FileCheck -check-prefix=EXE_DIS_EL %s
+# RUN: llvm-readobj -relocations %t-el.exe | FileCheck -check-prefix=NORELOC %s
+# RUN: llvm-readobj -sections %t-el.exe | FileCheck -check-prefix=SHFLAGS %s
+
+# RUN: ld.lld2 -shared %t-be.o -o %t-be.so
+# RUN: llvm-objdump -section-headers -t %t-be.so | FileCheck -check-prefix=DSO_SYM %s
+# RUN: llvm-objdump -s -section=.got %t-be.so | FileCheck -check-prefix=DSO_GOT_BE %s
+# RUN: llvm-objdump -d %t-be.so | FileCheck -check-prefix=DSO_DIS_BE %s
+# RUN: llvm-readobj -relocations %t-be.so | FileCheck -check-prefix=NORELOC %s
+# RUN: llvm-readobj -sections %t-be.so | FileCheck -check-prefix=SHFLAGS %s
+
+# RUN: ld.lld2 -shared %t-el.o -o %t-el.so
+# RUN: llvm-objdump -section-headers -t %t-el.so | FileCheck -check-prefix=DSO_SYM %s
+# RUN: llvm-objdump -s -section=.got %t-el.so | FileCheck -check-prefix=DSO_GOT_EL %s
+# RUN: llvm-objdump -d %t-el.so | FileCheck -check-prefix=DSO_DIS_EL %s
+# RUN: llvm-readobj -relocations %t-el.so | FileCheck -check-prefix=NORELOC %s
+# RUN: llvm-readobj -sections %t-el.so | FileCheck -check-prefix=SHFLAGS %s
+
+# REQUIRES: mips
+
+  .text
+  .globl  __start
+__start:
+  lui $2, %got(v1)
+
+  .data
+  .globl v1
+  .type  v1, at object
+  .size  v1,4
+v1:
+  .word 0
+
+# EXE_SYM: Sections:
+# EXE_SYM: .got 0000000c 0000000000030004 DATA
+# EXE_SYM: SYMBOL TABLE:
+# EXE_SYM: 00037ff4         *ABS*		 00000000 _gp
+#          ^-- .got + GP offset (0x7ff0)
+# EXE_SYM: 00030000 g       .data		 00000004 v1
+
+# EXE_GOT_BE: Contents of section .got:
+# EXE_GOT_BE:  30004 00000000 80000000 00030000
+#                    ^        ^        ^-- v1 (0x30000)
+#                    |        +-- Module pointer (0x80000000)
+#                    +-- Lazy resolver (0x0)
+
+# EXE_GOT_EL: Contents of section .got:
+# EXE_GOT_EL:  30004 00000000 00000080 00000300
+#                    ^        ^        ^-- v1 (0x30000)
+#                    |        +-- Module pointer (0x80000000)
+#                    +-- Lazy resolver (0x0)
+
+# v1GotAddr (0x3000c) - _gp (0x37ff4) = -0x7fe8 => 0x8018 = 32792
+# EXE_DIS_BE:  20000:  3c 02 80 18  lui $2, 32792
+# EXE_DIS_EL:  20000:  18 80 02 3c  lui $2, 32792
+
+# DSO_SYM: Sections:
+# DSO_SYM: .got 0000000c 0000000000020034 DATA
+# DSO_SYM: SYMBOL TABLE:
+# DSO_SYM: 00028024         *ABS*		 00000000 _gp
+#          ^-- .got + GP offset (0x7ff0)
+# DSO_SYM: 00020000 g       .data		 00000004 v1
+
+# DSO_GOT_BE: Contents of section .got:
+# DSO_GOT_BE:  20034 00000000 80000000 00020000
+#                    ^        ^        ^-- v1 (0x20000)
+#                    |        +-- Module pointer (0x80000000)
+#                    +-- Lazy resolver (0x0)
+
+# DSO_GOT_EL: Contents of section .got:
+# DSO_GOT_EL:  20034 00000000 00000080 00000200
+#                    ^        ^        ^-- v1 (0x20000)
+#                    |        +-- Module pointer (0x80000000)
+#                    +-- Lazy resolver (0x0)
+
+# v1GotAddr (0x2003c) - _gp (0x28024) = -0x7fe8 => 0x8018 = 32792
+# DSO_DIS_BE:  10000:  3c 02 80 18  lui $2, 32792
+# DSO_DIS_EL:  10000:  18 80 02 3c  lui $2, 32792
+
+# NORELOC:      Relocations [
+# NORELOC-NEXT: ]
+
+# SHFLAGS:      Name: .got
+# SHFLAGS-NEXT: Type: SHT_PROGBITS
+# SHFLAGS-NEXT: Flags [ (0x10000003)
+#                        ^-- SHF_MIPS_GPREL | SHF_ALLOC | SHF_WRITE




More information about the llvm-commits mailing list