From 2903a8a11f9ef0782867fc7efff07b705ea75838 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Mon, 12 Dec 2016 21:34:11 +0000 Subject: [PATCH] [ELF][MIPS] Calculate default _gp value relative to the GPREL section with the lowest address llvm-svn: 289471 --- lld/ELF/Writer.cpp | 12 ++++++++++-- lld/test/ELF/mips-gp-lowest.s | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/mips-gp-lowest.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c63b883..d1c1ecd 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1490,8 +1490,16 @@ template void Writer::fixAbsoluteSymbols() { // Setup MIPS _gp_disp/__gnu_local_gp symbols which should // be equal to the _gp symbol's value. if (Config->EMachine == EM_MIPS) { - if (!ElfSym::MipsGp->Value) - ElfSym::MipsGp->Value = In::MipsGot->getVA() + 0x7ff0; + if (!ElfSym::MipsGp->Value) { + // Find GP-relative section with the lowest address + // and use this address to calculate default _gp value. + uintX_t Gp = -1; + for (const OutputSectionBase * OS : OutputSections) + if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp) + Gp = OS->Addr; + if (Gp != (uintX_t)-1) + ElfSym::MipsGp->Value = Gp + 0x7ff0; + } if (ElfSym::MipsGpDisp) ElfSym::MipsGpDisp->Value = ElfSym::MipsGp->Value; if (ElfSym::MipsLocalGp) diff --git a/lld/test/ELF/mips-gp-lowest.s b/lld/test/ELF/mips-gp-lowest.s new file mode 100644 index 0000000..b3d30aa --- /dev/null +++ b/lld/test/ELF/mips-gp-lowest.s @@ -0,0 +1,44 @@ +# Check that default _gp value is calculated relative +# to the GP-relative section with the lowest address. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .sdata : { *(.sdata) } \ +# RUN: .got : { *(.got) } }" > %t.rel.script +# RUN: ld.lld %t.o --script %t.rel.script -shared -o %t.so +# RUN: llvm-readobj -s -t %t.so | FileCheck %s + +# REQUIRES: mips + + .text + .global foo +foo: + lui $gp, %call16(foo) + + .sdata + .word 0 + +# CHECK: Section { +# CHECK: Name: .sdata +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_MIPS_GPREL +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0xDD +# CHECK: } +# CHECK: Section { +# CHECK: Name: .got +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_MIPS_GPREL +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0xE4 +# CHECK: } + +# CHECK: Name: _gp (5) +# CHECK-NEXT: Value: 0x80CD +# ^-- 0xDD + 0x7ff0 -- 2.7.4