2008-06-13 00:58:40 +08:00
|
|
|
// powerpc.h -- ELF definitions specific to EM_PPC and EM_PPC64 -*- C++ -*-
|
|
|
|
|
2018-01-03 13:17:27 +08:00
|
|
|
// Copyright (C) 2008-2018 Free Software Foundation, Inc.
|
2008-06-13 00:58:40 +08:00
|
|
|
// Written by David S. Miller <davem@davemloft.net>.
|
|
|
|
|
|
|
|
// This file is part of elfcpp.
|
|
|
|
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Library General Public License
|
|
|
|
// as published by the Free Software Foundation; either version 2, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// In addition to the permissions in the GNU Library General Public
|
|
|
|
// License, the Free Software Foundation gives you unlimited
|
|
|
|
// permission to link the compiled version of this file into
|
|
|
|
// combinations with other programs, and to distribute those
|
|
|
|
// combinations without any restriction coming from the use of this
|
|
|
|
// file. (The Library Public License restrictions do apply in other
|
|
|
|
// respects; for example, they cover modification of the file, and
|
|
|
|
/// distribution when not linked into a combined executable.)
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Library General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU Library General Public
|
|
|
|
// License along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
|
|
|
// 02110-1301, USA.
|
|
|
|
|
|
|
|
#ifndef ELFCPP_POWERPC_H
|
|
|
|
#define ELFCPP_POWERPC_H
|
|
|
|
|
|
|
|
namespace elfcpp
|
|
|
|
{
|
|
|
|
|
|
|
|
// The relocation numbers for 32-bit and 64-bit powerpc are nearly
|
|
|
|
// identical. Therefore I've adopted the convention of using
|
|
|
|
// R_POWERPC_foo for values which are the same in R_PPC_* and R_PPC64_*.
|
|
|
|
// For relocations which are specific to the word size I will use
|
|
|
|
// R_PPC_foo or R_PPC64_foo.
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
R_POWERPC_NONE = 0,
|
|
|
|
R_POWERPC_ADDR32 = 1,
|
|
|
|
R_POWERPC_ADDR24 = 2,
|
|
|
|
R_POWERPC_ADDR16 = 3,
|
|
|
|
R_POWERPC_ADDR16_LO = 4,
|
|
|
|
R_POWERPC_ADDR16_HI = 5,
|
|
|
|
R_POWERPC_ADDR16_HA = 6,
|
|
|
|
R_POWERPC_ADDR14 = 7,
|
|
|
|
R_POWERPC_ADDR14_BRTAKEN = 8,
|
|
|
|
R_POWERPC_ADDR14_BRNTAKEN = 9,
|
|
|
|
R_POWERPC_REL24 = 10,
|
|
|
|
R_POWERPC_REL14 = 11,
|
|
|
|
R_POWERPC_REL14_BRTAKEN = 12,
|
|
|
|
R_POWERPC_REL14_BRNTAKEN = 13,
|
|
|
|
R_POWERPC_GOT16 = 14,
|
|
|
|
R_POWERPC_GOT16_LO = 15,
|
|
|
|
R_POWERPC_GOT16_HI = 16,
|
|
|
|
R_POWERPC_GOT16_HA = 17,
|
|
|
|
R_PPC_PLTREL24 = 18,
|
|
|
|
R_POWERPC_COPY = 19,
|
|
|
|
R_POWERPC_GLOB_DAT = 20,
|
|
|
|
R_POWERPC_JMP_SLOT = 21,
|
|
|
|
R_POWERPC_RELATIVE = 22,
|
|
|
|
R_PPC_LOCAL24PC = 23,
|
|
|
|
R_POWERPC_UADDR32 = 24,
|
|
|
|
R_POWERPC_UADDR16 = 25,
|
|
|
|
R_POWERPC_REL32 = 26,
|
|
|
|
R_POWERPC_PLT32 = 27,
|
|
|
|
R_POWERPC_PLTREL32 = 28,
|
|
|
|
R_POWERPC_PLT16_LO = 29,
|
|
|
|
R_POWERPC_PLT16_HI = 30,
|
|
|
|
R_POWERPC_PLT16_HA = 31,
|
|
|
|
R_PPC_SDAREL16 = 32,
|
|
|
|
R_POWERPC_SECTOFF = 33,
|
|
|
|
R_POWERPC_SECTOFF_LO = 34,
|
|
|
|
R_POWERPC_SECTOFF_HI = 35,
|
|
|
|
R_POWERPC_SECTOFF_HA = 36,
|
|
|
|
R_POWERPC_ADDR30 = 37,
|
|
|
|
R_PPC64_ADDR64 = 38,
|
|
|
|
R_PPC64_ADDR16_HIGHER = 39,
|
|
|
|
R_PPC64_ADDR16_HIGHERA = 40,
|
|
|
|
R_PPC64_ADDR16_HIGHEST = 41,
|
|
|
|
R_PPC64_ADDR16_HIGHESTA = 42,
|
|
|
|
R_PPC64_UADDR64 = 43,
|
|
|
|
R_PPC64_REL64 = 44,
|
|
|
|
R_PPC64_PLT64 = 45,
|
|
|
|
R_PPC64_PLTREL64 = 46,
|
|
|
|
R_PPC64_TOC16 = 47,
|
|
|
|
R_PPC64_TOC16_LO = 48,
|
|
|
|
R_PPC64_TOC16_HI = 49,
|
|
|
|
R_PPC64_TOC16_HA = 50,
|
|
|
|
R_PPC64_TOC = 51,
|
|
|
|
R_PPC64_PLTGOT16 = 52,
|
|
|
|
R_PPC64_PLTGOT16_LO = 53,
|
|
|
|
R_PPC64_PLTGOT16_HI = 54,
|
|
|
|
R_PPC64_PLTGOT16_HA = 55,
|
|
|
|
R_PPC64_ADDR16_DS = 56,
|
|
|
|
R_PPC64_ADDR16_LO_DS = 57,
|
|
|
|
R_PPC64_GOT16_DS = 58,
|
|
|
|
R_PPC64_GOT16_LO_DS = 59,
|
|
|
|
R_PPC64_PLT16_LO_DS = 60,
|
|
|
|
R_PPC64_SECTOFF_DS = 61,
|
|
|
|
R_PPC64_SECTOFF_LO_DS = 62,
|
|
|
|
R_PPC64_TOC16_DS = 63,
|
|
|
|
R_PPC64_TOC16_LO_DS = 64,
|
|
|
|
R_PPC64_PLTGOT16_DS = 65,
|
|
|
|
R_PPC64_PLTGOT16_LO_DS = 66,
|
|
|
|
R_POWERPC_TLS = 67,
|
|
|
|
R_POWERPC_DTPMOD = 68,
|
|
|
|
R_POWERPC_TPREL16 = 69,
|
|
|
|
R_POWERPC_TPREL16_LO = 70,
|
|
|
|
R_POWERPC_TPREL16_HI = 71,
|
|
|
|
R_POWERPC_TPREL16_HA = 72,
|
|
|
|
R_POWERPC_TPREL = 73,
|
|
|
|
R_POWERPC_DTPREL16 = 74,
|
|
|
|
R_POWERPC_DTPREL16_LO = 75,
|
|
|
|
R_POWERPC_DTPREL16_HI = 76,
|
|
|
|
R_POWERPC_DTPREL16_HA = 77,
|
|
|
|
R_POWERPC_DTPREL = 78,
|
|
|
|
R_POWERPC_GOT_TLSGD16 = 79,
|
|
|
|
R_POWERPC_GOT_TLSGD16_LO = 80,
|
|
|
|
R_POWERPC_GOT_TLSGD16_HI = 81,
|
|
|
|
R_POWERPC_GOT_TLSGD16_HA = 82,
|
|
|
|
R_POWERPC_GOT_TLSLD16 = 83,
|
|
|
|
R_POWERPC_GOT_TLSLD16_LO = 84,
|
|
|
|
R_POWERPC_GOT_TLSLD16_HI = 85,
|
|
|
|
R_POWERPC_GOT_TLSLD16_HA = 86,
|
|
|
|
R_POWERPC_GOT_TPREL16 = 87,
|
|
|
|
R_POWERPC_GOT_TPREL16_LO = 88,
|
|
|
|
R_POWERPC_GOT_TPREL16_HI = 89,
|
|
|
|
R_POWERPC_GOT_TPREL16_HA = 90,
|
|
|
|
R_POWERPC_GOT_DTPREL16 = 91,
|
|
|
|
R_POWERPC_GOT_DTPREL16_LO = 92,
|
|
|
|
R_POWERPC_GOT_DTPREL16_HI = 93,
|
|
|
|
R_POWERPC_GOT_DTPREL16_HA = 94,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC_TLSGD = 95,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC64_TPREL16_DS = 95,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC_TLSLD = 96,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC64_TPREL16_LO_DS = 96,
|
|
|
|
R_PPC64_TPREL16_HIGHER = 97,
|
|
|
|
R_PPC64_TPREL16_HIGHERA = 98,
|
|
|
|
R_PPC64_TPREL16_HIGHEST = 99,
|
|
|
|
R_PPC64_TPREL16_HIGHESTA = 100,
|
|
|
|
R_PPC_EMB_NADDR32 = 101,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_DS = 101,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_NADDR16 = 102,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_LO_DS = 102,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_NADDR16_LO = 103,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_HIGHER = 103,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_NADDR16_HI = 104,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_HIGHERA = 104,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_NADDR16_HA = 105,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_HIGHEST = 105,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_SDAI16 = 106,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_DTPREL16_HIGHESTA = 106,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_SDA2I16 = 107,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_TLSGD = 107,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_SDA2REL = 108,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_TLSLD = 108,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_SDA21 = 109,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_TOCSAVE = 109,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_MRKREF = 110,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_ADDR16_HIGH = 110,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_RELSEC16 = 111,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_ADDR16_HIGHA = 111,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_RELST_LO = 112,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_TPREL16_HIGH = 112,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_RELST_HI = 113,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_TPREL16_HIGHA = 113,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_RELST_HA = 114,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_DTPREL16_HIGH = 114,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_BIT_FLD = 115,
|
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors
on 32-bit overflow. The motivation for this change is that on
PowerPC64, most uses of @h and @ha modifiers and their corresponding
relocations are to build up 32-bit offsets. We'd like to know when
such offsets overflow. Only rarely do people use @h or @ha with the
high 32-bit modifiers to build a 64-bit constant. Those uses will now
need to use two new modifiers, @high and @higha, if the constant isn't
known at assembly time. For now, we won't report overflow at assembly
time..
This also fixes an error when applying some of the HIGHER and HIGHEST
relocations.
include/elf/
* ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New.
(IS_PPC64_TLS_RELOC): Match new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
* elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
Make all _HA and _HI relocs report signed overflow.
(ppc64_elf_reloc_type_lookup): Handle new relocs.
(must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
(dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
(ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (SEX16): Don't mask.
(REPORT_OVERFLOW_HI): Define as zero.
(ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha,
@tprel@high, and @tprel@higha modifiers.
(md_assemble): Ignore X_unsigned when applying 16-bit insn fields.
Add (disabled) code to check @h and @ha reloc overflow for powerpc64.
Handle new relocs.
(md_apply_fix): Similarly.
elfcpp/
* powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA,
R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA,
R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
(Target_powerpc::Scan::global, local): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Check for overflow
on all ppc64 @h and @ha relocs.
2013-10-29 14:23:25 +08:00
|
|
|
R_PPC64_DTPREL16_HIGHA = 115,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_PPC_EMB_RELSDA = 116,
|
2014-03-05 17:27:39 +08:00
|
|
|
R_PPC64_REL24_NOTOC = 116,
|
|
|
|
R_PPC64_ADDR64_LOCAL = 117,
|
2015-12-07 10:45:24 +08:00
|
|
|
R_PPC64_ENTRY = 118,
|
PowerPC inline PLT call support
In addition to the existing relocs we need two more to mark all
instructions in the call sequence, PLTCALL on the call itself (plus
the toc restore insn for ppc64), and PLTSEQ on others. All
relocations in a particular sequence have the same symbol.
Example ppc64 ELFv2 assembly:
.reloc .,R_PPC64_PLTSEQ,puts
std 2,24(1)
addis 12,2,puts@plt@ha # .reloc .,R_PPC64_PLT16_HA,puts
ld 12,puts@plt@l(12) # .reloc .,R_PPC64_PLT16_LO_DS,puts
.reloc .,R_PPC64_PLTSEQ,puts
mtctr 12
.reloc .,R_PPC64_PLTCALL,puts
bctrl
ld 2,24(1)
Example ppc32 -fPIC assembly:
addis 12,30,puts+32768@plt@ha # .reloc .,R_PPC_PLT16_HA,puts+0x8000
lwz 12,12,puts+32768@plt@l # .reloc .,R_PPC_PLT16_LO,puts+0x8000
.reloc .,R_PPC_PLTSEQ,puts+32768
mtctr 12
.reloc .,R_PPC_PLTCALL,puts+32768
bctrl
Marking sequences like this allows the linker to convert them to nops
and a direct call if the target symbol turns out to be local.
When the call is __tls_get_addr, each relocation shown above is paired
with an R_PPC*_TLSLD or R_PPC*_TLSGD reloc to additionally mark the
sequence for possible TLS optimization. The TLSLD or TLSGD relocs are
emitted first.
include/
* elf/ppc.h (R_PPC_PLTSEQ, R_PPC_PLTCALL): Define.
* elf/ppc64.h (R_PPC64_PLTSEQ, R_PPC64_PLTCALL): Define.
bfd/
* elf32-ppc.c (ppc_elf_howto_raw): Add PLTSEQ and PLTCALL howtos.
(is_plt_seq_reloc): New function.
(ppc_elf_check_relocs): Handle PLTSEQ and PLTCALL relocs.
(ppc_elf_tls_optimize): Handle inline plt call sequence.
(ppc_elf_relax_section): Handle PLTCALL reloc.
(ppc_elf_relocate_section): Nop out inline plt call sequence when
resolving locally.
* elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_PLTSEQ and
R_PPC64_PLTCALL entries. Comment R_PPC64_TOCSAVE.
(has_tls_get_addr_call): Correct comment.
(is_branch_reloc): Add PLTCALL.
(is_plt_seq_reloc): New function.
(ppc64_elf_check_relocs): Handle PLT16_LO_DS reloc. Set
has_tls_reloc for R_PPC64_TLSGD and R_PPC64_TLSLD. Create plt
entry for R_PPC64_PLTCALL.
(ppc64_elf_tls_optimize): Handle inline plt call sequence.
(ppc_type_of_stub): Handle PLTCALL reloc.
(toc_adjusting_stub_needed): Likewise.
(ppc64_elf_relocate_section): Set "can_plt_call" for PLTCALL
reloc insn. Nop out inline plt call sequence when resolving
locally. Handle __tls_get_addr inline plt call optimization.
elfcpp/
* powerpc.h (R_POWERPC_PLTSEQ, R_POWERPC_PLTCALL): Define.
gold/
* powerpc.cc (Target_powerpc::Track_tls::maybe_skip_tls_get_addr_call):
Handle inline plt sequence relocs.
(Stub_table::Plt_stub_key::Plt_stub_key): Likewise.
(Target_powerpc::Scan::reloc_needs_plt_for_ifunc): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
2018-04-09 07:55:10 +08:00
|
|
|
R_POWERPC_PLTSEQ = 119,
|
|
|
|
R_POWERPC_PLTCALL = 120,
|
2010-08-04 17:53:38 +08:00
|
|
|
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC_VLE_REL8 = 216,
|
|
|
|
R_PPC_VLE_REL15 = 217,
|
|
|
|
R_PPC_VLE_REL24 = 218,
|
|
|
|
R_PPC_VLE_LO16A = 219,
|
|
|
|
R_PPC_VLE_LO16D = 220,
|
|
|
|
R_PPC_VLE_HI16A = 221,
|
|
|
|
R_PPC_VLE_HI16D = 222,
|
|
|
|
R_PPC_VLE_HA16A = 223,
|
|
|
|
R_PPC_VLE_HA16D = 224,
|
|
|
|
R_PPC_VLE_SDA21 = 225,
|
|
|
|
R_PPC_VLE_SDA21_LO = 226,
|
|
|
|
R_PPC_VLE_SDAREL_LO16A = 227,
|
|
|
|
R_PPC_VLE_SDAREL_LO16D = 228,
|
|
|
|
R_PPC_VLE_SDAREL_HI16A = 229,
|
|
|
|
R_PPC_VLE_SDAREL_HI16D = 230,
|
|
|
|
R_PPC_VLE_SDAREL_HA16A = 231,
|
|
|
|
R_PPC_VLE_SDAREL_HA16D = 232,
|
|
|
|
|
Add assembler, disassembler and linker support for power9.
include/opcode/
* ppc.h (PPC_OPCODE_POWER9): New define.
(PPC_OPCODE_VSX3): Likewise.
opcodes/
* ppc-dis.c (ppc_opts): Add "power9" and "pwr9" entries.
Add PPC_OPCODE_VSX3 to the vsx entry.
(powerpc_init_dialect): Set default dialect to power9.
* ppc-opc.c (insert_dcmxs, extract_dcmxs, insert_dxd, extract_dxd,
insert_dxdn, extract_dxdn, insert_l0, extract_l0, insert_l1,
extract_l1 insert_xtq6, extract_xtq6): New static functions.
(insert_esync): Test for illegal L operand value.
(DCMX, DCMXS, DXD, NDXD, L0, L1, RC, FC, UIM6, X_R, RIC, PRS, XSQ6,
XTQ6, LRAND, IMM8, DQX, DQX_MASK, DX, DX_MASK, VXVAPS_MASK, VXVA,XVA,
XX2VA, XVARC, XBF_MASK, XX2UIM4_MASK, XX2BFD_MASK, XX2DCMXS_MASK,
XVA_MASK, XRLA_MASK, XBFRARB_MASK, XLRAND_MASK, POWER9, PPCVEC3,
PPCVSX3): New defines.
(powerpc_opcodes) <ps_cmpu0, ps_cmpo0, ps_cmpu1, ps_cmpo1, fcmpu,
fcmpo, ftdiv, ftsqrt>: Use XBF_MASK.
<mcrxr>: Use XBFRARB_MASK.
<addpcis, bcdcfn., bcdcfsq., bcdcfz., bcdcpsgn., bcdctn., bcdctsq.,
bcdctz., bcds., bcdsetsgn., bcdsr., bcdtrunc., bcdus., bcdutrunc.,
cmpeqb, cmprb, cnttzd, cnttzd., cnttzw, cnttzw., copy, copy_first,
cp_abort, darn, dtstsfi, dtstsfiq, extswsli, extswsli., ldat, ldmx,
lwat, lxsd, lxsibzx, lxsihzx, lxssp, lxv, lxvb16x, lxvh8x, lxvl, lxvll,
lxvwsx, lxvx, maddhd, maddhdu, maddld, mcrxrx, mfvsrld, modsd, modsw,
modud, moduw, msgsync, mtvsrdd, mtvsrws, paste, paste., paste_last,
rmieg, setb, slbieg, slbsync, stdat, stop, stwat, stxsd, stxsibx,
stxsihx, stxssp, stxv, stxvb16x, stxvh8x, stxvl, stxvll, stxvx,
subpcis, urfid, vbpermd, vclzlsbb, vcmpneb, vcmpneb., vcmpneh,
vcmpneh., vcmpnew, vcmpnew., vcmpnezb, vcmpnezb., vcmpnezh, vcmpnezh.,
vcmpnezw, vcmpnezw., vctzb, vctzd, vctzh, vctzlsbb, vctzw, vextractd,
vextractub, vextractuh, vextractuw, vextsb2d, vextsb2w, vextsh2d,
vextsh2w, vextsw2d, vextublx, vextubrx, vextuhlx, vextuhrx, vextuwlx,
vextuwrx, vinsertb, vinsertd, vinserth, vinsertw, vmul10cuq,
vmul10ecuq, vmul10euq, vmul10uq, vnegd, vnegw, vpermr, vprtybd,
vprtybq, vprtybw, vrldmi, vrldnm, vrlwmi, vrlwnm, vslv, vsrv, wait,
xsabsqp, xsaddqp, xsaddqpo, xscmpeqdp, xscmpexpdp, xscmpexpqp,
xscmpgedp, xscmpgtdp, xscmpnedp, xscmpoqp, xscmpuqp, xscpsgnqp,
xscvdphp, xscvdpqp, xscvhpdp, xscvqpdp, xscvqpdpo, xscvqpsdz,
xscvqpswz, xscvqpudz, xscvqpuwz, xscvsdqp, xscvudqp, xsdivqp,
xsdivqpo, xsiexpdp, xsiexpqp, xsmaddqp, xsmaddqpo, xsmaxcdp,
xsmaxjdp, xsmincdp, xsminjdp, xsmsubqp, xsmsubqpo, xsmulqp, xsmulqpo,
xsnabsqp, xsnegqp, xsnmaddqp, xsnmaddqpo, xsnmsubqp, xsnmsubqpo,
xsrqpi, xsrqpix, xsrqpxp, xssqrtqp, xssqrtqpo, xssubqp, xssubqpo,
xststdcdp, xststdcqp, xststdcsp, xsxexpdp, xsxexpqp, xsxsigdp,
xsxsigqp, xvcmpnedp, xvcmpnedp., xvcmpnesp, xvcmpnesp., xvcvhpsp,
xvcvsphp, xviexpdp, xviexpsp, xvtstdcdp, xvtstdcsp, xvxexpdp,
xvxexpsp, xvxsigdp, xvxsigsp, xxbrd, xxbrh, xxbrq, xxbrw, xxextractuw,
xxinsertw, xxperm, xxpermr, xxspltib>: New instructions.
<doze, nap, sleep, rvwinkle, waitasec, lxvx, stxvx>: Disable on POWER9.
<tlbiel, tlbie, sync, slbmfev, slbmfee>: Add additional operands.
include/elf/
* ppc.h (R_PPC_REL16DX_HA): New reloction.
* ppc64.h (R_PPC64_REL16DX_HA): Likewise.
bfd/
* elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_REL16DX_HA.
(ppc_elf_reloc_type_lookup): Handle R_PPC_REL16DX_HA.
(ppc_elf_addr16_ha_reloc): Likewise.
(ppc_elf_check_relocs): Likewise.
(ppc_elf_relocate_section): Likewise.
(is_insn_dq_form): Handle lxv and stxv instructions.
* elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_REL16DX_HA.
(ppc64_elf_reloc_type_lookup): Handle R_PPC64_REL16DX_HA.
(ppc64_elf_ha_reloc): Likewise.
(ppc64_elf_check_relocs): Likewise.
(ppc64_elf_relocate_section): Likewise.
* bfd-in2.h: Regenerate.
* libbfd.h: Likewise.
* reloc.c (BFD_RELOC_PPC_REL16DX_HA): New.
elfcpp/
* powerpc.h (R_POWERPC_REL16DX_HA): Define.
gas/
* doc/as.texinfo (Target PowerPC): Document -mpower9 and -mpwr9.
* doc/c-ppc.texi (PowerPC-Opts): Likewise.
* config/tc-ppc.c (md_show_usage): Likewise.
(md_assemble): Handle BFD_RELOC_PPC_REL16DX_HA.
(md_apply_fix): Likewise.
(ppc_handle_align): Handle power9's group ending nop.
gas/testsuite/
* gas/ppc/altivec3.s: New test.
* gas/ppc/altivec3.d: Likewise.
* gas/ppc/vsx3.s: Likewise.
* gas/ppc/vsx3.d: Likewise.
* gas/ppc/power9.s: Likewise.
* gas/ppc/power9.d: Likewise.
* gas/ppc/ppc.exp: Run them.
* gas/ppc/power8.s <lxvx, lxvd2x, stxvx, stxvd2x>: Add new tests.
* gas/ppc/power8.d: Likewise.
* gas/ppc/vsx.s: <lxvx, stxvx>: Rename invalid mnemonics ...
<lxvd2x, stxvd2x>: ...to this.
* gas/ppc/vsx.d: Likewise.
gold/
* gold/powerpc.cc (Powerpc_relocate_functions::addr16_dq): New function.
(Powerpc_relocate_functions::addr16dx_ha): Likewise.
(Target_powerpc::Scan::local): Handle R_POWERPC_REL16DX_HA.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
ld/testsuite/
* ld-powerpc/addpcis.d: New test.
* ld-powerpc/addpcis.s: New test.
* ld-powerpc/powerpc.exp: Run it.
2015-11-12 09:52:52 +08:00
|
|
|
R_POWERPC_REL16DX_HA = 246,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_PPC64_JMP_IREL = 247,
|
2010-08-04 17:53:38 +08:00
|
|
|
R_POWERPC_IRELATIVE = 248,
|
2012-08-14 10:22:32 +08:00
|
|
|
R_POWERPC_REL16 = 249,
|
|
|
|
R_POWERPC_REL16_LO = 250,
|
|
|
|
R_POWERPC_REL16_HI = 251,
|
|
|
|
R_POWERPC_REL16_HA = 252,
|
2008-06-13 00:58:40 +08:00
|
|
|
R_POWERPC_GNU_VTINHERIT = 253,
|
|
|
|
R_POWERPC_GNU_VTENTRY = 254,
|
|
|
|
R_PPC_TOC16 = 255,
|
|
|
|
};
|
|
|
|
|
|
|
|
// e_flags values defined for powerpc
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
EF_PPC_EMB = 0x80000000, // PowerPC embedded flag.
|
|
|
|
EF_PPC_RELOCATABLE = 0x00010000, // PowerPC -mrelocatable flag. */
|
|
|
|
EF_PPC_RELOCATABLE_LIB = 0x00008000, // PowerPC -mrelocatable-lib flag. */
|
|
|
|
};
|
|
|
|
|
PowerPC64 ELFv2 support for gold.
elfcpp/
* powerpc.h (EF_PPC64_ABI): New enum constant.
(STO_PPC64_LOCAL_BIT, STO_PPC64_LOCAL_MASK): Likewise.
(ppc64_decode_local_entry): New function.
(ppc64_encode_local_entry): Likewise.
gold/
* powerpc.cc (Powerpc_relobj::abiversion, set_abiversion,
ppc64_local_entry_offset, ppc64_local_entry_offset,
do_read_symbols): New functions.
(Powerpc_relobj::e_flags_, st_other_): New vars.
(Powerpc_relobj::Powerpc_relobj): Call set_abiversion.
(Powerpc_dynobj::abiversion, set_abiversion): New functions.
(Powerpc_relobj::e_flags_): New var.
(Target_powerpc::first_plt_entry_offset, plt_entry_size): Inline
and adjust for ELFv2.
(Target_powerpc::abiversion, set_abiversion, stk_toc): New functions.
(Powerpc_relobj::do_find_special_sections): Check no .opd in ELFv2.
(Powerpc_dynobj::do_find_special_sections): Likewise.
(Target_powerpc::do_define_standard_symbols): Define ".TOC.".
(Target_powerpc::Branch_info::make_stub): Adjust stub destination
to ELFv2 local entry.
(Target_powerpc::do_relax): No thread safe barriers needed for
ELFv2.
(Output_data_plt_powerpc::initial_plt_entry_size_,
plt_entry_size): Delete. Replace all uses with
first_plt_entry_offset() and plt_entry_size().
(Output_data_plt_powerpc::Output_data_plt_powerpc): Remove
reserved_size parm. Update callers.
(Output_data_plt_powerpc::entry_count): Update.
(Output_data_plt_powerpc::first_plt_entry_offset): Make private
and use Target_powerpc::first_plt_entry_offset().
(Output_data_plt_powerpc::get_plt_entry_size): Similarly and
rename to plt_entry_size.
(Output_data_plt_powerpc::add_ifunc_entry,
add_local_ifunc_entry): Adjust reloc for ELFv2.
(glink_eh_frame_fde_64): Rename to glink_eh_frame_fde_64v1.
(glink_eh_frame_fde_64v2): New.
(Stub_table::plt_call_size): Support ELFv2 sizing.
(Output_data_glink::add_eh_frame): Use the new FDE.
(Output_data_glink::set_final_data_size): Adjust for ELFv2 glink.
(Stub_table::do_write): Write ELFv2 stubs and glink.
(Target_powerpc::Relocate::relocate): Replaces nop after call
with ld 2,24(1) and adjust local offset destination for ELFv2.
2013-10-29 15:15:48 +08:00
|
|
|
// e_flags values defined for powerpc64
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
// ABI version
|
|
|
|
// 1 for original function descriptor using ABI,
|
|
|
|
// 2 for revised ABI without function descriptors,
|
|
|
|
// 0 for unspecified or not using any features affected by the differences.
|
|
|
|
EF_PPC64_ABI = 3
|
|
|
|
};
|
|
|
|
|
2018-07-05 23:38:16 +08:00
|
|
|
// Object attribute tags. 0-3 are generic.
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
// FP ABI, low 2 bits:
|
|
|
|
// 1 for double precision hard-float,
|
|
|
|
// 2 for soft-float,
|
|
|
|
// 3 for single precision hard-float.
|
|
|
|
// 0 for not tagged or not using any ABIs affected by the differences.
|
|
|
|
// Next 2 bits:
|
|
|
|
// 1 for ibm long double
|
|
|
|
// 2 for 64-bit long double
|
|
|
|
// 3 for IEEE long double.
|
|
|
|
// 0 for not tagged or not using any ABIs affected by the differences.
|
|
|
|
Tag_GNU_Power_ABI_FP = 4,
|
|
|
|
|
|
|
|
// Value 1 for general purpose registers only, 2 for AltiVec
|
|
|
|
// registers, 3 for SPE registers; 0 for not tagged or not using any
|
|
|
|
// ABIs affected by the differences.
|
|
|
|
Tag_GNU_Power_ABI_Vector = 8,
|
|
|
|
|
|
|
|
// Value 1 for ABIs using r3/r4 for returning structures <= 8 bytes,
|
|
|
|
// 2 for ABIs using memory; 0 for not tagged or not using any ABIs
|
|
|
|
// affected by the differences.
|
|
|
|
Tag_GNU_Power_ABI_Struct_Return = 12
|
|
|
|
};
|
|
|
|
|
[GOLD] PowerPC tls_get_addr_optimize
This implements the special __tls_get_addr_opt call stub for powerpc
gold that returns __thread variable addresses without actually making
a call to __tls_get_addr in most cases. Shared libraries that are
loaded at program load time (ie. dlopen is not used) have a known
layout for their __thread variables, and thus DTPMOD64/DPTREL64 pairs
describing those variables can be set up by ld.so for the
__tls_get_addr_opt call stub fast exit.
Ref https://sourceware.org/ml/libc-alpha/2015-03/msg00626.html
I really, really wish I'd used a differently versioned __tls_get_addr
symbol than the base symbol to indicate glibc support for the
optimized call, rather than having glibc export __tls_get_addr_opt. A
lot of the messing around here, flipping symbols from __tls_get_addr
to __tls_get_addr_opt, is caused by that decision. About the only
benefit is that a user can see at a glance that their disassembled
code is calling __tls_get_addr via the fancy call stub.. Anyway, we
need references to __tls_get_addr to seem like they were to
__tls_get_addr_opt, and in cases like the tsan interceptor, a
definition of __tls_get_addr to seem like one of __tls_get_addr_opt
as well. That's the reason for Symbol::clear_in_reg and
Symbol_table::clone, and why symbols are substituted in Scan::global
and other places dealing with dynamic linking.
elfcpp/
* elfcpp.h (DT_PPC_OPT): Define.
* powerpc.h (PPC_OPT_TLS): Define.
gold/
* options.h (tls_get_addr_optimize): New option.
* symtab.h (Symbol::clear_in_reg, clone): New functions.
(Sized_symbol::clone): New function.
(Symbol_table::clone): New function.
* resolve.cc (Symbol::clone, Sized_symbol::clone): New functions.
* powerpc.cc (Target_powerpc::has_tls_get_addr_opt_,
tls_get_addr_, tls_get_addr_opt_): New vars.
(Target_powerpc::tls_get_addr_opt, tls_get_addr,
is_tls_get_addr_opt, replace_tls_get_addr,
set_has_tls_get_addr_opt, stk_linker): New functions.
(Target_powerpc::Track_tls::maybe_skip_tls_get_addr_call): Add
target param. Update callers. Compare symbols rather than names.
(Target_powerpc::do_define_standard_symbols): Init tls_get_addr_
and tls_get_addr_opt_.
(Target_powerpc::Branch_info::mark_pltcall): Translate tls_get_addr
sym to tls_get_addr_opt.
(Target_powerpc::Branch_info::make_stub): Likewise.
(Stub_table::define_stub_syms): Likewise.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
(add_3_12_2, add_3_12_13, bctrl, beqlr, cmpdi_11_0, cmpwi_11_0,
ld_11_1, ld_11_3, ld_12_3, lwz_11_3, lwz_12_3, mr_0_3, mr_3_0,
mtlr_11, std_11_1): New constants.
(Stub_table::eh_frame_added_): Delete.
(Stub_table::tls_get_addr_opt_bctrl_, plt_fde_len_, plt_fde_): New vars.
(Stub_table::init_plt_fde): New functions.
(Stub_table::add_eh_frame, replace_eh_frame): Move definition out
of line. Init and use plt_fde_.
(Stub_table::plt_call_size): Return size for tls_get_addr stub.
Extract alignment code to..
(Stub_table::plt_call_align): ..this new function. Adjust all callers.
(Stub_table::add_plt_call_entry): Set has_tls_get_addr_opt and
tls_get_addr_opt_bctrl, and align after that.
(Stub_table::do_write): Write out tls_get_addr stub.
(Target_powerpc::do_finalize_sections): Emit DT_PPC_OPT
PPC_OPT_TLS/PPC64_OPT_TLS bit.
(Target_powerpc::Relocate::relocate): Don't check for or modify
nop following bl for tls_get_addr stub.
2017-08-29 14:25:33 +08:00
|
|
|
// DT_PPC_OPT bits
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PPC_OPT_TLS = 1
|
|
|
|
};
|
|
|
|
|
2017-06-23 19:09:43 +08:00
|
|
|
// DT_PPC64_OPT bits
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PPC64_OPT_TLS = 1,
|
|
|
|
PPC64_OPT_MULTI_TOC = 2,
|
|
|
|
PPC64_OPT_LOCALENTRY = 4
|
|
|
|
};
|
|
|
|
|
PowerPC64 ELFv2 support for gold.
elfcpp/
* powerpc.h (EF_PPC64_ABI): New enum constant.
(STO_PPC64_LOCAL_BIT, STO_PPC64_LOCAL_MASK): Likewise.
(ppc64_decode_local_entry): New function.
(ppc64_encode_local_entry): Likewise.
gold/
* powerpc.cc (Powerpc_relobj::abiversion, set_abiversion,
ppc64_local_entry_offset, ppc64_local_entry_offset,
do_read_symbols): New functions.
(Powerpc_relobj::e_flags_, st_other_): New vars.
(Powerpc_relobj::Powerpc_relobj): Call set_abiversion.
(Powerpc_dynobj::abiversion, set_abiversion): New functions.
(Powerpc_relobj::e_flags_): New var.
(Target_powerpc::first_plt_entry_offset, plt_entry_size): Inline
and adjust for ELFv2.
(Target_powerpc::abiversion, set_abiversion, stk_toc): New functions.
(Powerpc_relobj::do_find_special_sections): Check no .opd in ELFv2.
(Powerpc_dynobj::do_find_special_sections): Likewise.
(Target_powerpc::do_define_standard_symbols): Define ".TOC.".
(Target_powerpc::Branch_info::make_stub): Adjust stub destination
to ELFv2 local entry.
(Target_powerpc::do_relax): No thread safe barriers needed for
ELFv2.
(Output_data_plt_powerpc::initial_plt_entry_size_,
plt_entry_size): Delete. Replace all uses with
first_plt_entry_offset() and plt_entry_size().
(Output_data_plt_powerpc::Output_data_plt_powerpc): Remove
reserved_size parm. Update callers.
(Output_data_plt_powerpc::entry_count): Update.
(Output_data_plt_powerpc::first_plt_entry_offset): Make private
and use Target_powerpc::first_plt_entry_offset().
(Output_data_plt_powerpc::get_plt_entry_size): Similarly and
rename to plt_entry_size.
(Output_data_plt_powerpc::add_ifunc_entry,
add_local_ifunc_entry): Adjust reloc for ELFv2.
(glink_eh_frame_fde_64): Rename to glink_eh_frame_fde_64v1.
(glink_eh_frame_fde_64v2): New.
(Stub_table::plt_call_size): Support ELFv2 sizing.
(Output_data_glink::add_eh_frame): Use the new FDE.
(Output_data_glink::set_final_data_size): Adjust for ELFv2 glink.
(Stub_table::do_write): Write ELFv2 stubs and glink.
(Target_powerpc::Relocate::relocate): Replaces nop after call
with ld 2,24(1) and adjust local offset destination for ELFv2.
2013-10-29 15:15:48 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
// The ELFv2 ABI uses three bits in the symbol st_other field of a
|
|
|
|
// function definition to specify the number of instructions between a
|
|
|
|
// function's global entry point and local entry point.
|
|
|
|
// The global entry point is used when it is necessary to set up the
|
|
|
|
// toc pointer (r2) for the function. Callers must enter the global
|
|
|
|
// entry point with r12 set to the global entry point address. On
|
|
|
|
// return from the function, r2 may have a different value to that
|
|
|
|
// which it had on entry.
|
|
|
|
// The local entry point is used when r2 is known to already be valid
|
|
|
|
// for the function. There is no requirement on r12 when using the
|
|
|
|
// local entry point, and on return r2 will contain the same value as
|
|
|
|
// at entry.
|
|
|
|
// A value of zero in these bits means that the function has a single
|
|
|
|
// entry point with no requirement on r12 or r2, and that on return r2
|
|
|
|
// will contain the same value as at entry.
|
|
|
|
// Values of one and seven are reserved.
|
|
|
|
|
|
|
|
STO_PPC64_LOCAL_BIT = 5,
|
|
|
|
STO_PPC64_LOCAL_MASK = 0xE0
|
|
|
|
};
|
|
|
|
|
|
|
|
// 3 bit other field to bytes.
|
|
|
|
static inline unsigned int
|
|
|
|
ppc64_decode_local_entry(unsigned int other)
|
|
|
|
{
|
|
|
|
return ((1 << other) >> 2) << 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// bytes to field value.
|
|
|
|
static inline unsigned int
|
|
|
|
ppc64_encode_local_entry(unsigned int val)
|
|
|
|
{
|
|
|
|
return (val >= 4 * 4
|
|
|
|
? (val >= 8 * 4
|
|
|
|
? (val >= 16 * 4 ? 6 : 5)
|
|
|
|
: 4)
|
|
|
|
: (val >= 2 * 4
|
|
|
|
? 3
|
|
|
|
: (val >= 1 * 4 ? 2 : 0)));
|
|
|
|
}
|
|
|
|
|
2008-06-13 00:58:40 +08:00
|
|
|
} // End namespace elfcpp.
|
|
|
|
|
|
|
|
#endif // !defined(ELFCPP_POWERPC_H)
|