From owner-svn-src-stable-11@freebsd.org Sat Jun 17 19:00:13 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6931ABFF902; Sat, 17 Jun 2017 19:00:13 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 423FE74EBB; Sat, 17 Jun 2017 19:00:13 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v5HJ0C8F006204; Sat, 17 Jun 2017 19:00:12 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5HJ0CLR006202; Sat, 17 Jun 2017 19:00:12 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201706171900.v5HJ0CLR006202@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Sat, 17 Jun 2017 19:00:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r320060 - stable/11/contrib/llvm/tools/lld/ELF X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Jun 2017 19:00:13 -0000 Author: emaste Date: Sat Jun 17 19:00:12 2017 New Revision: 320060 URL: https://svnweb.freebsd.org/changeset/base/320060 Log: lld: Fix weak symbols on arm and aarch64 MFC r319955: lld: sort relocations No functional change; applied to facilitate merge of later LLD commit. MFC r319956: lld: Fix weak symbols on arm and aarch64 Given .weak target .global _start _start: b target The intention is that the branch goes to the instruction after the branch, effectively turning it on a nop. The branch adds the runtime PC, but we were adding it statically too. I noticed the oddity by inspection, but llvm-objdump seems to agree, since it now prints things like: b #-4 <_start+0x4> Obtained from: LLD r298797, r305212 Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Modified: stable/11/contrib/llvm/tools/lld/ELF/InputSection.cpp stable/11/contrib/llvm/tools/lld/ELF/Relocations.h Directory Properties: stable/11/ (props changed) Modified: stable/11/contrib/llvm/tools/lld/ELF/InputSection.cpp ============================================================================== --- stable/11/contrib/llvm/tools/lld/ELF/InputSection.cpp Sat Jun 17 17:42:52 2017 (r320059) +++ stable/11/contrib/llvm/tools/lld/ELF/InputSection.cpp Sat Jun 17 19:00:12 2017 (r320060) @@ -255,7 +255,7 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t uint32_t P) { switch (Type) { case R_ARM_THM_JUMP11: - return P + 2; + return P + 2 + A; case R_ARM_CALL: case R_ARM_JUMP24: case R_ARM_PC24: @@ -263,12 +263,12 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t case R_ARM_PREL31: case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: - return P + 4; + return P + 4 + A; case R_ARM_THM_CALL: // We don't want an interworking BLX to ARM - return P + 5; + return P + 5 + A; default: - return A; + return P + A; } } @@ -279,9 +279,9 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint case R_AARCH64_CONDBR19: case R_AARCH64_JUMP26: case R_AARCH64_TSTBR14: - return P + 4; + return P + 4 + A; default: - return A; + return P + A; } } @@ -290,82 +290,37 @@ static typename ELFT::uint getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, const SymbolBody &Body, RelExpr Expr) { switch (Expr) { - case R_HINT: - case R_TLSDESC_CALL: - llvm_unreachable("cannot relocate hint relocs"); - case R_TLSLD: - return In::Got->getTlsIndexOff() + A - In::Got->getSize(); - case R_TLSLD_PC: - return In::Got->getTlsIndexVA() + A - P; - case R_THUNK_ABS: - return Body.getThunkVA() + A; - case R_THUNK_PC: - case R_THUNK_PLT_PC: - return Body.getThunkVA() + A - P; - case R_PPC_TOC: - return getPPC64TocBase() + A; - case R_TLSGD: - return In::Got->getGlobalDynOffset(Body) + A - - In::Got->getSize(); - case R_TLSGD_PC: - return In::Got->getGlobalDynAddr(Body) + A - P; - case R_TLSDESC: - return In::Got->getGlobalDynAddr(Body) + A; - case R_TLSDESC_PAGE: - return getAArch64Page(In::Got->getGlobalDynAddr(Body) + A) - - getAArch64Page(P); - case R_PLT: - return Body.getPltVA() + A; - case R_PLT_PC: - case R_PPC_PLT_OPD: - return Body.getPltVA() + A - P; - case R_SIZE: - return Body.getSize() + A; + case R_ABS: + case R_RELAX_GOT_PC_NOPIC: + return Body.getVA(A); + case R_GOT: + case R_RELAX_TLS_GD_TO_IE_ABS: + return Body.getGotVA() + A; + case R_GOTONLY_PC: + return In::Got->getVA() + A - P; + case R_GOTONLY_PC_FROM_END: + return In::Got->getVA() + A - P + In::Got->getSize(); case R_GOTREL: return Body.getVA(A) - In::Got->getVA(); case R_GOTREL_FROM_END: return Body.getVA(A) - In::Got->getVA() - In::Got->getSize(); - case R_RELAX_TLS_GD_TO_IE_END: case R_GOT_FROM_END: + case R_RELAX_TLS_GD_TO_IE_END: return Body.getGotOffset() + A - In::Got->getSize(); - case R_RELAX_TLS_GD_TO_IE_ABS: - case R_GOT: - return Body.getGotVA() + A; - case R_RELAX_TLS_GD_TO_IE_PAGE_PC: + case R_GOT_OFF: + return Body.getGotOffset() + A; case R_GOT_PAGE_PC: + case R_RELAX_TLS_GD_TO_IE_PAGE_PC: return getAArch64Page(Body.getGotVA() + A) - getAArch64Page(P); - case R_RELAX_TLS_GD_TO_IE: case R_GOT_PC: + case R_RELAX_TLS_GD_TO_IE: return Body.getGotVA() + A - P; - case R_GOTONLY_PC: - return In::Got->getVA() + A - P; - case R_GOTONLY_PC_FROM_END: - return In::Got->getVA() + A - P + In::Got->getSize(); - case R_RELAX_TLS_LD_TO_LE: - case R_RELAX_TLS_IE_TO_LE: - case R_RELAX_TLS_GD_TO_LE: - case R_TLS: - // A weak undefined TLS symbol resolves to the base of the TLS - // block, i.e. gets a value of zero. If we pass --gc-sections to - // lld and .tbss is not referenced, it gets reclaimed and we don't - // create a TLS program header. Therefore, we resolve this - // statically to zero. - if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) && - Body.symbol()->isWeak()) - return 0; - if (Target->TcbSize) - return Body.getVA(A) + - alignTo(Target->TcbSize, Out::TlsPhdr->p_align); - return Body.getVA(A) - Out::TlsPhdr->p_memsz; - case R_RELAX_TLS_GD_TO_LE_NEG: - case R_NEG_TLS: - return Out::TlsPhdr->p_memsz - Body.getVA(A); - case R_ABS: - case R_RELAX_GOT_PC_NOPIC: - return Body.getVA(A); - case R_GOT_OFF: - return Body.getGotOffset() + A; + case R_HINT: + case R_TLSDESC_CALL: + llvm_unreachable("cannot relocate hint relocs"); + case R_MIPS_GOTREL: + return Body.getVA(A) - In::MipsGot->getGp(); case R_MIPS_GOT_LOCAL_PAGE: // If relocation against MIPS local symbol requires GOT entry, this entry // should be initialized by 'page address'. This address is high 16-bits @@ -381,8 +336,6 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, return In::MipsGot->getVA() + In::MipsGot->getBodyEntryOffset(Body, A) - In::MipsGot->getGp(); - case R_MIPS_GOTREL: - return Body.getVA(A) - In::MipsGot->getGp(); case R_MIPS_TLSGD: return In::MipsGot->getVA() + In::MipsGot->getTlsOffset() + In::MipsGot->getGlobalDynOffset(Body) - @@ -390,6 +343,36 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, case R_MIPS_TLSLD: return In::MipsGot->getVA() + In::MipsGot->getTlsOffset() + In::MipsGot->getTlsIndexOff() - In::MipsGot->getGp(); + case R_PAGE_PC: + case R_PLT_PAGE_PC: { + uint64_t Dest; + if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) + Dest = getAArch64Page(A); + else + Dest = getAArch64Page(Body.getVA(A)); + return Dest - getAArch64Page(P); + } + case R_PC: { + uint64_t Dest; + if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) { + // On ARM and AArch64 a branch to an undefined weak resolves to the + // next instruction, otherwise the place. + if (Config->EMachine == EM_ARM) + Dest = getARMUndefinedRelativeWeakVA(Type, A, P); + else if (Config->EMachine == EM_AARCH64) + Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P); + else + Dest = Body.getVA(A); + } else { + Dest = Body.getVA(A); + } + return Dest - P; + } + case R_PLT: + return Body.getPltVA() + A; + case R_PLT_PC: + case R_PPC_PLT_OPD: + return Body.getPltVA() + A - P; case R_PPC_OPD: { uint64_t SymVA = Body.getVA(A); // If we have an undefined weak symbol, we might get here with a symbol @@ -408,22 +391,50 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, } return SymVA - P; } - case R_PC: - if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) { - // On ARM and AArch64 a branch to an undefined weak resolves to the - // next instruction, otherwise the place. - if (Config->EMachine == EM_ARM) - return getARMUndefinedRelativeWeakVA(Type, A, P); - if (Config->EMachine == EM_AARCH64) - return getAArch64UndefinedRelativeWeakVA(Type, A, P); - } + case R_PPC_TOC: + return getPPC64TocBase() + A; case R_RELAX_GOT_PC: return Body.getVA(A) - P; - case R_PLT_PAGE_PC: - case R_PAGE_PC: - if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) - return getAArch64Page(A); - return getAArch64Page(Body.getVA(A)) - getAArch64Page(P); + case R_RELAX_TLS_GD_TO_LE: + case R_RELAX_TLS_IE_TO_LE: + case R_RELAX_TLS_LD_TO_LE: + case R_TLS: + // A weak undefined TLS symbol resolves to the base of the TLS + // block, i.e. gets a value of zero. If we pass --gc-sections to + // lld and .tbss is not referenced, it gets reclaimed and we don't + // create a TLS program header. Therefore, we resolve this + // statically to zero. + if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) && + Body.symbol()->isWeak()) + return 0; + if (Target->TcbSize) + return Body.getVA(A) + + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); + return Body.getVA(A) - Out::TlsPhdr->p_memsz; + case R_RELAX_TLS_GD_TO_LE_NEG: + case R_NEG_TLS: + return Out::TlsPhdr->p_memsz - Body.getVA(A); + case R_SIZE: + return Body.getSize() + A; + case R_THUNK_ABS: + return Body.getThunkVA() + A; + case R_THUNK_PC: + case R_THUNK_PLT_PC: + return Body.getThunkVA() + A - P; + case R_TLSDESC: + return In::Got->getGlobalDynAddr(Body) + A; + case R_TLSDESC_PAGE: + return getAArch64Page(In::Got->getGlobalDynAddr(Body) + A) - + getAArch64Page(P); + case R_TLSGD: + return In::Got->getGlobalDynOffset(Body) + A - + In::Got->getSize(); + case R_TLSGD_PC: + return In::Got->getGlobalDynAddr(Body) + A - P; + case R_TLSLD: + return In::Got->getTlsIndexOff() + A - In::Got->getSize(); + case R_TLSLD_PC: + return In::Got->getTlsIndexVA() + A - P; } llvm_unreachable("Invalid expression"); } Modified: stable/11/contrib/llvm/tools/lld/ELF/Relocations.h ============================================================================== --- stable/11/contrib/llvm/tools/lld/ELF/Relocations.h Sat Jun 17 17:42:52 2017 (r320059) +++ stable/11/contrib/llvm/tools/lld/ELF/Relocations.h Sat Jun 17 19:00:12 2017 (r320060) @@ -34,26 +34,26 @@ enum RelExpr { R_GOT_PAGE_PC, R_GOT_PC, R_HINT, + R_MIPS_GOTREL, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, - R_MIPS_GOTREL, R_MIPS_TLSGD, R_MIPS_TLSLD, R_NEG_TLS, R_PAGE_PC, R_PC, R_PLT, - R_PLT_PC, R_PLT_PAGE_PC, + R_PLT_PC, R_PPC_OPD, R_PPC_PLT_OPD, R_PPC_TOC, R_RELAX_GOT_PC, R_RELAX_GOT_PC_NOPIC, R_RELAX_TLS_GD_TO_IE, - R_RELAX_TLS_GD_TO_IE_END, R_RELAX_TLS_GD_TO_IE_ABS, + R_RELAX_TLS_GD_TO_IE_END, R_RELAX_TLS_GD_TO_IE_PAGE_PC, R_RELAX_TLS_GD_TO_LE, R_RELAX_TLS_GD_TO_LE_NEG, @@ -65,8 +65,8 @@ enum RelExpr { R_THUNK_PLT_PC, R_TLS, R_TLSDESC, - R_TLSDESC_PAGE, R_TLSDESC_CALL, + R_TLSDESC_PAGE, R_TLSGD, R_TLSGD_PC, R_TLSLD,