diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index b5ade14715c69261d2a4f7e7bc2a2248f00cf8b1..1b3cb2dc2265c1a7769f2d4f497c0f19a645ba7d 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -403,10 +403,10 @@ template struct ElfSym { static DefinedRegular *End2; // The content for _gp symbol for MIPS target. - static DefinedRegular *MipsGp; + static SymbolBody *MipsGp; - static DefinedRegular *MipsLocalGp; - static DefinedRegular *MipsGpDisp; + static SymbolBody *MipsLocalGp; + static SymbolBody *MipsGpDisp; // __rel_iplt_start/__rel_iplt_end for signaling // where R_[*]_IRELATIVE relocations do live. @@ -420,9 +420,9 @@ template DefinedRegular *ElfSym::Edata; template DefinedRegular *ElfSym::Edata2; template DefinedRegular *ElfSym::End; template DefinedRegular *ElfSym::End2; -template DefinedRegular *ElfSym::MipsGp; -template DefinedRegular *ElfSym::MipsLocalGp; -template DefinedRegular *ElfSym::MipsGpDisp; +template SymbolBody *ElfSym::MipsGp; +template SymbolBody *ElfSym::MipsLocalGp; +template SymbolBody *ElfSym::MipsGpDisp; template SymbolBody *ElfSym::RelaIpltStart; template SymbolBody *ElfSym::RelaIpltEnd; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index bb1297c2177023d5ded6dc99bf708713cb36281d..ce272739f8df88db37531191750ed465b91b50e5 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1920,8 +1920,7 @@ bool MipsTargetInfo::isRelRelative(uint32_t Type) const { // a location that is relative to GOT. This function returns // the value for the symbol. template typename ELFT::uint getMipsGpAddr() { - unsigned GPOffset = 0x7ff0; - return Out::Got->getVA() + GPOffset; + return Out::Got->getVA() + MipsGPOffset; } template uint32_t getMipsGpAddr(); diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index b81db7d37b8d6e18bf62010493d29f1d842d2a92..7d23772f8f7e77cd615cf62a1846a304c9a91e53 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -119,6 +119,7 @@ private: uint64_t getPPC64TocBase(); +const unsigned MipsGPOffset = 0x7ff0; template typename ELFT::uint getMipsGpAddr(); extern TargetInfo *Target; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index d990990a2667d733cf24eb70bd3fc1fb1a76a6b8..4bbd812dec7d9ec35a3850e180a160c5f377d93e 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -795,6 +795,16 @@ bool Writer::isDiscarded(InputSectionBase *S) const { Script->isDiscarded(S); } +template +static SymbolBody * +addOptionalSynthetic(SymbolTable &Table, StringRef Name, + OutputSectionBase &Sec, typename ELFT::uint Val, + uint8_t Visibility) { + if (!Table.find(Name)) + return nullptr; + return Table.addSynthetic(Name, Sec, Val, Visibility); +} + // The beginning and the ending of .rel[a].plt section are marked // with __rel[a]_iplt_{start,end} symbols if it is a statically linked // executable. The runtime needs these symbols in order to resolve @@ -806,14 +816,13 @@ void Writer::addRelIpltSymbols() { if (isOutputDynamic() || !Out::RelaPlt) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - if (Symtab.find(S)) - ElfSym::RelaIpltStart = - Symtab.addSynthetic(S, *Out::RelaPlt, 0, STV_HIDDEN); + ElfSym::RelaIpltStart = + addOptionalSynthetic(Symtab, S, *Out::RelaPlt, 0, STV_HIDDEN); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - if (Symtab.find(S)) - ElfSym::RelaIpltEnd = Symtab.addSynthetic( - S, *Out::RelaPlt, DefinedSynthetic::SectionEnd, STV_HIDDEN); + ElfSym::RelaIpltEnd = + addOptionalSynthetic(Symtab, S, *Out::RelaPlt, + DefinedSynthetic::SectionEnd, STV_HIDDEN); } template static bool includeInSymtab(const SymbolBody &B) { @@ -932,16 +941,19 @@ template void Writer::addReservedSymbols() { // 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 - ElfSym::MipsGp = Symtab.addAbsolute("_gp", STV_DEFAULT); + ElfSym::MipsGp = + Symtab.addSynthetic("_gp", *Out::Got, MipsGPOffset, STV_DEFAULT); // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between // start of function and 'gp' pointer into GOT. - ElfSym::MipsGpDisp = Symtab.addIgnored("_gp_disp"); + ElfSym::MipsGpDisp = addOptionalSynthetic( + Symtab, "_gp_disp", *Out::Got, MipsGPOffset, STV_HIDDEN); // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' // pointer. This symbol is used in the code generated by .cpload pseudo-op // in case of using -mno-shared option. // https://sourceware.org/ml/binutils/2004-12/msg00094.html - ElfSym::MipsLocalGp = Symtab.addIgnored("__gnu_local_gp"); + ElfSym::MipsLocalGp = addOptionalSynthetic( + Symtab, "__gnu_local_gp", *Out::Got, MipsGPOffset, STV_HIDDEN); } // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -1515,16 +1527,6 @@ static uint16_t getELFType() { // to each section. This function fixes some predefined absolute // symbol values that depend on section address and size. template void Writer::fixAbsoluteSymbols() { - // Update MIPS _gp absolute symbol so that it points to the static data. - - if (Config->EMachine == EM_MIPS) { - ElfSym::MipsGp->Value = getMipsGpAddr(); - if (ElfSym::MipsLocalGp) - ElfSym::MipsLocalGp->Value = getMipsGpAddr(); - if (ElfSym::MipsGpDisp) - ElfSym::MipsGpDisp->Value = getMipsGpAddr(); - } - // _etext is the first location after the last read-only loadable segment. // _edata is the first location after the last read-write loadable segment. // _end is the first location after the uninitialized data region. diff --git a/lld/test/ELF/basic-mips.s b/lld/test/ELF/basic-mips.s index 0a1ff3011435ed7306b93a4bc12b054e548eebd3..1f6dcf240398570d56742b30e8b983ffb25be957 100644 --- a/lld/test/ELF/basic-mips.s +++ b/lld/test/ELF/basic-mips.s @@ -219,7 +219,7 @@ __start: # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: None (0x0) # CHECK-NEXT: Other: 0 -# CHECK-NEXT: Section: Absolute (0xFFF1) +# CHECK-NEXT: Section: .got # CHECK-NEXT: } # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ diff --git a/lld/test/ELF/mips-got-relocs.s b/lld/test/ELF/mips-got-relocs.s index 408a08536329f9eb177a3a37ed543f8d596d2d2d..0933dfea6e4b1f87ff57de6f5d57a0ee23a755d9 100644 --- a/lld/test/ELF/mips-got-relocs.s +++ b/lld/test/ELF/mips-got-relocs.s @@ -48,7 +48,7 @@ v1: # EXE_SYM: .got 0000000c 0000000000030000 DATA # EXE_SYM: SYMBOL TABLE: # EXE_SYM: 00040000 g .data 00000004 v1 -# EXE_SYM: 00037ff0 *ABS* 00000000 _gp +# EXE_SYM: 00037ff0 .got 00000000 _gp # ^-- .got + GP offset (0x7ff0) @@ -72,7 +72,7 @@ v1: # DSO_SYM: .got 0000000c 0000000000020000 DATA # DSO_SYM: SYMBOL TABLE: # DSO_SYM: 00030000 g .data 00000004 v1 -# DSO_SYM: 00027ff0 *ABS* 00000000 _gp +# DSO_SYM: 00027ff0 .got 00000000 _gp # ^-- .got + GP offset (0x7ff0) # DSO_GOT_BE: Contents of section .got: diff --git a/lld/test/ELF/mips-gp-disp.s b/lld/test/ELF/mips-gp-disp.s index 2110d7c04fd82fd18d6d2161a644222f88aec2f7..823ac5a9fa4938c3da53053fcb5bcd4eb5616d5f 100644 --- a/lld/test/ELF/mips-gp-disp.s +++ b/lld/test/ELF/mips-gp-disp.s @@ -24,7 +24,7 @@ # DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1 # DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752 # ^-- 0x37ff0 & 0xffff -# DIS: 00027ff0 *ABS* 00000000 _gp +# DIS: 00027ff0 .got 00000000 _gp # REL: Relocations [ # REL-NEXT: ] diff --git a/lld/test/ELF/mips-gp-local.s b/lld/test/ELF/mips-gp-local.s index 50c9865641605ab7609c08f66bf8e767f46f0879..d8453bcb480e971e3d0e10689b14b489b52889ac 100644 --- a/lld/test/ELF/mips-gp-local.s +++ b/lld/test/ELF/mips-gp-local.s @@ -11,7 +11,7 @@ # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 # CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752 -# CHECK: 00037ff0 *ABS* 00000000 _gp +# CHECK: 00037ff0 .got 00000000 _gp .text .globl __start diff --git a/lld/test/ELF/mips-gprel32-relocs.s b/lld/test/ELF/mips-gprel32-relocs.s index 4f93d50363c099988ad6fec0254a08d51e3f7c9d..da0474c5255ccd1963db07cdf219f1c3517cd387 100644 --- a/lld/test/ELF/mips-gprel32-relocs.s +++ b/lld/test/ELF/mips-gprel32-relocs.s @@ -28,4 +28,4 @@ v1: # CHECK: SYMBOL TABLE: # CHECK: 00010008 .text 00000000 bar # CHECK: 00010004 .text 00000000 foo -# CHECK: 00027ff0 *ABS* 00000000 _gp +# CHECK: 00027ff0 .got 00000000 _gp diff --git a/lld/test/ELF/mips-hilo-gp-disp.s b/lld/test/ELF/mips-hilo-gp-disp.s index 41d09b2b33a906688e640e5b79c89e0c261d2878..a9c7fd957dbc8dc1ca312229805e2d18fc79b285 100644 --- a/lld/test/ELF/mips-hilo-gp-disp.s +++ b/lld/test/ELF/mips-hilo-gp-disp.s @@ -27,7 +27,7 @@ __start: # EXE: SYMBOL TABLE: # EXE: 00020000 .text 00000000 __start # EXE: 00020010 .text 00000000 _foo -# EXE: 00037ff0 *ABS* 00000000 _gp +# EXE: 00037ff0 .got 00000000 _gp # SO: Disassembly of section .text: # SO-NEXT: __start: @@ -39,4 +39,4 @@ __start: # SO: SYMBOL TABLE: # SO: 00010000 .text 00000000 __start # SO: 00010010 .text 00000000 _foo -# SO: 00027ff0 *ABS* 00000000 _gp +# SO: 00027ff0 .got 00000000 _gp