From 8396f72f7b07867fa61baed56723df8adaaf2ed7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 11 Apr 2016 20:34:27 +0000 Subject: [PATCH] Simplify handling of mips gp* symbols. Give them values instead of computing it during relocation. llvm-svn: 265986 --- lld/ELF/Config.h | 2 -- lld/ELF/InputSection.cpp | 10 ++++------ lld/ELF/Symbols.h | 5 +++++ lld/ELF/Writer.cpp | 16 +++++++++++----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 792a42febf0e..8295e7379be5 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -38,8 +38,6 @@ enum class BuildIdKind { None, Fnv1, Md5, Sha1 }; // Most fields are initialized by the driver. struct Configuration { SymbolBody *EntrySym = nullptr; - SymbolBody *MipsGpDisp = nullptr; - SymbolBody *MipsLocalGp = nullptr; InputFile *FirstElf = nullptr; llvm::StringRef DynamicLinker; llvm::StringRef Entry; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index c641957c6d4e..ba77b3e9d0d6 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -206,12 +206,10 @@ template static uintX_t adjustMipsSymVA(uint32_t Type, const elf::ObjectFile &File, const SymbolBody &Body, uintX_t AddrLoc, uintX_t SymVA) { - if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp) - return getMipsGpAddr() - AddrLoc; - if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp) - return getMipsGpAddr() - AddrLoc + 4; - if (&Body == Config->MipsLocalGp) - return getMipsGpAddr(); + if (Type == R_MIPS_HI16 && &Body == ElfSym::MipsGpDisp) + return SymVA - AddrLoc; + if (Type == R_MIPS_LO16 && &Body == ElfSym::MipsGpDisp) + return SymVA - AddrLoc + 4; if (Body.isLocal() && (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32)) // We need to adjust SymVA value in case of R_MIPS_GPREL16/32 // relocations because they use the following expression to calculate diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 6e22131c4621..b5ade14715c6 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -405,6 +405,9 @@ template struct ElfSym { // The content for _gp symbol for MIPS target. static DefinedRegular *MipsGp; + static DefinedRegular *MipsLocalGp; + static DefinedRegular *MipsGpDisp; + // __rel_iplt_start/__rel_iplt_end for signaling // where R_[*]_IRELATIVE relocations do live. static SymbolBody *RelaIpltStart; @@ -418,6 +421,8 @@ 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::RelaIpltStart; template SymbolBody *ElfSym::RelaIpltEnd; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b46b0786d3ea..483c069bb9db 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -454,8 +454,8 @@ void Writer::scanRelocs(InputSectionBase &C, ArrayRef Rels) { // pointer into GOT. __gnu_local_gp is equal to the current value of // the 'gp'. Therefore any relocations against them do not require // dynamic relocation. - if (Config->EMachine == EM_MIPS && - (&Body == Config->MipsGpDisp || &Body == Config->MipsLocalGp)) + if (Config->EMachine == EM_MIPS && (&Body == ElfSym::MipsGpDisp || + &Body == ElfSym::MipsLocalGp)) continue; if (Preemptible) { @@ -930,12 +930,12 @@ template void Writer::addReservedSymbols() { if (Config->EMachine == EM_MIPS) { // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between // start of function and 'gp' pointer into GOT. - Config->MipsGpDisp = Symtab.addIgnored("_gp_disp"); + ElfSym::MipsGpDisp = Symtab.addIgnored("_gp_disp"); // 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 - Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp"); + ElfSym::MipsLocalGp = Symtab.addIgnored("__gnu_local_gp"); } // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -1510,8 +1510,14 @@ static uint16_t getELFType() { // 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) + + 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.