171671b9obrien/* PowerPC-specific support for 32-bit ELF
271671b9obrien   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3d0f678fdim   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
471671b9obrien   Written by Ian Lance Taylor, Cygnus Support.
571671b9obrien
671671b9obrien   This file is part of BFD, the Binary File Descriptor library.
771671b9obrien
871671b9obrien   This program is free software; you can redistribute it and/or modify
971671b9obrien   it under the terms of the GNU General Public License as published by
1071671b9obrien   the Free Software Foundation; either version 2 of the License, or
1171671b9obrien   (at your option) any later version.
1271671b9obrien
1371671b9obrien   This program is distributed in the hope that it will be useful,
1471671b9obrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1571671b9obrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1671671b9obrien   GNU General Public License for more details.
1771671b9obrien
1871671b9obrien   You should have received a copy of the GNU General Public License
1971671b9obrien   along with this program; if not, write to the
200acbbeedim   Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
210acbbeedim   Boston, MA 02110-1301, USA.  */
2271671b9obrien
2371671b9obrien/* This file is based on a preliminary PowerPC ELF ABI.  The
2471671b9obrien   information may not match the final PowerPC ELF ABI.  It includes
2571671b9obrien   suggestions from the in-progress Embedded PowerPC ABI, and that
2671671b9obrien   information may also not match.  */
2771671b9obrien
2871671b9obrien#include "sysdep.h"
29d0f678fdim#include <stdarg.h>
30d0f678fdim#include "bfd.h"
3171671b9obrien#include "bfdlink.h"
3271671b9obrien#include "libbfd.h"
3371671b9obrien#include "elf-bfd.h"
3471671b9obrien#include "elf/ppc.h"
3571671b9obrien#include "elf32-ppc.h"
360acbbeedim#include "elf-vxworks.h"
3771671b9obrien
3871671b9obrien/* RELA relocations are used here.  */
3971671b9obrien
4071671b9obrienstatic bfd_reloc_status_type ppc_elf_addr16_ha_reloc
4171671b9obrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4271671b9obrienstatic bfd_reloc_status_type ppc_elf_unhandled_reloc
4371671b9obrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4471671b9obrien
4571671b9obrien/* Branch prediction bit for branch taken relocs.  */
4671671b9obrien#define BRANCH_PREDICT_BIT 0x200000
4771671b9obrien/* Mask to set RA in memory instructions.  */
4871671b9obrien#define RA_REGISTER_MASK 0x001f0000
4971671b9obrien/* Value to shift register by to insert RA.  */
5071671b9obrien#define RA_REGISTER_SHIFT 16
5171671b9obrien
5271671b9obrien/* The name of the dynamic interpreter.  This is put in the .interp
5371671b9obrien   section.  */
5471671b9obrien#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
5571671b9obrien
560acbbeedim/* For old-style PLT.  */
5771671b9obrien/* The number of single-slot PLT entries (the rest use two slots).  */
5871671b9obrien#define PLT_NUM_SINGLE_ENTRIES 8192
5971671b9obrien
600acbbeedim/* For new-style .glink and .plt.  */
610acbbeedim#define GLINK_PLTRESOLVE 16*4
620acbbeedim#define GLINK_ENTRY_SIZE 4*4
6371671b9obrien
640acbbeedim/* VxWorks uses its own plt layout, filled in by the static linker.  */
6571671b9obrien
660acbbeedim/* The standard VxWorks PLT entry.  */
670acbbeedim#define VXWORKS_PLT_ENTRY_SIZE 32
680acbbeedimstatic const bfd_vma ppc_elf_vxworks_plt_entry
690acbbeedim    [VXWORKS_PLT_ENTRY_SIZE / 4] =
700acbbeedim  {
710acbbeedim    0x3d800000, /* lis     r12,0                 */
720acbbeedim    0x818c0000, /* lwz     r12,0(r12)            */
730acbbeedim    0x7d8903a6, /* mtctr   r12                   */
740acbbeedim    0x4e800420, /* bctr                          */
750acbbeedim    0x39600000, /* li      r11,0                 */
760acbbeedim    0x48000000, /* b       14 <.PLT0resolve+0x4> */
770acbbeedim    0x60000000, /* nop                           */
780acbbeedim    0x60000000, /* nop                           */
790acbbeedim  };
800acbbeedimstatic const bfd_vma ppc_elf_vxworks_pic_plt_entry
810acbbeedim    [VXWORKS_PLT_ENTRY_SIZE / 4] =
820acbbeedim  {
830acbbeedim    0x3d9e0000, /* addis r12,r30,0 */
840acbbeedim    0x818c0000, /* lwz	 r12,0(r12) */
850acbbeedim    0x7d8903a6, /* mtctr r12 */
860acbbeedim    0x4e800420, /* bctr */
870acbbeedim    0x39600000, /* li	 r11,0 */
880acbbeedim    0x48000000, /* b	 14 <.PLT0resolve+0x4> 14: R_PPC_REL24 .PLTresolve */
890acbbeedim    0x60000000, /* nop */
900acbbeedim    0x60000000, /* nop */
910acbbeedim  };
9271671b9obrien
930acbbeedim/* The initial VxWorks PLT entry.  */
940acbbeedim#define VXWORKS_PLT_INITIAL_ENTRY_SIZE 32
950acbbeedimstatic const bfd_vma ppc_elf_vxworks_plt0_entry
960acbbeedim    [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
970acbbeedim  {
980acbbeedim    0x3d800000, /* lis     r12,0        */
990acbbeedim    0x398c0000, /* addi    r12,r12,0    */
1000acbbeedim    0x800c0008, /* lwz     r0,8(r12)    */
1010acbbeedim    0x7c0903a6, /* mtctr   r0           */
1020acbbeedim    0x818c0004, /* lwz     r12,4(r12)   */
1030acbbeedim    0x4e800420, /* bctr                 */
1040acbbeedim    0x60000000, /* nop                  */
1050acbbeedim    0x60000000, /* nop                  */
1060acbbeedim  };
1070acbbeedimstatic const bfd_vma ppc_elf_vxworks_pic_plt0_entry
1080acbbeedim    [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
1090acbbeedim  {
1100acbbeedim    0x819e0008, /* lwz	 r12,8(r30) */
1110acbbeedim    0x7d8903a6, /* mtctr r12        */
1120acbbeedim    0x819e0004, /* lwz	 r12,4(r30) */
1130acbbeedim    0x4e800420, /* bctr             */
1140acbbeedim    0x60000000, /* nop              */
1150acbbeedim    0x60000000, /* nop              */
1160acbbeedim    0x60000000, /* nop              */
1170acbbeedim    0x60000000, /* nop              */
1180acbbeedim  };
11971671b9obrien
1200acbbeedim/* For executables, we have some additional relocations in
1210acbbeedim   .rela.plt.unloaded, for the kernel loader.  */
1220acbbeedim
1230acbbeedim/* The number of non-JMP_SLOT relocations per PLT0 slot. */
1240acbbeedim#define VXWORKS_PLT_NON_JMP_SLOT_RELOCS 3
1250acbbeedim/* The number of relocations in the PLTResolve slot. */
1260acbbeedim#define VXWORKS_PLTRESOLVE_RELOCS 2
1270acbbeedim/* The number of relocations in the PLTResolve slot when when creating
1280acbbeedim   a shared library. */
1290acbbeedim#define VXWORKS_PLTRESOLVE_RELOCS_SHLIB 0
1300acbbeedim
1310acbbeedim/* Some instructions.  */
1320acbbeedim#define ADDIS_11_11	0x3d6b0000
1330acbbeedim#define ADDIS_11_30	0x3d7e0000
1340acbbeedim#define ADDIS_12_12	0x3d8c0000
1350acbbeedim#define ADDI_11_11	0x396b0000
1360acbbeedim#define ADD_0_11_11	0x7c0b5a14
1370acbbeedim#define ADD_11_0_11	0x7d605a14
1380acbbeedim#define B		0x48000000
1390acbbeedim#define BCL_20_31	0x429f0005
1400acbbeedim#define BCTR		0x4e800420
1410acbbeedim#define LIS_11		0x3d600000
1420acbbeedim#define LIS_12		0x3d800000
1430acbbeedim#define LWZU_0_12	0x840c0000
1440acbbeedim#define LWZ_0_12	0x800c0000
1450acbbeedim#define LWZ_11_11	0x816b0000
1460acbbeedim#define LWZ_11_30	0x817e0000
1470acbbeedim#define LWZ_12_12	0x818c0000
1480acbbeedim#define MFLR_0		0x7c0802a6
1490acbbeedim#define MFLR_12		0x7d8802a6
1500acbbeedim#define MTCTR_0		0x7c0903a6
1510acbbeedim#define MTCTR_11	0x7d6903a6
1520acbbeedim#define MTLR_0		0x7c0803a6
1530acbbeedim#define NOP		0x60000000
1540acbbeedim#define SUB_11_11_12	0x7d6c5850
15571671b9obrien
1560acbbeedim/* Offset of tp and dtp pointers from start of TLS block.  */
1570acbbeedim#define TP_OFFSET	0x7000
1580acbbeedim#define DTP_OFFSET	0x8000
15971671b9obrien
16071671b9obrienstatic reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
16171671b9obrien
16271671b9obrienstatic reloc_howto_type ppc_elf_howto_raw[] = {
16371671b9obrien  /* This reloc does nothing.  */
16471671b9obrien  HOWTO (R_PPC_NONE,		/* type */
16571671b9obrien	 0,			/* rightshift */
16671671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
16771671b9obrien	 32,			/* bitsize */
16871671b9obrien	 FALSE,			/* pc_relative */
16971671b9obrien	 0,			/* bitpos */
17071671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
17171671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
17271671b9obrien	 "R_PPC_NONE",		/* name */
17371671b9obrien	 FALSE,			/* partial_inplace */
17471671b9obrien	 0,			/* src_mask */
17571671b9obrien	 0,			/* dst_mask */
17671671b9obrien	 FALSE),		/* pcrel_offset */
17771671b9obrien
17871671b9obrien  /* A standard 32 bit relocation.  */
17971671b9obrien  HOWTO (R_PPC_ADDR32,		/* type */
18071671b9obrien	 0,			/* rightshift */
18171671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
18271671b9obrien	 32,			/* bitsize */
18371671b9obrien	 FALSE,			/* pc_relative */
18471671b9obrien	 0,			/* bitpos */
18571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
18671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
18771671b9obrien	 "R_PPC_ADDR32",	/* name */
18871671b9obrien	 FALSE,			/* partial_inplace */
18971671b9obrien	 0,			/* src_mask */
19071671b9obrien	 0xffffffff,		/* dst_mask */
19171671b9obrien	 FALSE),		/* pcrel_offset */
19271671b9obrien
19371671b9obrien  /* An absolute 26 bit branch; the lower two bits must be zero.
19471671b9obrien     FIXME: we don't check that, we just clear them.  */
19571671b9obrien  HOWTO (R_PPC_ADDR24,		/* type */
19671671b9obrien	 0,			/* rightshift */
19771671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
19871671b9obrien	 26,			/* bitsize */
19971671b9obrien	 FALSE,			/* pc_relative */
20071671b9obrien	 0,			/* bitpos */
20171671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
20271671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
20371671b9obrien	 "R_PPC_ADDR24",	/* name */
20471671b9obrien	 FALSE,			/* partial_inplace */
20571671b9obrien	 0,			/* src_mask */
20671671b9obrien	 0x3fffffc,		/* dst_mask */
20771671b9obrien	 FALSE),		/* pcrel_offset */
20871671b9obrien
20971671b9obrien  /* A standard 16 bit relocation.  */
21071671b9obrien  HOWTO (R_PPC_ADDR16,		/* type */
21171671b9obrien	 0,			/* rightshift */
21271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
21371671b9obrien	 16,			/* bitsize */
21471671b9obrien	 FALSE,			/* pc_relative */
21571671b9obrien	 0,			/* bitpos */
21671671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
21771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
21871671b9obrien	 "R_PPC_ADDR16",	/* name */
21971671b9obrien	 FALSE,			/* partial_inplace */
22071671b9obrien	 0,			/* src_mask */
22171671b9obrien	 0xffff,		/* dst_mask */
22271671b9obrien	 FALSE),		/* pcrel_offset */
22371671b9obrien
22471671b9obrien  /* A 16 bit relocation without overflow.  */
22571671b9obrien  HOWTO (R_PPC_ADDR16_LO,	/* type */
22671671b9obrien	 0,			/* rightshift */
22771671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
22871671b9obrien	 16,			/* bitsize */
22971671b9obrien	 FALSE,			/* pc_relative */
23071671b9obrien	 0,			/* bitpos */
23171671b9obrien	 complain_overflow_dont,/* complain_on_overflow */
23271671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
23371671b9obrien	 "R_PPC_ADDR16_LO",	/* name */
23471671b9obrien	 FALSE,			/* partial_inplace */
23571671b9obrien	 0,			/* src_mask */
23671671b9obrien	 0xffff,		/* dst_mask */
23771671b9obrien	 FALSE),		/* pcrel_offset */
23871671b9obrien
23971671b9obrien  /* The high order 16 bits of an address.  */
24071671b9obrien  HOWTO (R_PPC_ADDR16_HI,	/* type */
24171671b9obrien	 16,			/* rightshift */
24271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
24371671b9obrien	 16,			/* bitsize */
24471671b9obrien	 FALSE,			/* pc_relative */
24571671b9obrien	 0,			/* bitpos */
24671671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
24771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
24871671b9obrien	 "R_PPC_ADDR16_HI",	/* name */
24971671b9obrien	 FALSE,			/* partial_inplace */
25071671b9obrien	 0,			/* src_mask */
25171671b9obrien	 0xffff,		/* dst_mask */
25271671b9obrien	 FALSE),		/* pcrel_offset */
25371671b9obrien
25471671b9obrien  /* The high order 16 bits of an address, plus 1 if the contents of
25571671b9obrien     the low 16 bits, treated as a signed number, is negative.  */
25671671b9obrien  HOWTO (R_PPC_ADDR16_HA,	/* type */
25771671b9obrien	 16,			/* rightshift */
25871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
25971671b9obrien	 16,			/* bitsize */
26071671b9obrien	 FALSE,			/* pc_relative */
26171671b9obrien	 0,			/* bitpos */
26271671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
26371671b9obrien	 ppc_elf_addr16_ha_reloc, /* special_function */
26471671b9obrien	 "R_PPC_ADDR16_HA",	/* name */
26571671b9obrien	 FALSE,			/* partial_inplace */
26671671b9obrien	 0,			/* src_mask */
26771671b9obrien	 0xffff,		/* dst_mask */
26871671b9obrien	 FALSE),		/* pcrel_offset */
26971671b9obrien
27071671b9obrien  /* An absolute 16 bit branch; the lower two bits must be zero.
27171671b9obrien     FIXME: we don't check that, we just clear them.  */
27271671b9obrien  HOWTO (R_PPC_ADDR14,		/* type */
27371671b9obrien	 0,			/* rightshift */
27471671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
27571671b9obrien	 16,			/* bitsize */
27671671b9obrien	 FALSE,			/* pc_relative */
27771671b9obrien	 0,			/* bitpos */
27871671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
27971671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
28071671b9obrien	 "R_PPC_ADDR14",	/* name */
28171671b9obrien	 FALSE,			/* partial_inplace */
28271671b9obrien	 0,			/* src_mask */
28371671b9obrien	 0xfffc,		/* dst_mask */
28471671b9obrien	 FALSE),		/* pcrel_offset */
28571671b9obrien
28671671b9obrien  /* An absolute 16 bit branch, for which bit 10 should be set to
28771671b9obrien     indicate that the branch is expected to be taken.	The lower two
28871671b9obrien     bits must be zero.  */
28971671b9obrien  HOWTO (R_PPC_ADDR14_BRTAKEN,	/* type */
29071671b9obrien	 0,			/* rightshift */
29171671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
29271671b9obrien	 16,			/* bitsize */
29371671b9obrien	 FALSE,			/* pc_relative */
29471671b9obrien	 0,			/* bitpos */
29571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
29671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
29771671b9obrien	 "R_PPC_ADDR14_BRTAKEN",/* name */
29871671b9obrien	 FALSE,			/* partial_inplace */
29971671b9obrien	 0,			/* src_mask */
30071671b9obrien	 0xfffc,		/* dst_mask */
30171671b9obrien	 FALSE),		/* pcrel_offset */
30271671b9obrien
30371671b9obrien  /* An absolute 16 bit branch, for which bit 10 should be set to
30471671b9obrien     indicate that the branch is not expected to be taken.  The lower
30571671b9obrien     two bits must be zero.  */
30671671b9obrien  HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
30771671b9obrien	 0,			/* rightshift */
30871671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
30971671b9obrien	 16,			/* bitsize */
31071671b9obrien	 FALSE,			/* pc_relative */
31171671b9obrien	 0,			/* bitpos */
31271671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
31371671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
31471671b9obrien	 "R_PPC_ADDR14_BRNTAKEN",/* name */
31571671b9obrien	 FALSE,			/* partial_inplace */
31671671b9obrien	 0,			/* src_mask */
31771671b9obrien	 0xfffc,		/* dst_mask */
31871671b9obrien	 FALSE),		/* pcrel_offset */
31971671b9obrien
32071671b9obrien  /* A relative 26 bit branch; the lower two bits must be zero.  */
32171671b9obrien  HOWTO (R_PPC_REL24,		/* type */
32271671b9obrien	 0,			/* rightshift */
32371671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
32471671b9obrien	 26,			/* bitsize */
32571671b9obrien	 TRUE,			/* pc_relative */
32671671b9obrien	 0,			/* bitpos */
32771671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
32871671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
32971671b9obrien	 "R_PPC_REL24",		/* name */
33071671b9obrien	 FALSE,			/* partial_inplace */
33171671b9obrien	 0,			/* src_mask */
33271671b9obrien	 0x3fffffc,		/* dst_mask */
33371671b9obrien	 TRUE),			/* pcrel_offset */
33471671b9obrien
33571671b9obrien  /* A relative 16 bit branch; the lower two bits must be zero.  */
33671671b9obrien  HOWTO (R_PPC_REL14,		/* type */
33771671b9obrien	 0,			/* rightshift */
33871671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
33971671b9obrien	 16,			/* bitsize */
34071671b9obrien	 TRUE,			/* pc_relative */
34171671b9obrien	 0,			/* bitpos */
34271671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
34371671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
34471671b9obrien	 "R_PPC_REL14",		/* name */
34571671b9obrien	 FALSE,			/* partial_inplace */
34671671b9obrien	 0,			/* src_mask */
34771671b9obrien	 0xfffc,		/* dst_mask */
34871671b9obrien	 TRUE),			/* pcrel_offset */
34971671b9obrien
35071671b9obrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
35171671b9obrien     the branch is expected to be taken.  The lower two bits must be
35271671b9obrien     zero.  */
35371671b9obrien  HOWTO (R_PPC_REL14_BRTAKEN,	/* type */
35471671b9obrien	 0,			/* rightshift */
35571671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
35671671b9obrien	 16,			/* bitsize */
35771671b9obrien	 TRUE,			/* pc_relative */
35871671b9obrien	 0,			/* bitpos */
35971671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
36071671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
36171671b9obrien	 "R_PPC_REL14_BRTAKEN",	/* name */
36271671b9obrien	 FALSE,			/* partial_inplace */
36371671b9obrien	 0,			/* src_mask */
36471671b9obrien	 0xfffc,		/* dst_mask */
36571671b9obrien	 TRUE),			/* pcrel_offset */
36671671b9obrien
36771671b9obrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
36871671b9obrien     the branch is not expected to be taken.  The lower two bits must
36971671b9obrien     be zero.  */
37071671b9obrien  HOWTO (R_PPC_REL14_BRNTAKEN,	/* type */
37171671b9obrien	 0,			/* rightshift */
37271671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
37371671b9obrien	 16,			/* bitsize */
37471671b9obrien	 TRUE,			/* pc_relative */
37571671b9obrien	 0,			/* bitpos */
37671671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
37771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
37871671b9obrien	 "R_PPC_REL14_BRNTAKEN",/* name */
37971671b9obrien	 FALSE,			/* partial_inplace */
38071671b9obrien	 0,			/* src_mask */
38171671b9obrien	 0xfffc,		/* dst_mask */
38271671b9obrien	 TRUE),			/* pcrel_offset */
38371671b9obrien
38471671b9obrien  /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
38571671b9obrien     symbol.  */
38671671b9obrien  HOWTO (R_PPC_GOT16,		/* type */
38771671b9obrien	 0,			/* rightshift */
38871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
38971671b9obrien	 16,			/* bitsize */
39071671b9obrien	 FALSE,			/* pc_relative */
39171671b9obrien	 0,			/* bitpos */
39271671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
39371671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
39471671b9obrien	 "R_PPC_GOT16",		/* name */
39571671b9obrien	 FALSE,			/* partial_inplace */
39671671b9obrien	 0,			/* src_mask */
39771671b9obrien	 0xffff,		/* dst_mask */
39871671b9obrien	 FALSE),		/* pcrel_offset */
39971671b9obrien
40071671b9obrien  /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
40171671b9obrien     the symbol.  */
40271671b9obrien  HOWTO (R_PPC_GOT16_LO,	/* type */
40371671b9obrien	 0,			/* rightshift */
40471671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
40571671b9obrien	 16,			/* bitsize */
40671671b9obrien	 FALSE,			/* pc_relative */
40771671b9obrien	 0,			/* bitpos */
40871671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
40971671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
41071671b9obrien	 "R_PPC_GOT16_LO",	/* name */
41171671b9obrien	 FALSE,			/* partial_inplace */
41271671b9obrien	 0,			/* src_mask */
41371671b9obrien	 0xffff,		/* dst_mask */
41471671b9obrien	 FALSE),		/* pcrel_offset */
41571671b9obrien
41671671b9obrien  /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
41771671b9obrien     the symbol.  */
41871671b9obrien  HOWTO (R_PPC_GOT16_HI,	/* type */
41971671b9obrien	 16,			/* rightshift */
42071671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
42171671b9obrien	 16,			/* bitsize */
42271671b9obrien	 FALSE,			/* pc_relative */
42371671b9obrien	 0,			/* bitpos */
42471671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
42571671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
42671671b9obrien	 "R_PPC_GOT16_HI",	/* name */
42771671b9obrien	 FALSE,			/* partial_inplace */
42871671b9obrien	 0,			/* src_mask */
42971671b9obrien	 0xffff,		/* dst_mask */
43071671b9obrien	 FALSE),		 /* pcrel_offset */
43171671b9obrien
43271671b9obrien  /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
43371671b9obrien     the symbol.  */
43471671b9obrien  HOWTO (R_PPC_GOT16_HA,	/* type */
43571671b9obrien	 16,			/* rightshift */
43671671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
43771671b9obrien	 16,			/* bitsize */
43871671b9obrien	 FALSE,			/* pc_relative */
43971671b9obrien	 0,			/* bitpos */
44071671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
44171671b9obrien	 ppc_elf_addr16_ha_reloc, /* special_function */
44271671b9obrien	 "R_PPC_GOT16_HA",	/* name */
44371671b9obrien	 FALSE,			/* partial_inplace */
44471671b9obrien	 0,			/* src_mask */
44571671b9obrien	 0xffff,		/* dst_mask */
44671671b9obrien	 FALSE),		/* pcrel_offset */
44771671b9obrien
44871671b9obrien  /* Like R_PPC_REL24, but referring to the procedure linkage table
44971671b9obrien     entry for the symbol.  */
45071671b9obrien  HOWTO (R_PPC_PLTREL24,	/* type */
45171671b9obrien	 0,			/* rightshift */
45271671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
45371671b9obrien	 26,			/* bitsize */
45471671b9obrien	 TRUE,			/* pc_relative */
45571671b9obrien	 0,			/* bitpos */
45671671b9obrien	 complain_overflow_signed,  /* complain_on_overflow */
45771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
45871671b9obrien	 "R_PPC_PLTREL24",	/* name */
45971671b9obrien	 FALSE,			/* partial_inplace */
46071671b9obrien	 0,			/* src_mask */
46171671b9obrien	 0x3fffffc,		/* dst_mask */
46271671b9obrien	 TRUE),			/* pcrel_offset */
46371671b9obrien
46471671b9obrien  /* This is used only by the dynamic linker.  The symbol should exist
46571671b9obrien     both in the object being run and in some shared library.  The
46671671b9obrien     dynamic linker copies the data addressed by the symbol from the
46771671b9obrien     shared library into the object, because the object being
46871671b9obrien     run has to have the data at some particular address.  */
46971671b9obrien  HOWTO (R_PPC_COPY,		/* type */
47071671b9obrien	 0,			/* rightshift */
47171671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
47271671b9obrien	 32,			/* bitsize */
47371671b9obrien	 FALSE,			/* pc_relative */
47471671b9obrien	 0,			/* bitpos */
47571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
47671671b9obrien	 bfd_elf_generic_reloc,	 /* special_function */
47771671b9obrien	 "R_PPC_COPY",		/* name */
47871671b9obrien	 FALSE,			/* partial_inplace */
47971671b9obrien	 0,			/* src_mask */
48071671b9obrien	 0,			/* dst_mask */
48171671b9obrien	 FALSE),		/* pcrel_offset */
48271671b9obrien
48371671b9obrien  /* Like R_PPC_ADDR32, but used when setting global offset table
48471671b9obrien     entries.  */
48571671b9obrien  HOWTO (R_PPC_GLOB_DAT,	/* type */
48671671b9obrien	 0,			/* rightshift */
48771671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
48871671b9obrien	 32,			/* bitsize */
48971671b9obrien	 FALSE,			/* pc_relative */
49071671b9obrien	 0,			/* bitpos */
49171671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
49271671b9obrien	 bfd_elf_generic_reloc,	 /* special_function */
49371671b9obrien	 "R_PPC_GLOB_DAT",	/* name */
49471671b9obrien	 FALSE,			/* partial_inplace */
49571671b9obrien	 0,			/* src_mask */
49671671b9obrien	 0xffffffff,		/* dst_mask */
49771671b9obrien	 FALSE),		/* pcrel_offset */
49871671b9obrien
49971671b9obrien  /* Marks a procedure linkage table entry for a symbol.  */
50071671b9obrien  HOWTO (R_PPC_JMP_SLOT,	/* type */
50171671b9obrien	 0,			/* rightshift */
50271671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
50371671b9obrien	 32,			/* bitsize */
50471671b9obrien	 FALSE,			/* pc_relative */
50571671b9obrien	 0,			/* bitpos */
50671671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
50771671b9obrien	 bfd_elf_generic_reloc,	 /* special_function */
50871671b9obrien	 "R_PPC_JMP_SLOT",	/* name */
50971671b9obrien	 FALSE,			/* partial_inplace */
51071671b9obrien	 0,			/* src_mask */
51171671b9obrien	 0,			/* dst_mask */
51271671b9obrien	 FALSE),		/* pcrel_offset */
51371671b9obrien
51471671b9obrien  /* Used only by the dynamic linker.  When the object is run, this
51571671b9obrien     longword is set to the load address of the object, plus the
51671671b9obrien     addend.  */
51771671b9obrien  HOWTO (R_PPC_RELATIVE,	/* type */
51871671b9obrien	 0,			/* rightshift */
51971671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
52071671b9obrien	 32,			/* bitsize */
52171671b9obrien	 FALSE,			/* pc_relative */
52271671b9obrien	 0,			/* bitpos */
52371671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
52471671b9obrien	 bfd_elf_generic_reloc,	 /* special_function */
52571671b9obrien	 "R_PPC_RELATIVE",	/* name */
52671671b9obrien	 FALSE,			/* partial_inplace */
52771671b9obrien	 0,			/* src_mask */
52871671b9obrien	 0xffffffff,		/* dst_mask */
52971671b9obrien	 FALSE),		/* pcrel_offset */
53071671b9obrien
53171671b9obrien  /* Like R_PPC_REL24, but uses the value of the symbol within the
53271671b9obrien     object rather than the final value.  Normally used for
53371671b9obrien     _GLOBAL_OFFSET_TABLE_.  */
53471671b9obrien  HOWTO (R_PPC_LOCAL24PC,	/* type */
53571671b9obrien	 0,			/* rightshift */
53671671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
53771671b9obrien	 26,			/* bitsize */
53871671b9obrien	 TRUE,			/* pc_relative */
53971671b9obrien	 0,			/* bitpos */
54071671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
54171671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
54271671b9obrien	 "R_PPC_LOCAL24PC",	/* name */
54371671b9obrien	 FALSE,			/* partial_inplace */
54471671b9obrien	 0,			/* src_mask */
54571671b9obrien	 0x3fffffc,		/* dst_mask */
54671671b9obrien	 TRUE),			/* pcrel_offset */
54771671b9obrien
54871671b9obrien  /* Like R_PPC_ADDR32, but may be unaligned.  */
54971671b9obrien  HOWTO (R_PPC_UADDR32,		/* type */
55071671b9obrien	 0,			/* rightshift */
55171671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
55271671b9obrien	 32,			/* bitsize */
55371671b9obrien	 FALSE,			/* pc_relative */
55471671b9obrien	 0,			/* bitpos */
55571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
55671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
55771671b9obrien	 "R_PPC_UADDR32",	/* name */
55871671b9obrien	 FALSE,			/* partial_inplace */
55971671b9obrien	 0,			/* src_mask */
56071671b9obrien	 0xffffffff,		/* dst_mask */
56171671b9obrien	 FALSE),		/* pcrel_offset */
56271671b9obrien
56371671b9obrien  /* Like R_PPC_ADDR16, but may be unaligned.  */
56471671b9obrien  HOWTO (R_PPC_UADDR16,		/* type */
56571671b9obrien	 0,			/* rightshift */
56671671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
56771671b9obrien	 16,			/* bitsize */
56871671b9obrien	 FALSE,			/* pc_relative */
56971671b9obrien	 0,			/* bitpos */
57071671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
57171671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
57271671b9obrien	 "R_PPC_UADDR16",	/* name */
57371671b9obrien	 FALSE,			/* partial_inplace */
57471671b9obrien	 0,			/* src_mask */
57571671b9obrien	 0xffff,		/* dst_mask */
57671671b9obrien	 FALSE),		/* pcrel_offset */
57771671b9obrien
57871671b9obrien  /* 32-bit PC relative */
57971671b9obrien  HOWTO (R_PPC_REL32,		/* type */
58071671b9obrien	 0,			/* rightshift */
58171671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
58271671b9obrien	 32,			/* bitsize */
58371671b9obrien	 TRUE,			/* pc_relative */
58471671b9obrien	 0,			/* bitpos */
58571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
58671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
58771671b9obrien	 "R_PPC_REL32",		/* name */
58871671b9obrien	 FALSE,			/* partial_inplace */
58971671b9obrien	 0,			/* src_mask */
59071671b9obrien	 0xffffffff,		/* dst_mask */
59171671b9obrien	 TRUE),			/* pcrel_offset */
59271671b9obrien
59371671b9obrien  /* 32-bit relocation to the symbol's procedure linkage table.
59471671b9obrien     FIXME: not supported.  */
59571671b9obrien  HOWTO (R_PPC_PLT32,		/* type */
59671671b9obrien	 0,			/* rightshift */
59771671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
59871671b9obrien	 32,			/* bitsize */
59971671b9obrien	 FALSE,			/* pc_relative */
60071671b9obrien	 0,			/* bitpos */
60171671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
60271671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
60371671b9obrien	 "R_PPC_PLT32",		/* name */
60471671b9obrien	 FALSE,			/* partial_inplace */
60571671b9obrien	 0,			/* src_mask */
60671671b9obrien	 0,			/* dst_mask */
60771671b9obrien	 FALSE),		/* pcrel_offset */
60871671b9obrien
60971671b9obrien  /* 32-bit PC relative relocation to the symbol's procedure linkage table.
61071671b9obrien     FIXME: not supported.  */
61171671b9obrien  HOWTO (R_PPC_PLTREL32,	/* type */
61271671b9obrien	 0,			/* rightshift */
61371671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
61471671b9obrien	 32,			/* bitsize */
61571671b9obrien	 TRUE,			/* pc_relative */
61671671b9obrien	 0,			/* bitpos */
61771671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
61871671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
61971671b9obrien	 "R_PPC_PLTREL32",	/* name */
62071671b9obrien	 FALSE,			/* partial_inplace */
62171671b9obrien	 0,			/* src_mask */
62271671b9obrien	 0,			/* dst_mask */
62371671b9obrien	 TRUE),			/* pcrel_offset */
62471671b9obrien
62571671b9obrien  /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
62671671b9obrien     the symbol.  */
62771671b9obrien  HOWTO (R_PPC_PLT16_LO,	/* type */
62871671b9obrien	 0,			/* rightshift */
62971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
63071671b9obrien	 16,			/* bitsize */
63171671b9obrien	 FALSE,			/* pc_relative */
63271671b9obrien	 0,			/* bitpos */
63371671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
63471671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
63571671b9obrien	 "R_PPC_PLT16_LO",	/* name */
63671671b9obrien	 FALSE,			/* partial_inplace */
63771671b9obrien	 0,			/* src_mask */
63871671b9obrien	 0xffff,		/* dst_mask */
63971671b9obrien	 FALSE),		/* pcrel_offset */
64071671b9obrien
64171671b9obrien  /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
64271671b9obrien     the symbol.  */
64371671b9obrien  HOWTO (R_PPC_PLT16_HI,	/* type */
64471671b9obrien	 16,			/* rightshift */
64571671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
64671671b9obrien	 16,			/* bitsize */
64771671b9obrien	 FALSE,			/* pc_relative */
64871671b9obrien	 0,			/* bitpos */
64971671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
65071671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
65171671b9obrien	 "R_PPC_PLT16_HI",	/* name */
65271671b9obrien	 FALSE,			/* partial_inplace */
65371671b9obrien	 0,			/* src_mask */
65471671b9obrien	 0xffff,		/* dst_mask */
65571671b9obrien	 FALSE),		 /* pcrel_offset */
65671671b9obrien
65771671b9obrien  /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
65871671b9obrien     the symbol.  */
65971671b9obrien  HOWTO (R_PPC_PLT16_HA,	/* type */
66071671b9obrien	 16,			/* rightshift */
66171671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
66271671b9obrien	 16,			/* bitsize */
66371671b9obrien	 FALSE,			/* pc_relative */
66471671b9obrien	 0,			/* bitpos */
66571671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
66671671b9obrien	 ppc_elf_addr16_ha_reloc, /* special_function */
66771671b9obrien	 "R_PPC_PLT16_HA",	/* name */
66871671b9obrien	 FALSE,			/* partial_inplace */
66971671b9obrien	 0,			/* src_mask */
67071671b9obrien	 0xffff,		/* dst_mask */
67171671b9obrien	 FALSE),		/* pcrel_offset */
67271671b9obrien
67371671b9obrien  /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
67471671b9obrien     small data items.  */
67571671b9obrien  HOWTO (R_PPC_SDAREL16,	/* type */
67671671b9obrien	 0,			/* rightshift */
67771671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
67871671b9obrien	 16,			/* bitsize */
67971671b9obrien	 FALSE,			/* pc_relative */
68071671b9obrien	 0,			/* bitpos */
68171671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
68271671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
68371671b9obrien	 "R_PPC_SDAREL16",	/* name */
68471671b9obrien	 FALSE,			/* partial_inplace */
68571671b9obrien	 0,			/* src_mask */
68671671b9obrien	 0xffff,		/* dst_mask */
68771671b9obrien	 FALSE),		/* pcrel_offset */
68871671b9obrien
68971671b9obrien  /* 16-bit section relative relocation.  */
69071671b9obrien  HOWTO (R_PPC_SECTOFF,		/* type */
69171671b9obrien	 0,			/* rightshift */
69271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
69371671b9obrien	 16,			/* bitsize */
69471671b9obrien	 FALSE,			/* pc_relative */
69571671b9obrien	 0,			/* bitpos */
69671671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
69771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
69871671b9obrien	 "R_PPC_SECTOFF",	/* name */
69971671b9obrien	 FALSE,			/* partial_inplace */
70071671b9obrien	 0,			/* src_mask */
70171671b9obrien	 0xffff,		/* dst_mask */
70271671b9obrien	 FALSE),		/* pcrel_offset */
70371671b9obrien
70471671b9obrien  /* 16-bit lower half section relative relocation.  */
70571671b9obrien  HOWTO (R_PPC_SECTOFF_LO,	  /* type */
70671671b9obrien	 0,			/* rightshift */
70771671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
70871671b9obrien	 16,			/* bitsize */
70971671b9obrien	 FALSE,			/* pc_relative */
71071671b9obrien	 0,			/* bitpos */
71171671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
71271671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
71371671b9obrien	 "R_PPC_SECTOFF_LO",	/* name */
71471671b9obrien	 FALSE,			/* partial_inplace */
71571671b9obrien	 0,			/* src_mask */
71671671b9obrien	 0xffff,		/* dst_mask */
71771671b9obrien	 FALSE),		/* pcrel_offset */
71871671b9obrien
71971671b9obrien  /* 16-bit upper half section relative relocation.  */
72071671b9obrien  HOWTO (R_PPC_SECTOFF_HI,	/* type */
72171671b9obrien	 16,			/* rightshift */
72271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
72371671b9obrien	 16,			/* bitsize */
72471671b9obrien	 FALSE,			/* pc_relative */
72571671b9obrien	 0,			/* bitpos */
72671671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
72771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
72871671b9obrien	 "R_PPC_SECTOFF_HI",	/* name */
72971671b9obrien	 FALSE,			/* partial_inplace */
73071671b9obrien	 0,			/* src_mask */
73171671b9obrien	 0xffff,		/* dst_mask */
73271671b9obrien	 FALSE),		 /* pcrel_offset */
73371671b9obrien
73471671b9obrien  /* 16-bit upper half adjusted section relative relocation.  */
73571671b9obrien  HOWTO (R_PPC_SECTOFF_HA,	/* type */
73671671b9obrien	 16,			/* rightshift */
73771671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
73871671b9obrien	 16,			/* bitsize */
73971671b9obrien	 FALSE,			/* pc_relative */
74071671b9obrien	 0,			/* bitpos */
74171671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
74271671b9obrien	 ppc_elf_addr16_ha_reloc, /* special_function */
74371671b9obrien	 "R_PPC_SECTOFF_HA",	/* name */
74471671b9obrien	 FALSE,			/* partial_inplace */
74571671b9obrien	 0,			/* src_mask */
74671671b9obrien	 0xffff,		/* dst_mask */
74771671b9obrien	 FALSE),		/* pcrel_offset */
74871671b9obrien
74996e9bafjhibbits  /* Marker relocs for TLS.  */
75071671b9obrien  HOWTO (R_PPC_TLS,
75171671b9obrien	 0,			/* rightshift */
75271671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
75371671b9obrien	 32,			/* bitsize */
75471671b9obrien	 FALSE,			/* pc_relative */
75571671b9obrien	 0,			/* bitpos */
75671671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
75771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
75871671b9obrien	 "R_PPC_TLS",		/* name */
75971671b9obrien	 FALSE,			/* partial_inplace */
76071671b9obrien	 0,			/* src_mask */
76171671b9obrien	 0,			/* dst_mask */
76271671b9obrien	 FALSE),		/* pcrel_offset */
76371671b9obrien
76496e9bafjhibbits  HOWTO (R_PPC_TLSGD,
76596e9bafjhibbits	 0,			/* rightshift */
76696e9bafjhibbits	 2,			/* size (0 = byte, 1 = short, 2 = long) */
76796e9bafjhibbits	 32,			/* bitsize */
76896e9bafjhibbits	 FALSE,			/* pc_relative */
76996e9bafjhibbits	 0,			/* bitpos */
77096e9bafjhibbits	 complain_overflow_dont, /* complain_on_overflow */
77196e9bafjhibbits	 bfd_elf_generic_reloc, /* special_function */
77296e9bafjhibbits	 "R_PPC_TLSGD",		/* name */
77396e9bafjhibbits	 FALSE,			/* partial_inplace */
77496e9bafjhibbits	 0,			/* src_mask */
77596e9bafjhibbits	 0,			/* dst_mask */
77696e9bafjhibbits	 FALSE),		/* pcrel_offset */
77796e9bafjhibbits
77896e9bafjhibbits  HOWTO (R_PPC_TLSLD,
77996e9bafjhibbits	 0,			/* rightshift */
78096e9bafjhibbits	 2,			/* size (0 = byte, 1 = short, 2 = long) */
78196e9bafjhibbits	 32,			/* bitsize */
78296e9bafjhibbits	 FALSE,			/* pc_relative */
78396e9bafjhibbits	 0,			/* bitpos */
78496e9bafjhibbits	 complain_overflow_dont, /* complain_on_overflow */
78596e9bafjhibbits	 bfd_elf_generic_reloc, /* special_function */
78696e9bafjhibbits	 "R_PPC_TLSLD",		/* name */
78796e9bafjhibbits	 FALSE,			/* partial_inplace */
78896e9bafjhibbits	 0,			/* src_mask */
78996e9bafjhibbits	 0,			/* dst_mask */
79096e9bafjhibbits	 FALSE),		/* pcrel_offset */
79196e9bafjhibbits
79271671b9obrien  /* Computes the load module index of the load module that contains the
79371671b9obrien     definition of its TLS sym.  */
79471671b9obrien  HOWTO (R_PPC_DTPMOD32,
79571671b9obrien	 0,			/* rightshift */
79671671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
79771671b9obrien	 32,			/* bitsize */
79871671b9obrien	 FALSE,			/* pc_relative */
79971671b9obrien	 0,			/* bitpos */
80071671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
80171671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
80271671b9obrien	 "R_PPC_DTPMOD32",	/* name */
80371671b9obrien	 FALSE,			/* partial_inplace */
80471671b9obrien	 0,			/* src_mask */
80571671b9obrien	 0xffffffff,		/* dst_mask */
80671671b9obrien	 FALSE),		/* pcrel_offset */
80771671b9obrien
80871671b9obrien  /* Computes a dtv-relative displacement, the difference between the value
80971671b9obrien     of sym+add and the base address of the thread-local storage block that
81071671b9obrien     contains the definition of sym, minus 0x8000.  */
81171671b9obrien  HOWTO (R_PPC_DTPREL32,
81271671b9obrien	 0,			/* rightshift */
81371671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
81471671b9obrien	 32,			/* bitsize */
81571671b9obrien	 FALSE,			/* pc_relative */
81671671b9obrien	 0,			/* bitpos */
81771671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
81871671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
81971671b9obrien	 "R_PPC_DTPREL32",	/* name */
82071671b9obrien	 FALSE,			/* partial_inplace */
82171671b9obrien	 0,			/* src_mask */
82271671b9obrien	 0xffffffff,		/* dst_mask */
82371671b9obrien	 FALSE),		/* pcrel_offset */
82471671b9obrien
82571671b9obrien  /* A 16 bit dtprel reloc.  */
82671671b9obrien  HOWTO (R_PPC_DTPREL16,
82771671b9obrien	 0,			/* rightshift */
82871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
82971671b9obrien	 16,			/* bitsize */
83071671b9obrien	 FALSE,			/* pc_relative */
83171671b9obrien	 0,			/* bitpos */
83271671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
83371671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
83471671b9obrien	 "R_PPC_DTPREL16",	/* name */
83571671b9obrien	 FALSE,			/* partial_inplace */
83671671b9obrien	 0,			/* src_mask */
83771671b9obrien	 0xffff,		/* dst_mask */
83871671b9obrien	 FALSE),		/* pcrel_offset */
83971671b9obrien
84071671b9obrien  /* Like DTPREL16, but no overflow.  */
84171671b9obrien  HOWTO (R_PPC_DTPREL16_LO,
84271671b9obrien	 0,			/* rightshift */
84371671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
84471671b9obrien	 16,			/* bitsize */
84571671b9obrien	 FALSE,			/* pc_relative */
84671671b9obrien	 0,			/* bitpos */
84771671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
84871671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
84971671b9obrien	 "R_PPC_DTPREL16_LO",	/* name */
85071671b9obrien	 FALSE,			/* partial_inplace */
85171671b9obrien	 0,			/* src_mask */
85271671b9obrien	 0xffff,		/* dst_mask */
85371671b9obrien	 FALSE),		/* pcrel_offset */
85471671b9obrien
85571671b9obrien  /* Like DTPREL16_LO, but next higher group of 16 bits.  */
85671671b9obrien  HOWTO (R_PPC_DTPREL16_HI,
85771671b9obrien	 16,			/* rightshift */
85871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
85971671b9obrien	 16,			/* bitsize */
86071671b9obrien	 FALSE,			/* pc_relative */
86171671b9obrien	 0,			/* bitpos */
86271671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
86371671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
86471671b9obrien	 "R_PPC_DTPREL16_HI",	/* name */
86571671b9obrien	 FALSE,			/* partial_inplace */
86671671b9obrien	 0,			/* src_mask */
86771671b9obrien	 0xffff,		/* dst_mask */
86871671b9obrien	 FALSE),		/* pcrel_offset */
86971671b9obrien
87071671b9obrien  /* Like DTPREL16_HI, but adjust for low 16 bits.  */
87171671b9obrien  HOWTO (R_PPC_DTPREL16_HA,
87271671b9obrien	 16,			/* rightshift */
87371671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
87471671b9obrien	 16,			/* bitsize */
87571671b9obrien	 FALSE,			/* pc_relative */
87671671b9obrien	 0,			/* bitpos */
87771671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
87871671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
87971671b9obrien	 "R_PPC_DTPREL16_HA",	/* name */
88071671b9obrien	 FALSE,			/* partial_inplace */
88171671b9obrien	 0,			/* src_mask */
88271671b9obrien	 0xffff,		/* dst_mask */
88371671b9obrien	 FALSE),		/* pcrel_offset */
88471671b9obrien
88571671b9obrien  /* Computes a tp-relative displacement, the difference between the value of
88671671b9obrien     sym+add and the value of the thread pointer (r13).  */
88771671b9obrien  HOWTO (R_PPC_TPREL32,
88871671b9obrien	 0,			/* rightshift */
88971671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
89071671b9obrien	 32,			/* bitsize */
89171671b9obrien	 FALSE,			/* pc_relative */
89271671b9obrien	 0,			/* bitpos */
89371671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
89471671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
89571671b9obrien	 "R_PPC_TPREL32",	/* name */
89671671b9obrien	 FALSE,			/* partial_inplace */
89771671b9obrien	 0,			/* src_mask */
89871671b9obrien	 0xffffffff,		/* dst_mask */
89971671b9obrien	 FALSE),		/* pcrel_offset */
90071671b9obrien
90171671b9obrien  /* A 16 bit tprel reloc.  */
90271671b9obrien  HOWTO (R_PPC_TPREL16,
90371671b9obrien	 0,			/* rightshift */
90471671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
90571671b9obrien	 16,			/* bitsize */
90671671b9obrien	 FALSE,			/* pc_relative */
90771671b9obrien	 0,			/* bitpos */
90871671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
90971671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
91071671b9obrien	 "R_PPC_TPREL16",	/* name */
91171671b9obrien	 FALSE,			/* partial_inplace */
91271671b9obrien	 0,			/* src_mask */
91371671b9obrien	 0xffff,		/* dst_mask */
91471671b9obrien	 FALSE),		/* pcrel_offset */
91571671b9obrien
91671671b9obrien  /* Like TPREL16, but no overflow.  */
91771671b9obrien  HOWTO (R_PPC_TPREL16_LO,
91871671b9obrien	 0,			/* rightshift */
91971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
92071671b9obrien	 16,			/* bitsize */
92171671b9obrien	 FALSE,			/* pc_relative */
92271671b9obrien	 0,			/* bitpos */
92371671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
92471671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
92571671b9obrien	 "R_PPC_TPREL16_LO",	/* name */
92671671b9obrien	 FALSE,			/* partial_inplace */
92771671b9obrien	 0,			/* src_mask */
92871671b9obrien	 0xffff,		/* dst_mask */
92971671b9obrien	 FALSE),		/* pcrel_offset */
93071671b9obrien
93171671b9obrien  /* Like TPREL16_LO, but next higher group of 16 bits.  */
93271671b9obrien  HOWTO (R_PPC_TPREL16_HI,
93371671b9obrien	 16,			/* rightshift */
93471671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
93571671b9obrien	 16,			/* bitsize */
93671671b9obrien	 FALSE,			/* pc_relative */
93771671b9obrien	 0,			/* bitpos */
93871671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
93971671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
94071671b9obrien	 "R_PPC_TPREL16_HI",	/* name */
94171671b9obrien	 FALSE,			/* partial_inplace */
94271671b9obrien	 0,			/* src_mask */
94371671b9obrien	 0xffff,		/* dst_mask */
94471671b9obrien	 FALSE),		/* pcrel_offset */
94571671b9obrien
94671671b9obrien  /* Like TPREL16_HI, but adjust for low 16 bits.  */
94771671b9obrien  HOWTO (R_PPC_TPREL16_HA,
94871671b9obrien	 16,			/* rightshift */
94971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
95071671b9obrien	 16,			/* bitsize */
95171671b9obrien	 FALSE,			/* pc_relative */
95271671b9obrien	 0,			/* bitpos */
95371671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
95471671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
95571671b9obrien	 "R_PPC_TPREL16_HA",	/* name */
95671671b9obrien	 FALSE,			/* partial_inplace */
95771671b9obrien	 0,			/* src_mask */
95871671b9obrien	 0xffff,		/* dst_mask */
95971671b9obrien	 FALSE),		/* pcrel_offset */
96071671b9obrien
96171671b9obrien  /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
96271671b9obrien     with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
96371671b9obrien     to the first entry.  */
96471671b9obrien  HOWTO (R_PPC_GOT_TLSGD16,
96571671b9obrien	 0,			/* rightshift */
96671671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
96771671b9obrien	 16,			/* bitsize */
96871671b9obrien	 FALSE,			/* pc_relative */
96971671b9obrien	 0,			/* bitpos */
97071671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
97171671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
97271671b9obrien	 "R_PPC_GOT_TLSGD16",	/* name */
97371671b9obrien	 FALSE,			/* partial_inplace */
97471671b9obrien	 0,			/* src_mask */
97571671b9obrien	 0xffff,		/* dst_mask */
97671671b9obrien	 FALSE),		/* pcrel_offset */
97771671b9obrien
97871671b9obrien  /* Like GOT_TLSGD16, but no overflow.  */
97971671b9obrien  HOWTO (R_PPC_GOT_TLSGD16_LO,
98071671b9obrien	 0,			/* rightshift */
98171671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
98271671b9obrien	 16,			/* bitsize */
98371671b9obrien	 FALSE,			/* pc_relative */
98471671b9obrien	 0,			/* bitpos */
98571671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
98671671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
98771671b9obrien	 "R_PPC_GOT_TLSGD16_LO", /* name */
98871671b9obrien	 FALSE,			/* partial_inplace */
98971671b9obrien	 0,			/* src_mask */
99071671b9obrien	 0xffff,		/* dst_mask */
99171671b9obrien	 FALSE),		/* pcrel_offset */
99271671b9obrien
99371671b9obrien  /* Like GOT_TLSGD16_LO, but next higher group of 16 bits.  */
99471671b9obrien  HOWTO (R_PPC_GOT_TLSGD16_HI,
99571671b9obrien	 16,			/* rightshift */
99671671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
99771671b9obrien	 16,			/* bitsize */
99871671b9obrien	 FALSE,			/* pc_relative */
99971671b9obrien	 0,			/* bitpos */
100071671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
100171671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
100271671b9obrien	 "R_PPC_GOT_TLSGD16_HI", /* name */
100371671b9obrien	 FALSE,			/* partial_inplace */
100471671b9obrien	 0,			/* src_mask */
100571671b9obrien	 0xffff,		/* dst_mask */
100671671b9obrien	 FALSE),		/* pcrel_offset */
100771671b9obrien
100871671b9obrien  /* Like GOT_TLSGD16_HI, but adjust for low 16 bits.  */
100971671b9obrien  HOWTO (R_PPC_GOT_TLSGD16_HA,
101071671b9obrien	 16,			/* rightshift */
101171671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
101271671b9obrien	 16,			/* bitsize */
101371671b9obrien	 FALSE,			/* pc_relative */
101471671b9obrien	 0,			/* bitpos */
101571671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
101671671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
101771671b9obrien	 "R_PPC_GOT_TLSGD16_HA", /* name */
101871671b9obrien	 FALSE,			/* partial_inplace */
101971671b9obrien	 0,			/* src_mask */
102071671b9obrien	 0xffff,		/* dst_mask */
102171671b9obrien	 FALSE),		/* pcrel_offset */
102271671b9obrien
102371671b9obrien  /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
102471671b9obrien     with values (sym+add)@dtpmod and zero, and computes the offset to the
102571671b9obrien     first entry.  */
102671671b9obrien  HOWTO (R_PPC_GOT_TLSLD16,
102771671b9obrien	 0,			/* rightshift */
102871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
102971671b9obrien	 16,			/* bitsize */
103071671b9obrien	 FALSE,			/* pc_relative */
103171671b9obrien	 0,			/* bitpos */
103271671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
103371671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
103471671b9obrien	 "R_PPC_GOT_TLSLD16",	/* name */
103571671b9obrien	 FALSE,			/* partial_inplace */
103671671b9obrien	 0,			/* src_mask */
103771671b9obrien	 0xffff,		/* dst_mask */
103871671b9obrien	 FALSE),		/* pcrel_offset */
103971671b9obrien
104071671b9obrien  /* Like GOT_TLSLD16, but no overflow.  */
104171671b9obrien  HOWTO (R_PPC_GOT_TLSLD16_LO,
104271671b9obrien	 0,			/* rightshift */
104371671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
104471671b9obrien	 16,			/* bitsize */
104571671b9obrien	 FALSE,			/* pc_relative */
104671671b9obrien	 0,			/* bitpos */
104771671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
104871671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
104971671b9obrien	 "R_PPC_GOT_TLSLD16_LO", /* name */
105071671b9obrien	 FALSE,			/* partial_inplace */
105171671b9obrien	 0,			/* src_mask */
105271671b9obrien	 0xffff,		/* dst_mask */
105371671b9obrien	 FALSE),		/* pcrel_offset */
105471671b9obrien
105571671b9obrien  /* Like GOT_TLSLD16_LO, but next higher group of 16 bits.  */
105671671b9obrien  HOWTO (R_PPC_GOT_TLSLD16_HI,
105771671b9obrien	 16,			/* rightshift */
105871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
105971671b9obrien	 16,			/* bitsize */
106071671b9obrien	 FALSE,			/* pc_relative */
106171671b9obrien	 0,			/* bitpos */
106271671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
106371671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
106471671b9obrien	 "R_PPC_GOT_TLSLD16_HI", /* name */
106571671b9obrien	 FALSE,			/* partial_inplace */
106671671b9obrien	 0,			/* src_mask */
106771671b9obrien	 0xffff,		/* dst_mask */
106871671b9obrien	 FALSE),		/* pcrel_offset */
106971671b9obrien
107071671b9obrien  /* Like GOT_TLSLD16_HI, but adjust for low 16 bits.  */
107171671b9obrien  HOWTO (R_PPC_GOT_TLSLD16_HA,
107271671b9obrien	 16,			/* rightshift */
107371671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
107471671b9obrien	 16,			/* bitsize */
107571671b9obrien	 FALSE,			/* pc_relative */
107671671b9obrien	 0,			/* bitpos */
107771671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
107871671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
107971671b9obrien	 "R_PPC_GOT_TLSLD16_HA", /* name */
108071671b9obrien	 FALSE,			/* partial_inplace */
108171671b9obrien	 0,			/* src_mask */
108271671b9obrien	 0xffff,		/* dst_mask */
108371671b9obrien	 FALSE),		/* pcrel_offset */
108471671b9obrien
108571671b9obrien  /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
108671671b9obrien     the offset to the entry.  */
108771671b9obrien  HOWTO (R_PPC_GOT_DTPREL16,
108871671b9obrien	 0,			/* rightshift */
108971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
109071671b9obrien	 16,			/* bitsize */
109171671b9obrien	 FALSE,			/* pc_relative */
109271671b9obrien	 0,			/* bitpos */
109371671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
109471671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
109571671b9obrien	 "R_PPC_GOT_DTPREL16",	/* name */
109671671b9obrien	 FALSE,			/* partial_inplace */
109771671b9obrien	 0,			/* src_mask */
109871671b9obrien	 0xffff,		/* dst_mask */
109971671b9obrien	 FALSE),		/* pcrel_offset */
110071671b9obrien
110171671b9obrien  /* Like GOT_DTPREL16, but no overflow.  */
110271671b9obrien  HOWTO (R_PPC_GOT_DTPREL16_LO,
110371671b9obrien	 0,			/* rightshift */
110471671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
110571671b9obrien	 16,			/* bitsize */
110671671b9obrien	 FALSE,			/* pc_relative */
110771671b9obrien	 0,			/* bitpos */
110871671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
110971671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
111071671b9obrien	 "R_PPC_GOT_DTPREL16_LO", /* name */
111171671b9obrien	 FALSE,			/* partial_inplace */
111271671b9obrien	 0,			/* src_mask */
111371671b9obrien	 0xffff,		/* dst_mask */
111471671b9obrien	 FALSE),		/* pcrel_offset */
111571671b9obrien
111671671b9obrien  /* Like GOT_DTPREL16_LO, but next higher group of 16 bits.  */
111771671b9obrien  HOWTO (R_PPC_GOT_DTPREL16_HI,
111871671b9obrien	 16,			/* rightshift */
111971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
112071671b9obrien	 16,			/* bitsize */
112171671b9obrien	 FALSE,			/* pc_relative */
112271671b9obrien	 0,			/* bitpos */
112371671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
112471671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
112571671b9obrien	 "R_PPC_GOT_DTPREL16_HI", /* name */
112671671b9obrien	 FALSE,			/* partial_inplace */
112771671b9obrien	 0,			/* src_mask */
112871671b9obrien	 0xffff,		/* dst_mask */
112971671b9obrien	 FALSE),		/* pcrel_offset */
113071671b9obrien
113171671b9obrien  /* Like GOT_DTPREL16_HI, but adjust for low 16 bits.  */
113271671b9obrien  HOWTO (R_PPC_GOT_DTPREL16_HA,
113371671b9obrien	 16,			/* rightshift */
113471671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
113571671b9obrien	 16,			/* bitsize */
113671671b9obrien	 FALSE,			/* pc_relative */
113771671b9obrien	 0,			/* bitpos */
113871671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
113971671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
114071671b9obrien	 "R_PPC_GOT_DTPREL16_HA", /* name */
114171671b9obrien	 FALSE,			/* partial_inplace */
114271671b9obrien	 0,			/* src_mask */
114371671b9obrien	 0xffff,		/* dst_mask */
114471671b9obrien	 FALSE),		/* pcrel_offset */
114571671b9obrien
114671671b9obrien  /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
114771671b9obrien     offset to the entry.  */
114871671b9obrien  HOWTO (R_PPC_GOT_TPREL16,
114971671b9obrien	 0,			/* rightshift */
115071671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
115171671b9obrien	 16,			/* bitsize */
115271671b9obrien	 FALSE,			/* pc_relative */
115371671b9obrien	 0,			/* bitpos */
115471671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
115571671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
115671671b9obrien	 "R_PPC_GOT_TPREL16",	/* name */
115771671b9obrien	 FALSE,			/* partial_inplace */
115871671b9obrien	 0,			/* src_mask */
115971671b9obrien	 0xffff,		/* dst_mask */
116071671b9obrien	 FALSE),		/* pcrel_offset */
116171671b9obrien
116271671b9obrien  /* Like GOT_TPREL16, but no overflow.  */
116371671b9obrien  HOWTO (R_PPC_GOT_TPREL16_LO,
116471671b9obrien	 0,			/* rightshift */
116571671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
116671671b9obrien	 16,			/* bitsize */
116771671b9obrien	 FALSE,			/* pc_relative */
116871671b9obrien	 0,			/* bitpos */
116971671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
117071671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
117171671b9obrien	 "R_PPC_GOT_TPREL16_LO", /* name */
117271671b9obrien	 FALSE,			/* partial_inplace */
117371671b9obrien	 0,			/* src_mask */
117471671b9obrien	 0xffff,		/* dst_mask */
117571671b9obrien	 FALSE),		/* pcrel_offset */
117671671b9obrien
117771671b9obrien  /* Like GOT_TPREL16_LO, but next higher group of 16 bits.  */
117871671b9obrien  HOWTO (R_PPC_GOT_TPREL16_HI,
117971671b9obrien	 16,			/* rightshift */
118071671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
118171671b9obrien	 16,			/* bitsize */
118271671b9obrien	 FALSE,			/* pc_relative */
118371671b9obrien	 0,			/* bitpos */
118471671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
118571671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
118671671b9obrien	 "R_PPC_GOT_TPREL16_HI", /* name */
118771671b9obrien	 FALSE,			/* partial_inplace */
118871671b9obrien	 0,			/* src_mask */
118971671b9obrien	 0xffff,		/* dst_mask */
119071671b9obrien	 FALSE),		/* pcrel_offset */
119171671b9obrien
119271671b9obrien  /* Like GOT_TPREL16_HI, but adjust for low 16 bits.  */
119371671b9obrien  HOWTO (R_PPC_GOT_TPREL16_HA,
119471671b9obrien	 16,			/* rightshift */
119571671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
119671671b9obrien	 16,			/* bitsize */
119771671b9obrien	 FALSE,			/* pc_relative */
119871671b9obrien	 0,			/* bitpos */
119971671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
120071671b9obrien	 ppc_elf_unhandled_reloc, /* special_function */
120171671b9obrien	 "R_PPC_GOT_TPREL16_HA", /* name */
120271671b9obrien	 FALSE,			/* partial_inplace */
120371671b9obrien	 0,			/* src_mask */
120471671b9obrien	 0xffff,		/* dst_mask */
120571671b9obrien	 FALSE),		/* pcrel_offset */
120671671b9obrien
120771671b9obrien  /* The remaining relocs are from the Embedded ELF ABI, and are not
120871671b9obrien     in the SVR4 ELF ABI.  */
120971671b9obrien
121071671b9obrien  /* 32 bit value resulting from the addend minus the symbol.  */
121171671b9obrien  HOWTO (R_PPC_EMB_NADDR32,	/* type */
121271671b9obrien	 0,			/* rightshift */
121371671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
121471671b9obrien	 32,			/* bitsize */
121571671b9obrien	 FALSE,			/* pc_relative */
121671671b9obrien	 0,			/* bitpos */
121771671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
121871671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
121971671b9obrien	 "R_PPC_EMB_NADDR32",	/* name */
122071671b9obrien	 FALSE,			/* partial_inplace */
122171671b9obrien	 0,			/* src_mask */
122271671b9obrien	 0xffffffff,		/* dst_mask */
122371671b9obrien	 FALSE),		/* pcrel_offset */
122471671b9obrien
122571671b9obrien  /* 16 bit value resulting from the addend minus the symbol.  */
122671671b9obrien  HOWTO (R_PPC_EMB_NADDR16,	/* type */
122771671b9obrien	 0,			/* rightshift */
122871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
122971671b9obrien	 16,			/* bitsize */
123071671b9obrien	 FALSE,			/* pc_relative */
123171671b9obrien	 0,			/* bitpos */
123271671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
123371671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
123471671b9obrien	 "R_PPC_EMB_NADDR16",	/* name */
123571671b9obrien	 FALSE,			/* partial_inplace */
123671671b9obrien	 0,			/* src_mask */
123771671b9obrien	 0xffff,		/* dst_mask */
123871671b9obrien	 FALSE),		/* pcrel_offset */
123971671b9obrien
124071671b9obrien  /* 16 bit value resulting from the addend minus the symbol.  */
124171671b9obrien  HOWTO (R_PPC_EMB_NADDR16_LO,	/* type */
124271671b9obrien	 0,			/* rightshift */
124371671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
124471671b9obrien	 16,			/* bitsize */
124571671b9obrien	 FALSE,			/* pc_relative */
124671671b9obrien	 0,			/* bitpos */
124771671b9obrien	 complain_overflow_dont,/* complain_on_overflow */
124871671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
124971671b9obrien	 "R_PPC_EMB_ADDR16_LO",	/* name */
125071671b9obrien	 FALSE,			/* partial_inplace */
125171671b9obrien	 0,			/* src_mask */
125271671b9obrien	 0xffff,		/* dst_mask */
125371671b9obrien	 FALSE),		/* pcrel_offset */
125471671b9obrien
125571671b9obrien  /* The high order 16 bits of the addend minus the symbol.  */
125671671b9obrien  HOWTO (R_PPC_EMB_NADDR16_HI,	/* type */
125771671b9obrien	 16,			/* rightshift */
125871671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
125971671b9obrien	 16,			/* bitsize */
126071671b9obrien	 FALSE,			/* pc_relative */
126171671b9obrien	 0,			/* bitpos */
126271671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
126371671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
126471671b9obrien	 "R_PPC_EMB_NADDR16_HI", /* name */
126571671b9obrien	 FALSE,			/* partial_inplace */
126671671b9obrien	 0,			/* src_mask */
126771671b9obrien	 0xffff,		/* dst_mask */
126871671b9obrien	 FALSE),		/* pcrel_offset */
126971671b9obrien
127071671b9obrien  /* The high order 16 bits of the result of the addend minus the address,
127171671b9obrien     plus 1 if the contents of the low 16 bits, treated as a signed number,
127271671b9obrien     is negative.  */
127371671b9obrien  HOWTO (R_PPC_EMB_NADDR16_HA,	/* type */
127471671b9obrien	 16,			/* rightshift */
127571671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
127671671b9obrien	 16,			/* bitsize */
127771671b9obrien	 FALSE,			/* pc_relative */
127871671b9obrien	 0,			/* bitpos */
127971671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
128071671b9obrien	 ppc_elf_addr16_ha_reloc, /* special_function */
128171671b9obrien	 "R_PPC_EMB_NADDR16_HA", /* name */
128271671b9obrien	 FALSE,			/* partial_inplace */
128371671b9obrien	 0,			/* src_mask */
128471671b9obrien	 0xffff,		/* dst_mask */
128571671b9obrien	 FALSE),		/* pcrel_offset */
128671671b9obrien
128771671b9obrien  /* 16 bit value resulting from allocating a 4 byte word to hold an
128871671b9obrien     address in the .sdata section, and returning the offset from
128971671b9obrien     _SDA_BASE_ for that relocation.  */
129071671b9obrien  HOWTO (R_PPC_EMB_SDAI16,	/* type */
129171671b9obrien	 0,			/* rightshift */
129271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
129371671b9obrien	 16,			/* bitsize */
129471671b9obrien	 FALSE,			/* pc_relative */
129571671b9obrien	 0,			/* bitpos */
129671671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
129771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
129871671b9obrien	 "R_PPC_EMB_SDAI16",	/* name */
129971671b9obrien	 FALSE,			/* partial_inplace */
130071671b9obrien	 0,			/* src_mask */
130171671b9obrien	 0xffff,		/* dst_mask */
130271671b9obrien	 FALSE),		/* pcrel_offset */
130371671b9obrien
130471671b9obrien  /* 16 bit value resulting from allocating a 4 byte word to hold an
130571671b9obrien     address in the .sdata2 section, and returning the offset from
130671671b9obrien     _SDA2_BASE_ for that relocation.  */
130771671b9obrien  HOWTO (R_PPC_EMB_SDA2I16,	/* type */
130871671b9obrien	 0,			/* rightshift */
130971671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
131071671b9obrien	 16,			/* bitsize */
131171671b9obrien	 FALSE,			/* pc_relative */
131271671b9obrien	 0,			/* bitpos */
131371671b9obrien	 complain_overflow_bitfield, /* complain_on_overflow */
131471671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
131571671b9obrien	 "R_PPC_EMB_SDA2I16",	/* name */
131671671b9obrien	 FALSE,			/* partial_inplace */
131771671b9obrien	 0,			/* src_mask */
131871671b9obrien	 0xffff,		/* dst_mask */
131971671b9obrien	 FALSE),		/* pcrel_offset */
132071671b9obrien
132171671b9obrien  /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with
132271671b9obrien     small data items.	 */
132371671b9obrien  HOWTO (R_PPC_EMB_SDA2REL,	/* type */
132471671b9obrien	 0,			/* rightshift */
132571671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
132671671b9obrien	 16,			/* bitsize */
132771671b9obrien	 FALSE,			/* pc_relative */
132871671b9obrien	 0,			/* bitpos */
132971671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
133071671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
133171671b9obrien	 "R_PPC_EMB_SDA2REL",	/* name */
133271671b9obrien	 FALSE,			/* partial_inplace */
133371671b9obrien	 0,			/* src_mask */
133471671b9obrien	 0xffff,		/* dst_mask */
133571671b9obrien	 FALSE),		/* pcrel_offset */
133671671b9obrien
133771671b9obrien  /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit
133871671b9obrien     signed offset from the appropriate base, and filling in the register
133971671b9obrien     field with the appropriate register (0, 2, or 13).  */
134071671b9obrien  HOWTO (R_PPC_EMB_SDA21,	/* type */
134171671b9obrien	 0,			/* rightshift */
134271671b9obrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
134371671b9obrien	 16,			/* bitsize */
134471671b9obrien	 FALSE,			/* pc_relative */
134571671b9obrien	 0,			/* bitpos */
134671671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
134771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
134871671b9obrien	 "R_PPC_EMB_SDA21",	/* name */
134971671b9obrien	 FALSE,			/* partial_inplace */
135071671b9obrien	 0,			/* src_mask */
135171671b9obrien	 0xffff,		/* dst_mask */
135271671b9obrien	 FALSE),		/* pcrel_offset */
135371671b9obrien
135471671b9obrien  /* Relocation not handled: R_PPC_EMB_MRKREF */
135571671b9obrien  /* Relocation not handled: R_PPC_EMB_RELSEC16 */
135671671b9obrien  /* Relocation not handled: R_PPC_EMB_RELST_LO */
135771671b9obrien  /* Relocation not handled: R_PPC_EMB_RELST_HI */
135871671b9obrien  /* Relocation not handled: R_PPC_EMB_RELST_HA */
135971671b9obrien  /* Relocation not handled: R_PPC_EMB_BIT_FLD */
136071671b9obrien
136171671b9obrien  /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling
136271671b9obrien     in the 16 bit signed offset from the appropriate base, and filling in the
136371671b9obrien     register field with the appropriate register (0, 2, or 13).  */
136471671b9obrien  HOWTO (R_PPC_EMB_RELSDA,	/* type */
136571671b9obrien	 0,			/* rightshift */
136671671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
136771671b9obrien	 16,			/* bitsize */
136871671b9obrien	 TRUE,			/* pc_relative */
136971671b9obrien	 0,			/* bitpos */
137071671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
137171671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
137271671b9obrien	 "R_PPC_EMB_RELSDA",	/* name */
137371671b9obrien	 FALSE,			/* partial_inplace */
137471671b9obrien	 0,			/* src_mask */
137571671b9obrien	 0xffff,		/* dst_mask */
137671671b9obrien	 FALSE),		/* pcrel_offset */
137771671b9obrien
13780acbbeedim  /* A 16 bit relative relocation.  */
13790acbbeedim  HOWTO (R_PPC_REL16,		/* type */
138071671b9obrien	 0,			/* rightshift */
13810acbbeedim	 1,			/* size (0 = byte, 1 = short, 2 = long) */
13820acbbeedim	 16,			/* bitsize */
13830acbbeedim	 TRUE,			/* pc_relative */
138471671b9obrien	 0,			/* bitpos */
13850acbbeedim	 complain_overflow_bitfield, /* complain_on_overflow */
138671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
13870acbbeedim	 "R_PPC_REL16",		/* name */
138871671b9obrien	 FALSE,			/* partial_inplace */
138971671b9obrien	 0,			/* src_mask */
13900acbbeedim	 0xffff,		/* dst_mask */
13910acbbeedim	 TRUE),			/* pcrel_offset */
139271671b9obrien
13930acbbeedim  /* A 16 bit relative relocation without overflow.  */
13940acbbeedim  HOWTO (R_PPC_REL16_LO,	/* type */
139571671b9obrien	 0,			/* rightshift */
13960acbbeedim	 1,			/* size (0 = byte, 1 = short, 2 = long) */
13970acbbeedim	 16,			/* bitsize */
13980acbbeedim	 TRUE,			/* pc_relative */
13990acbbeedim	 0,			/* bitpos */
14000acbbeedim	 complain_overflow_dont,/* complain_on_overflow */
14010acbbeedim	 bfd_elf_generic_reloc,	/* special_function */
14020acbbeedim	 "R_PPC_REL16_LO",	/* name */
14030acbbeedim	 FALSE,			/* partial_inplace */
14040acbbeedim	 0,			/* src_mask */
14050acbbeedim	 0xffff,		/* dst_mask */
14060acbbeedim	 TRUE),			/* pcrel_offset */
14070acbbeedim
14080acbbeedim  /* The high order 16 bits of a relative address.  */
14090acbbeedim  HOWTO (R_PPC_REL16_HI,	/* type */
14100acbbeedim	 16,			/* rightshift */
14110acbbeedim	 1,			/* size (0 = byte, 1 = short, 2 = long) */
14120acbbeedim	 16,			/* bitsize */
14130acbbeedim	 TRUE,			/* pc_relative */
141471671b9obrien	 0,			/* bitpos */
141571671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
141671671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
14170acbbeedim	 "R_PPC_REL16_HI",	/* name */
141871671b9obrien	 FALSE,			/* partial_inplace */
141971671b9obrien	 0,			/* src_mask */
14200acbbeedim	 0xffff,		/* dst_mask */
14210acbbeedim	 TRUE),			/* pcrel_offset */
14220acbbeedim
14230acbbeedim  /* The high order 16 bits of a relative address, plus 1 if the contents of
14240acbbeedim     the low 16 bits, treated as a signed number, is negative.  */
14250acbbeedim  HOWTO (R_PPC_REL16_HA,	/* type */
14260acbbeedim	 16,			/* rightshift */
14270acbbeedim	 1,			/* size (0 = byte, 1 = short, 2 = long) */
14280acbbeedim	 16,			/* bitsize */
14290acbbeedim	 TRUE,			/* pc_relative */
14300acbbeedim	 0,			/* bitpos */
14310acbbeedim	 complain_overflow_dont, /* complain_on_overflow */
14320acbbeedim	 ppc_elf_addr16_ha_reloc, /* special_function */
14330acbbeedim	 "R_PPC_REL16_HA",	/* name */
14340acbbeedim	 FALSE,			/* partial_inplace */
14350acbbeedim	 0,			/* src_mask */
14360acbbeedim	 0xffff,		/* dst_mask */
14370acbbeedim	 TRUE),			/* pcrel_offset */
143871671b9obrien
143971671b9obrien  /* GNU extension to record C++ vtable hierarchy.  */
144071671b9obrien  HOWTO (R_PPC_GNU_VTINHERIT,	/* type */
144171671b9obrien	 0,			/* rightshift */
144271671b9obrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
144371671b9obrien	 0,			/* bitsize */
144471671b9obrien	 FALSE,			/* pc_relative */
144571671b9obrien	 0,			/* bitpos */
144671671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
144771671b9obrien	 NULL,			/* special_function */
144871671b9obrien	 "R_PPC_GNU_VTINHERIT",	/* name */
144971671b9obrien	 FALSE,			/* partial_inplace */
145071671b9obrien	 0,			/* src_mask */
145171671b9obrien	 0,			/* dst_mask */
145271671b9obrien	 FALSE),		/* pcrel_offset */
145371671b9obrien
145471671b9obrien  /* GNU extension to record C++ vtable member usage.  */
145571671b9obrien  HOWTO (R_PPC_GNU_VTENTRY,	/* type */
145671671b9obrien	 0,			/* rightshift */
145771671b9obrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
145871671b9obrien	 0,			/* bitsize */
145971671b9obrien	 FALSE,			/* pc_relative */
146071671b9obrien	 0,			/* bitpos */
146171671b9obrien	 complain_overflow_dont, /* complain_on_overflow */
146271671b9obrien	 NULL,			/* special_function */
146371671b9obrien	 "R_PPC_GNU_VTENTRY",	/* name */
146471671b9obrien	 FALSE,			/* partial_inplace */
146571671b9obrien	 0,			/* src_mask */
146671671b9obrien	 0,			/* dst_mask */
146771671b9obrien	 FALSE),		/* pcrel_offset */
146871671b9obrien
146971671b9obrien  /* Phony reloc to handle AIX style TOC entries.  */
147071671b9obrien  HOWTO (R_PPC_TOC16,		/* type */
147171671b9obrien	 0,			/* rightshift */
147271671b9obrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
147371671b9obrien	 16,			/* bitsize */
147471671b9obrien	 FALSE,			/* pc_relative */
147571671b9obrien	 0,			/* bitpos */
147671671b9obrien	 complain_overflow_signed, /* complain_on_overflow */
147771671b9obrien	 bfd_elf_generic_reloc,	/* special_function */
147871671b9obrien	 "R_PPC_TOC16",		/* name */
147971671b9obrien	 FALSE,			/* partial_inplace */
148071671b9obrien	 0,			/* src_mask */
148171671b9obrien	 0xffff,		/* dst_mask */
148271671b9obrien	 FALSE),		/* pcrel_offset */
148371671b9obrien};
148471671b9obrien
148571671b9obrien/* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
148671671b9obrien
148771671b9obrienstatic void
148871671b9obrienppc_elf_howto_init (void)
148971671b9obrien{
149071671b9obrien  unsigned int i, type;
149171671b9obrien
149271671b9obrien  for (i = 0;
149371671b9obrien       i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
149471671b9obrien       i++)
149571671b9obrien    {
149671671b9obrien      type = ppc_elf_howto_raw[i].type;
149771671b9obrien      if (type >= (sizeof (ppc_elf_howto_table)
149871671b9obrien		   / sizeof (ppc_elf_howto_table[0])))
149971671b9obrien	abort ();
150071671b9obrien      ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
150171671b9obrien    }
150271671b9obrien}
150371671b9obrien
15040acbbeedimstatic reloc_howto_type *
15050acbbeedimppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
15060acbbeedim			   bfd_reloc_code_real_type code)
15070acbbeedim{
15080acbbeedim  enum elf_ppc_reloc_type r;
150971671b9obrien
15100acbbeedim  /* Initialize howto table if not already done.  */
15110acbbeedim  if (!ppc_elf_howto_table[R_PPC_ADDR32])
15120acbbeedim    ppc_elf_howto_init ();
151371671b9obrien
15140acbbeedim  switch (code)
15150acbbeedim    {
15160acbbeedim    default:
15170acbbeedim      return NULL;
151871671b9obrien
15190acbbeedim    case BFD_RELOC_NONE:		r = R_PPC_NONE;			break;
15200acbbeedim    case BFD_RELOC_32:			r = R_PPC_ADDR32;		break;
15210acbbeedim    case BFD_RELOC_PPC_BA26:		r = R_PPC_ADDR24;		break;
15220acbbeedim    case BFD_RELOC_16:			r = R_PPC_ADDR16;		break;
15230acbbeedim    case BFD_RELOC_LO16:		r = R_PPC_ADDR16_LO;		break;
15240acbbeedim    case BFD_RELOC_HI16:		r = R_PPC_ADDR16_HI;		break;
15250acbbeedim    case BFD_RELOC_HI16_S:		r = R_PPC_ADDR16_HA;		break;
15260acbbeedim    case BFD_RELOC_PPC_BA16:		r = R_PPC_ADDR14;		break;
15270acbbeedim    case BFD_RELOC_PPC_BA16_BRTAKEN:	r = R_PPC_ADDR14_BRTAKEN;	break;
15280acbbeedim    case BFD_RELOC_PPC_BA16_BRNTAKEN:	r = R_PPC_ADDR14_BRNTAKEN;	break;
15290acbbeedim    case BFD_RELOC_PPC_B26:		r = R_PPC_REL24;		break;
15300acbbeedim    case BFD_RELOC_PPC_B16:		r = R_PPC_REL14;		break;
15310acbbeedim    case BFD_RELOC_PPC_B16_BRTAKEN:	r = R_PPC_REL14_BRTAKEN;	break;
15320acbbeedim    case BFD_RELOC_PPC_B16_BRNTAKEN:	r = R_PPC_REL14_BRNTAKEN;	break;
15330acbbeedim    case BFD_RELOC_16_GOTOFF:		r = R_PPC_GOT16;		break;
15340acbbeedim    case BFD_RELOC_LO16_GOTOFF:		r = R_PPC_GOT16_LO;		break;
15350acbbeedim    case BFD_RELOC_HI16_GOTOFF:		r = R_PPC_GOT16_HI;		break;
15360acbbeedim    case BFD_RELOC_HI16_S_GOTOFF:	r = R_PPC_GOT16_HA;		break;
15370acbbeedim    case BFD_RELOC_24_PLT_PCREL:	r = R_PPC_PLTREL24;		break;
15380acbbeedim    case BFD_RELOC_PPC_COPY:		r = R_PPC_COPY;			break;
15390acbbeedim    case BFD_RELOC_PPC_GLOB_DAT:	r = R_PPC_GLOB_DAT;		break;
15400acbbeedim    case BFD_RELOC_PPC_LOCAL24PC:	r = R_PPC_LOCAL24PC;		break;
15410acbbeedim    case BFD_RELOC_32_PCREL:		r = R_PPC_REL32;		break;
15420acbbeedim    case BFD_RELOC_32_PLTOFF:		r = R_PPC_PLT32;		break;
15430acbbeedim    case BFD_RELOC_32_PLT_PCREL:	r = R_PPC_PLTREL32;		break;
15440acbbeedim    case BFD_RELOC_LO16_PLTOFF:		r = R_PPC_PLT16_LO;		break;
15450acbbeedim    case BFD_RELOC_HI16_PLTOFF:		r = R_PPC_PLT16_HI;		break;
15460acbbeedim    case BFD_RELOC_HI16_S_PLTOFF:	r = R_PPC_PLT16_HA;		break;
15470acbbeedim    case BFD_RELOC_GPREL16:		r = R_PPC_SDAREL16;		break;
15480acbbeedim    case BFD_RELOC_16_BASEREL:		r = R_PPC_SECTOFF;		break;
15490acbbeedim    case BFD_RELOC_LO16_BASEREL:	r = R_PPC_SECTOFF_LO;		break;
15500acbbeedim    case BFD_RELOC_HI16_BASEREL:	r = R_PPC_SECTOFF_HI;		break;
15510acbbeedim    case BFD_RELOC_HI16_S_BASEREL:	r = R_PPC_SECTOFF_HA;		break;
15520acbbeedim    case BFD_RELOC_CTOR:		r = R_PPC_ADDR32;		break;
15530acbbeedim    case BFD_RELOC_PPC_TOC16:		r = R_PPC_TOC16;		break;
15540acbbeedim    case BFD_RELOC_PPC_TLS:		r = R_PPC_TLS;			break;
155596e9bafjhibbits    case BFD_RELOC_PPC_TLSGD:		r = R_PPC_TLSGD;		break;
155696e9bafjhibbits    case BFD_RELOC_PPC_TLSLD:		r = R_PPC_TLSLD;		break;
15570acbbeedim    case BFD_RELOC_PPC_DTPMOD:		r = R_PPC_DTPMOD32;		break;
15580acbbeedim    case BFD_RELOC_PPC_TPREL16:		r = R_PPC_TPREL16;		break;
15590acbbeedim    case BFD_RELOC_PPC_TPREL16_LO:	r = R_PPC_TPREL16_LO;		break;
15600acbbeedim    case BFD_RELOC_PPC_TPREL16_HI:	r = R_PPC_TPREL16_HI;		break;
15610acbbeedim    case BFD_RELOC_PPC_TPREL16_HA:	r = R_PPC_TPREL16_HA;		break;
15620acbbeedim    case BFD_RELOC_PPC_TPREL:		r = R_PPC_TPREL32;		break;
15630acbbeedim    case BFD_RELOC_PPC_DTPREL16:	r = R_PPC_DTPREL16;		break;
15640acbbeedim    case BFD_RELOC_PPC_DTPREL16_LO:	r = R_PPC_DTPREL16_LO;		break;
15650acbbeedim    case BFD_RELOC_PPC_DTPREL16_HI:	r = R_PPC_DTPREL16_HI;		break;
15660acbbeedim    case BFD_RELOC_PPC_DTPREL16_HA:	r = R_PPC_DTPREL16_HA;		break;
15670acbbeedim    case BFD_RELOC_PPC_DTPREL:		r = R_PPC_DTPREL32;		break;
15680acbbeedim    case BFD_RELOC_PPC_GOT_TLSGD16:	r = R_PPC_GOT_TLSGD16;		break;
15690acbbeedim    case BFD_RELOC_PPC_GOT_TLSGD16_LO:	r = R_PPC_GOT_TLSGD16_LO;	break;
15700acbbeedim    case BFD_RELOC_PPC_GOT_TLSGD16_HI:	r = R_PPC_GOT_TLSGD16_HI;	break;
15710acbbeedim    case BFD_RELOC_PPC_GOT_TLSGD16_HA:	r = R_PPC_GOT_TLSGD16_HA;	break;
15720acbbeedim    case BFD_RELOC_PPC_GOT_TLSLD16:	r = R_PPC_GOT_TLSLD16;		break;
15730acbbeedim    case BFD_RELOC_PPC_GOT_TLSLD16_LO:	r = R_PPC_GOT_TLSLD16_LO;	break;
15740acbbeedim    case BFD_RELOC_PPC_GOT_TLSLD16_HI:	r = R_PPC_GOT_TLSLD16_HI;	break;
15750acbbeedim    case BFD_RELOC_PPC_GOT_TLSLD16_HA:	r = R_PPC_GOT_TLSLD16_HA;	break;
15760acbbeedim    case BFD_RELOC_PPC_GOT_TPREL16:	r = R_PPC_GOT_TPREL16;		break;
15770acbbeedim    case BFD_RELOC_PPC_GOT_TPREL16_LO:	r = R_PPC_GOT_TPREL16_LO;	break;
15780acbbeedim    case BFD_RELOC_PPC_GOT_TPREL16_HI:	r = R_PPC_GOT_TPREL16_HI;	break;
15790acbbeedim    case BFD_RELOC_PPC_GOT_TPREL16_HA:	r = R_PPC_GOT_TPREL16_HA;	break;
15800acbbeedim    case BFD_RELOC_PPC_GOT_DTPREL16:	r = R_PPC_GOT_DTPREL16;		break;
15810acbbeedim    case BFD_RELOC_PPC_GOT_DTPREL16_LO:	r = R_PPC_GOT_DTPREL16_LO;	break;
15820acbbeedim    case BFD_RELOC_PPC_GOT_DTPREL16_HI:	r = R_PPC_GOT_DTPREL16_HI;	break;
15830acbbeedim    case BFD_RELOC_PPC_GOT_DTPREL16_HA:	r = R_PPC_GOT_DTPREL16_HA;	break;
15840acbbeedim    case BFD_RELOC_PPC_EMB_NADDR32:	r = R_PPC_EMB_NADDR32;		break;
15850acbbeedim    case BFD_RELOC_PPC_EMB_NADDR16:	r = R_PPC_EMB_NADDR16;		break;
15860acbbeedim    case BFD_RELOC_PPC_EMB_NADDR16_LO:	r = R_PPC_EMB_NADDR16_LO;	break;
15870acbbeedim    case BFD_RELOC_PPC_EMB_NADDR16_HI:	r = R_PPC_EMB_NADDR16_HI;	break;
15880acbbeedim    case BFD_RELOC_PPC_EMB_NADDR16_HA:	r = R_PPC_EMB_NADDR16_HA;	break;
15890acbbeedim    case BFD_RELOC_PPC_EMB_SDAI16:	r = R_PPC_EMB_SDAI16;		break;
15900acbbeedim    case BFD_RELOC_PPC_EMB_SDA2I16:	r = R_PPC_EMB_SDA2I16;		break;
15910acbbeedim    case BFD_RELOC_PPC_EMB_SDA2REL:	r = R_PPC_EMB_SDA2REL;		break;
15920acbbeedim    case BFD_RELOC_PPC_EMB_SDA21:	r = R_PPC_EMB_SDA21;		break;
15930acbbeedim    case BFD_RELOC_PPC_EMB_MRKREF:	r = R_PPC_EMB_MRKREF;		break;
15940acbbeedim    case BFD_RELOC_PPC_EMB_RELSEC16:	r = R_PPC_EMB_RELSEC16;		break;
15950acbbeedim    case BFD_RELOC_PPC_EMB_RELST_LO:	r = R_PPC_EMB_RELST_LO;		break;
15960acbbeedim    case BFD_RELOC_PPC_EMB_RELST_HI:	r = R_PPC_EMB_RELST_HI;		break;
15970acbbeedim    case BFD_RELOC_PPC_EMB_RELST_HA:	r = R_PPC_EMB_RELST_HA;		break;
15980acbbeedim    case BFD_RELOC_PPC_EMB_BIT_FLD:	r = R_PPC_EMB_BIT_FLD;		break;
15990acbbeedim    case BFD_RELOC_PPC_EMB_RELSDA:	r = R_PPC_EMB_RELSDA;		break;
16000acbbeedim    case BFD_RELOC_16_PCREL:		r = R_PPC_REL16;		break;
16010acbbeedim    case BFD_RELOC_LO16_PCREL:		r = R_PPC_REL16_LO;		break;
16020acbbeedim    case BFD_RELOC_HI16_PCREL:		r = R_PPC_REL16_HI;		break;
16030acbbeedim    case BFD_RELOC_HI16_S_PCREL:	r = R_PPC_REL16_HA;		break;
16040acbbeedim    case BFD_RELOC_VTABLE_INHERIT:	r = R_PPC_GNU_VTINHERIT;	break;
16050acbbeedim    case BFD_RELOC_VTABLE_ENTRY:	r = R_PPC_GNU_VTENTRY;		break;
16060acbbeedim    }
160771671b9obrien
16080acbbeedim  return ppc_elf_howto_table[r];
16090acbbeedim};
161071671b9obrien
1611d0f678fdimstatic reloc_howto_type *
1612d0f678fdimppc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1613d0f678fdim			   const char *r_name)
1614d0f678fdim{
1615d0f678fdim  unsigned int i;
1616d0f678fdim
1617d0f678fdim  for (i = 0;
1618d0f678fdim       i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
1619d0f678fdim       i++)
1620d0f678fdim    if (ppc_elf_howto_raw[i].name != NULL
1621d0f678fdim	&& strcasecmp (ppc_elf_howto_raw[i].name, r_name) == 0)
1622d0f678fdim      return &ppc_elf_howto_raw[i];
1623d0f678fdim
1624d0f678fdim  return NULL;
1625d0f678fdim}
1626d0f678fdim
16270acbbeedim/* Set the howto pointer for a PowerPC ELF reloc.  */
162871671b9obrien
16290acbbeedimstatic void
16300acbbeedimppc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
16310acbbeedim		       arelent *cache_ptr,
16320acbbeedim		       Elf_Internal_Rela *dst)
16330acbbeedim{
16340acbbeedim  /* Initialize howto table if not already done.  */
16350acbbeedim  if (!ppc_elf_howto_table[R_PPC_ADDR32])
16360acbbeedim    ppc_elf_howto_init ();
163771671b9obrien
16380acbbeedim  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
16390acbbeedim  cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
1640d0f678fdim
1641d0f678fdim  /* Just because the above assert didn't trigger doesn't mean that
1642d0f678fdim     ELF32_R_TYPE (dst->r_info) is necessarily a valid relocation.  */
1643d0f678fdim  if (!cache_ptr->howto)
1644d0f678fdim    {
1645d0f678fdim      (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
1646d0f678fdim                             abfd, ELF32_R_TYPE (dst->r_info));
1647d0f678fdim      bfd_set_error (bfd_error_bad_value);
1648d0f678fdim
1649d0f678fdim      cache_ptr->howto = ppc_elf_howto_table[R_PPC_NONE];
1650d0f678fdim    }
16510acbbeedim}
165271671b9obrien
16530acbbeedim/* Handle the R_PPC_ADDR16_HA and R_PPC_REL16_HA relocs.  */
165471671b9obrien
16550acbbeedimstatic bfd_reloc_status_type
16560acbbeedimppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
16570acbbeedim			 arelent *reloc_entry,
16580acbbeedim			 asymbol *symbol,
16590acbbeedim			 void *data ATTRIBUTE_UNUSED,
16600acbbeedim			 asection *input_section,
16610acbbeedim			 bfd *output_bfd,
16620acbbeedim			 char **error_message ATTRIBUTE_UNUSED)
16630acbbeedim{
16640acbbeedim  bfd_vma relocation;
166571671b9obrien
16660acbbeedim  if (output_bfd != NULL)
16670acbbeedim    {
16680acbbeedim      reloc_entry->address += input_section->output_offset;
16690acbbeedim      return bfd_reloc_ok;
16700acbbeedim    }
167171671b9obrien
16720acbbeedim  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
16730acbbeedim    return bfd_reloc_outofrange;
167471671b9obrien
16750acbbeedim  if (bfd_is_com_section (symbol->section))
16760acbbeedim    relocation = 0;
167771671b9obrien  else
16780acbbeedim    relocation = symbol->value;
167971671b9obrien
16800acbbeedim  relocation += symbol->section->output_section->vma;
16810acbbeedim  relocation += symbol->section->output_offset;
16820acbbeedim  relocation += reloc_entry->addend;
16830acbbeedim  if (reloc_entry->howto->pc_relative)
16840acbbeedim    relocation -= reloc_entry->address;
168571671b9obrien
16860acbbeedim  reloc_entry->addend += (relocation & 0x8000) << 1;
168771671b9obrien
16880acbbeedim  return bfd_reloc_continue;
16890acbbeedim}
169071671b9obrien
16910acbbeedimstatic bfd_reloc_status_type
16920acbbeedimppc_elf_unhandled_reloc (bfd *abfd,
16930acbbeedim			 arelent *reloc_entry,
16940acbbeedim			 asymbol *symbol,
16950acbbeedim			 void *data,
16960acbbeedim			 asection *input_section,
16970acbbeedim			 bfd *output_bfd,
16980acbbeedim			 char **error_message)
16990acbbeedim{
17000acbbeedim  /* If this is a relocatable link (output_bfd test tells us), just
17010acbbeedim     call the generic function.  Any adjustment will be done at final
17020acbbeedim     link time.  */
17030acbbeedim  if (output_bfd != NULL)
17040acbbeedim    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
17050acbbeedim				  input_section, output_bfd, error_message);
170671671b9obrien
17070acbbeedim  if (error_message != NULL)
17080acbbeedim    {
17090acbbeedim      static char buf[60];
17100acbbeedim      sprintf (buf, _("generic linker can't handle %s"),
17110acbbeedim	       reloc_entry->howto->name);
17120acbbeedim      *error_message = buf;
17130acbbeedim    }
17140acbbeedim  return bfd_reloc_dangerous;
17150acbbeedim}
17160acbbeedim
17170acbbeedim/* Sections created by the linker.  */
171871671b9obrien
17190acbbeedimtypedef struct elf_linker_section
17200acbbeedim{
17210acbbeedim  /* Pointer to the bfd section.  */
17220acbbeedim  asection *section;
17230acbbeedim  /* Section name.  */
17240acbbeedim  const char *name;
17250acbbeedim  /* Associated bss section name.  */
17260acbbeedim  const char *bss_name;
17270acbbeedim  /* Associated symbol name.  */
17280acbbeedim  const char *sym_name;
17290acbbeedim  /* Associated symbol.  */
17300acbbeedim  struct elf_link_hash_entry *sym;
17310acbbeedim} elf_linker_section_t;
173271671b9obrien
17330acbbeedim/* Linked list of allocated pointer entries.  This hangs off of the
17340acbbeedim   symbol lists, and provides allows us to return different pointers,
17350acbbeedim   based on different addend's.  */
173671671b9obrien
17370acbbeedimtypedef struct elf_linker_section_pointers
17380acbbeedim{
17390acbbeedim  /* next allocated pointer for this symbol */
17400acbbeedim  struct elf_linker_section_pointers *next;
17410acbbeedim  /* offset of pointer from beginning of section */
17420acbbeedim  bfd_vma offset;
17430acbbeedim  /* addend used */
17440acbbeedim  bfd_vma addend;
17450acbbeedim  /* which linker section this is */
17460acbbeedim  elf_linker_section_t *lsect;
17470acbbeedim} elf_linker_section_pointers_t;
174871671b9obrien
17490acbbeedimstruct ppc_elf_obj_tdata
17500acbbeedim{
17510acbbeedim  struct elf_obj_tdata elf;
175271671b9obrien
17530acbbeedim  /* A mapping from local symbols to offsets into the various linker
17540acbbeedim     sections added.  This is index by the symbol index.  */
17550acbbeedim  elf_linker_section_pointers_t **linker_section_pointers;
1756d0f678fdim
1757d0f678fdim  /* Flags used to auto-detect plt type.  */
1758d0f678fdim  unsigned int makes_plt_call : 1;
1759d0f678fdim  unsigned int has_rel16 : 1;
17600acbbeedim};
176171671b9obrien
17620acbbeedim#define ppc_elf_tdata(bfd) \
17630acbbeedim  ((struct ppc_elf_obj_tdata *) (bfd)->tdata.any)
176471671b9obrien
17650acbbeedim#define elf_local_ptr_offsets(bfd) \
17660acbbeedim  (ppc_elf_tdata (bfd)->linker_section_pointers)
176771671b9obrien
17680acbbeedim/* Override the generic function because we store some extras.  */
176971671b9obrien
17700acbbeedimstatic bfd_boolean
17710acbbeedimppc_elf_mkobject (bfd *abfd)
17720acbbeedim{
17730acbbeedim  if (abfd->tdata.any == NULL)
1774d0f678fdim    {
1775d0f678fdim      bfd_size_type amt = sizeof (struct ppc_elf_obj_tdata);
1776d0f678fdim      abfd->tdata.any = bfd_zalloc (abfd, amt);
1777d0f678fdim      if (abfd->tdata.any == NULL)
1778d0f678fdim	return FALSE;
1779d0f678fdim    }
1780d0f678fdim  return bfd_elf_mkobject (abfd);
17810acbbeedim}
178271671b9obrien
17830acbbeedim/* Fix bad default arch selected for a 32 bit input bfd when the
17840acbbeedim   default is 64 bit.  */
178571671b9obrien
17860acbbeedimstatic bfd_boolean
17870acbbeedimppc_elf_object_p (bfd *abfd)
17880acbbeedim{
17890acbbeedim  if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
17900acbbeedim    {
17910acbbeedim      Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
179271671b9obrien
17930acbbeedim      if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32)
179471671b9obrien	{
17950acbbeedim	  /* Relies on arch after 64 bit default being 32 bit default.  */
17960acbbeedim	  abfd->arch_info = abfd->arch_info->next;
17970acbbeedim	  BFD_ASSERT (abfd->arch_info->bits_per_word == 32);
17980acbbeedim	}
17990acbbeedim    }
18000acbbeedim  return TRUE;
18010acbbeedim}
180271671b9obrien
18030acbbeedim/* Function to set whether a module needs the -mrelocatable bit set.  */
180471671b9obrien
18050acbbeedimstatic bfd_boolean
18060acbbeedimppc_elf_set_private_flags (bfd *abfd, flagword flags)
18070acbbeedim{
18080acbbeedim  BFD_ASSERT (!elf_flags_init (abfd)
18090acbbeedim	      || elf_elfheader (abfd)->e_flags == flags);
181071671b9obrien
18110acbbeedim  elf_elfheader (abfd)->e_flags = flags;
18120acbbeedim  elf_flags_init (abfd) = TRUE;
18130acbbeedim  return TRUE;
18140acbbeedim}
181571671b9obrien
18160acbbeedim/* Support for core dump NOTE sections.  */
181771671b9obrien
18180acbbeedimstatic bfd_boolean
18190acbbeedimppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
18200acbbeedim{
18210acbbeedim  int offset;
18220acbbeedim  unsigned int size;
182371671b9obrien
18240acbbeedim  switch (note->descsz)
18250acbbeedim    {
18260acbbeedim    default:
18270acbbeedim      return FALSE;
182871671b9obrien
18290acbbeedim    case 268:		/* Linux/PPC.  */
18300acbbeedim      /* pr_cursig */
18310acbbeedim      elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
183271671b9obrien
18330acbbeedim      /* pr_pid */
18340acbbeedim      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
18350acbbeedim
18360acbbeedim      /* pr_reg */
18370acbbeedim      offset = 72;
18380acbbeedim      size = 192;
18390acbbeedim
18400acbbeedim      break;
184171671b9obrien    }
184271671b9obrien
18430acbbeedim  /* Make a ".reg/999" section.  */
18440acbbeedim  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
18450acbbeedim					  size, note->descpos + offset);
18460acbbeedim}
184771671b9obrien
18480acbbeedimstatic bfd_boolean
18490acbbeedimppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
18500acbbeedim{
18510acbbeedim  switch (note->descsz)
18520acbbeedim    {
18530acbbeedim    default:
18540acbbeedim      return FALSE;
185571671b9obrien
18560acbbeedim    case 128:		/* Linux/PPC elf_prpsinfo.  */
18570acbbeedim      elf_tdata (abfd)->core_program
18580acbbeedim	= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
18590acbbeedim      elf_tdata (abfd)->core_command
18600acbbeedim	= _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
186171671b9obrien    }
186271671b9obrien
18630acbbeedim  /* Note that for some reason, a spurious space is tacked
18640acbbeedim     onto the end of the args in some (at least one anyway)
18650acbbeedim     implementations, so strip it off if it exists.  */
186671671b9obrien
18670acbbeedim  {
18680acbbeedim    char *command = elf_tdata (abfd)->core_command;
18690acbbeedim    int n = strlen (command);
187071671b9obrien
18710acbbeedim    if (0 < n && command[n - 1] == ' ')
18720acbbeedim      command[n - 1] = '\0';
18730acbbeedim  }
187471671b9obrien
187571671b9obrien  return TRUE;
18760acbbeedim}
187771671b9obrien
1878d0f678fdimstatic char *
1879d0f678fdimppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
1880d0f678fdim{
1881d0f678fdim  switch (note_type)
1882d0f678fdim    {
1883d0f678fdim    default:
1884d0f678fdim      return NULL;
1885d0f678fdim
1886d0f678fdim    case NT_PRPSINFO:
1887d0f678fdim      {
1888d0f678fdim	char data[128];
1889d0f678fdim	va_list ap;
1890d0f678fdim
1891d0f678fdim	va_start (ap, note_type);
1892d0f678fdim	memset (data, 0, 32);
1893d0f678fdim	strncpy (data + 32, va_arg (ap, const char *), 16);
1894d0f678fdim	strncpy (data + 48, va_arg (ap, const char *), 80);
1895d0f678fdim	va_end (ap);
1896d0f678fdim	return elfcore_write_note (abfd, buf, bufsiz,
1897d0f678fdim				   "CORE", note_type, data, sizeof (data));
1898d0f678fdim      }
1899d0f678fdim
1900d0f678fdim    case NT_PRSTATUS:
1901d0f678fdim      {
1902d0f678fdim	char data[268];
1903d0f678fdim	va_list ap;
1904d0f678fdim	long pid;
1905d0f678fdim	int cursig;
1906d0f678fdim	const void *greg;
1907d0f678fdim
1908d0f678fdim	va_start (ap, note_type);
1909d0f678fdim	memset (data, 0, 72);
1910d0f678fdim	pid = va_arg (ap, long);
1911d0f678fdim	bfd_put_32 (abfd, pid, data + 24);
1912d0f678fdim	cursig = va_arg (ap, int);
1913d0f678fdim	bfd_put_16 (abfd, cursig, data + 12);
1914d0f678fdim	greg = va_arg (ap, const void *);
1915d0f678fdim	memcpy (data + 72, greg, 192);
1916d0f678fdim	memset (data + 264, 0, 4);
1917d0f678fdim	va_end (ap);
1918d0f678fdim	return elfcore_write_note (abfd, buf, bufsiz,
1919d0f678fdim				   "CORE", note_type, data, sizeof (data));
1920d0f678fdim      }
1921d0f678fdim    }
1922d0f678fdim}
1923d0f678fdim
19240acbbeedim/* Return address for Ith PLT stub in section PLT, for relocation REL
19250acbbeedim   or (bfd_vma) -1 if it should not be included.  */
19260acbbeedim
19270acbbeedimstatic bfd_vma
19280acbbeedimppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
19290acbbeedim		     const asection *plt ATTRIBUTE_UNUSED,
19300acbbeedim		     const arelent *rel)
19310acbbeedim{
19320acbbeedim  return rel->address;
193371671b9obrien}
19340acbbeedim
19350acbbeedim/* Handle a PowerPC specific section when reading an object file.  This
19360acbbeedim   is called when bfd_section_from_shdr finds a section with an unknown
19370acbbeedim   type.  */
19380acbbeedim
19390acbbeedimstatic bfd_boolean
19400acbbeedimppc_elf_section_from_shdr (bfd *abfd,
19410acbbeedim			   Elf_Internal_Shdr *hdr,
19420acbbeedim			   const char *name,
19430acbbeedim			   int shindex)
194471671b9obrien{
19450acbbeedim  asection *newsect;
19460acbbeedim  flagword flags;
194771671b9obrien
19480acbbeedim  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
19490acbbeedim    return FALSE;
195071671b9obrien
19510acbbeedim  newsect = hdr->bfd_section;
19520acbbeedim  flags = bfd_get_section_flags (abfd, newsect);
19530acbbeedim  if (hdr->sh_flags & SHF_EXCLUDE)
19540acbbeedim    flags |= SEC_EXCLUDE;
195571671b9obrien
19560acbbeedim  if (hdr->sh_type == SHT_ORDERED)
19570acbbeedim    flags |= SEC_SORT_ENTRIES;
195871671b9obrien
19590acbbeedim  bfd_set_section_flags (abfd, newsect, flags);
19600acbbeedim  return TRUE;
19610acbbeedim}
196271671b9obrien
19630acbbeedim/* Set up any other section flags and such that may be necessary.  */
196471671b9obrien
19650acbbeedimstatic bfd_boolean
19660acbbeedimppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
19670acbbeedim		       Elf_Internal_Shdr *shdr,
19680acbbeedim		       asection *asect)
196971671b9obrien{
19700acbbeedim  if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
19710acbbeedim    shdr->sh_flags |= SHF_EXCLUDE;
197271671b9obrien
19730acbbeedim  if ((asect->flags & SEC_SORT_ENTRIES) != 0)
19740acbbeedim    shdr->sh_type = SHT_ORDERED;
19750acbbeedim
19760acbbeedim  return TRUE;
197771671b9obrien}
197871671b9obrien
19790acbbeedim/* If we have .sbss2 or .PPC.EMB.sbss0 output sections, we
19800acbbeedim   need to bump up the number of section headers.  */
198171671b9obrien
19820acbbeedimstatic int
1983d0f678fdimppc_elf_additional_program_headers (bfd *abfd,
1984d0f678fdim				    struct bfd_link_info *info ATTRIBUTE_UNUSED)
198571671b9obrien{
19860acbbeedim  asection *s;
19870acbbeedim  int ret = 0;
198871671b9obrien
19890acbbeedim  s = bfd_get_section_by_name (abfd, ".sbss2");
19900acbbeedim  if (s != NULL && (s->flags & SEC_ALLOC) != 0)
19910acbbeedim    ++ret;
199271671b9obrien
19930acbbeedim  s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
19940acbbeedim  if (s != NULL && (s->flags & SEC_ALLOC) != 0)
19950acbbeedim    ++ret;
199671671b9obrien
19970acbbeedim  return ret;
19980acbbeedim}
199971671b9obrien
20000acbbeedim/* Add extra PPC sections -- Note, for now, make .sbss2 and
20010acbbeedim   .PPC.EMB.sbss0 a normal section, and not a bss section so
20020acbbeedim   that the linker doesn't crater when trying to make more than
20030acbbeedim   2 sections.  */
200471671b9obrien
20050acbbeedimstatic const struct bfd_elf_special_section ppc_elf_special_sections[] =
20060acbbeedim{
2007d0f678fdim  { STRING_COMMA_LEN (".plt"),             0, SHT_NOBITS,   SHF_ALLOC + SHF_EXECINSTR },
2008d0f678fdim  { STRING_COMMA_LEN (".sbss"),           -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
2009d0f678fdim  { STRING_COMMA_LEN (".sbss2"),          -2, SHT_PROGBITS, SHF_ALLOC },
2010d0f678fdim  { STRING_COMMA_LEN (".sdata"),          -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2011d0f678fdim  { STRING_COMMA_LEN (".sdata2"),         -2, SHT_PROGBITS, SHF_ALLOC },
2012d0f678fdim  { STRING_COMMA_LEN (".tags"),            0, SHT_ORDERED,  SHF_ALLOC },
2013d0f678fdim  { STRING_COMMA_LEN (".PPC.EMB.apuinfo"), 0, SHT_NOTE,     0 },
2014d0f678fdim  { STRING_COMMA_LEN (".PPC.EMB.sbss0"),   0, SHT_PROGBITS, SHF_ALLOC },
2015d0f678fdim  { STRING_COMMA_LEN (".PPC.EMB.sdata0"),  0, SHT_PROGBITS, SHF_ALLOC },
2016d0f678fdim  { NULL,                              0,  0, 0,            0 }
20170acbbeedim};
201871671b9obrien
20190acbbeedim/* This is what we want for new plt/got.  */
20200acbbeedimstatic struct bfd_elf_special_section ppc_alt_plt =
2021d0f678fdim  { STRING_COMMA_LEN (".plt"),             0, SHT_PROGBITS, SHF_ALLOC };
202271671b9obrien
20230acbbeedimstatic const struct bfd_elf_special_section *
20240acbbeedimppc_elf_get_sec_type_attr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
202571671b9obrien{
20260acbbeedim  const struct bfd_elf_special_section *ssect;
202771671b9obrien
20280acbbeedim  /* See if this is one of the special sections.  */
20290acbbeedim  if (sec->name == NULL)
20300acbbeedim    return NULL;
20310acbbeedim
20320acbbeedim  ssect = _bfd_elf_get_special_section (sec->name, ppc_elf_special_sections,
20330acbbeedim					sec->use_rela_p);
20340acbbeedim  if (ssect != NULL)
203571671b9obrien    {
20360acbbeedim      if (ssect == ppc_elf_special_sections && (sec->flags & SEC_LOAD) != 0)
20370acbbeedim	ssect = &ppc_alt_plt;
20380acbbeedim      return ssect;
203971671b9obrien    }
20400acbbeedim
20410acbbeedim  return _bfd_elf_get_sec_type_attr (abfd, sec);
20420acbbeedim}
20430acbbeedim
20440acbbeedim/* Very simple linked list structure for recording apuinfo values.  */
20450acbbeedimtypedef struct apuinfo_list
20460acbbeedim{
20470acbbeedim  struct apuinfo_list *next;
20480acbbeedim  unsigned long value;
204971671b9obrien}
20500acbbeedimapuinfo_list;
205171671b9obrien
20520acbbeedimstatic apuinfo_list *head;
205371671b9obrien
20540acbbeedim
20550acbbeedimstatic void
20560acbbeedimapuinfo_list_init (void)
205771671b9obrien{
20580acbbeedim  head = NULL;
20590acbbeedim}
206071671b9obrien
20610acbbeedimstatic void
20620acbbeedimapuinfo_list_add (unsigned long value)
20630acbbeedim{
20640acbbeedim  apuinfo_list *entry = head;
20650acbbeedim
20660acbbeedim  while (entry != NULL)
20670acbbeedim    {
20680acbbeedim      if (entry->value == value)
20690acbbeedim	return;
20700acbbeedim      entry = entry->next;
207171671b9obrien    }
207271671b9obrien
20730acbbeedim  entry = bfd_malloc (sizeof (* entry));
20740acbbeedim  if (entry == NULL)
20750acbbeedim    return;
207671671b9obrien
20770acbbeedim  entry->value = value;
20780acbbeedim  entry->next  = head;
20790acbbeedim  head = entry;
20800acbbeedim}
20810acbbeedim
20820acbbeedimstatic unsigned
20830acbbeedimapuinfo_list_length (void)
208471671b9obrien{
20850acbbeedim  apuinfo_list *entry;
20860acbbeedim  unsigned long count;
208771671b9obrien
20880acbbeedim  for (entry = head, count = 0;
20890acbbeedim       entry;
20900acbbeedim       entry = entry->next)
20910acbbeedim    ++ count;
209271671b9obrien
20930acbbeedim  return count;
20940acbbeedim}
209571671b9obrien
20960acbbeedimstatic inline unsigned long
20970acbbeedimapuinfo_list_element (unsigned long number)
209871671b9obrien{
20990acbbeedim  apuinfo_list * entry;
210071671b9obrien
21010acbbeedim  for (entry = head;
21020acbbeedim       entry && number --;
21030acbbeedim       entry = entry->next)
21040acbbeedim    ;
210571671b9obrien
21060acbbeedim  return entry ? entry->value : 0;
21070acbbeedim}
210871671b9obrien
21090acbbeedimstatic void
21100acbbeedimapuinfo_list_finish (void)
21110acbbeedim{
21120acbbeedim  apuinfo_list *entry;
21130acbbeedim
21140acbbeedim  for (entry = head; entry;)
211571671b9obrien    {
21160acbbeedim      apuinfo_list *next = entry->next;
21170acbbeedim      free (entry);
21180acbbeedim      entry = next;
211971671b9obrien    }
212071671b9obrien
21210acbbeedim  head = NULL;
21220acbbeedim}
212371671b9obrien
21240acbbeedim#define APUINFO_SECTION_NAME	".PPC.EMB.apuinfo"
21250acbbeedim#define APUINFO_LABEL		"APUinfo"
21260acbbeedim
21270acbbeedim/* Scan the input BFDs and create a linked list of
21280acbbeedim   the APUinfo values that will need to be emitted.  */
21290acbbeedim
21300acbbeedimstatic void
21310acbbeedimppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
21320acbbeedim{
21330acbbeedim  bfd *ibfd;
21340acbbeedim  asection *asec;
21350acbbeedim  char *buffer;
21360acbbeedim  unsigned num_input_sections;
21370acbbeedim  bfd_size_type	output_section_size;
21380acbbeedim  unsigned i;
21390acbbeedim  unsigned num_entries;
21400acbbeedim  unsigned long	offset;
21410acbbeedim  unsigned long length;
21420acbbeedim  const char *error_message = NULL;
21430acbbeedim
21440acbbeedim  if (link_info == NULL)
21450acbbeedim    return;
21460acbbeedim
21470acbbeedim  /* Scan the input bfds, looking for apuinfo sections.  */
21480acbbeedim  num_input_sections = 0;
21490acbbeedim  output_section_size = 0;
21500acbbeedim
21510acbbeedim  for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
215271671b9obrien    {
21530acbbeedim      asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
21540acbbeedim      if (asec)
215571671b9obrien	{
21560acbbeedim	  ++ num_input_sections;
21570acbbeedim	  output_section_size += asec->size;
215871671b9obrien	}
21590acbbeedim    }
216071671b9obrien
21610acbbeedim  /* We need at least one input sections
21620acbbeedim     in order to make merging worthwhile.  */
21630acbbeedim  if (num_input_sections < 1)
21640acbbeedim    return;
216571671b9obrien
21660acbbeedim  /* Just make sure that the output section exists as well.  */
21670acbbeedim  asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
21680acbbeedim  if (asec == NULL)
21690acbbeedim    return;
217071671b9obrien
21710acbbeedim  /* Allocate a buffer for the contents of the input sections.  */
21720acbbeedim  buffer = bfd_malloc (output_section_size);
21730acbbeedim  if (buffer == NULL)
21740acbbeedim    return;
217571671b9obrien
21760acbbeedim  offset = 0;
21770acbbeedim  apuinfo_list_init ();
217871671b9obrien
21790acbbeedim  /* Read in the input sections contents.  */
21800acbbeedim  for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
21810acbbeedim    {
21820acbbeedim      unsigned long datum;
21830acbbeedim      char *ptr;
21840acbbeedim
21850acbbeedim      asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
21860acbbeedim      if (asec == NULL)
21870acbbeedim	continue;
21880acbbeedim
21890acbbeedim      length = asec->size;
21900acbbeedim      if (length < 24)
219171671b9obrien	{
21920acbbeedim	  error_message = _("corrupt or empty %s section in %B");
21930acbbeedim	  goto fail;
219471671b9obrien	}
219571671b9obrien
21960acbbeedim      if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
21970acbbeedim	  || (bfd_bread (buffer + offset, length, ibfd) != length))
219871671b9obrien	{
21990acbbeedim	  error_message = _("unable to read in %s section from %B");
22000acbbeedim	  goto fail;
220171671b9obrien	}
220271671b9obrien
22030acbbeedim      /* Process the contents of the section.  */
22040acbbeedim      ptr = buffer + offset;
22050acbbeedim      error_message = _("corrupt %s section in %B");
220671671b9obrien
22070acbbeedim      /* Verify the contents of the header.  Note - we have to
22080acbbeedim	 extract the values this way in order to allow for a
22090acbbeedim	 host whose endian-ness is different from the target.  */
22100acbbeedim      datum = bfd_get_32 (ibfd, ptr);
22110acbbeedim      if (datum != sizeof APUINFO_LABEL)
22120acbbeedim	goto fail;
221371671b9obrien
22140acbbeedim      datum = bfd_get_32 (ibfd, ptr + 8);
22150acbbeedim      if (datum != 0x2)
22160acbbeedim	goto fail;
221771671b9obrien
22180acbbeedim      if (strcmp (ptr + 12, APUINFO_LABEL) != 0)
22190acbbeedim	goto fail;
222071671b9obrien
22210acbbeedim      /* Get the number of bytes used for apuinfo entries.  */
22220acbbeedim      datum = bfd_get_32 (ibfd, ptr + 4);
22230acbbeedim      if (datum + 20 != length)
22240acbbeedim	goto fail;
222571671b9obrien
22260acbbeedim      /* Make sure that we do not run off the end of the section.  */
22270acbbeedim      if (offset + length > output_section_size)
22280acbbeedim	goto fail;
222971671b9obrien
22300acbbeedim      /* Scan the apuinfo section, building a list of apuinfo numbers.  */
22310acbbeedim      for (i = 0; i < datum; i += 4)
22320acbbeedim	apuinfo_list_add (bfd_get_32 (ibfd, ptr + 20 + i));
223371671b9obrien
22340acbbeedim      /* Update the offset.  */
22350acbbeedim      offset += length;
22360acbbeedim    }
223771671b9obrien
22380acbbeedim  error_message = NULL;
223971671b9obrien
22400acbbeedim  /* Compute the size of the output section.  */
22410acbbeedim  num_entries = apuinfo_list_length ();
22420acbbeedim  output_section_size = 20 + num_entries * 4;
224371671b9obrien
22440acbbeedim  asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
224571671b9obrien
22460acbbeedim  if (! bfd_set_section_size (abfd, asec, output_section_size))
22470acbbeedim    ibfd = abfd,
22480acbbeedim      error_message = _("warning: unable to set size of %s section in %B");
224971671b9obrien
22500acbbeedim fail:
22510acbbeedim  free (buffer);
225271671b9obrien
22530acbbeedim  if (error_message)
22540acbbeedim    (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
22550acbbeedim}
225671671b9obrien
22570acbbeedim/* Prevent the output section from accumulating the input sections'
22580acbbeedim   contents.  We have already stored this in our linked list structure.  */
225971671b9obrien
22600acbbeedimstatic bfd_boolean
22610acbbeedimppc_elf_write_section (bfd *abfd ATTRIBUTE_UNUSED,
2262d0f678fdim		       struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
22630acbbeedim		       asection *asec,
22640acbbeedim		       bfd_byte *contents ATTRIBUTE_UNUSED)
22650acbbeedim{
22660acbbeedim  return (apuinfo_list_length ()
22670acbbeedim	  && strcmp (asec->name, APUINFO_SECTION_NAME) == 0);
22680acbbeedim}
226971671b9obrien
22700acbbeedim/* Finally we can generate the output section.  */
227171671b9obrien
22720acbbeedimstatic void
22730acbbeedimppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
22740acbbeedim{
22750acbbeedim  bfd_byte *buffer;
22760acbbeedim  asection *asec;
22770acbbeedim  unsigned i;
22780acbbeedim  unsigned num_entries;
22790acbbeedim  bfd_size_type length;
228071671b9obrien
22810acbbeedim  asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
22820acbbeedim  if (asec == NULL)
22830acbbeedim    return;
228471671b9obrien
22850acbbeedim  if (apuinfo_list_length () == 0)
22860acbbeedim    return;
228771671b9obrien
22880acbbeedim  length = asec->size;
22890acbbeedim  if (length < 20)
22900acbbeedim    return;
229171671b9obrien
22920acbbeedim  buffer = bfd_malloc (length);
22930acbbeedim  if (buffer == NULL)
22940acbbeedim    {
22950acbbeedim      (*_bfd_error_handler)
22960acbbeedim	(_("failed to allocate space for new APUinfo section."));
22970acbbeedim      return;
229871671b9obrien    }
229971671b9obrien
23000acbbeedim  /* Create the apuinfo header.  */
23010acbbeedim  num_entries = apuinfo_list_length ();
23020acbbeedim  bfd_put_32 (abfd, sizeof APUINFO_LABEL, buffer);
23030acbbeedim  bfd_put_32 (abfd, num_entries * 4, buffer + 4);
23040acbbeedim  bfd_put_32 (abfd, 0x2, buffer + 8);
23050acbbeedim  strcpy ((char *) buffer + 12, APUINFO_LABEL);
230671671b9obrien
23070acbbeedim  length = 20;
23080acbbeedim  for (i = 0; i < num_entries; i++)
23090acbbeedim    {
23100acbbeedim      bfd_put_32 (abfd, apuinfo_list_element (i), buffer + length);
23110acbbeedim      length += 4;
23120acbbeedim    }
231371671b9obrien
23140acbbeedim  if (length != asec->size)
23150acbbeedim    (*_bfd_error_handler) (_("failed to compute new APUinfo section."));
231671671b9obrien
23170acbbeedim  if (! bfd_set_section_contents (abfd, asec, buffer, (file_ptr) 0, length))
23180acbbeedim    (*_bfd_error_handler) (_("failed to install new APUinfo section."));
231971671b9obrien
23200acbbeedim  free (buffer);
232171671b9obrien
23220acbbeedim  apuinfo_list_finish ();
232371671b9obrien}
232471671b9obrien
23250acbbeedim/* The following functions are specific to the ELF linker, while
23260acbbeedim   functions above are used generally.  They appear in this file more
23270acbbeedim   or less in the order in which they are called.  eg.
23280acbbeedim   ppc_elf_check_relocs is called early in the link process,
23290acbbeedim   ppc_elf_finish_dynamic_sections is one of the last functions
23300acbbeedim   called.  */
233171671b9obrien
23320acbbeedim/* The PPC linker needs to keep track of the number of relocs that it
23330acbbeedim   decides to copy as dynamic relocs in check_relocs for each symbol.
23340acbbeedim   This is so that it can later discard them if they are found to be
23350acbbeedim   unnecessary.  We store the information in a field extending the
23360acbbeedim   regular ELF linker hash table.  */
233771671b9obrien
23380acbbeedimstruct ppc_elf_dyn_relocs
233971671b9obrien{
23400acbbeedim  struct ppc_elf_dyn_relocs *next;
234171671b9obrien
23420acbbeedim  /* The input section of the reloc.  */
23430acbbeedim  asection *sec;
234471671b9obrien
23450acbbeedim  /* Total number of relocs copied for the input section.  */
23460acbbeedim  bfd_size_type count;
234771671b9obrien
23480acbbeedim  /* Number of pc-relative relocs copied for the input section.  */
23490acbbeedim  bfd_size_type pc_count;
23500acbbeedim};
235171671b9obrien
23520acbbeedim/* Track PLT entries needed for a given symbol.  We might need more
23530acbbeedim   than one glink entry per symbol.  */
23540acbbeedimstruct plt_entry
23550acbbeedim{
23560acbbeedim  struct plt_entry *next;
235771671b9obrien
23580acbbeedim  /* -fPIC uses multiple GOT sections, one per file, called ".got2".
23590acbbeedim     This field stores the offset into .got2 used to initialise the
23600acbbeedim     GOT pointer reg.  It will always be at least 32768 (and for
23610acbbeedim     current gcc this is the only offset used).  */
23620acbbeedim  bfd_vma addend;
236371671b9obrien
23640acbbeedim  /* The .got2 section.  */
23650acbbeedim  asection *sec;
236671671b9obrien
23670acbbeedim  /* PLT refcount or offset.  */
23680acbbeedim  union
23690acbbeedim    {
23700acbbeedim      bfd_signed_vma refcount;
23710acbbeedim      bfd_vma offset;
23720acbbeedim    } plt;
237371671b9obrien
23740acbbeedim  /* .glink stub offset.  */
23750acbbeedim  bfd_vma glink_offset;
23760acbbeedim};
237771671b9obrien
237896e9bafjhibbits/* Of those relocs that might be copied as dynamic relocs, this function
23790acbbeedim   selects those that must be copied when linking a shared library,
23800acbbeedim   even when the symbol is local.  */
238171671b9obrien
238296e9bafjhibbitsstatic int
238396e9bafjhibbitsmust_be_dyn_reloc (struct bfd_link_info *info,
238496e9bafjhibbits		   enum elf_ppc_reloc_type r_type)
238596e9bafjhibbits{
238696e9bafjhibbits  switch (r_type)
238796e9bafjhibbits    {
238896e9bafjhibbits    default:
238996e9bafjhibbits      return 1;
239096e9bafjhibbits
239196e9bafjhibbits    case R_PPC_REL24:
239296e9bafjhibbits    case R_PPC_REL14:
239396e9bafjhibbits    case R_PPC_REL14_BRTAKEN:
239496e9bafjhibbits    case R_PPC_REL14_BRNTAKEN:
239596e9bafjhibbits    case R_PPC_REL32:
239696e9bafjhibbits      return 0;
239796e9bafjhibbits
239896e9bafjhibbits    case R_PPC_TPREL32:
239996e9bafjhibbits    case R_PPC_TPREL16:
240096e9bafjhibbits    case R_PPC_TPREL16_LO:
240196e9bafjhibbits    case R_PPC_TPREL16_HI:
240296e9bafjhibbits    case R_PPC_TPREL16_HA:
240396e9bafjhibbits      return !info->executable;
240496e9bafjhibbits    }
240596e9bafjhibbits}
240671671b9obrien
24070acbbeedim/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
24080acbbeedim   copying dynamic variables from a shared lib into an app's dynbss
24090acbbeedim   section, and instead use a dynamic relocation to point into the
24100acbbeedim   shared lib.  */
24110acbbeedim#define ELIMINATE_COPY_RELOCS 1
241271671b9obrien
24130acbbeedim/* PPC ELF linker hash entry.  */
241471671b9obrien
24150acbbeedimstruct ppc_elf_link_hash_entry
24160acbbeedim{
24170acbbeedim  struct elf_link_hash_entry elf;
241871671b9obrien
24190acbbeedim  /* If this symbol is used in the linker created sections, the processor
24200acbbeedim     specific backend uses this field to map the field into the offset
24210acbbeedim     from the beginning of the section.  */
24220acbbeedim  elf_linker_section_pointers_t *linker_section_pointer;
24230acbbeedim
24240acbbeedim  /* Track dynamic relocs copied for this symbol.  */
24250acbbeedim  struct ppc_elf_dyn_relocs *dyn_relocs;
24260acbbeedim
24270acbbeedim  /* Contexts in which symbol is used in the GOT (or TOC).
24280acbbeedim     TLS_GD .. TLS_TLS bits are or'd into the mask as the
24290acbbeedim     corresponding relocs are encountered during check_relocs.
24300acbbeedim     tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
24310acbbeedim     indicate the corresponding GOT entry type is not needed.  */
24320acbbeedim#define TLS_GD		 1	/* GD reloc. */
24330acbbeedim#define TLS_LD		 2	/* LD reloc. */
24340acbbeedim#define TLS_TPREL	 4	/* TPREL reloc, => IE. */
24350acbbeedim#define TLS_DTPREL	 8	/* DTPREL reloc, => LD. */
24360acbbeedim#define TLS_TLS		16	/* Any TLS reloc.  */
24370acbbeedim#define TLS_TPRELGD	32	/* TPREL reloc resulting from GD->IE. */
24380acbbeedim  char tls_mask;
24390acbbeedim
24400acbbeedim  /* Nonzero if we have seen a small data relocation referring to this
24410acbbeedim     symbol.  */
24420acbbeedim  unsigned char has_sda_refs;
24430acbbeedim};
24440acbbeedim
24450acbbeedim#define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
24460acbbeedim
24470acbbeedim/* PPC ELF linker hash table.  */
24480acbbeedim
24490acbbeedimstruct ppc_elf_link_hash_table
245071671b9obrien{
24510acbbeedim  struct elf_link_hash_table elf;
24520acbbeedim
24530acbbeedim  /* Short-cuts to get to dynamic linker sections.  */
24540acbbeedim  asection *got;
24550acbbeedim  asection *relgot;
24560acbbeedim  asection *glink;
24570acbbeedim  asection *plt;
24580acbbeedim  asection *relplt;
24590acbbeedim  asection *dynbss;
24600acbbeedim  asection *relbss;
24610acbbeedim  asection *