elf64-ppc.c revision 107492
189857Sobrien/* PowerPC64-specific support for 64-bit ELF.
289857Sobrien   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
389857Sobrien   Written by Linus Nordberg, Swox AB <info@swox.com>,
489857Sobrien   based on elf32-ppc.c by Ian Lance Taylor.
589857Sobrien
689857SobrienThis file is part of BFD, the Binary File Descriptor library.
789857Sobrien
889857SobrienThis program is free software; you can redistribute it and/or modify
989857Sobrienit under the terms of the GNU General Public License as published by
1089857Sobrienthe Free Software Foundation; either version 2 of the License, or
1189857Sobrien(at your option) any later version.
1289857Sobrien
1389857SobrienThis program is distributed in the hope that it will be useful,
1489857Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1589857SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1689857SobrienGNU General Public License for more details.
1789857Sobrien
1889857SobrienYou should have received a copy of the GNU General Public License
1989857Sobrienalong with this program; if not, write to the Free Software
2089857SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2189857Sobrien
2289857Sobrien/* This file is based on the 64-bit PowerPC ELF ABI.  It is also based
2389857Sobrien   on the file elf32-ppc.c.  */
2489857Sobrien
2589857Sobrien#include "bfd.h"
2689857Sobrien#include "sysdep.h"
2789857Sobrien#include "bfdlink.h"
2889857Sobrien#include "libbfd.h"
2989857Sobrien#include "elf-bfd.h"
3089857Sobrien#include "elf/ppc.h"
3189857Sobrien#include "elf64-ppc.h"
3289857Sobrien
3389857Sobrien#define USE_RELA		/* we want RELA relocations, not REL.  */
3489857Sobrien
3589857Sobrien
3689857Sobrienstatic void ppc_howto_init
3789857Sobrien  PARAMS ((void));
3889857Sobrienstatic reloc_howto_type *ppc64_elf_reloc_type_lookup
3989857Sobrien  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
4089857Sobrienstatic void ppc64_elf_info_to_howto
4189857Sobrien  PARAMS ((bfd *abfd, arelent *cache_ptr, Elf64_Internal_Rela *dst));
4299461Sobrienstatic bfd_reloc_status_type ppc64_elf_ha_reloc
4389857Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
4499461Sobrienstatic bfd_reloc_status_type ppc64_elf_brtaken_reloc
4599461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
4699461Sobrienstatic bfd_reloc_status_type ppc64_elf_sectoff_reloc
4799461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
4899461Sobrienstatic bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc
4999461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
5099461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc_reloc
5199461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
5299461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc_ha_reloc
5399461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
5499461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc64_reloc
5599461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
5699461Sobrienstatic bfd_reloc_status_type ppc64_elf_unhandled_reloc
5799461Sobrien  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
58104834Sobrienstatic boolean ppc64_elf_object_p
59104834Sobrien  PARAMS ((bfd *));
6089857Sobrienstatic boolean ppc64_elf_merge_private_bfd_data
6189857Sobrien  PARAMS ((bfd *, bfd *));
6289857Sobrien
6389857Sobrien
6489857Sobrien/* The name of the dynamic interpreter.  This is put in the .interp
6589857Sobrien   section.  */
6689857Sobrien#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
6789857Sobrien
6889857Sobrien/* The size in bytes of an entry in the procedure linkage table.  */
6989857Sobrien#define PLT_ENTRY_SIZE 24
7089857Sobrien
7189857Sobrien/* The initial size of the plt reserved for the dynamic linker.  */
7289857Sobrien#define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
7389857Sobrien
7489857Sobrien/* TOC base pointers offset from start of TOC.  */
7589857Sobrien#define TOC_BASE_OFF (0x8000)
7689857Sobrien
7789857Sobrien/* .plt call stub instructions.  */
7889857Sobrien#define ADDIS_R12_R2	0x3d820000	/* addis %r12,%r2,xxx@ha     */
7989857Sobrien#define STD_R2_40R1	0xf8410028	/* std	 %r2,40(%r1)	     */
8089857Sobrien#define LD_R11_0R12	0xe96c0000	/* ld	 %r11,xxx+0@l(%r12)  */
8189857Sobrien#define LD_R2_0R12	0xe84c0000	/* ld	 %r2,xxx+8@l(%r12)   */
8289857Sobrien#define MTCTR_R11	0x7d6903a6	/* mtctr %r11		     */
8389857Sobrien					/* ld	 %r11,xxx+16@l(%r12) */
8489857Sobrien#define BCTR		0x4e800420	/* bctr			     */
8589857Sobrien
8689857Sobrien/* The normal stub is this size.  */
8789857Sobrien#define PLT_CALL_STUB_SIZE (7*4)
8889857Sobrien
8989857Sobrien/* But sometimes the .plt entry crosses a 64k boundary, and we need
9089857Sobrien   to adjust the high word with this insn.  */
9189857Sobrien#define ADDIS_R12_R12_1	0x3d8c0001	/* addis %r12,%r12,1	*/
9289857Sobrien
9389857Sobrien/* The .glink fixup call stub is the same as the .plt call stub, but
9489857Sobrien   the first instruction restores r2, and the std is omitted.  */
9589857Sobrien#define LD_R2_40R1	0xe8410028	/* ld    %r2,40(%r1)	*/
9689857Sobrien
9789857Sobrien/* Always allow this much space.  */
9889857Sobrien#define GLINK_CALL_STUB_SIZE (8*4)
9989857Sobrien
10089857Sobrien/* Pad with this.  */
10189857Sobrien#define NOP		0x60000000
10289857Sobrien
10399461Sobrien/* Some other nops.  */
10499461Sobrien#define CROR_151515	0x4def7b82
10599461Sobrien#define CROR_313131	0x4ffffb82
10699461Sobrien
107104834Sobrien/* .glink entries for the first 32k functions are two instructions.  */
10889857Sobrien#define LI_R0_0		0x38000000	/* li    %r0,0		*/
10989857Sobrien#define B_DOT		0x48000000	/* b     .		*/
11089857Sobrien
11189857Sobrien/* After that, we need two instructions to load the index, followed by
11289857Sobrien   a branch.  */
11389857Sobrien#define LIS_R0_0	0x3c000000	/* lis   %r0,0		*/
11489857Sobrien#define ORI_R0_R0_0	0x60000000	/* ori	 %r0,%r0,0	*/
11589857Sobrien
11692828Sobrien/* Instructions to save and restore floating point regs.  */
11792828Sobrien#define STFD_FR0_0R1	0xd8010000	/* stfd  %fr0,0(%r1)	*/
11892828Sobrien#define LFD_FR0_0R1	0xc8010000	/* lfd   %fr0,0(%r1)	*/
11992828Sobrien#define BLR		0x4e800020	/* blr			*/
12092828Sobrien
12189857Sobrien/* Since .opd is an array of descriptors and each entry will end up
12289857Sobrien   with identical R_PPC64_RELATIVE relocs, there is really no need to
12389857Sobrien   propagate .opd relocs;  The dynamic linker should be taught to
124104834Sobrien   relocate .opd without reloc entries.  */
12589857Sobrien#ifndef NO_OPD_RELOCS
12689857Sobrien#define NO_OPD_RELOCS 0
12789857Sobrien#endif
12889857Sobrien
129104834Sobrien#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
130104834Sobrien
13189857Sobrien/* Relocation HOWTO's.  */
13289857Sobrienstatic reloc_howto_type *ppc64_elf_howto_table[(int) R_PPC_max];
13389857Sobrien
13489857Sobrienstatic reloc_howto_type ppc64_elf_howto_raw[] = {
13589857Sobrien  /* This reloc does nothing.  */
13689857Sobrien  HOWTO (R_PPC64_NONE,		/* type */
13789857Sobrien	 0,			/* rightshift */
138104834Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
139104834Sobrien	 8,			/* bitsize */
14089857Sobrien	 false,			/* pc_relative */
14189857Sobrien	 0,			/* bitpos */
142104834Sobrien	 complain_overflow_dont, /* complain_on_overflow */
14389857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
14489857Sobrien	 "R_PPC64_NONE",	/* name */
14589857Sobrien	 false,			/* partial_inplace */
14689857Sobrien	 0,			/* src_mask */
14789857Sobrien	 0,			/* dst_mask */
14889857Sobrien	 false),		/* pcrel_offset */
14989857Sobrien
15089857Sobrien  /* A standard 32 bit relocation.  */
15189857Sobrien  HOWTO (R_PPC64_ADDR32,	/* type */
15289857Sobrien	 0,			/* rightshift */
15389857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
15489857Sobrien	 32,			/* bitsize */
15589857Sobrien	 false,			/* pc_relative */
15689857Sobrien	 0,			/* bitpos */
15789857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
15889857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
15989857Sobrien	 "R_PPC64_ADDR32",	/* name */
16089857Sobrien	 false,			/* partial_inplace */
16189857Sobrien	 0,			/* src_mask */
16289857Sobrien	 0xffffffff,		/* dst_mask */
16389857Sobrien	 false),		/* pcrel_offset */
16489857Sobrien
16589857Sobrien  /* An absolute 26 bit branch; the lower two bits must be zero.
16689857Sobrien     FIXME: we don't check that, we just clear them.  */
16789857Sobrien  HOWTO (R_PPC64_ADDR24,	/* type */
16889857Sobrien	 0,			/* rightshift */
16989857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
17089857Sobrien	 26,			/* bitsize */
17189857Sobrien	 false,			/* pc_relative */
17289857Sobrien	 0,			/* bitpos */
17389857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
17489857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
17589857Sobrien	 "R_PPC64_ADDR24",	/* name */
17689857Sobrien	 false,			/* partial_inplace */
17789857Sobrien	 0,			/* src_mask */
178104834Sobrien	 0x03fffffc,		/* dst_mask */
17989857Sobrien	 false),		/* pcrel_offset */
18089857Sobrien
18189857Sobrien  /* A standard 16 bit relocation.  */
18289857Sobrien  HOWTO (R_PPC64_ADDR16,	/* type */
18389857Sobrien	 0,			/* rightshift */
18489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
18589857Sobrien	 16,			/* bitsize */
18689857Sobrien	 false,			/* pc_relative */
18789857Sobrien	 0,			/* bitpos */
18889857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
18989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
19089857Sobrien	 "R_PPC64_ADDR16",	/* name */
19189857Sobrien	 false,			/* partial_inplace */
19289857Sobrien	 0,			/* src_mask */
19389857Sobrien	 0xffff,		/* dst_mask */
19489857Sobrien	 false),		/* pcrel_offset */
19589857Sobrien
19689857Sobrien  /* A 16 bit relocation without overflow.  */
19789857Sobrien  HOWTO (R_PPC64_ADDR16_LO,	/* type */
19889857Sobrien	 0,			/* rightshift */
19989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
20089857Sobrien	 16,			/* bitsize */
20189857Sobrien	 false,			/* pc_relative */
20289857Sobrien	 0,			/* bitpos */
20389857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
20489857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
20589857Sobrien	 "R_PPC64_ADDR16_LO",	/* name */
20689857Sobrien	 false,			/* partial_inplace */
20789857Sobrien	 0,			/* src_mask */
20889857Sobrien	 0xffff,		/* dst_mask */
20989857Sobrien	 false),		/* pcrel_offset */
21089857Sobrien
21189857Sobrien  /* Bits 16-31 of an address.  */
21289857Sobrien  HOWTO (R_PPC64_ADDR16_HI,	/* type */
21389857Sobrien	 16,			/* rightshift */
21489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
21589857Sobrien	 16,			/* bitsize */
21689857Sobrien	 false,			/* pc_relative */
21789857Sobrien	 0,			/* bitpos */
21889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
21989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
22089857Sobrien	 "R_PPC64_ADDR16_HI",	/* name */
22189857Sobrien	 false,			/* partial_inplace */
22289857Sobrien	 0,			/* src_mask */
22389857Sobrien	 0xffff,		/* dst_mask */
22489857Sobrien	 false),		/* pcrel_offset */
22589857Sobrien
22689857Sobrien  /* Bits 16-31 of an address, plus 1 if the contents of the low 16
22789857Sobrien     bits, treated as a signed number, is negative.  */
22889857Sobrien  HOWTO (R_PPC64_ADDR16_HA,	/* type */
22989857Sobrien	 16,			/* rightshift */
23089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
23189857Sobrien	 16,			/* bitsize */
23289857Sobrien	 false,			/* pc_relative */
23389857Sobrien	 0,			/* bitpos */
23489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
23599461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
23689857Sobrien	 "R_PPC64_ADDR16_HA",	/* name */
23789857Sobrien	 false,			/* partial_inplace */
23889857Sobrien	 0,			/* src_mask */
23989857Sobrien	 0xffff,		/* dst_mask */
24089857Sobrien	 false),		/* pcrel_offset */
24189857Sobrien
24289857Sobrien  /* An absolute 16 bit branch; the lower two bits must be zero.
24389857Sobrien     FIXME: we don't check that, we just clear them.  */
24489857Sobrien  HOWTO (R_PPC64_ADDR14,	/* type */
24589857Sobrien	 0,			/* rightshift */
24689857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
24789857Sobrien	 16,			/* bitsize */
24889857Sobrien	 false,			/* pc_relative */
24989857Sobrien	 0,			/* bitpos */
25089857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
25189857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
25289857Sobrien	 "R_PPC64_ADDR14",	/* name */
25389857Sobrien	 false,			/* partial_inplace */
25489857Sobrien	 0,			/* src_mask */
255104834Sobrien	 0x0000fffc,		/* dst_mask */
25689857Sobrien	 false),		/* pcrel_offset */
25789857Sobrien
25889857Sobrien  /* An absolute 16 bit branch, for which bit 10 should be set to
25989857Sobrien     indicate that the branch is expected to be taken.  The lower two
26089857Sobrien     bits must be zero.  */
26189857Sobrien  HOWTO (R_PPC64_ADDR14_BRTAKEN, /* type */
26289857Sobrien	 0,			/* rightshift */
26389857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
26489857Sobrien	 16,			/* bitsize */
26589857Sobrien	 false,			/* pc_relative */
26689857Sobrien	 0,			/* bitpos */
26789857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
26899461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
26989857Sobrien	 "R_PPC64_ADDR14_BRTAKEN",/* name */
27089857Sobrien	 false,			/* partial_inplace */
27189857Sobrien	 0,			/* src_mask */
272104834Sobrien	 0x0000fffc,		/* dst_mask */
27389857Sobrien	 false),		/* pcrel_offset */
27489857Sobrien
27589857Sobrien  /* An absolute 16 bit branch, for which bit 10 should be set to
27689857Sobrien     indicate that the branch is not expected to be taken.  The lower
27789857Sobrien     two bits must be zero.  */
27889857Sobrien  HOWTO (R_PPC64_ADDR14_BRNTAKEN, /* type */
27989857Sobrien	 0,			/* rightshift */
28089857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
28189857Sobrien	 16,			/* bitsize */
28289857Sobrien	 false,			/* pc_relative */
28389857Sobrien	 0,			/* bitpos */
28489857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
28599461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
28689857Sobrien	 "R_PPC64_ADDR14_BRNTAKEN",/* name */
28789857Sobrien	 false,			/* partial_inplace */
28889857Sobrien	 0,			/* src_mask */
289104834Sobrien	 0x0000fffc,		/* dst_mask */
29089857Sobrien	 false),		/* pcrel_offset */
29189857Sobrien
29289857Sobrien  /* A relative 26 bit branch; the lower two bits must be zero.  */
29389857Sobrien  HOWTO (R_PPC64_REL24,		/* type */
29489857Sobrien	 0,			/* rightshift */
29589857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
29689857Sobrien	 26,			/* bitsize */
29789857Sobrien	 true,			/* pc_relative */
29889857Sobrien	 0,			/* bitpos */
29989857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
30089857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
30189857Sobrien	 "R_PPC64_REL24",	/* name */
30289857Sobrien	 false,			/* partial_inplace */
30389857Sobrien	 0,			/* src_mask */
304104834Sobrien	 0x03fffffc,		/* dst_mask */
30589857Sobrien	 true),			/* pcrel_offset */
30689857Sobrien
30789857Sobrien  /* A relative 16 bit branch; the lower two bits must be zero.  */
30889857Sobrien  HOWTO (R_PPC64_REL14,		/* type */
30989857Sobrien	 0,			/* rightshift */
31089857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
31189857Sobrien	 16,			/* bitsize */
31289857Sobrien	 true,			/* pc_relative */
31389857Sobrien	 0,			/* bitpos */
31489857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
31589857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
31689857Sobrien	 "R_PPC64_REL14",	/* name */
31789857Sobrien	 false,			/* partial_inplace */
31889857Sobrien	 0,			/* src_mask */
319104834Sobrien	 0x0000fffc,		/* dst_mask */
32089857Sobrien	 true),			/* pcrel_offset */
32189857Sobrien
32289857Sobrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
32389857Sobrien     the branch is expected to be taken.  The lower two bits must be
32489857Sobrien     zero.  */
32589857Sobrien  HOWTO (R_PPC64_REL14_BRTAKEN,	/* type */
32689857Sobrien	 0,			/* rightshift */
32789857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
32889857Sobrien	 16,			/* bitsize */
32989857Sobrien	 true,			/* pc_relative */
33089857Sobrien	 0,			/* bitpos */
33189857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
33299461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
33389857Sobrien	 "R_PPC64_REL14_BRTAKEN", /* name */
33489857Sobrien	 false,			/* partial_inplace */
33589857Sobrien	 0,			/* src_mask */
336104834Sobrien	 0x0000fffc,		/* dst_mask */
33789857Sobrien	 true),			/* pcrel_offset */
33889857Sobrien
33989857Sobrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
34089857Sobrien     the branch is not expected to be taken.  The lower two bits must
34189857Sobrien     be zero.  */
34289857Sobrien  HOWTO (R_PPC64_REL14_BRNTAKEN, /* type */
34389857Sobrien	 0,			/* rightshift */
34489857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
34589857Sobrien	 16,			/* bitsize */
34689857Sobrien	 true,			/* pc_relative */
34789857Sobrien	 0,			/* bitpos */
34889857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
34999461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
35089857Sobrien	 "R_PPC64_REL14_BRNTAKEN",/* name */
35189857Sobrien	 false,			/* partial_inplace */
35289857Sobrien	 0,			/* src_mask */
353104834Sobrien	 0x0000fffc,		/* dst_mask */
35489857Sobrien	 true),			/* pcrel_offset */
35589857Sobrien
35689857Sobrien  /* Like R_PPC64_ADDR16, but referring to the GOT table entry for the
35789857Sobrien     symbol.  */
35889857Sobrien  HOWTO (R_PPC64_GOT16,		/* type */
35989857Sobrien	 0,			/* rightshift */
36089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
36189857Sobrien	 16,			/* bitsize */
36289857Sobrien	 false,			/* pc_relative */
36389857Sobrien	 0,			/* bitpos */
36489857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
36599461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
36689857Sobrien	 "R_PPC64_GOT16",	/* name */
36789857Sobrien	 false,			/* partial_inplace */
36889857Sobrien	 0,			/* src_mask */
36989857Sobrien	 0xffff,		/* dst_mask */
37089857Sobrien	 false),		/* pcrel_offset */
37189857Sobrien
37289857Sobrien  /* Like R_PPC64_ADDR16_LO, but referring to the GOT table entry for
37389857Sobrien     the symbol.  */
37489857Sobrien  HOWTO (R_PPC64_GOT16_LO,	/* type */
37589857Sobrien	 0,			/* rightshift */
37689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
37789857Sobrien	 16,			/* bitsize */
37889857Sobrien	 false,			/* pc_relative */
37989857Sobrien	 0,			/* bitpos */
38089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
38199461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
38289857Sobrien	 "R_PPC64_GOT16_LO",	/* name */
38389857Sobrien	 false,			/* partial_inplace */
38489857Sobrien	 0,			/* src_mask */
38589857Sobrien	 0xffff,		/* dst_mask */
38689857Sobrien	 false),		/* pcrel_offset */
38789857Sobrien
38889857Sobrien  /* Like R_PPC64_ADDR16_HI, but referring to the GOT table entry for
38989857Sobrien     the symbol.  */
39089857Sobrien  HOWTO (R_PPC64_GOT16_HI,	/* type */
39189857Sobrien	 16,			/* rightshift */
39289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
39389857Sobrien	 16,			/* bitsize */
39489857Sobrien	 false,			/* pc_relative */
39589857Sobrien	 0,			/* bitpos */
39689857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
39799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
39889857Sobrien	 "R_PPC64_GOT16_HI",	/* name */
39989857Sobrien	 false,			/* partial_inplace */
40089857Sobrien	 0,			/* src_mask */
40189857Sobrien	 0xffff,		/* dst_mask */
40289857Sobrien	 false),		/* pcrel_offset */
40389857Sobrien
40489857Sobrien  /* Like R_PPC64_ADDR16_HA, but referring to the GOT table entry for
40589857Sobrien     the symbol.  */
40689857Sobrien  HOWTO (R_PPC64_GOT16_HA,	/* type */
40789857Sobrien	 16,			/* rightshift */
40889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
40989857Sobrien	 16,			/* bitsize */
41089857Sobrien	 false,			/* pc_relative */
41189857Sobrien	 0,			/* bitpos */
41289857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
41399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
41489857Sobrien	 "R_PPC64_GOT16_HA",	/* name */
41589857Sobrien	 false,			/* partial_inplace */
41689857Sobrien	 0,			/* src_mask */
41789857Sobrien	 0xffff,		/* dst_mask */
41889857Sobrien	 false),		/* pcrel_offset */
41989857Sobrien
42089857Sobrien  /* This is used only by the dynamic linker.  The symbol should exist
42189857Sobrien     both in the object being run and in some shared library.  The
42289857Sobrien     dynamic linker copies the data addressed by the symbol from the
42389857Sobrien     shared library into the object, because the object being
42489857Sobrien     run has to have the data at some particular address.  */
42589857Sobrien  HOWTO (R_PPC64_COPY,		/* type */
42689857Sobrien	 0,			/* rightshift */
427104834Sobrien	 0,			/* this one is variable size */
428104834Sobrien	 0,			/* bitsize */
42989857Sobrien	 false,			/* pc_relative */
43089857Sobrien	 0,			/* bitpos */
431104834Sobrien	 complain_overflow_dont, /* complain_on_overflow */
432104834Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
43389857Sobrien	 "R_PPC64_COPY",	/* name */
43489857Sobrien	 false,			/* partial_inplace */
43589857Sobrien	 0,			/* src_mask */
43689857Sobrien	 0,			/* dst_mask */
43789857Sobrien	 false),		/* pcrel_offset */
43889857Sobrien
43989857Sobrien  /* Like R_PPC64_ADDR64, but used when setting global offset table
44089857Sobrien     entries.  */
44189857Sobrien  HOWTO (R_PPC64_GLOB_DAT,	/* type */
44289857Sobrien	 0,			/* rightshift */
44389857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
44489857Sobrien	 64,			/* bitsize */
44589857Sobrien	 false,			/* pc_relative */
44689857Sobrien	 0,			/* bitpos */
44789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
44899461Sobrien	 ppc64_elf_unhandled_reloc,  /* special_function */
44989857Sobrien	 "R_PPC64_GLOB_DAT",	/* name */
45089857Sobrien	 false,			/* partial_inplace */
45189857Sobrien	 0,			/* src_mask */
452104834Sobrien	 ONES (64),		/* dst_mask */
45389857Sobrien	 false),		/* pcrel_offset */
45489857Sobrien
45589857Sobrien  /* Created by the link editor.  Marks a procedure linkage table
45689857Sobrien     entry for a symbol.  */
45789857Sobrien  HOWTO (R_PPC64_JMP_SLOT,	/* type */
45889857Sobrien	 0,			/* rightshift */
45989857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
46089857Sobrien	 0,			/* bitsize */
46189857Sobrien	 false,			/* pc_relative */
46289857Sobrien	 0,			/* bitpos */
46389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
46499461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
46589857Sobrien	 "R_PPC64_JMP_SLOT",	/* name */
46689857Sobrien	 false,			/* partial_inplace */
46789857Sobrien	 0,			/* src_mask */
46889857Sobrien	 0,			/* dst_mask */
46989857Sobrien	 false),		/* pcrel_offset */
47089857Sobrien
47189857Sobrien  /* Used only by the dynamic linker.  When the object is run, this
47289857Sobrien     doubleword64 is set to the load address of the object, plus the
47389857Sobrien     addend.  */
47489857Sobrien  HOWTO (R_PPC64_RELATIVE,	/* type */
47589857Sobrien	 0,			/* rightshift */
47689857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
47789857Sobrien	 64,			/* bitsize */
47889857Sobrien	 false,			/* pc_relative */
47989857Sobrien	 0,			/* bitpos */
48089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
48189857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
48289857Sobrien	 "R_PPC64_RELATIVE",	/* name */
48389857Sobrien	 false,			/* partial_inplace */
48489857Sobrien	 0,			/* src_mask */
485104834Sobrien	 ONES (64),		/* dst_mask */
48689857Sobrien	 false),		/* pcrel_offset */
48789857Sobrien
48889857Sobrien  /* Like R_PPC64_ADDR32, but may be unaligned.  */
48989857Sobrien  HOWTO (R_PPC64_UADDR32,	/* type */
49089857Sobrien	 0,			/* rightshift */
49189857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
49289857Sobrien	 32,			/* bitsize */
49389857Sobrien	 false,			/* pc_relative */
49489857Sobrien	 0,			/* bitpos */
49589857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
49689857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
49789857Sobrien	 "R_PPC64_UADDR32",	/* name */
49889857Sobrien	 false,			/* partial_inplace */
49989857Sobrien	 0,			/* src_mask */
50089857Sobrien	 0xffffffff,		/* dst_mask */
50189857Sobrien	 false),		/* pcrel_offset */
50289857Sobrien
50389857Sobrien  /* Like R_PPC64_ADDR16, but may be unaligned.  */
50489857Sobrien  HOWTO (R_PPC64_UADDR16,	/* type */
50589857Sobrien	 0,			/* rightshift */
50689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
50789857Sobrien	 16,			/* bitsize */
50889857Sobrien	 false,			/* pc_relative */
50989857Sobrien	 0,			/* bitpos */
51089857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
51189857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
51289857Sobrien	 "R_PPC64_UADDR16",	/* name */
51389857Sobrien	 false,			/* partial_inplace */
51489857Sobrien	 0,			/* src_mask */
51589857Sobrien	 0xffff,		/* dst_mask */
51689857Sobrien	 false),		/* pcrel_offset */
51789857Sobrien
51889857Sobrien  /* 32-bit PC relative.  */
51989857Sobrien  HOWTO (R_PPC64_REL32,		/* type */
52089857Sobrien	 0,			/* rightshift */
52189857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
52289857Sobrien	 32,			/* bitsize */
52389857Sobrien	 true,			/* pc_relative */
52489857Sobrien	 0,			/* bitpos */
525104834Sobrien	 /* FIXME: Verify.  Was complain_overflow_bitfield.  */
52689857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
52789857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
52889857Sobrien	 "R_PPC64_REL32",	/* name */
52989857Sobrien	 false,			/* partial_inplace */
53089857Sobrien	 0,			/* src_mask */
53189857Sobrien	 0xffffffff,		/* dst_mask */
53289857Sobrien	 true),			/* pcrel_offset */
53389857Sobrien
53489857Sobrien  /* 32-bit relocation to the symbol's procedure linkage table.  */
53589857Sobrien  HOWTO (R_PPC64_PLT32,		/* type */
53689857Sobrien	 0,			/* rightshift */
53789857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
53889857Sobrien	 32,			/* bitsize */
53989857Sobrien	 false,			/* pc_relative */
54089857Sobrien	 0,			/* bitpos */
54189857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
54299461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
54389857Sobrien	 "R_PPC64_PLT32",	/* name */
54489857Sobrien	 false,			/* partial_inplace */
54589857Sobrien	 0,			/* src_mask */
546104834Sobrien	 0xffffffff,		/* dst_mask */
54789857Sobrien	 false),		/* pcrel_offset */
54889857Sobrien
54989857Sobrien  /* 32-bit PC relative relocation to the symbol's procedure linkage table.
55089857Sobrien     FIXME: R_PPC64_PLTREL32 not supported.  */
55189857Sobrien  HOWTO (R_PPC64_PLTREL32,	/* type */
55289857Sobrien	 0,			/* rightshift */
55389857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
55489857Sobrien	 32,			/* bitsize */
55589857Sobrien	 true,			/* pc_relative */
55689857Sobrien	 0,			/* bitpos */
55789857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
55889857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
55989857Sobrien	 "R_PPC64_PLTREL32",	/* name */
56089857Sobrien	 false,			/* partial_inplace */
56189857Sobrien	 0,			/* src_mask */
562104834Sobrien	 0xffffffff,		/* dst_mask */
56389857Sobrien	 true),			/* pcrel_offset */
56489857Sobrien
56589857Sobrien  /* Like R_PPC64_ADDR16_LO, but referring to the PLT table entry for
56689857Sobrien     the symbol.  */
56789857Sobrien  HOWTO (R_PPC64_PLT16_LO,	/* type */
56889857Sobrien	 0,			/* rightshift */
56989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
57089857Sobrien	 16,			/* bitsize */
57189857Sobrien	 false,			/* pc_relative */
57289857Sobrien	 0,			/* bitpos */
57389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
57499461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
57589857Sobrien	 "R_PPC64_PLT16_LO",	/* name */
57689857Sobrien	 false,			/* partial_inplace */
57789857Sobrien	 0,			/* src_mask */
57889857Sobrien	 0xffff,		/* dst_mask */
57989857Sobrien	 false),		/* pcrel_offset */
58089857Sobrien
58189857Sobrien  /* Like R_PPC64_ADDR16_HI, but referring to the PLT table entry for
58289857Sobrien     the symbol.  */
58389857Sobrien  HOWTO (R_PPC64_PLT16_HI,	/* type */
58489857Sobrien	 16,			/* rightshift */
58589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
58689857Sobrien	 16,			/* bitsize */
58789857Sobrien	 false,			/* pc_relative */
58889857Sobrien	 0,			/* bitpos */
58989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
59099461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
59189857Sobrien	 "R_PPC64_PLT16_HI",	/* name */
59289857Sobrien	 false,			/* partial_inplace */
59389857Sobrien	 0,			/* src_mask */
59489857Sobrien	 0xffff,		/* dst_mask */
59589857Sobrien	 false),		/* pcrel_offset */
59689857Sobrien
59789857Sobrien  /* Like R_PPC64_ADDR16_HA, but referring to the PLT table entry for
59889857Sobrien     the symbol.  */
59989857Sobrien  HOWTO (R_PPC64_PLT16_HA,	/* type */
60089857Sobrien	 16,			/* rightshift */
60189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
60289857Sobrien	 16,			/* bitsize */
60389857Sobrien	 false,			/* pc_relative */
60489857Sobrien	 0,			/* bitpos */
60589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
60699461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
60789857Sobrien	 "R_PPC64_PLT16_HA",	/* name */
60889857Sobrien	 false,			/* partial_inplace */
60989857Sobrien	 0,			/* src_mask */
61089857Sobrien	 0xffff,		/* dst_mask */
61189857Sobrien	 false),		/* pcrel_offset */
61289857Sobrien
61399461Sobrien  /* 16-bit section relative relocation.  */
61489857Sobrien  HOWTO (R_PPC64_SECTOFF,	/* type */
61589857Sobrien	 0,			/* rightshift */
61699461Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
61799461Sobrien	 16,			/* bitsize */
61899461Sobrien	 false,			/* pc_relative */
61989857Sobrien	 0,			/* bitpos */
62089857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
62199461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
62289857Sobrien	 "R_PPC64_SECTOFF",	/* name */
62389857Sobrien	 false,			/* partial_inplace */
62489857Sobrien	 0,			/* src_mask */
62599461Sobrien	 0xffff,		/* dst_mask */
62699461Sobrien	 false),		/* pcrel_offset */
62789857Sobrien
62899461Sobrien  /* Like R_PPC64_SECTOFF, but no overflow warning.  */
62989857Sobrien  HOWTO (R_PPC64_SECTOFF_LO,	/* type */
63089857Sobrien	 0,			/* rightshift */
63189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
63289857Sobrien	 16,			/* bitsize */
63389857Sobrien	 false,			/* pc_relative */
63489857Sobrien	 0,			/* bitpos */
63589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
63699461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
63789857Sobrien	 "R_PPC64_SECTOFF_LO",	/* name */
63889857Sobrien	 false,			/* partial_inplace */
63989857Sobrien	 0,			/* src_mask */
64089857Sobrien	 0xffff,		/* dst_mask */
64189857Sobrien	 false),		/* pcrel_offset */
64289857Sobrien
64389857Sobrien  /* 16-bit upper half section relative relocation.  */
64489857Sobrien  HOWTO (R_PPC64_SECTOFF_HI,	/* type */
64589857Sobrien	 16,			/* rightshift */
64689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
64789857Sobrien	 16,			/* bitsize */
64889857Sobrien	 false,			/* pc_relative */
64989857Sobrien	 0,			/* bitpos */
65089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
65199461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
65289857Sobrien	 "R_PPC64_SECTOFF_HI",	/* name */
65389857Sobrien	 false,			/* partial_inplace */
65489857Sobrien	 0,			/* src_mask */
65589857Sobrien	 0xffff,		/* dst_mask */
65689857Sobrien	 false),		/* pcrel_offset */
65789857Sobrien
65889857Sobrien  /* 16-bit upper half adjusted section relative relocation.  */
65989857Sobrien  HOWTO (R_PPC64_SECTOFF_HA,	/* type */
66089857Sobrien	 16,			/* rightshift */
66189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
66289857Sobrien	 16,			/* bitsize */
66389857Sobrien	 false,			/* pc_relative */
66489857Sobrien	 0,			/* bitpos */
66589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
66699461Sobrien	 ppc64_elf_sectoff_ha_reloc, /* special_function */
66789857Sobrien	 "R_PPC64_SECTOFF_HA",	/* name */
66889857Sobrien	 false,			/* partial_inplace */
66989857Sobrien	 0,			/* src_mask */
67089857Sobrien	 0xffff,		/* dst_mask */
67189857Sobrien	 false),		/* pcrel_offset */
67289857Sobrien
67389857Sobrien  /* Like R_PPC64_REL24 without touching the two least significant
67499461Sobrien     bits.  Should have been named R_PPC64_REL30!  */
67589857Sobrien  HOWTO (R_PPC64_ADDR30,	/* type */
67689857Sobrien	 2,			/* rightshift */
67789857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
67889857Sobrien	 30,			/* bitsize */
67989857Sobrien	 true,			/* pc_relative */
68089857Sobrien	 0,			/* bitpos */
68189857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
68289857Sobrien	 bfd_elf_generic_reloc, /* special_function */
68389857Sobrien	 "R_PPC64_ADDR30",	/* name */
68489857Sobrien	 false,			/* partial_inplace */
68589857Sobrien	 0,			/* src_mask */
68689857Sobrien	 0xfffffffc,		/* dst_mask */
68789857Sobrien	 true),			/* pcrel_offset */
68889857Sobrien
68989857Sobrien  /* Relocs in the 64-bit PowerPC ELF ABI, not in the 32-bit ABI.  */
69089857Sobrien
69189857Sobrien  /* A standard 64-bit relocation.  */
69289857Sobrien  HOWTO (R_PPC64_ADDR64,	/* type */
69389857Sobrien	 0,			/* rightshift */
69489857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
69589857Sobrien	 64,			/* bitsize */
69689857Sobrien	 false,			/* pc_relative */
69789857Sobrien	 0,			/* bitpos */
69889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
69989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
70089857Sobrien	 "R_PPC64_ADDR64",	/* name */
70189857Sobrien	 false,			/* partial_inplace */
70289857Sobrien	 0,			/* src_mask */
703104834Sobrien	 ONES (64),		/* dst_mask */
70489857Sobrien	 false),		/* pcrel_offset */
70589857Sobrien
70689857Sobrien  /* The bits 32-47 of an address.  */
70789857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHER,	/* type */
70889857Sobrien	 32,			/* rightshift */
70989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
71089857Sobrien	 16,			/* bitsize */
71189857Sobrien	 false,			/* pc_relative */
71289857Sobrien	 0,			/* bitpos */
71389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
71489857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
71589857Sobrien	 "R_PPC64_ADDR16_HIGHER", /* name */
71689857Sobrien	 false,			/* partial_inplace */
71789857Sobrien	 0,			/* src_mask */
71889857Sobrien	 0xffff,		/* dst_mask */
71989857Sobrien	 false),		/* pcrel_offset */
72089857Sobrien
72189857Sobrien  /* The bits 32-47 of an address, plus 1 if the contents of the low
72289857Sobrien     16 bits, treated as a signed number, is negative.  */
72389857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHERA, /* type */
72489857Sobrien	 32,			/* rightshift */
72589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
72689857Sobrien	 16,			/* bitsize */
72789857Sobrien	 false,			/* pc_relative */
72889857Sobrien	 0,			/* bitpos */
72989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
73099461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
73189857Sobrien	 "R_PPC64_ADDR16_HIGHERA", /* name */
73289857Sobrien	 false,			/* partial_inplace */
73389857Sobrien	 0,			/* src_mask */
73489857Sobrien	 0xffff,		/* dst_mask */
73589857Sobrien	 false),		/* pcrel_offset */
73689857Sobrien
73789857Sobrien  /* The bits 48-63 of an address.  */
73889857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHEST,/* type */
73989857Sobrien	 48,			/* rightshift */
74089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
74189857Sobrien	 16,			/* bitsize */
74289857Sobrien	 false,			/* pc_relative */
74389857Sobrien	 0,			/* bitpos */
74489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
74589857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
74689857Sobrien	 "R_PPC64_ADDR16_HIGHEST", /* name */
74789857Sobrien	 false,			/* partial_inplace */
74889857Sobrien	 0,			/* src_mask */
74989857Sobrien	 0xffff,		/* dst_mask */
75089857Sobrien	 false),		/* pcrel_offset */
75189857Sobrien
75289857Sobrien  /* The bits 48-63 of an address, plus 1 if the contents of the low
75389857Sobrien     16 bits, treated as a signed number, is negative.  */
75489857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHESTA,/* type */
75589857Sobrien	 48,			/* rightshift */
75689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
75789857Sobrien	 16,			/* bitsize */
75889857Sobrien	 false,			/* pc_relative */
75989857Sobrien	 0,			/* bitpos */
76089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
76199461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
76289857Sobrien	 "R_PPC64_ADDR16_HIGHESTA", /* name */
76389857Sobrien	 false,			/* partial_inplace */
76489857Sobrien	 0,			/* src_mask */
76589857Sobrien	 0xffff,		/* dst_mask */
76689857Sobrien	 false),		/* pcrel_offset */
76789857Sobrien
76889857Sobrien  /* Like ADDR64, but may be unaligned.  */
76989857Sobrien  HOWTO (R_PPC64_UADDR64,	/* type */
77089857Sobrien	 0,			/* rightshift */
77189857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
77289857Sobrien	 64,			/* bitsize */
77389857Sobrien	 false,			/* pc_relative */
77489857Sobrien	 0,			/* bitpos */
77589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
77689857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
77789857Sobrien	 "R_PPC64_UADDR64",	/* name */
77889857Sobrien	 false,			/* partial_inplace */
77989857Sobrien	 0,			/* src_mask */
780104834Sobrien	 ONES (64),		/* dst_mask */
78189857Sobrien	 false),		/* pcrel_offset */
78289857Sobrien
78389857Sobrien  /* 64-bit relative relocation.  */
78489857Sobrien  HOWTO (R_PPC64_REL64,		/* type */
78589857Sobrien	 0,			/* rightshift */
78689857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
78789857Sobrien	 64,			/* bitsize */
78889857Sobrien	 true,			/* pc_relative */
78989857Sobrien	 0,			/* bitpos */
79089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
79189857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
79289857Sobrien	 "R_PPC64_REL64",	/* name */
79389857Sobrien	 false,			/* partial_inplace */
79489857Sobrien	 0,			/* src_mask */
795104834Sobrien	 ONES (64),		/* dst_mask */
79689857Sobrien	 true),			/* pcrel_offset */
79789857Sobrien
798104834Sobrien  /* 64-bit relocation to the symbol's procedure linkage table.  */
79989857Sobrien  HOWTO (R_PPC64_PLT64,		/* type */
80089857Sobrien	 0,			/* rightshift */
80189857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
80289857Sobrien	 64,			/* bitsize */
80389857Sobrien	 false,			/* pc_relative */
80489857Sobrien	 0,			/* bitpos */
80589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
80699461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
80789857Sobrien	 "R_PPC64_PLT64",	/* name */
80889857Sobrien	 false,			/* partial_inplace */
80989857Sobrien	 0,			/* src_mask */
810104834Sobrien	 ONES (64),		/* dst_mask */
81189857Sobrien	 false),		/* pcrel_offset */
81289857Sobrien
81389857Sobrien  /* 64-bit PC relative relocation to the symbol's procedure linkage
81489857Sobrien     table.  */
81589857Sobrien  /* FIXME: R_PPC64_PLTREL64 not supported.  */
81689857Sobrien  HOWTO (R_PPC64_PLTREL64,	/* type */
81789857Sobrien	 0,			/* rightshift */
81889857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
81989857Sobrien	 64,			/* bitsize */
82089857Sobrien	 true,			/* pc_relative */
82189857Sobrien	 0,			/* bitpos */
82289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
82399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
82489857Sobrien	 "R_PPC64_PLTREL64",	/* name */
82589857Sobrien	 false,			/* partial_inplace */
82689857Sobrien	 0,			/* src_mask */
827104834Sobrien	 ONES (64),		/* dst_mask */
82889857Sobrien	 true),			/* pcrel_offset */
82989857Sobrien
83089857Sobrien  /* 16 bit TOC-relative relocation.  */
83189857Sobrien
83289857Sobrien  /* R_PPC64_TOC16	  47	   half16*	S + A - .TOC.  */
83389857Sobrien  HOWTO (R_PPC64_TOC16,		/* type */
83489857Sobrien	 0,			/* rightshift */
83589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
83689857Sobrien	 16,			/* bitsize */
83789857Sobrien	 false,			/* pc_relative */
83889857Sobrien	 0,			/* bitpos */
83989857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
84099461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
84189857Sobrien	 "R_PPC64_TOC16",	/* name */
84289857Sobrien	 false,			/* partial_inplace */
84389857Sobrien	 0,			/* src_mask */
84489857Sobrien	 0xffff,		/* dst_mask */
84589857Sobrien	 false),		/* pcrel_offset */
84689857Sobrien
84789857Sobrien  /* 16 bit TOC-relative relocation without overflow.  */
84889857Sobrien
84989857Sobrien  /* R_PPC64_TOC16_LO	  48	   half16	 #lo (S + A - .TOC.)  */
85089857Sobrien  HOWTO (R_PPC64_TOC16_LO,	/* type */
85189857Sobrien	 0,			/* rightshift */
85289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
85389857Sobrien	 16,			/* bitsize */
85489857Sobrien	 false,			/* pc_relative */
85589857Sobrien	 0,			/* bitpos */
85689857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
85799461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
85889857Sobrien	 "R_PPC64_TOC16_LO",	/* name */
85989857Sobrien	 false,			/* partial_inplace */
86089857Sobrien	 0,			/* src_mask */
86189857Sobrien	 0xffff,		/* dst_mask */
86289857Sobrien	 false),		/* pcrel_offset */
86389857Sobrien
86489857Sobrien  /* 16 bit TOC-relative relocation, high 16 bits.  */
86589857Sobrien
86689857Sobrien  /* R_PPC64_TOC16_HI	  49	   half16	 #hi (S + A - .TOC.)  */
86789857Sobrien  HOWTO (R_PPC64_TOC16_HI,	/* type */
86889857Sobrien	 16,			/* rightshift */
86989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
87089857Sobrien	 16,			/* bitsize */
87189857Sobrien	 false,			/* pc_relative */
87289857Sobrien	 0,			/* bitpos */
87389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
87499461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
87589857Sobrien	 "R_PPC64_TOC16_HI",	/* name */
87689857Sobrien	 false,			/* partial_inplace */
87789857Sobrien	 0,			/* src_mask */
87889857Sobrien	 0xffff,		/* dst_mask */
87989857Sobrien	 false),		/* pcrel_offset */
88089857Sobrien
88189857Sobrien  /* 16 bit TOC-relative relocation, high 16 bits, plus 1 if the
88289857Sobrien     contents of the low 16 bits, treated as a signed number, is
88389857Sobrien     negative.  */
88489857Sobrien
88589857Sobrien  /* R_PPC64_TOC16_HA	  50	   half16	 #ha (S + A - .TOC.)  */
88689857Sobrien  HOWTO (R_PPC64_TOC16_HA,	/* type */
88789857Sobrien	 16,			/* rightshift */
88889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
88989857Sobrien	 16,			/* bitsize */
89089857Sobrien	 false,			/* pc_relative */
89189857Sobrien	 0,			/* bitpos */
89289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
89399461Sobrien	 ppc64_elf_toc_ha_reloc, /* special_function */
89489857Sobrien	 "R_PPC64_TOC16_HA",	/* name */
89589857Sobrien	 false,			/* partial_inplace */
89689857Sobrien	 0,			/* src_mask */
89789857Sobrien	 0xffff,		/* dst_mask */
89889857Sobrien	 false),		/* pcrel_offset */
89989857Sobrien
90089857Sobrien  /* 64-bit relocation; insert value of TOC base (.TOC.).  */
90189857Sobrien
90289857Sobrien  /* R_PPC64_TOC		  51	   doubleword64	 .TOC.  */
90389857Sobrien  HOWTO (R_PPC64_TOC,		/* type */
90489857Sobrien	 0,			/* rightshift */
90589857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
90689857Sobrien	 64,			/* bitsize */
90789857Sobrien	 false,			/* pc_relative */
90889857Sobrien	 0,			/* bitpos */
90989857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
91099461Sobrien	 ppc64_elf_toc64_reloc,	/* special_function */
91189857Sobrien	 "R_PPC64_TOC",		/* name */
91289857Sobrien	 false,			/* partial_inplace */
91389857Sobrien	 0,			/* src_mask */
914104834Sobrien	 ONES (64),		/* dst_mask */
91589857Sobrien	 false),		/* pcrel_offset */
91689857Sobrien
91789857Sobrien  /* Like R_PPC64_GOT16, but also informs the link editor that the
91889857Sobrien     value to relocate may (!) refer to a PLT entry which the link
91989857Sobrien     editor (a) may replace with the symbol value.  If the link editor
92089857Sobrien     is unable to fully resolve the symbol, it may (b) create a PLT
92189857Sobrien     entry and store the address to the new PLT entry in the GOT.
92289857Sobrien     This permits lazy resolution of function symbols at run time.
92389857Sobrien     The link editor may also skip all of this and just (c) emit a
92489857Sobrien     R_PPC64_GLOB_DAT to tie the symbol to the GOT entry.  */
92589857Sobrien  /* FIXME: R_PPC64_PLTGOT16 not implemented.  */
92689857Sobrien    HOWTO (R_PPC64_PLTGOT16,	/* type */
92789857Sobrien	 0,			/* rightshift */
92889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
92989857Sobrien	 16,			/* bitsize */
93089857Sobrien	 false,			/* pc_relative */
93189857Sobrien	 0,			/* bitpos */
93289857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
93399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
93489857Sobrien	 "R_PPC64_PLTGOT16",	/* name */
93589857Sobrien	 false,			/* partial_inplace */
93689857Sobrien	 0,			/* src_mask */
93789857Sobrien	 0xffff,		/* dst_mask */
93889857Sobrien	 false),		/* pcrel_offset */
93989857Sobrien
94089857Sobrien  /* Like R_PPC64_PLTGOT16, but without overflow.  */
94189857Sobrien  /* FIXME: R_PPC64_PLTGOT16_LO not implemented.  */
94289857Sobrien  HOWTO (R_PPC64_PLTGOT16_LO,	/* type */
94389857Sobrien	 0,			/* rightshift */
94489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
94589857Sobrien	 16,			/* bitsize */
94689857Sobrien	 false,			/* pc_relative */
94789857Sobrien	 0,			/* bitpos */
94889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
94999461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
95089857Sobrien	 "R_PPC64_PLTGOT16_LO",	/* name */
95189857Sobrien	 false,			/* partial_inplace */
95289857Sobrien	 0,			/* src_mask */
95389857Sobrien	 0xffff,		/* dst_mask */
95489857Sobrien	 false),		/* pcrel_offset */
95589857Sobrien
95689857Sobrien  /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address.  */
95789857Sobrien  /* FIXME: R_PPC64_PLTGOT16_HI not implemented.  */
95889857Sobrien  HOWTO (R_PPC64_PLTGOT16_HI,	/* type */
95989857Sobrien	 16,			/* rightshift */
96089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
96189857Sobrien	 16,			/* bitsize */
96289857Sobrien	 false,			/* pc_relative */
96389857Sobrien	 0,			/* bitpos */
96489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
96599461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
96689857Sobrien	 "R_PPC64_PLTGOT16_HI",	/* name */
96789857Sobrien	 false,			/* partial_inplace */
96889857Sobrien	 0,			/* src_mask */
96989857Sobrien	 0xffff,		/* dst_mask */
97089857Sobrien	 false),		/* pcrel_offset */
97189857Sobrien
97289857Sobrien  /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address, plus
97389857Sobrien     1 if the contents of the low 16 bits, treated as a signed number,
97489857Sobrien     is negative.  */
97589857Sobrien  /* FIXME: R_PPC64_PLTGOT16_HA not implemented.  */
97689857Sobrien  HOWTO (R_PPC64_PLTGOT16_HA,	/* type */
97789857Sobrien	 16,			/* rightshift */
97889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
97989857Sobrien	 16,			/* bitsize */
98089857Sobrien	 false,			/* pc_relative */
98189857Sobrien	 0,			/* bitpos */
98289857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
98399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
98489857Sobrien	 "R_PPC64_PLTGOT16_HA",	/* name */
98589857Sobrien	 false,			/* partial_inplace */
98689857Sobrien	 0,			/* src_mask */
98789857Sobrien	 0xffff,		/* dst_mask */
98889857Sobrien	 false),		/* pcrel_offset */
98989857Sobrien
99089857Sobrien  /* Like R_PPC64_ADDR16, but for instructions with a DS field.  */
99189857Sobrien  HOWTO (R_PPC64_ADDR16_DS,	/* type */
99289857Sobrien	 0,			/* rightshift */
99389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
99489857Sobrien	 16,			/* bitsize */
99589857Sobrien	 false,			/* pc_relative */
99689857Sobrien	 0,			/* bitpos */
99789857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
99889857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
99989857Sobrien	 "R_PPC64_ADDR16_DS",	/* name */
100089857Sobrien	 false,			/* partial_inplace */
100189857Sobrien	 0,			/* src_mask */
100289857Sobrien	 0xfffc,		/* dst_mask */
100389857Sobrien	 false),		/* pcrel_offset */
100489857Sobrien
100589857Sobrien  /* Like R_PPC64_ADDR16_LO, but for instructions with a DS field.  */
100689857Sobrien  HOWTO (R_PPC64_ADDR16_LO_DS,	/* type */
100789857Sobrien	 0,			/* rightshift */
100889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
100989857Sobrien	 16,			/* bitsize */
101089857Sobrien	 false,			/* pc_relative */
101189857Sobrien	 0,			/* bitpos */
101289857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
101389857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
101489857Sobrien	 "R_PPC64_ADDR16_LO_DS",/* name */
101589857Sobrien	 false,			/* partial_inplace */
101689857Sobrien	 0,			/* src_mask */
101789857Sobrien	 0xfffc,		/* dst_mask */
101889857Sobrien	 false),		/* pcrel_offset */
101989857Sobrien
102089857Sobrien  /* Like R_PPC64_GOT16, but for instructions with a DS field.  */
102189857Sobrien  HOWTO (R_PPC64_GOT16_DS,	/* type */
102289857Sobrien	 0,			/* rightshift */
102389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
102489857Sobrien	 16,			/* bitsize */
102589857Sobrien	 false,			/* pc_relative */
102689857Sobrien	 0,			/* bitpos */
102789857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
102899461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
102989857Sobrien	 "R_PPC64_GOT16_DS",	/* name */
103089857Sobrien	 false,			/* partial_inplace */
103189857Sobrien	 0,			/* src_mask */
103289857Sobrien	 0xfffc,		/* dst_mask */
103389857Sobrien	 false),		/* pcrel_offset */
103489857Sobrien
103589857Sobrien  /* Like R_PPC64_GOT16_LO, but for instructions with a DS field.  */
103689857Sobrien  HOWTO (R_PPC64_GOT16_LO_DS,	/* type */
103789857Sobrien	 0,			/* rightshift */
103889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
103989857Sobrien	 16,			/* bitsize */
104089857Sobrien	 false,			/* pc_relative */
104189857Sobrien	 0,			/* bitpos */
104289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
104399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
104489857Sobrien	 "R_PPC64_GOT16_LO_DS",	/* name */
104589857Sobrien	 false,			/* partial_inplace */
104689857Sobrien	 0,			/* src_mask */
104789857Sobrien	 0xfffc,		/* dst_mask */
104889857Sobrien	 false),		/* pcrel_offset */
104989857Sobrien
105089857Sobrien  /* Like R_PPC64_PLT16_LO, but for instructions with a DS field.  */
105189857Sobrien  HOWTO (R_PPC64_PLT16_LO_DS,	/* type */
105289857Sobrien	 0,			/* rightshift */
105389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
105489857Sobrien	 16,			/* bitsize */
105589857Sobrien	 false,			/* pc_relative */
105689857Sobrien	 0,			/* bitpos */
105789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
105899461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
105989857Sobrien	 "R_PPC64_PLT16_LO_DS",	/* name */
106089857Sobrien	 false,			/* partial_inplace */
106189857Sobrien	 0,			/* src_mask */
106289857Sobrien	 0xfffc,		/* dst_mask */
106389857Sobrien	 false),		/* pcrel_offset */
106489857Sobrien
106589857Sobrien  /* Like R_PPC64_SECTOFF, but for instructions with a DS field.  */
106689857Sobrien  HOWTO (R_PPC64_SECTOFF_DS,	/* type */
106789857Sobrien	 0,			/* rightshift */
106899461Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
106999461Sobrien	 16,			/* bitsize */
107099461Sobrien	 false,			/* pc_relative */
107189857Sobrien	 0,			/* bitpos */
107289857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
107399461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
107489857Sobrien	 "R_PPC64_SECTOFF_DS",	/* name */
107589857Sobrien	 false,			/* partial_inplace */
107689857Sobrien	 0,			/* src_mask */
107799461Sobrien	 0xfffc,		/* dst_mask */
107899461Sobrien	 false),		/* pcrel_offset */
107989857Sobrien
108089857Sobrien  /* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field.  */
108189857Sobrien  HOWTO (R_PPC64_SECTOFF_LO_DS, /* type */
108289857Sobrien	 0,			/* rightshift */
108389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
108489857Sobrien	 16,			/* bitsize */
108589857Sobrien	 false,			/* pc_relative */
108689857Sobrien	 0,			/* bitpos */
108789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
108899461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
108989857Sobrien	 "R_PPC64_SECTOFF_LO_DS",/* name */
109089857Sobrien	 false,			/* partial_inplace */
109189857Sobrien	 0,			/* src_mask */
109289857Sobrien	 0xfffc,		/* dst_mask */
109389857Sobrien	 false),		/* pcrel_offset */
109489857Sobrien
109589857Sobrien  /* Like R_PPC64_TOC16, but for instructions with a DS field.  */
109689857Sobrien  HOWTO (R_PPC64_TOC16_DS,	/* type */
109789857Sobrien	 0,			/* rightshift */
109889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
109989857Sobrien	 16,			/* bitsize */
110089857Sobrien	 false,			/* pc_relative */
110189857Sobrien	 0,			/* bitpos */
110289857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
110399461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
110489857Sobrien	 "R_PPC64_TOC16_DS",	/* name */
110589857Sobrien	 false,			/* partial_inplace */
110689857Sobrien	 0,			/* src_mask */
110789857Sobrien	 0xfffc,		/* dst_mask */
110889857Sobrien	 false),		/* pcrel_offset */
110989857Sobrien
111089857Sobrien  /* Like R_PPC64_TOC16_LO, but for instructions with a DS field.  */
111189857Sobrien  HOWTO (R_PPC64_TOC16_LO_DS,	/* type */
111289857Sobrien	 0,			/* rightshift */
111389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
111489857Sobrien	 16,			/* bitsize */
111589857Sobrien	 false,			/* pc_relative */
111689857Sobrien	 0,			/* bitpos */
111789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
111899461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
111989857Sobrien	 "R_PPC64_TOC16_LO_DS",	/* name */
112089857Sobrien	 false,			/* partial_inplace */
112189857Sobrien	 0,			/* src_mask */
112289857Sobrien	 0xfffc,		/* dst_mask */
112389857Sobrien	 false),		/* pcrel_offset */
112489857Sobrien
112589857Sobrien  /* Like R_PPC64_PLTGOT16, but for instructions with a DS field.  */
112689857Sobrien  /* FIXME: R_PPC64_PLTGOT16_DS not implemented.  */
112789857Sobrien    HOWTO (R_PPC64_PLTGOT16_DS,	/* type */
112889857Sobrien	 0,			/* rightshift */
112989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
113089857Sobrien	 16,			/* bitsize */
113189857Sobrien	 false,			/* pc_relative */
113289857Sobrien	 0,			/* bitpos */
113389857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
113499461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
113589857Sobrien	 "R_PPC64_PLTGOT16_DS",	/* name */
113689857Sobrien	 false,			/* partial_inplace */
113789857Sobrien	 0,			/* src_mask */
113889857Sobrien	 0xfffc,		/* dst_mask */
113989857Sobrien	 false),		/* pcrel_offset */
114089857Sobrien
114189857Sobrien  /* Like R_PPC64_PLTGOT16_LO, but for instructions with a DS field.  */
114289857Sobrien  /* FIXME: R_PPC64_PLTGOT16_LO not implemented.  */
114389857Sobrien  HOWTO (R_PPC64_PLTGOT16_LO_DS,/* type */
114489857Sobrien	 0,			/* rightshift */
114589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
114689857Sobrien	 16,			/* bitsize */
114789857Sobrien	 false,			/* pc_relative */
114889857Sobrien	 0,			/* bitpos */
114989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
115099461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
115189857Sobrien	 "R_PPC64_PLTGOT16_LO_DS",/* name */
115289857Sobrien	 false,			/* partial_inplace */
115389857Sobrien	 0,			/* src_mask */
115489857Sobrien	 0xfffc,		/* dst_mask */
115589857Sobrien	 false),		/* pcrel_offset */
115689857Sobrien
115789857Sobrien  /* GNU extension to record C++ vtable hierarchy.  */
115889857Sobrien  HOWTO (R_PPC64_GNU_VTINHERIT,	/* type */
115989857Sobrien	 0,			/* rightshift */
116089857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
116189857Sobrien	 0,			/* bitsize */
116289857Sobrien	 false,			/* pc_relative */
116389857Sobrien	 0,			/* bitpos */
116489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
116589857Sobrien	 NULL,			/* special_function */
116689857Sobrien	 "R_PPC64_GNU_VTINHERIT", /* name */
116789857Sobrien	 false,			/* partial_inplace */
116889857Sobrien	 0,			/* src_mask */
116989857Sobrien	 0,			/* dst_mask */
117089857Sobrien	 false),		/* pcrel_offset */
117189857Sobrien
117289857Sobrien  /* GNU extension to record C++ vtable member usage.  */
117389857Sobrien  HOWTO (R_PPC64_GNU_VTENTRY,	/* type */
117489857Sobrien	 0,			/* rightshift */
117589857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
117689857Sobrien	 0,			/* bitsize */
117789857Sobrien	 false,			/* pc_relative */
117889857Sobrien	 0,			/* bitpos */
117989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
118089857Sobrien	 NULL,			/* special_function */
118189857Sobrien	 "R_PPC64_GNU_VTENTRY",	/* name */
118289857Sobrien	 false,			/* partial_inplace */
118389857Sobrien	 0,			/* src_mask */
118489857Sobrien	 0,			/* dst_mask */
118589857Sobrien	 false),		/* pcrel_offset */
118689857Sobrien};
118789857Sobrien
118889857Sobrien
118989857Sobrien/* Initialize the ppc64_elf_howto_table, so that linear accesses can
119089857Sobrien   be done.  */
119189857Sobrien
119289857Sobrienstatic void
119389857Sobrienppc_howto_init ()
119489857Sobrien{
119589857Sobrien  unsigned int i, type;
119689857Sobrien
119789857Sobrien  for (i = 0;
119889857Sobrien       i < sizeof (ppc64_elf_howto_raw) / sizeof (ppc64_elf_howto_raw[0]);
119989857Sobrien       i++)
120089857Sobrien    {
120189857Sobrien      type = ppc64_elf_howto_raw[i].type;
120289857Sobrien      BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
120389857Sobrien			  / sizeof (ppc64_elf_howto_table[0])));
120489857Sobrien      ppc64_elf_howto_table[type] = &ppc64_elf_howto_raw[i];
120589857Sobrien    }
120689857Sobrien}
120789857Sobrien
120889857Sobrienstatic reloc_howto_type *
120989857Sobrienppc64_elf_reloc_type_lookup (abfd, code)
121089857Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
121189857Sobrien     bfd_reloc_code_real_type code;
121289857Sobrien{
121389857Sobrien  enum elf_ppc_reloc_type ppc_reloc = R_PPC_NONE;
121489857Sobrien
121589857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
121689857Sobrien    /* Initialize howto table if needed.  */
121789857Sobrien    ppc_howto_init ();
121889857Sobrien
121989857Sobrien  switch ((int) code)
122089857Sobrien    {
122189857Sobrien    default:
122289857Sobrien      return (reloc_howto_type *) NULL;
122389857Sobrien
122489857Sobrien    case BFD_RELOC_NONE:		 ppc_reloc = R_PPC64_NONE;
122589857Sobrien      break;
122689857Sobrien    case BFD_RELOC_32:			 ppc_reloc = R_PPC64_ADDR32;
122789857Sobrien      break;
122889857Sobrien    case BFD_RELOC_PPC_BA26:		 ppc_reloc = R_PPC64_ADDR24;
122989857Sobrien      break;
123089857Sobrien    case BFD_RELOC_16:			 ppc_reloc = R_PPC64_ADDR16;
123189857Sobrien      break;
123289857Sobrien    case BFD_RELOC_LO16:		 ppc_reloc = R_PPC64_ADDR16_LO;
123389857Sobrien      break;
123489857Sobrien    case BFD_RELOC_HI16:		 ppc_reloc = R_PPC64_ADDR16_HI;
123589857Sobrien      break;
123689857Sobrien    case BFD_RELOC_HI16_S:		 ppc_reloc = R_PPC64_ADDR16_HA;
123789857Sobrien      break;
123889857Sobrien    case BFD_RELOC_PPC_BA16:		 ppc_reloc = R_PPC64_ADDR14;
123989857Sobrien      break;
124089857Sobrien    case BFD_RELOC_PPC_BA16_BRTAKEN:	 ppc_reloc = R_PPC64_ADDR14_BRTAKEN;
124189857Sobrien      break;
124289857Sobrien    case BFD_RELOC_PPC_BA16_BRNTAKEN:	 ppc_reloc = R_PPC64_ADDR14_BRNTAKEN;
124389857Sobrien      break;
124489857Sobrien    case BFD_RELOC_PPC_B26:		 ppc_reloc = R_PPC64_REL24;
124589857Sobrien      break;
124689857Sobrien    case BFD_RELOC_PPC_B16:		 ppc_reloc = R_PPC64_REL14;
124789857Sobrien      break;
124889857Sobrien    case BFD_RELOC_PPC_B16_BRTAKEN:	 ppc_reloc = R_PPC64_REL14_BRTAKEN;
124989857Sobrien      break;
125089857Sobrien    case BFD_RELOC_PPC_B16_BRNTAKEN:	 ppc_reloc = R_PPC64_REL14_BRNTAKEN;
125189857Sobrien      break;
125289857Sobrien    case BFD_RELOC_16_GOTOFF:		 ppc_reloc = R_PPC64_GOT16;
125389857Sobrien      break;
125489857Sobrien    case BFD_RELOC_LO16_GOTOFF:		 ppc_reloc = R_PPC64_GOT16_LO;
125589857Sobrien      break;
125689857Sobrien    case BFD_RELOC_HI16_GOTOFF:		 ppc_reloc = R_PPC64_GOT16_HI;
125789857Sobrien      break;
125889857Sobrien    case BFD_RELOC_HI16_S_GOTOFF:	 ppc_reloc = R_PPC64_GOT16_HA;
125989857Sobrien      break;
126089857Sobrien    case BFD_RELOC_PPC_COPY:		 ppc_reloc = R_PPC64_COPY;
126189857Sobrien      break;
126289857Sobrien    case BFD_RELOC_PPC_GLOB_DAT:	 ppc_reloc = R_PPC64_GLOB_DAT;
126389857Sobrien      break;
126489857Sobrien    case BFD_RELOC_32_PCREL:		 ppc_reloc = R_PPC64_REL32;
126589857Sobrien      break;
126689857Sobrien    case BFD_RELOC_32_PLTOFF:		 ppc_reloc = R_PPC64_PLT32;
126789857Sobrien      break;
126889857Sobrien    case BFD_RELOC_32_PLT_PCREL:	 ppc_reloc = R_PPC64_PLTREL32;
126989857Sobrien      break;
127089857Sobrien    case BFD_RELOC_LO16_PLTOFF:		 ppc_reloc = R_PPC64_PLT16_LO;
127189857Sobrien      break;
127289857Sobrien    case BFD_RELOC_HI16_PLTOFF:		 ppc_reloc = R_PPC64_PLT16_HI;
127389857Sobrien      break;
127489857Sobrien    case BFD_RELOC_HI16_S_PLTOFF:	 ppc_reloc = R_PPC64_PLT16_HA;
127589857Sobrien      break;
127699461Sobrien    case BFD_RELOC_16_BASEREL:		 ppc_reloc = R_PPC64_SECTOFF;
127789857Sobrien      break;
127889857Sobrien    case BFD_RELOC_LO16_BASEREL:	 ppc_reloc = R_PPC64_SECTOFF_LO;
127989857Sobrien      break;
128089857Sobrien    case BFD_RELOC_HI16_BASEREL:	 ppc_reloc = R_PPC64_SECTOFF_HI;
128189857Sobrien      break;
128289857Sobrien    case BFD_RELOC_HI16_S_BASEREL:	 ppc_reloc = R_PPC64_SECTOFF_HA;
128389857Sobrien      break;
128489857Sobrien    case BFD_RELOC_CTOR:		 ppc_reloc = R_PPC64_ADDR64;
128589857Sobrien      break;
128689857Sobrien    case BFD_RELOC_64:			 ppc_reloc = R_PPC64_ADDR64;
128789857Sobrien      break;
128889857Sobrien    case BFD_RELOC_PPC64_HIGHER:	 ppc_reloc = R_PPC64_ADDR16_HIGHER;
128989857Sobrien      break;
129089857Sobrien    case BFD_RELOC_PPC64_HIGHER_S:	 ppc_reloc = R_PPC64_ADDR16_HIGHERA;
129189857Sobrien      break;
129289857Sobrien    case BFD_RELOC_PPC64_HIGHEST:	 ppc_reloc = R_PPC64_ADDR16_HIGHEST;
129389857Sobrien      break;
129489857Sobrien    case BFD_RELOC_PPC64_HIGHEST_S:	 ppc_reloc = R_PPC64_ADDR16_HIGHESTA;
129589857Sobrien      break;
129689857Sobrien    case BFD_RELOC_64_PCREL:		 ppc_reloc = R_PPC64_REL64;
129789857Sobrien      break;
129889857Sobrien    case BFD_RELOC_64_PLTOFF:		 ppc_reloc = R_PPC64_PLT64;
129989857Sobrien      break;
130089857Sobrien    case BFD_RELOC_64_PLT_PCREL:	 ppc_reloc = R_PPC64_PLTREL64;
130189857Sobrien      break;
130289857Sobrien    case BFD_RELOC_PPC_TOC16:		 ppc_reloc = R_PPC64_TOC16;
130389857Sobrien      break;
130489857Sobrien    case BFD_RELOC_PPC64_TOC16_LO:	 ppc_reloc = R_PPC64_TOC16_LO;
130589857Sobrien      break;
130689857Sobrien    case BFD_RELOC_PPC64_TOC16_HI:	 ppc_reloc = R_PPC64_TOC16_HI;
130789857Sobrien      break;
130889857Sobrien    case BFD_RELOC_PPC64_TOC16_HA:	 ppc_reloc = R_PPC64_TOC16_HA;
130989857Sobrien      break;
131089857Sobrien    case BFD_RELOC_PPC64_TOC:		 ppc_reloc = R_PPC64_TOC;
131189857Sobrien      break;
131289857Sobrien    case BFD_RELOC_PPC64_PLTGOT16:	 ppc_reloc = R_PPC64_PLTGOT16;
131389857Sobrien      break;
131489857Sobrien    case BFD_RELOC_PPC64_PLTGOT16_LO:	 ppc_reloc = R_PPC64_PLTGOT16_LO;
131589857Sobrien      break;
131689857Sobrien    case BFD_RELOC_PPC64_PLTGOT16_HI:	 ppc_reloc = R_PPC64_PLTGOT16_HI;
131789857Sobrien      break;
131889857Sobrien    case BFD_RELOC_PPC64_PLTGOT16_HA:	 ppc_reloc = R_PPC64_PLTGOT16_HA;
131989857Sobrien      break;
132089857Sobrien    case BFD_RELOC_PPC64_ADDR16_DS:      ppc_reloc = R_PPC64_ADDR16_DS;
132189857Sobrien      break;
132289857Sobrien    case BFD_RELOC_PPC64_ADDR16_LO_DS:   ppc_reloc = R_PPC64_ADDR16_LO_DS;
132389857Sobrien      break;
132489857Sobrien    case BFD_RELOC_PPC64_GOT16_DS:       ppc_reloc = R_PPC64_GOT16_DS;
132589857Sobrien      break;
132689857Sobrien    case BFD_RELOC_PPC64_GOT16_LO_DS:    ppc_reloc = R_PPC64_GOT16_LO_DS;
132789857Sobrien      break;
132889857Sobrien    case BFD_RELOC_PPC64_PLT16_LO_DS:    ppc_reloc = R_PPC64_PLT16_LO_DS;
132989857Sobrien      break;
133089857Sobrien    case BFD_RELOC_PPC64_SECTOFF_DS:     ppc_reloc = R_PPC64_SECTOFF_DS;
133189857Sobrien      break;
133289857Sobrien    case BFD_RELOC_PPC64_SECTOFF_LO_DS:  ppc_reloc = R_PPC64_SECTOFF_LO_DS;
133389857Sobrien      break;
133489857Sobrien    case BFD_RELOC_PPC64_TOC16_DS:       ppc_reloc = R_PPC64_TOC16_DS;
133589857Sobrien      break;
133689857Sobrien    case BFD_RELOC_PPC64_TOC16_LO_DS:    ppc_reloc = R_PPC64_TOC16_LO_DS;
133789857Sobrien      break;
133889857Sobrien    case BFD_RELOC_PPC64_PLTGOT16_DS:    ppc_reloc = R_PPC64_PLTGOT16_DS;
133989857Sobrien      break;
134089857Sobrien    case BFD_RELOC_PPC64_PLTGOT16_LO_DS: ppc_reloc = R_PPC64_PLTGOT16_LO_DS;
134189857Sobrien      break;
134289857Sobrien    case BFD_RELOC_VTABLE_INHERIT:	 ppc_reloc = R_PPC64_GNU_VTINHERIT;
134389857Sobrien      break;
134489857Sobrien    case BFD_RELOC_VTABLE_ENTRY:	 ppc_reloc = R_PPC64_GNU_VTENTRY;
134589857Sobrien      break;
134689857Sobrien    }
134789857Sobrien
134889857Sobrien  return ppc64_elf_howto_table[(int) ppc_reloc];
134989857Sobrien};
135089857Sobrien
135189857Sobrien/* Set the howto pointer for a PowerPC ELF reloc.  */
135289857Sobrien
135389857Sobrienstatic void
135489857Sobrienppc64_elf_info_to_howto (abfd, cache_ptr, dst)
135589857Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
135689857Sobrien     arelent *cache_ptr;
135789857Sobrien     Elf64_Internal_Rela *dst;
135889857Sobrien{
135989857Sobrien  unsigned int type;
136089857Sobrien
1361104834Sobrien  /* Initialize howto table if needed.  */
136289857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
136389857Sobrien    ppc_howto_init ();
136489857Sobrien
136589857Sobrien  type = ELF64_R_TYPE (dst->r_info);
136689857Sobrien  BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
136789857Sobrien		      / sizeof (ppc64_elf_howto_table[0])));
136889857Sobrien  cache_ptr->howto = ppc64_elf_howto_table[type];
136989857Sobrien}
137089857Sobrien
137189857Sobrien/* Handle the R_PPC_ADDR16_HA and similar relocs.  */
137289857Sobrien
137389857Sobrienstatic bfd_reloc_status_type
137499461Sobrienppc64_elf_ha_reloc (abfd, reloc_entry, symbol, data,
137599461Sobrien		    input_section, output_bfd, error_message)
137699461Sobrien     bfd *abfd;
137789857Sobrien     arelent *reloc_entry;
137889857Sobrien     asymbol *symbol;
137999461Sobrien     PTR data;
138089857Sobrien     asection *input_section;
138189857Sobrien     bfd *output_bfd;
138299461Sobrien     char **error_message;
138389857Sobrien{
138499461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
138599461Sobrien     call the generic function.  Any adjustment will be done at final
138699461Sobrien     link time.  */
138799461Sobrien  if (output_bfd != NULL)
1388104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
138999461Sobrien				  input_section, output_bfd, error_message);
139089857Sobrien
139199461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.
139299461Sobrien     We won't actually be using the low 16 bits, so trashing them
139399461Sobrien     doesn't matter.  */
139499461Sobrien  reloc_entry->addend += 0x8000;
139599461Sobrien  return bfd_reloc_continue;
139699461Sobrien}
139799461Sobrien
139899461Sobrienstatic bfd_reloc_status_type
139999461Sobrienppc64_elf_brtaken_reloc (abfd, reloc_entry, symbol, data,
140099461Sobrien			 input_section, output_bfd, error_message)
140199461Sobrien     bfd *abfd;
140299461Sobrien     arelent *reloc_entry;
140399461Sobrien     asymbol *symbol;
140499461Sobrien     PTR data;
140599461Sobrien     asection *input_section;
140699461Sobrien     bfd *output_bfd;
140799461Sobrien     char **error_message;
140899461Sobrien{
140999461Sobrien  long insn;
141099461Sobrien  enum elf_ppc_reloc_type r_type;
141199461Sobrien  bfd_size_type octets;
141299461Sobrien  /* Disabled until we sort out how ld should choose 'y' vs 'at'.  */
141399461Sobrien  boolean is_power4 = false;
141499461Sobrien
141599461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
141699461Sobrien     call the generic function.  Any adjustment will be done at final
141799461Sobrien     link time.  */
141889857Sobrien  if (output_bfd != NULL)
1419104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
142099461Sobrien				  input_section, output_bfd, error_message);
142199461Sobrien
142299461Sobrien  octets = reloc_entry->address * bfd_octets_per_byte (abfd);
142399461Sobrien  insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
142499461Sobrien  insn &= ~(0x01 << 21);
142599461Sobrien  r_type = (enum elf_ppc_reloc_type) reloc_entry->howto->type;
142699461Sobrien  if (r_type == R_PPC64_ADDR14_BRTAKEN
142799461Sobrien      || r_type == R_PPC64_REL14_BRTAKEN)
1428104834Sobrien    insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field.  */
142999461Sobrien
143099461Sobrien  if (is_power4)
143189857Sobrien    {
143299461Sobrien      /* Set 'a' bit.  This is 0b00010 in BO field for branch
143399461Sobrien	 on CR(BI) insns (BO == 001at or 011at), and 0b01000
143499461Sobrien	 for branch on CTR insns (BO == 1a00t or 1a01t).  */
143599461Sobrien      if ((insn & (0x14 << 21)) == (0x04 << 21))
143699461Sobrien	insn |= 0x02 << 21;
143799461Sobrien      else if ((insn & (0x14 << 21)) == (0x10 << 21))
143899461Sobrien	insn |= 0x08 << 21;
143999461Sobrien      else
144099461Sobrien	return bfd_reloc_continue;
144189857Sobrien    }
144299461Sobrien  else
144399461Sobrien    {
144499461Sobrien      bfd_vma target = 0;
144599461Sobrien      bfd_vma from;
144689857Sobrien
144799461Sobrien      if (!bfd_is_com_section (symbol->section))
144899461Sobrien	target = symbol->value;
144999461Sobrien      target += symbol->section->output_section->vma;
145099461Sobrien      target += symbol->section->output_offset;
145199461Sobrien      target += reloc_entry->addend;
145289857Sobrien
145399461Sobrien      from = (reloc_entry->address
145499461Sobrien	      + input_section->output_offset
145599461Sobrien	      + input_section->output_section->vma);
145689857Sobrien
145799461Sobrien      /* Invert 'y' bit if not the default.  */
145899461Sobrien      if ((bfd_signed_vma) (target - from) < 0)
145999461Sobrien	insn ^= 0x01 << 21;
146099461Sobrien    }
146199461Sobrien  bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + octets);
146299461Sobrien  return bfd_reloc_continue;
146399461Sobrien}
146489857Sobrien
146599461Sobrienstatic bfd_reloc_status_type
146699461Sobrienppc64_elf_sectoff_reloc (abfd, reloc_entry, symbol, data,
146799461Sobrien			 input_section, output_bfd, error_message)
146899461Sobrien     bfd *abfd;
146999461Sobrien     arelent *reloc_entry;
147099461Sobrien     asymbol *symbol;
147199461Sobrien     PTR data;
147299461Sobrien     asection *input_section;
147399461Sobrien     bfd *output_bfd;
147499461Sobrien     char **error_message;
147599461Sobrien{
147699461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
147799461Sobrien     call the generic function.  Any adjustment will be done at final
147899461Sobrien     link time.  */
147999461Sobrien  if (output_bfd != NULL)
1480104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
148199461Sobrien				  input_section, output_bfd, error_message);
148289857Sobrien
148399461Sobrien  /* Subtract the symbol section base address.  */
148499461Sobrien  reloc_entry->addend -= symbol->section->output_section->vma;
148589857Sobrien  return bfd_reloc_continue;
148689857Sobrien}
148789857Sobrien
148899461Sobrienstatic bfd_reloc_status_type
148999461Sobrienppc64_elf_sectoff_ha_reloc (abfd, reloc_entry, symbol, data,
149099461Sobrien			    input_section, output_bfd, error_message)
149199461Sobrien     bfd *abfd;
149299461Sobrien     arelent *reloc_entry;
149399461Sobrien     asymbol *symbol;
149499461Sobrien     PTR data;
149599461Sobrien     asection *input_section;
149699461Sobrien     bfd *output_bfd;
149799461Sobrien     char **error_message;
149899461Sobrien{
149999461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
150099461Sobrien     call the generic function.  Any adjustment will be done at final
150199461Sobrien     link time.  */
150299461Sobrien  if (output_bfd != NULL)
1503104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
150499461Sobrien				  input_section, output_bfd, error_message);
150599461Sobrien
150699461Sobrien  /* Subtract the symbol section base address.  */
150799461Sobrien  reloc_entry->addend -= symbol->section->output_section->vma;
150899461Sobrien
150999461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.  */
151099461Sobrien  reloc_entry->addend += 0x8000;
151199461Sobrien  return bfd_reloc_continue;
151299461Sobrien}
151399461Sobrien
151499461Sobrienstatic bfd_reloc_status_type
151599461Sobrienppc64_elf_toc_reloc (abfd, reloc_entry, symbol, data,
151699461Sobrien		     input_section, output_bfd, error_message)
151799461Sobrien     bfd *abfd;
151899461Sobrien     arelent *reloc_entry;
151999461Sobrien     asymbol *symbol;
152099461Sobrien     PTR data;
152199461Sobrien     asection *input_section;
152299461Sobrien     bfd *output_bfd;
152399461Sobrien     char **error_message;
152499461Sobrien{
152599461Sobrien  bfd_vma TOCstart;
152699461Sobrien
152799461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
152899461Sobrien     call the generic function.  Any adjustment will be done at final
152999461Sobrien     link time.  */
153099461Sobrien  if (output_bfd != NULL)
1531104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
153299461Sobrien				  input_section, output_bfd, error_message);
153399461Sobrien
153499461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
153599461Sobrien  if (TOCstart == 0)
153699461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
153799461Sobrien
153899461Sobrien  /* Subtract the TOC base address.  */
153999461Sobrien  reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
154099461Sobrien  return bfd_reloc_continue;
154199461Sobrien}
154299461Sobrien
154399461Sobrienstatic bfd_reloc_status_type
154499461Sobrienppc64_elf_toc_ha_reloc (abfd, reloc_entry, symbol, data,
154599461Sobrien			input_section, output_bfd, error_message)
154699461Sobrien     bfd *abfd;
154799461Sobrien     arelent *reloc_entry;
154899461Sobrien     asymbol *symbol;
154999461Sobrien     PTR data;
155099461Sobrien     asection *input_section;
155199461Sobrien     bfd *output_bfd;
155299461Sobrien     char **error_message;
155399461Sobrien{
155499461Sobrien  bfd_vma TOCstart;
155599461Sobrien
155699461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
155799461Sobrien     call the generic function.  Any adjustment will be done at final
155899461Sobrien     link time.  */
155999461Sobrien  if (output_bfd != NULL)
1560104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
156199461Sobrien				  input_section, output_bfd, error_message);
156299461Sobrien
156399461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
156499461Sobrien  if (TOCstart == 0)
156599461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
156699461Sobrien
156799461Sobrien  /* Subtract the TOC base address.  */
156899461Sobrien  reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
156999461Sobrien
157099461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.  */
157199461Sobrien  reloc_entry->addend += 0x8000;
157299461Sobrien  return bfd_reloc_continue;
157399461Sobrien}
157499461Sobrien
157599461Sobrienstatic bfd_reloc_status_type
157699461Sobrienppc64_elf_toc64_reloc (abfd, reloc_entry, symbol, data,
157799461Sobrien		       input_section, output_bfd, error_message)
157899461Sobrien     bfd *abfd;
157999461Sobrien     arelent *reloc_entry;
158099461Sobrien     asymbol *symbol;
158199461Sobrien     PTR data;
158299461Sobrien     asection *input_section;
158399461Sobrien     bfd *output_bfd;
158499461Sobrien     char **error_message;
158599461Sobrien{
158699461Sobrien  bfd_vma TOCstart;
158799461Sobrien  bfd_size_type octets;
158899461Sobrien
158999461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
159099461Sobrien     call the generic function.  Any adjustment will be done at final
159199461Sobrien     link time.  */
159299461Sobrien  if (output_bfd != NULL)
1593104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
159499461Sobrien				  input_section, output_bfd, error_message);
159599461Sobrien
159699461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
159799461Sobrien  if (TOCstart == 0)
159899461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
159999461Sobrien
160099461Sobrien  octets = reloc_entry->address * bfd_octets_per_byte (abfd);
160199461Sobrien  bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
160299461Sobrien  return bfd_reloc_ok;
160399461Sobrien}
160499461Sobrien
160599461Sobrienstatic bfd_reloc_status_type
160699461Sobrienppc64_elf_unhandled_reloc (abfd, reloc_entry, symbol, data,
160799461Sobrien			   input_section, output_bfd, error_message)
160899461Sobrien     bfd *abfd;
160999461Sobrien     arelent *reloc_entry;
161099461Sobrien     asymbol *symbol;
161199461Sobrien     PTR data;
161299461Sobrien     asection *input_section;
161399461Sobrien     bfd *output_bfd;
161499461Sobrien     char **error_message;
161599461Sobrien{
161699461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
161799461Sobrien     call the generic function.  Any adjustment will be done at final
161899461Sobrien     link time.  */
161999461Sobrien  if (output_bfd != NULL)
1620104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
162199461Sobrien				  input_section, output_bfd, error_message);
162299461Sobrien
162399461Sobrien  if (error_message != NULL)
162499461Sobrien    {
162599461Sobrien      static char buf[60];
162699461Sobrien      sprintf (buf, "generic linker can't handle %s",
162799461Sobrien	       reloc_entry->howto->name);
162899461Sobrien      *error_message = buf;
162999461Sobrien    }
163099461Sobrien  return bfd_reloc_dangerous;
163199461Sobrien}
163299461Sobrien
1633104834Sobrien/* Fix bad default arch selected for a 64 bit input bfd when the
1634104834Sobrien   default is 32 bit.  */
163589857Sobrien
163689857Sobrienstatic boolean
1637104834Sobrienppc64_elf_object_p (abfd)
163889857Sobrien     bfd *abfd;
163989857Sobrien{
1640104834Sobrien  if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 32)
1641104834Sobrien    {
1642104834Sobrien      Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
164389857Sobrien
1644104834Sobrien      if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS64)
1645104834Sobrien	{
1646104834Sobrien	  /* Relies on arch after 32 bit default being 64 bit default.  */
1647104834Sobrien	  abfd->arch_info = abfd->arch_info->next;
1648104834Sobrien	  BFD_ASSERT (abfd->arch_info->bits_per_word == 64);
1649104834Sobrien	}
1650104834Sobrien    }
165189857Sobrien  return true;
165289857Sobrien}
165389857Sobrien
165489857Sobrien/* Merge backend specific data from an object file to the output
165589857Sobrien   object file when linking.  */
1656104834Sobrien
165789857Sobrienstatic boolean
165889857Sobrienppc64_elf_merge_private_bfd_data (ibfd, obfd)
165989857Sobrien     bfd *ibfd;
166089857Sobrien     bfd *obfd;
166189857Sobrien{
166289857Sobrien  /* Check if we have the same endianess.  */
166389857Sobrien  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1664107492Sobrien      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
166589857Sobrien      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
166689857Sobrien    {
166789857Sobrien      const char *msg;
166889857Sobrien
166989857Sobrien      if (bfd_big_endian (ibfd))
167089857Sobrien	msg = _("%s: compiled for a big endian system and target is little endian");
167189857Sobrien      else
167289857Sobrien	msg = _("%s: compiled for a little endian system and target is big endian");
167389857Sobrien
167489857Sobrien      (*_bfd_error_handler) (msg, bfd_archive_filename (ibfd));
167589857Sobrien
167689857Sobrien      bfd_set_error (bfd_error_wrong_format);
167789857Sobrien      return false;
167889857Sobrien    }
167989857Sobrien
168089857Sobrien  return true;
168189857Sobrien}
168289857Sobrien
168389857Sobrien/* The following functions are specific to the ELF linker, while
168489857Sobrien   functions above are used generally.  Those named ppc64_elf_* are
168589857Sobrien   called by the main ELF linker code.  They appear in this file more
168689857Sobrien   or less in the order in which they are called.  eg.
168789857Sobrien   ppc64_elf_check_relocs is called early in the link process,
168889857Sobrien   ppc64_elf_finish_dynamic_sections is one of the last functions
168989857Sobrien   called.
169089857Sobrien
169189857Sobrien   PowerPC64-ELF uses a similar scheme to PowerPC64-XCOFF in that
169289857Sobrien   functions have both a function code symbol and a function descriptor
169389857Sobrien   symbol.  A call to foo in a relocatable object file looks like:
169489857Sobrien
169589857Sobrien   .		.text
169689857Sobrien   .	x:
169789857Sobrien   .		bl	.foo
169889857Sobrien   .		nop
169989857Sobrien
170089857Sobrien   The function definition in another object file might be:
170189857Sobrien
170289857Sobrien   .		.section .opd
170389857Sobrien   .	foo:	.quad	.foo
170489857Sobrien   .		.quad	.TOC.@tocbase
170589857Sobrien   .		.quad	0
170689857Sobrien   .
170789857Sobrien   .		.text
170889857Sobrien   .	.foo:	blr
170989857Sobrien
171089857Sobrien   When the linker resolves the call during a static link, the branch
171189857Sobrien   unsurprisingly just goes to .foo and the .opd information is unused.
171289857Sobrien   If the function definition is in a shared library, things are a little
171389857Sobrien   different:  The call goes via a plt call stub, the opd information gets
171489857Sobrien   copied to the plt, and the linker patches the nop.
171589857Sobrien
171689857Sobrien   .	x:
171789857Sobrien   .		bl	.foo_stub
171889857Sobrien   .		ld	2,40(1)
171989857Sobrien   .
172089857Sobrien   .
172189857Sobrien   .	.foo_stub:
172289857Sobrien   .		addis	12,2,Lfoo@toc@ha	# in practice, the call stub
172389857Sobrien   .		addi	12,12,Lfoo@toc@l	# is slightly optimised, but
172489857Sobrien   .		std	2,40(1)			# this is the general idea
172589857Sobrien   .		ld	11,0(12)
172689857Sobrien   .		ld	2,8(12)
172789857Sobrien   .		mtctr	11
172889857Sobrien   .		ld	11,16(12)
172989857Sobrien   .		bctr
173089857Sobrien   .
173189857Sobrien   .		.section .plt
173289857Sobrien   .	Lfoo:	reloc (R_PPC64_JMP_SLOT, foo)
173389857Sobrien
173489857Sobrien   The "reloc ()" notation is supposed to indicate that the linker emits
173589857Sobrien   an R_PPC64_JMP_SLOT reloc against foo.  The dynamic linker does the opd
173689857Sobrien   copying.
173789857Sobrien
173889857Sobrien   What are the difficulties here?  Well, firstly, the relocations
173989857Sobrien   examined by the linker in check_relocs are against the function code
174089857Sobrien   sym .foo, while the dynamic relocation in the plt is emitted against
174189857Sobrien   the function descriptor symbol, foo.  Somewhere along the line, we need
174289857Sobrien   to carefully copy dynamic link information from one symbol to the other.
174389857Sobrien   Secondly, the generic part of the elf linker will make .foo a dynamic
174489857Sobrien   symbol as is normal for most other backends.  We need foo dynamic
174589857Sobrien   instead, at least for an application final link.  However, when
174689857Sobrien   creating a shared library containing foo, we need to have both symbols
174789857Sobrien   dynamic so that references to .foo are satisfied during the early
174889857Sobrien   stages of linking.  Otherwise the linker might decide to pull in a
174989857Sobrien   definition from some other object, eg. a static library.  */
175089857Sobrien
175189857Sobrien/* The linker needs to keep track of the number of relocs that it
175289857Sobrien   decides to copy as dynamic relocs in check_relocs for each symbol.
175389857Sobrien   This is so that it can later discard them if they are found to be
175489857Sobrien   unnecessary.  We store the information in a field extending the
175589857Sobrien   regular ELF linker hash table.  */
175689857Sobrien
175789857Sobrienstruct ppc_dyn_relocs
175889857Sobrien{
175989857Sobrien  struct ppc_dyn_relocs *next;
176089857Sobrien
176189857Sobrien  /* The input section of the reloc.  */
176289857Sobrien  asection *sec;
176389857Sobrien
176489857Sobrien  /* Total number of relocs copied for the input section.  */
176589857Sobrien  bfd_size_type count;
176689857Sobrien
176789857Sobrien  /* Number of pc-relative relocs copied for the input section.  */
176889857Sobrien  bfd_size_type pc_count;
176989857Sobrien};
177089857Sobrien
177189857Sobrien/* Of those relocs that might be copied as dynamic relocs, this macro
177289857Sobrien   selects between relative and absolute types.  */
177389857Sobrien
177489857Sobrien#define IS_ABSOLUTE_RELOC(RTYPE)		\
1775104834Sobrien  ((RTYPE) != R_PPC64_REL32			\
1776104834Sobrien   && (RTYPE) != R_PPC64_REL64			\
1777104834Sobrien   && (RTYPE) != R_PPC64_ADDR30)
177889857Sobrien
1779104834Sobrien/* Section name for stubs is the associated section name plus this
1780104834Sobrien   string.  */
1781104834Sobrien#define STUB_SUFFIX ".stub"
178289857Sobrien
1783104834Sobrien/* Linker stubs.
1784104834Sobrien   ppc_stub_long_branch:
1785104834Sobrien   Used when a 14 bit branch (or even a 24 bit branch) can't reach its
1786104834Sobrien   destination, but a 24 bit branch in a stub section will reach.
1787104834Sobrien   .	b	dest
1788104834Sobrien
1789104834Sobrien   ppc_stub_plt_branch:
1790104834Sobrien   Similar to the above, but a 24 bit branch in the stub section won't
1791104834Sobrien   reach its destination.
1792107492Sobrien   .	addis	%r12,%r2,xxx@toc@ha
1793107492Sobrien   .	ld	%r11,xxx@toc@l(%r12)
1794104834Sobrien   .	mtctr	%r11
1795104834Sobrien   .	bctr
1796104834Sobrien
1797104834Sobrien   ppc_stub_plt_call:
1798104834Sobrien   Used to call a function in a shared library.
1799107492Sobrien   .	addis	%r12,%r2,xxx@toc@ha
1800104834Sobrien   .	std	%r2,40(%r1)
1801107492Sobrien   .	ld	%r11,xxx+0@toc@l(%r12)
1802107492Sobrien   .	ld	%r2,xxx+8@toc@l(%r12)
1803104834Sobrien   .	mtctr	%r11
1804107492Sobrien   .	ld	%r11,xxx+16@toc@l(%r12)
1805104834Sobrien   .	bctr
1806104834Sobrien*/
1807104834Sobrien
1808104834Sobrienenum ppc_stub_type {
1809104834Sobrien  ppc_stub_none,
1810104834Sobrien  ppc_stub_long_branch,
1811104834Sobrien  ppc_stub_plt_branch,
1812104834Sobrien  ppc_stub_plt_call
1813104834Sobrien};
1814104834Sobrien
1815104834Sobrienstruct ppc_stub_hash_entry {
1816104834Sobrien
1817104834Sobrien  /* Base hash table entry structure.  */
1818104834Sobrien  struct bfd_hash_entry root;
1819104834Sobrien
1820104834Sobrien  /* The stub section.  */
1821104834Sobrien  asection *stub_sec;
1822104834Sobrien
1823104834Sobrien  /* Offset within stub_sec of the beginning of this stub.  */
1824104834Sobrien  bfd_vma stub_offset;
1825104834Sobrien
1826104834Sobrien  /* Given the symbol's value and its section we can determine its final
1827104834Sobrien     value when building the stubs (so the stub knows where to jump.  */
1828104834Sobrien  bfd_vma target_value;
1829104834Sobrien  asection *target_section;
1830104834Sobrien
1831104834Sobrien  enum ppc_stub_type stub_type;
1832104834Sobrien
1833104834Sobrien  /* The symbol table entry, if any, that this was derived from.  */
1834104834Sobrien  struct ppc_link_hash_entry *h;
1835104834Sobrien
1836104834Sobrien  /* Where this stub is being called from, or, in the case of combined
1837104834Sobrien     stub sections, the first input section in the group.  */
1838104834Sobrien  asection *id_sec;
1839104834Sobrien};
1840104834Sobrien
1841104834Sobrienstruct ppc_branch_hash_entry {
1842104834Sobrien
1843104834Sobrien  /* Base hash table entry structure.  */
1844104834Sobrien  struct bfd_hash_entry root;
1845104834Sobrien
1846104834Sobrien  /* Offset within .branch_lt.  */
1847104834Sobrien  unsigned int offset;
1848104834Sobrien
1849104834Sobrien  /* Generation marker.  */
1850104834Sobrien  unsigned int iter;
1851104834Sobrien};
1852104834Sobrien
185389857Sobrienstruct ppc_link_hash_entry
185489857Sobrien{
185589857Sobrien  struct elf_link_hash_entry elf;
185689857Sobrien
1857104834Sobrien  /* A pointer to the most recently used stub hash entry against this
1858104834Sobrien     symbol.  */
1859104834Sobrien  struct ppc_stub_hash_entry *stub_cache;
1860104834Sobrien
186189857Sobrien  /* Track dynamic relocs copied for this symbol.  */
186289857Sobrien  struct ppc_dyn_relocs *dyn_relocs;
186389857Sobrien
1864104834Sobrien  /* Link between function code and descriptor symbols.  */
1865104834Sobrien  struct elf_link_hash_entry *oh;
1866104834Sobrien
186789857Sobrien  /* Flag function code and descriptor symbols.  */
186889857Sobrien  unsigned int is_func:1;
186989857Sobrien  unsigned int is_func_descriptor:1;
1870104834Sobrien  unsigned int is_entry:1;
187189857Sobrien};
187289857Sobrien
187389857Sobrien/* ppc64 ELF linker hash table.  */
187489857Sobrien
187589857Sobrienstruct ppc_link_hash_table
187689857Sobrien{
187789857Sobrien  struct elf_link_hash_table elf;
187889857Sobrien
1879104834Sobrien  /* The stub hash table.  */
1880104834Sobrien  struct bfd_hash_table stub_hash_table;
1881104834Sobrien
1882104834Sobrien  /* Another hash table for plt_branch stubs.  */
1883104834Sobrien  struct bfd_hash_table branch_hash_table;
1884104834Sobrien
1885104834Sobrien  /* Linker stub bfd.  */
1886104834Sobrien  bfd *stub_bfd;
1887104834Sobrien
1888104834Sobrien  /* Linker call-backs.  */
1889104834Sobrien  asection * (*add_stub_section) PARAMS ((const char *, asection *));
1890104834Sobrien  void (*layout_sections_again) PARAMS ((void));
1891104834Sobrien
1892104834Sobrien  /* Array to keep track of which stub sections have been created, and
1893104834Sobrien     information on stub grouping.  */
1894104834Sobrien  struct map_stub {
1895104834Sobrien    /* This is the section to which stubs in the group will be attached.  */
1896104834Sobrien    asection *link_sec;
1897104834Sobrien    /* The stub section.  */
1898104834Sobrien    asection *stub_sec;
1899104834Sobrien  } *stub_group;
1900104834Sobrien
1901104834Sobrien  /* Assorted information used by ppc64_elf_size_stubs.  */
1902104834Sobrien  int top_index;
1903104834Sobrien  asection **input_list;
1904104834Sobrien
190589857Sobrien  /* Short-cuts to get to dynamic linker sections.  */
190689857Sobrien  asection *sgot;
190789857Sobrien  asection *srelgot;
190889857Sobrien  asection *splt;
190989857Sobrien  asection *srelplt;
191089857Sobrien  asection *sdynbss;
191189857Sobrien  asection *srelbss;
191289857Sobrien  asection *sglink;
191392828Sobrien  asection *sfpr;
1914104834Sobrien  asection *sbrlt;
1915104834Sobrien  asection *srelbrlt;
191689857Sobrien
191789857Sobrien  /* Set on error.  */
1918104834Sobrien  unsigned int stub_error;
191989857Sobrien
1920104834Sobrien  /* Flag set when small branches are detected.  Used to
1921104834Sobrien     select suitable defaults for the stub group size.  */
1922104834Sobrien  unsigned int has_14bit_branch;
1923104834Sobrien
192499461Sobrien  /* Set if we detect a reference undefined weak symbol.  */
192599461Sobrien  unsigned int have_undefweak;
192699461Sobrien
1927104834Sobrien  /* Incremented every time we size stubs.  */
1928104834Sobrien  unsigned int stub_iteration;
1929104834Sobrien
193089857Sobrien  /* Small local sym to section mapping cache.  */
193189857Sobrien  struct sym_sec_cache sym_sec;
193289857Sobrien};
193389857Sobrien
1934104834Sobrienstatic struct bfd_hash_entry *stub_hash_newfunc
1935104834Sobrien  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
1936104834Sobrienstatic struct bfd_hash_entry *branch_hash_newfunc
1937104834Sobrien  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
1938104834Sobrienstatic struct bfd_hash_entry *link_hash_newfunc
1939104834Sobrien  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
1940104834Sobrienstatic struct bfd_link_hash_table *ppc64_elf_link_hash_table_create
1941104834Sobrien  PARAMS ((bfd *));
1942104834Sobrienstatic void ppc64_elf_link_hash_table_free
1943104834Sobrien  PARAMS ((struct bfd_link_hash_table *));
1944104834Sobrienstatic char *ppc_stub_name
1945104834Sobrien  PARAMS ((const asection *, const asection *,
1946104834Sobrien	   const struct ppc_link_hash_entry *, const Elf_Internal_Rela *));
1947104834Sobrienstatic struct ppc_stub_hash_entry *ppc_get_stub_entry
1948104834Sobrien  PARAMS ((const asection *, const asection *, struct elf_link_hash_entry *,
1949104834Sobrien	   const Elf_Internal_Rela *, struct ppc_link_hash_table *));
1950104834Sobrienstatic struct ppc_stub_hash_entry *ppc_add_stub
1951104834Sobrien  PARAMS ((const char *, asection *, struct ppc_link_hash_table *));
1952104834Sobrienstatic boolean create_linkage_sections
1953104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1954104834Sobrienstatic boolean create_got_section
1955104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1956104834Sobrienstatic boolean ppc64_elf_create_dynamic_sections
1957104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1958104834Sobrienstatic void ppc64_elf_copy_indirect_symbol
1959104834Sobrien  PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
1960104834Sobrien	   struct elf_link_hash_entry *));
1961104834Sobrienstatic boolean ppc64_elf_check_relocs
1962104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *, asection *,
1963104834Sobrien	   const Elf_Internal_Rela *));
1964104834Sobrienstatic asection * ppc64_elf_gc_mark_hook
1965104834Sobrien  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
1966104834Sobrien	   struct elf_link_hash_entry *, Elf_Internal_Sym *));
1967104834Sobrienstatic boolean ppc64_elf_gc_sweep_hook
1968104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *, asection *,
1969104834Sobrien	   const Elf_Internal_Rela *));
1970104834Sobrienstatic boolean func_desc_adjust
1971104834Sobrien  PARAMS ((struct elf_link_hash_entry *, PTR));
1972104834Sobrienstatic boolean ppc64_elf_func_desc_adjust
1973104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1974104834Sobrienstatic boolean ppc64_elf_adjust_dynamic_symbol
1975104834Sobrien  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
1976104834Sobrienstatic void ppc64_elf_hide_symbol
1977104834Sobrien  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
1978104834Sobrienstatic boolean edit_opd
1979104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1980104834Sobrienstatic boolean allocate_dynrelocs
1981104834Sobrien  PARAMS ((struct elf_link_hash_entry *, PTR));
1982104834Sobrienstatic boolean readonly_dynrelocs
1983104834Sobrien  PARAMS ((struct elf_link_hash_entry *, PTR));
1984104834Sobrienstatic enum elf_reloc_type_class ppc64_elf_reloc_type_class
1985104834Sobrien  PARAMS ((const Elf_Internal_Rela *));
1986104834Sobrienstatic boolean ppc64_elf_size_dynamic_sections
1987104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
1988104834Sobrienstatic INLINE enum ppc_stub_type ppc_type_of_stub
1989104834Sobrien  PARAMS ((asection *, const Elf_Internal_Rela *,
1990104834Sobrien	   struct ppc_link_hash_entry **, bfd_vma));
1991104834Sobrienstatic bfd_byte *build_plt_stub
1992104834Sobrien  PARAMS ((bfd *, bfd_byte *, int, int));
1993104834Sobrienstatic boolean ppc_build_one_stub
1994104834Sobrien  PARAMS ((struct bfd_hash_entry *, PTR));
1995104834Sobrienstatic boolean ppc_size_one_stub
1996104834Sobrien  PARAMS ((struct bfd_hash_entry *, PTR));
1997104834Sobrienstatic void group_sections
1998104834Sobrien  PARAMS ((struct ppc_link_hash_table *, bfd_size_type, boolean));
1999104834Sobrienstatic boolean ppc64_elf_relocate_section
2000104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *info, bfd *, asection *, bfd_byte *,
2001104834Sobrien	   Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
2002104834Sobrien	   asection **));
2003104834Sobrienstatic boolean ppc64_elf_finish_dynamic_symbol
2004104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
2005104834Sobrien	   Elf_Internal_Sym *));
2006104834Sobrienstatic boolean ppc64_elf_finish_dynamic_sections
2007104834Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
2008104834Sobrien
200989857Sobrien/* Get the ppc64 ELF linker hash table from a link_info structure.  */
201089857Sobrien
201189857Sobrien#define ppc_hash_table(p) \
201289857Sobrien  ((struct ppc_link_hash_table *) ((p)->hash))
201389857Sobrien
2014104834Sobrien#define ppc_stub_hash_lookup(table, string, create, copy) \
2015104834Sobrien  ((struct ppc_stub_hash_entry *) \
2016104834Sobrien   bfd_hash_lookup ((table), (string), (create), (copy)))
2017104834Sobrien
2018104834Sobrien#define ppc_branch_hash_lookup(table, string, create, copy) \
2019104834Sobrien  ((struct ppc_branch_hash_entry *) \
2020104834Sobrien   bfd_hash_lookup ((table), (string), (create), (copy)))
2021104834Sobrien
2022104834Sobrien/* Create an entry in the stub hash table.  */
2023104834Sobrien
2024104834Sobrienstatic struct bfd_hash_entry *
2025104834Sobrienstub_hash_newfunc (entry, table, string)
2026104834Sobrien     struct bfd_hash_entry *entry;
2027104834Sobrien     struct bfd_hash_table *table;
2028104834Sobrien     const char *string;
2029104834Sobrien{
2030104834Sobrien  /* Allocate the structure if it has not already been allocated by a
2031104834Sobrien     subclass.  */
2032104834Sobrien  if (entry == NULL)
2033104834Sobrien    {
2034104834Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_stub_hash_entry));
2035104834Sobrien      if (entry == NULL)
2036104834Sobrien	return entry;
2037104834Sobrien    }
2038104834Sobrien
2039104834Sobrien  /* Call the allocation method of the superclass.  */
2040104834Sobrien  entry = bfd_hash_newfunc (entry, table, string);
2041104834Sobrien  if (entry != NULL)
2042104834Sobrien    {
2043104834Sobrien      struct ppc_stub_hash_entry *eh;
2044104834Sobrien
2045104834Sobrien      /* Initialize the local fields.  */
2046104834Sobrien      eh = (struct ppc_stub_hash_entry *) entry;
2047104834Sobrien      eh->stub_sec = NULL;
2048104834Sobrien      eh->stub_offset = 0;
2049104834Sobrien      eh->target_value = 0;
2050104834Sobrien      eh->target_section = NULL;
2051104834Sobrien      eh->stub_type = ppc_stub_none;
2052104834Sobrien      eh->h = NULL;
2053104834Sobrien      eh->id_sec = NULL;
2054104834Sobrien    }
2055104834Sobrien
2056104834Sobrien  return entry;
2057104834Sobrien}
2058104834Sobrien
2059104834Sobrien/* Create an entry in the branch hash table.  */
2060104834Sobrien
2061104834Sobrienstatic struct bfd_hash_entry *
2062104834Sobrienbranch_hash_newfunc (entry, table, string)
2063104834Sobrien     struct bfd_hash_entry *entry;
2064104834Sobrien     struct bfd_hash_table *table;
2065104834Sobrien     const char *string;
2066104834Sobrien{
2067104834Sobrien  /* Allocate the structure if it has not already been allocated by a
2068104834Sobrien     subclass.  */
2069104834Sobrien  if (entry == NULL)
2070104834Sobrien    {
2071104834Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_branch_hash_entry));
2072104834Sobrien      if (entry == NULL)
2073104834Sobrien	return entry;
2074104834Sobrien    }
2075104834Sobrien
2076104834Sobrien  /* Call the allocation method of the superclass.  */
2077104834Sobrien  entry = bfd_hash_newfunc (entry, table, string);
2078104834Sobrien  if (entry != NULL)
2079104834Sobrien    {
2080104834Sobrien      struct ppc_branch_hash_entry *eh;
2081104834Sobrien
2082104834Sobrien      /* Initialize the local fields.  */
2083104834Sobrien      eh = (struct ppc_branch_hash_entry *) entry;
2084104834Sobrien      eh->offset = 0;
2085104834Sobrien      eh->iter = 0;
2086104834Sobrien    }
2087104834Sobrien
2088104834Sobrien  return entry;
2089104834Sobrien}
2090104834Sobrien
209189857Sobrien/* Create an entry in a ppc64 ELF linker hash table.  */
209289857Sobrien
209389857Sobrienstatic struct bfd_hash_entry *
209489857Sobrienlink_hash_newfunc (entry, table, string)
209589857Sobrien     struct bfd_hash_entry *entry;
209689857Sobrien     struct bfd_hash_table *table;
209789857Sobrien     const char *string;
209889857Sobrien{
209989857Sobrien  /* Allocate the structure if it has not already been allocated by a
210089857Sobrien     subclass.  */
210189857Sobrien  if (entry == NULL)
210289857Sobrien    {
210389857Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_link_hash_entry));
210489857Sobrien      if (entry == NULL)
210589857Sobrien	return entry;
210689857Sobrien    }
210789857Sobrien
210889857Sobrien  /* Call the allocation method of the superclass.  */
210989857Sobrien  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
211089857Sobrien  if (entry != NULL)
211189857Sobrien    {
211289857Sobrien      struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) entry;
211389857Sobrien
2114104834Sobrien      eh->stub_cache = NULL;
211589857Sobrien      eh->dyn_relocs = NULL;
2116104834Sobrien      eh->oh = NULL;
211789857Sobrien      eh->is_func = 0;
211889857Sobrien      eh->is_func_descriptor = 0;
2119104834Sobrien      eh->is_entry = 0;
212089857Sobrien    }
212189857Sobrien
212289857Sobrien  return entry;
212389857Sobrien}
212489857Sobrien
212589857Sobrien/* Create a ppc64 ELF linker hash table.  */
212689857Sobrien
212789857Sobrienstatic struct bfd_link_hash_table *
212889857Sobrienppc64_elf_link_hash_table_create (abfd)
212989857Sobrien     bfd *abfd;
213089857Sobrien{
213189857Sobrien  struct ppc_link_hash_table *htab;
213289857Sobrien  bfd_size_type amt = sizeof (struct ppc_link_hash_table);
213389857Sobrien
2134104834Sobrien  htab = (struct ppc_link_hash_table *) bfd_malloc (amt);
213589857Sobrien  if (htab == NULL)
213689857Sobrien    return NULL;
213789857Sobrien
213889857Sobrien  if (! _bfd_elf_link_hash_table_init (&htab->elf, abfd, link_hash_newfunc))
213989857Sobrien    {
2140104834Sobrien      free (htab);
214189857Sobrien      return NULL;
214289857Sobrien    }
214389857Sobrien
2144104834Sobrien  /* Init the stub hash table too.  */
2145104834Sobrien  if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc))
2146104834Sobrien    return NULL;
2147104834Sobrien
2148104834Sobrien  /* And the branch hash table.  */
2149104834Sobrien  if (!bfd_hash_table_init (&htab->branch_hash_table, branch_hash_newfunc))
2150104834Sobrien    return NULL;
2151104834Sobrien
2152104834Sobrien  htab->stub_bfd = NULL;
2153104834Sobrien  htab->add_stub_section = NULL;
2154104834Sobrien  htab->layout_sections_again = NULL;
2155104834Sobrien  htab->stub_group = NULL;
215689857Sobrien  htab->sgot = NULL;
215789857Sobrien  htab->srelgot = NULL;
215889857Sobrien  htab->splt = NULL;
215989857Sobrien  htab->srelplt = NULL;
216089857Sobrien  htab->sdynbss = NULL;
216189857Sobrien  htab->srelbss = NULL;
216289857Sobrien  htab->sglink = NULL;
216392828Sobrien  htab->sfpr = NULL;
2164104834Sobrien  htab->sbrlt = NULL;
2165104834Sobrien  htab->srelbrlt = NULL;
2166104834Sobrien  htab->stub_error = 0;
2167104834Sobrien  htab->has_14bit_branch = 0;
216899461Sobrien  htab->have_undefweak = 0;
2169104834Sobrien  htab->stub_iteration = 0;
217089857Sobrien  htab->sym_sec.abfd = NULL;
217189857Sobrien
217289857Sobrien  return &htab->elf.root;
217389857Sobrien}
217489857Sobrien
2175104834Sobrien/* Free the derived linker hash table.  */
2176104834Sobrien
2177104834Sobrienstatic void
2178104834Sobrienppc64_elf_link_hash_table_free (hash)
2179104834Sobrien     struct bfd_link_hash_table *hash;
2180104834Sobrien{
2181104834Sobrien  struct ppc_link_hash_table *ret = (struct ppc_link_hash_table *) hash;
2182104834Sobrien
2183104834Sobrien  bfd_hash_table_free (&ret->stub_hash_table);
2184104834Sobrien  bfd_hash_table_free (&ret->branch_hash_table);
2185104834Sobrien  _bfd_generic_link_hash_table_free (hash);
2186104834Sobrien}
2187104834Sobrien
2188104834Sobrien/* Build a name for an entry in the stub hash table.  */
2189104834Sobrien
2190104834Sobrienstatic char *
2191104834Sobrienppc_stub_name (input_section, sym_sec, h, rel)
2192104834Sobrien     const asection *input_section;
2193104834Sobrien     const asection *sym_sec;
2194104834Sobrien     const struct ppc_link_hash_entry *h;
2195104834Sobrien     const Elf_Internal_Rela *rel;
2196104834Sobrien{
2197104834Sobrien  char *stub_name;
2198104834Sobrien  bfd_size_type len;
2199104834Sobrien
2200104834Sobrien  /* rel->r_addend is actually 64 bit, but who uses more than +/- 2^31
2201104834Sobrien     offsets from a sym as a branch target?  In fact, we could
2202104834Sobrien     probably assume the addend is always zero.  */
2203104834Sobrien  BFD_ASSERT (((int) rel->r_addend & 0xffffffff) == rel->r_addend);
2204104834Sobrien
2205104834Sobrien  if (h)
2206104834Sobrien    {
2207104834Sobrien      len = 8 + 1 + strlen (h->elf.root.root.string) + 1 + 8 + 1;
2208104834Sobrien      stub_name = bfd_malloc (len);
2209104834Sobrien      if (stub_name != NULL)
2210104834Sobrien	{
2211104834Sobrien	  sprintf (stub_name, "%08x_%s+%x",
2212104834Sobrien		   input_section->id & 0xffffffff,
2213104834Sobrien		   h->elf.root.root.string,
2214104834Sobrien		   (int) rel->r_addend & 0xffffffff);
2215104834Sobrien	}
2216104834Sobrien    }
2217104834Sobrien  else
2218104834Sobrien    {
2219104834Sobrien      len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2220104834Sobrien      stub_name = bfd_malloc (len);
2221104834Sobrien      if (stub_name != NULL)
2222104834Sobrien	{
2223104834Sobrien	  sprintf (stub_name, "%08x_%x:%x+%x",
2224104834Sobrien		   input_section->id & 0xffffffff,
2225104834Sobrien		   sym_sec->id & 0xffffffff,
2226104834Sobrien		   (int) ELF64_R_SYM (rel->r_info) & 0xffffffff,
2227104834Sobrien		   (int) rel->r_addend & 0xffffffff);
2228104834Sobrien	}
2229104834Sobrien    }
2230104834Sobrien  return stub_name;
2231104834Sobrien}
2232104834Sobrien
2233104834Sobrien/* Look up an entry in the stub hash.  Stub entries are cached because
2234104834Sobrien   creating the stub name takes a bit of time.  */
2235104834Sobrien
2236104834Sobrienstatic struct ppc_stub_hash_entry *
2237104834Sobrienppc_get_stub_entry (input_section, sym_sec, hash, rel, htab)
2238104834Sobrien     const asection *input_section;
2239104834Sobrien     const asection *sym_sec;
2240104834Sobrien     struct elf_link_hash_entry *hash;
2241104834Sobrien     const Elf_Internal_Rela *rel;
2242104834Sobrien     struct ppc_link_hash_table *htab;
2243104834Sobrien{
2244104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
2245104834Sobrien  struct ppc_link_hash_entry *h = (struct ppc_link_hash_entry *) hash;
2246104834Sobrien  const asection *id_sec;
2247104834Sobrien
2248104834Sobrien  /* If this input section is part of a group of sections sharing one
2249104834Sobrien     stub section, then use the id of the first section in the group.
2250104834Sobrien     Stub names need to include a section id, as there may well be
2251104834Sobrien     more than one stub used to reach say, printf, and we need to
2252104834Sobrien     distinguish between them.  */
2253104834Sobrien  id_sec = htab->stub_group[input_section->id].link_sec;
2254104834Sobrien
2255104834Sobrien  if (h != NULL && h->stub_cache != NULL
2256104834Sobrien      && h->stub_cache->h == h
2257104834Sobrien      && h->stub_cache->id_sec == id_sec)
2258104834Sobrien    {
2259104834Sobrien      stub_entry = h->stub_cache;
2260104834Sobrien    }
2261104834Sobrien  else
2262104834Sobrien    {
2263104834Sobrien      char *stub_name;
2264104834Sobrien
2265104834Sobrien      stub_name = ppc_stub_name (id_sec, sym_sec, h, rel);
2266104834Sobrien      if (stub_name == NULL)
2267104834Sobrien	return NULL;
2268104834Sobrien
2269104834Sobrien      stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
2270104834Sobrien					 stub_name, false, false);
2271104834Sobrien      if (h != NULL)
2272104834Sobrien	h->stub_cache = stub_entry;
2273104834Sobrien
2274104834Sobrien      free (stub_name);
2275104834Sobrien    }
2276104834Sobrien
2277104834Sobrien  return stub_entry;
2278104834Sobrien}
2279104834Sobrien
2280104834Sobrien/* Add a new stub entry to the stub hash.  Not all fields of the new
2281104834Sobrien   stub entry are initialised.  */
2282104834Sobrien
2283104834Sobrienstatic struct ppc_stub_hash_entry *
2284104834Sobrienppc_add_stub (stub_name, section, htab)
2285104834Sobrien     const char *stub_name;
2286104834Sobrien     asection *section;
2287104834Sobrien     struct ppc_link_hash_table *htab;
2288104834Sobrien{
2289104834Sobrien  asection *link_sec;
2290104834Sobrien  asection *stub_sec;
2291104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
2292104834Sobrien
2293104834Sobrien  link_sec = htab->stub_group[section->id].link_sec;
2294104834Sobrien  stub_sec = htab->stub_group[section->id].stub_sec;
2295104834Sobrien  if (stub_sec == NULL)
2296104834Sobrien    {
2297104834Sobrien      stub_sec = htab->stub_group[link_sec->id].stub_sec;
2298104834Sobrien      if (stub_sec == NULL)
2299104834Sobrien	{
2300104834Sobrien	  size_t namelen;
2301104834Sobrien	  bfd_size_type len;
2302104834Sobrien	  char *s_name;
2303104834Sobrien
2304104834Sobrien	  namelen = strlen (link_sec->name);
2305104834Sobrien	  len = namelen + sizeof (STUB_SUFFIX);
2306104834Sobrien	  s_name = bfd_alloc (htab->stub_bfd, len);
2307104834Sobrien	  if (s_name == NULL)
2308104834Sobrien	    return NULL;
2309104834Sobrien
2310104834Sobrien	  memcpy (s_name, link_sec->name, namelen);
2311104834Sobrien	  memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
2312104834Sobrien	  stub_sec = (*htab->add_stub_section) (s_name, link_sec);
2313104834Sobrien	  if (stub_sec == NULL)
2314104834Sobrien	    return NULL;
2315104834Sobrien	  htab->stub_group[link_sec->id].stub_sec = stub_sec;
2316104834Sobrien	}
2317104834Sobrien      htab->stub_group[section->id].stub_sec = stub_sec;
2318104834Sobrien    }
2319104834Sobrien
2320104834Sobrien  /* Enter this entry into the linker stub hash table.  */
2321104834Sobrien  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
2322104834Sobrien				     true, false);
2323104834Sobrien  if (stub_entry == NULL)
2324104834Sobrien    {
2325104834Sobrien      (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
2326104834Sobrien			     bfd_archive_filename (section->owner),
2327104834Sobrien			     stub_name);
2328104834Sobrien      return NULL;
2329104834Sobrien    }
2330104834Sobrien
2331104834Sobrien  stub_entry->stub_sec = stub_sec;
2332104834Sobrien  stub_entry->stub_offset = 0;
2333104834Sobrien  stub_entry->id_sec = link_sec;
2334104834Sobrien  return stub_entry;
2335104834Sobrien}
2336104834Sobrien
233792828Sobrien/* Create sections for linker generated code.  */
233892828Sobrien
233992828Sobrienstatic boolean
234092828Sobriencreate_linkage_sections (dynobj, info)
234192828Sobrien     bfd *dynobj;
234292828Sobrien     struct bfd_link_info *info;
234392828Sobrien{
234492828Sobrien  struct ppc_link_hash_table *htab;
234592828Sobrien  flagword flags;
234692828Sobrien
234792828Sobrien  htab = ppc_hash_table (info);
234892828Sobrien
234992828Sobrien  /* Create .sfpr for code to save and restore fp regs.  */
235092828Sobrien  flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
235192828Sobrien	   | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2352104834Sobrien  htab->sfpr = bfd_make_section_anyway (dynobj, ".sfpr");
235392828Sobrien  if (htab->sfpr == NULL
235492828Sobrien      || ! bfd_set_section_flags (dynobj, htab->sfpr, flags)
235592828Sobrien      || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
235692828Sobrien    return false;
235792828Sobrien
2358104834Sobrien  /* Create .glink for lazy dynamic linking support.  */
2359104834Sobrien  htab->sglink = bfd_make_section_anyway (dynobj, ".glink");
236092828Sobrien  if (htab->sglink == NULL
236192828Sobrien      || ! bfd_set_section_flags (dynobj, htab->sglink, flags)
236292828Sobrien      || ! bfd_set_section_alignment (dynobj, htab->sglink, 2))
236392828Sobrien    return false;
236492828Sobrien
2365104834Sobrien  /* Create .branch_lt for plt_branch stubs.  */
2366104834Sobrien  flags = (SEC_ALLOC | SEC_LOAD
2367104834Sobrien	   | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2368104834Sobrien  htab->sbrlt = bfd_make_section_anyway (dynobj, ".branch_lt");
2369104834Sobrien  if (htab->sbrlt == NULL
2370104834Sobrien      || ! bfd_set_section_flags (dynobj, htab->sbrlt, flags)
2371104834Sobrien      || ! bfd_set_section_alignment (dynobj, htab->sbrlt, 3))
2372104834Sobrien    return false;
2373104834Sobrien
2374104834Sobrien  if (info->shared)
2375104834Sobrien    {
2376104834Sobrien      flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
2377104834Sobrien	       | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2378104834Sobrien      htab->srelbrlt = bfd_make_section_anyway (dynobj, ".rela.branch_lt");
2379104834Sobrien      if (!htab->srelbrlt
2380104834Sobrien	  || ! bfd_set_section_flags (dynobj, htab->srelbrlt, flags)
2381104834Sobrien	  || ! bfd_set_section_alignment (dynobj, htab->srelbrlt, 3))
2382104834Sobrien	return false;
2383104834Sobrien    }
238492828Sobrien  return true;
238592828Sobrien}
238692828Sobrien
238789857Sobrien/* Create .got and .rela.got sections in DYNOBJ, and set up
238889857Sobrien   shortcuts to them in our hash table.  */
238989857Sobrien
239089857Sobrienstatic boolean
239189857Sobriencreate_got_section (dynobj, info)
239289857Sobrien     bfd *dynobj;
239389857Sobrien     struct bfd_link_info *info;
239489857Sobrien{
239589857Sobrien  struct ppc_link_hash_table *htab;
239689857Sobrien
239789857Sobrien  if (! _bfd_elf_create_got_section (dynobj, info))
239889857Sobrien    return false;
239989857Sobrien
240089857Sobrien  htab = ppc_hash_table (info);
240189857Sobrien  htab->sgot = bfd_get_section_by_name (dynobj, ".got");
240289857Sobrien  if (!htab->sgot)
240389857Sobrien    abort ();
240489857Sobrien
240589857Sobrien  htab->srelgot = bfd_make_section (dynobj, ".rela.got");
240689857Sobrien  if (!htab->srelgot
240789857Sobrien      || ! bfd_set_section_flags (dynobj, htab->srelgot,
240889857Sobrien				  (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
240989857Sobrien				   | SEC_IN_MEMORY | SEC_LINKER_CREATED
241089857Sobrien				   | SEC_READONLY))
241189857Sobrien      || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
241289857Sobrien    return false;
241389857Sobrien  return true;
241489857Sobrien}
241589857Sobrien
241692828Sobrien/* Create the dynamic sections, and set up shortcuts.  */
241789857Sobrien
241889857Sobrienstatic boolean
241989857Sobrienppc64_elf_create_dynamic_sections (dynobj, info)
242089857Sobrien     bfd *dynobj;
242189857Sobrien     struct bfd_link_info *info;
242289857Sobrien{
242389857Sobrien  struct ppc_link_hash_table *htab;
242489857Sobrien
242589857Sobrien  htab = ppc_hash_table (info);
242689857Sobrien  if (!htab->sgot && !create_got_section (dynobj, info))
242789857Sobrien    return false;
242889857Sobrien
242989857Sobrien  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
243089857Sobrien    return false;
243189857Sobrien
243289857Sobrien  htab->splt = bfd_get_section_by_name (dynobj, ".plt");
243389857Sobrien  htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
243489857Sobrien  htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
243589857Sobrien  if (!info->shared)
243689857Sobrien    htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
243789857Sobrien
243889857Sobrien  if (!htab->splt || !htab->srelplt || !htab->sdynbss
243989857Sobrien      || (!info->shared && !htab->srelbss))
244089857Sobrien    abort ();
244189857Sobrien
244289857Sobrien  return true;
244389857Sobrien}
244489857Sobrien
244589857Sobrien/* Copy the extra info we tack onto an elf_link_hash_entry.  */
244689857Sobrien
244789857Sobrienstatic void
2448104834Sobrienppc64_elf_copy_indirect_symbol (bed, dir, ind)
2449104834Sobrien     struct elf_backend_data *bed;
245089857Sobrien     struct elf_link_hash_entry *dir, *ind;
245189857Sobrien{
245289857Sobrien  struct ppc_link_hash_entry *edir, *eind;
245389857Sobrien
245489857Sobrien  edir = (struct ppc_link_hash_entry *) dir;
245589857Sobrien  eind = (struct ppc_link_hash_entry *) ind;
245689857Sobrien
245789857Sobrien  if (eind->dyn_relocs != NULL)
245889857Sobrien    {
245989857Sobrien      if (edir->dyn_relocs != NULL)
246089857Sobrien	{
246189857Sobrien	  struct ppc_dyn_relocs **pp;
246289857Sobrien	  struct ppc_dyn_relocs *p;
246389857Sobrien
246489857Sobrien	  if (ind->root.type == bfd_link_hash_indirect)
246589857Sobrien	    abort ();
246689857Sobrien
246789857Sobrien	  /* Add reloc counts against the weak sym to the strong sym
246889857Sobrien	     list.  Merge any entries against the same section.  */
246989857Sobrien	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
247089857Sobrien	    {
247189857Sobrien	      struct ppc_dyn_relocs *q;
247289857Sobrien
247389857Sobrien	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
247489857Sobrien		if (q->sec == p->sec)
247589857Sobrien		  {
247689857Sobrien		    q->pc_count += p->pc_count;
247789857Sobrien		    q->count += p->count;
247889857Sobrien		    *pp = p->next;
247989857Sobrien		    break;
248089857Sobrien		  }
248189857Sobrien	      if (q == NULL)
248289857Sobrien		pp = &p->next;
248389857Sobrien	    }
248489857Sobrien	  *pp = edir->dyn_relocs;
248589857Sobrien	}
248689857Sobrien
248789857Sobrien      edir->dyn_relocs = eind->dyn_relocs;
248889857Sobrien      eind->dyn_relocs = NULL;
248989857Sobrien    }
249089857Sobrien
249189857Sobrien  edir->is_func |= eind->is_func;
249289857Sobrien  edir->is_func_descriptor |= eind->is_func_descriptor;
2493104834Sobrien  edir->is_entry |= eind->is_entry;
249489857Sobrien
2495104834Sobrien  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
249689857Sobrien}
249789857Sobrien
2498104834Sobrien/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and
2499104834Sobrien   symbols undefined on the command-line.  */
2500104834Sobrien
2501104834Sobrienboolean
2502104834Sobrienppc64_elf_mark_entry_syms (info)
2503104834Sobrien     struct bfd_link_info *info;
2504104834Sobrien{
2505104834Sobrien  struct ppc_link_hash_table *htab;
2506104834Sobrien  struct bfd_sym_chain *sym;
2507104834Sobrien
2508104834Sobrien  htab = ppc_hash_table (info);
2509104834Sobrien  for (sym = info->gc_sym_list; sym; sym = sym->next)
2510104834Sobrien    {
2511104834Sobrien      struct elf_link_hash_entry *h;
2512104834Sobrien
2513104834Sobrien      h = elf_link_hash_lookup (&htab->elf, sym->name, false, false, false);
2514104834Sobrien      if (h != NULL)
2515104834Sobrien	((struct ppc_link_hash_entry *) h)->is_entry = 1;
2516104834Sobrien    }
2517104834Sobrien  return true;
2518104834Sobrien}
2519104834Sobrien
252089857Sobrien/* Look through the relocs for a section during the first phase, and
252189857Sobrien   calculate needed space in the global offset table, procedure
252289857Sobrien   linkage table, and dynamic reloc sections.  */
252389857Sobrien
252489857Sobrienstatic boolean
252589857Sobrienppc64_elf_check_relocs (abfd, info, sec, relocs)
252689857Sobrien     bfd *abfd;
252789857Sobrien     struct bfd_link_info *info;
252889857Sobrien     asection *sec;
252989857Sobrien     const Elf_Internal_Rela *relocs;
253089857Sobrien{
253189857Sobrien  struct ppc_link_hash_table *htab;
253289857Sobrien  Elf_Internal_Shdr *symtab_hdr;
253389857Sobrien  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
253489857Sobrien  const Elf_Internal_Rela *rel;
253589857Sobrien  const Elf_Internal_Rela *rel_end;
253689857Sobrien  asection *sreloc;
2537104834Sobrien  asection **opd_sym_map;
253889857Sobrien
253989857Sobrien  if (info->relocateable)
254089857Sobrien    return true;
254189857Sobrien
254289857Sobrien  htab = ppc_hash_table (info);
254389857Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
254489857Sobrien
254589857Sobrien  sym_hashes = elf_sym_hashes (abfd);
254689857Sobrien  sym_hashes_end = (sym_hashes
2547104834Sobrien		    + symtab_hdr->sh_size / sizeof (Elf64_External_Sym)
2548104834Sobrien		    - symtab_hdr->sh_info);
254989857Sobrien
255089857Sobrien  sreloc = NULL;
2551104834Sobrien  opd_sym_map = NULL;
2552104834Sobrien  if (strcmp (bfd_get_section_name (abfd, sec), ".opd") == 0)
2553104834Sobrien    {
2554104834Sobrien      /* Garbage collection needs some extra help with .opd sections.
2555104834Sobrien	 We don't want to necessarily keep everything referenced by
2556104834Sobrien	 relocs in .opd, as that would keep all functions.  Instead,
2557104834Sobrien	 if we reference an .opd symbol (a function descriptor), we
2558104834Sobrien	 want to keep the function code symbol's section.  This is
2559104834Sobrien	 easy for global symbols, but for local syms we need to keep
2560104834Sobrien	 information about the associated function section.  Later, if
2561104834Sobrien	 edit_opd deletes entries, we'll use this array to adjust
2562104834Sobrien	 local syms in .opd.  */
2563104834Sobrien      union opd_info {
2564104834Sobrien	asection *func_section;
2565104834Sobrien	long entry_adjust;
2566104834Sobrien      };
2567104834Sobrien      bfd_size_type amt;
256889857Sobrien
2569104834Sobrien      amt = sec->_raw_size * sizeof (union opd_info) / 24;
2570104834Sobrien      opd_sym_map = (asection **) bfd_zalloc (abfd, amt);
2571104834Sobrien      if (opd_sym_map == NULL)
2572104834Sobrien	return false;
2573104834Sobrien      elf_section_data (sec)->tdata = opd_sym_map;
2574104834Sobrien    }
2575104834Sobrien
257692828Sobrien  if (htab->elf.dynobj == NULL)
257792828Sobrien    htab->elf.dynobj = abfd;
257892828Sobrien  if (htab->sfpr == NULL
257992828Sobrien      && !create_linkage_sections (htab->elf.dynobj, info))
258092828Sobrien    return false;
258192828Sobrien
258289857Sobrien  rel_end = relocs + sec->reloc_count;
258389857Sobrien  for (rel = relocs; rel < rel_end; rel++)
258489857Sobrien    {
258589857Sobrien      unsigned long r_symndx;
258689857Sobrien      struct elf_link_hash_entry *h;
258789857Sobrien      enum elf_ppc_reloc_type r_type;
258889857Sobrien
258989857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
259089857Sobrien      if (r_symndx < symtab_hdr->sh_info)
259189857Sobrien	h = NULL;
259289857Sobrien      else
259389857Sobrien	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
259489857Sobrien
259589857Sobrien      r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info);
259689857Sobrien      switch (r_type)
259789857Sobrien	{
259889857Sobrien	  /* GOT16 relocations */
259989857Sobrien	case R_PPC64_GOT16:
260089857Sobrien	case R_PPC64_GOT16_DS:
260189857Sobrien	case R_PPC64_GOT16_HA:
260289857Sobrien	case R_PPC64_GOT16_HI:
260389857Sobrien	case R_PPC64_GOT16_LO:
260489857Sobrien	case R_PPC64_GOT16_LO_DS:
260589857Sobrien
260689857Sobrien	  /* This symbol requires a global offset table entry.  */
260792828Sobrien	  if (htab->sgot == NULL
260892828Sobrien	      && !create_got_section (htab->elf.dynobj, info))
260992828Sobrien	    return false;
261089857Sobrien
261189857Sobrien	  if (h != NULL)
261289857Sobrien	    {
261389857Sobrien	      h->got.refcount += 1;
261489857Sobrien	    }
261589857Sobrien	  else
261689857Sobrien	    {
261789857Sobrien	      bfd_signed_vma *local_got_refcounts;
261889857Sobrien
261989857Sobrien	      /* This is a global offset table entry for a local symbol.  */
262089857Sobrien	      local_got_refcounts = elf_local_got_refcounts (abfd);
262189857Sobrien	      if (local_got_refcounts == NULL)
262289857Sobrien		{
262389857Sobrien		  bfd_size_type size;
262489857Sobrien
262589857Sobrien		  size = symtab_hdr->sh_info;
262689857Sobrien		  size *= sizeof (bfd_signed_vma);
262789857Sobrien		  local_got_refcounts = ((bfd_signed_vma *)
262889857Sobrien					 bfd_zalloc (abfd, size));
262989857Sobrien		  if (local_got_refcounts == NULL)
263089857Sobrien		    return false;
263189857Sobrien		  elf_local_got_refcounts (abfd) = local_got_refcounts;
263289857Sobrien		}
263389857Sobrien	      local_got_refcounts[r_symndx] += 1;
263489857Sobrien	    }
263589857Sobrien	  break;
263689857Sobrien
263789857Sobrien	case R_PPC64_PLT16_HA:
263889857Sobrien	case R_PPC64_PLT16_HI:
263989857Sobrien	case R_PPC64_PLT16_LO:
264089857Sobrien	case R_PPC64_PLT32:
264189857Sobrien	case R_PPC64_PLT64:
264289857Sobrien	  /* This symbol requires a procedure linkage table entry.  We
2643104834Sobrien	     actually build the entry in adjust_dynamic_symbol,
2644104834Sobrien	     because this might be a case of linking PIC code without
2645104834Sobrien	     linking in any dynamic objects, in which case we don't
2646104834Sobrien	     need to generate a procedure linkage table after all.  */
264789857Sobrien	  if (h == NULL)
264889857Sobrien	    {
264989857Sobrien	      /* It does not make sense to have a procedure linkage
2650104834Sobrien		 table entry for a local symbol.  */
265189857Sobrien	      bfd_set_error (bfd_error_bad_value);
265289857Sobrien	      return false;
265389857Sobrien	    }
265489857Sobrien
265589857Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
265689857Sobrien	  h->plt.refcount += 1;
265789857Sobrien	  ((struct ppc_link_hash_entry *) h)->is_func = 1;
265889857Sobrien	  break;
265989857Sobrien
266089857Sobrien	  /* The following relocations don't need to propagate the
266189857Sobrien	     relocation if linking a shared object since they are
266289857Sobrien	     section relative.  */
266389857Sobrien	case R_PPC64_SECTOFF:
266489857Sobrien	case R_PPC64_SECTOFF_LO:
266589857Sobrien	case R_PPC64_SECTOFF_HI:
266689857Sobrien	case R_PPC64_SECTOFF_HA:
266789857Sobrien	case R_PPC64_SECTOFF_DS:
266889857Sobrien	case R_PPC64_SECTOFF_LO_DS:
266989857Sobrien	case R_PPC64_TOC16:
267089857Sobrien	case R_PPC64_TOC16_LO:
267189857Sobrien	case R_PPC64_TOC16_HI:
267289857Sobrien	case R_PPC64_TOC16_HA:
267389857Sobrien	case R_PPC64_TOC16_DS:
267489857Sobrien	case R_PPC64_TOC16_LO_DS:
267589857Sobrien	  break;
267689857Sobrien
267789857Sobrien	  /* This relocation describes the C++ object vtable hierarchy.
267889857Sobrien	     Reconstruct it for later use during GC.  */
267989857Sobrien	case R_PPC64_GNU_VTINHERIT:
268089857Sobrien	  if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
268189857Sobrien	    return false;
268289857Sobrien	  break;
268389857Sobrien
268489857Sobrien	  /* This relocation describes which C++ vtable entries are actually
268589857Sobrien	     used.  Record for later use during GC.  */
268689857Sobrien	case R_PPC64_GNU_VTENTRY:
268789857Sobrien	  if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
268889857Sobrien	    return false;
268989857Sobrien	  break;
269089857Sobrien
2691104834Sobrien	case R_PPC64_REL14:
2692104834Sobrien	case R_PPC64_REL14_BRTAKEN:
2693104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
2694104834Sobrien	  htab->has_14bit_branch = 1;
2695104834Sobrien	  /* Fall through.  */
2696104834Sobrien
269789857Sobrien	case R_PPC64_REL24:
269889857Sobrien	  if (h != NULL
269989857Sobrien	      && h->root.root.string[0] == '.'
270089857Sobrien	      && h->root.root.string[1] != 0)
270189857Sobrien	    {
270289857Sobrien	      /* We may need a .plt entry if the function this reloc
270389857Sobrien		 refers to is in a shared lib.  */
270489857Sobrien	      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
270589857Sobrien	      h->plt.refcount += 1;
270689857Sobrien	      ((struct ppc_link_hash_entry *) h)->is_func = 1;
270789857Sobrien	    }
270889857Sobrien	  break;
270989857Sobrien
271089857Sobrien	case R_PPC64_ADDR64:
2711104834Sobrien	  if (opd_sym_map != NULL
271289857Sobrien	      && h != NULL
271389857Sobrien	      && h->root.root.string[0] == '.'
271489857Sobrien	      && h->root.root.string[1] != 0)
271589857Sobrien	    {
271689857Sobrien	      struct elf_link_hash_entry *fdh;
271789857Sobrien
271889857Sobrien	      fdh = elf_link_hash_lookup (&htab->elf, h->root.root.string + 1,
271989857Sobrien					  false, false, false);
272089857Sobrien	      if (fdh != NULL)
272189857Sobrien		{
272289857Sobrien		  ((struct ppc_link_hash_entry *) fdh)->is_func_descriptor = 1;
2723104834Sobrien		  ((struct ppc_link_hash_entry *) fdh)->oh = h;
272489857Sobrien		  ((struct ppc_link_hash_entry *) h)->is_func = 1;
2725104834Sobrien		  ((struct ppc_link_hash_entry *) h)->oh = fdh;
272689857Sobrien		}
272789857Sobrien	    }
2728104834Sobrien	  if (opd_sym_map != NULL
2729104834Sobrien	      && h == NULL
2730104834Sobrien	      && rel + 1 < rel_end
2731104834Sobrien	      && ((enum elf_ppc_reloc_type) ELF64_R_TYPE ((rel + 1)->r_info)
2732104834Sobrien		  == R_PPC64_TOC))
2733104834Sobrien	    {
2734104834Sobrien	      asection *s;
2735104834Sobrien
2736104834Sobrien	      s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
2737104834Sobrien					     r_symndx);
2738104834Sobrien	      if (s == NULL)
2739104834Sobrien		return false;
2740104834Sobrien	      else if (s != sec)
2741104834Sobrien		opd_sym_map[rel->r_offset / 24] = s;
2742104834Sobrien	    }
274389857Sobrien	  /* Fall through.  */
274489857Sobrien
274589857Sobrien	case R_PPC64_REL64:
274689857Sobrien	case R_PPC64_REL32:
274789857Sobrien	case R_PPC64_ADDR14:
274889857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
274989857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
275089857Sobrien	case R_PPC64_ADDR16:
275189857Sobrien	case R_PPC64_ADDR16_DS:
275289857Sobrien	case R_PPC64_ADDR16_HA:
275389857Sobrien	case R_PPC64_ADDR16_HI:
275489857Sobrien	case R_PPC64_ADDR16_HIGHER:
275589857Sobrien	case R_PPC64_ADDR16_HIGHERA:
275689857Sobrien	case R_PPC64_ADDR16_HIGHEST:
275789857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
275889857Sobrien	case R_PPC64_ADDR16_LO:
275989857Sobrien	case R_PPC64_ADDR16_LO_DS:
276089857Sobrien	case R_PPC64_ADDR24:
276189857Sobrien	case R_PPC64_ADDR30:
276289857Sobrien	case R_PPC64_ADDR32:
276389857Sobrien	case R_PPC64_UADDR16:
276489857Sobrien	case R_PPC64_UADDR32:
276589857Sobrien	case R_PPC64_UADDR64:
276689857Sobrien	case R_PPC64_TOC:
276789857Sobrien	  /* Don't propagate .opd relocs.  */
2768104834Sobrien	  if (NO_OPD_RELOCS && opd_sym_map != NULL)
276989857Sobrien	    break;
277089857Sobrien
277189857Sobrien	  /* If we are creating a shared library, and this is a reloc
277289857Sobrien	     against a global symbol, or a non PC relative reloc
277389857Sobrien	     against a local symbol, then we need to copy the reloc
277489857Sobrien	     into the shared library.  However, if we are linking with
277589857Sobrien	     -Bsymbolic, we do not need to copy a reloc against a
277689857Sobrien	     global symbol which is defined in an object we are
277789857Sobrien	     including in the link (i.e., DEF_REGULAR is set).  At
277889857Sobrien	     this point we have not seen all the input files, so it is
277989857Sobrien	     possible that DEF_REGULAR is not set now but will be set
278089857Sobrien	     later (it is never cleared).  In case of a weak definition,
278189857Sobrien	     DEF_REGULAR may be cleared later by a strong definition in
278289857Sobrien	     a shared library.  We account for that possibility below by
278389857Sobrien	     storing information in the relocs_copied field of the hash
278489857Sobrien	     table entry.  A similar situation occurs when creating
278589857Sobrien	     shared libraries and symbol visibility changes render the
278689857Sobrien	     symbol local.
278789857Sobrien
278889857Sobrien	     If on the other hand, we are creating an executable, we
278989857Sobrien	     may need to keep relocations for symbols satisfied by a
279089857Sobrien	     dynamic library if we manage to avoid copy relocs for the
279189857Sobrien	     symbol.  */
279289857Sobrien	  if ((info->shared
279389857Sobrien	       && (sec->flags & SEC_ALLOC) != 0
279489857Sobrien	       && (IS_ABSOLUTE_RELOC (r_type)
279589857Sobrien		   || (h != NULL
279689857Sobrien		       && (! info->symbolic
279789857Sobrien			   || h->root.type == bfd_link_hash_defweak
279889857Sobrien			   || (h->elf_link_hash_flags
279989857Sobrien			       & ELF_LINK_HASH_DEF_REGULAR) == 0))))
280089857Sobrien	      || (!info->shared
280189857Sobrien		  && (sec->flags & SEC_ALLOC) != 0
280289857Sobrien		  && h != NULL
280389857Sobrien		  && (h->root.type == bfd_link_hash_defweak
280489857Sobrien		      || (h->elf_link_hash_flags
280589857Sobrien			  & ELF_LINK_HASH_DEF_REGULAR) == 0)))
280689857Sobrien	    {
280789857Sobrien	      struct ppc_dyn_relocs *p;
280889857Sobrien	      struct ppc_dyn_relocs **head;
280989857Sobrien
281089857Sobrien	      /* We must copy these reloc types into the output file.
281189857Sobrien		 Create a reloc section in dynobj and make room for
281289857Sobrien		 this reloc.  */
281389857Sobrien	      if (sreloc == NULL)
281489857Sobrien		{
281589857Sobrien		  const char *name;
281689857Sobrien		  bfd *dynobj;
281789857Sobrien
281889857Sobrien		  name = (bfd_elf_string_from_elf_section
281989857Sobrien			  (abfd,
282089857Sobrien			   elf_elfheader (abfd)->e_shstrndx,
282189857Sobrien			   elf_section_data (sec)->rel_hdr.sh_name));
282289857Sobrien		  if (name == NULL)
282389857Sobrien		    return false;
282489857Sobrien
282589857Sobrien		  if (strncmp (name, ".rela", 5) != 0
282689857Sobrien		      || strcmp (bfd_get_section_name (abfd, sec),
282789857Sobrien				 name + 5) != 0)
282889857Sobrien		    {
282989857Sobrien		      (*_bfd_error_handler)
283089857Sobrien			(_("%s: bad relocation section name `%s\'"),
283189857Sobrien			 bfd_archive_filename (abfd), name);
283289857Sobrien		      bfd_set_error (bfd_error_bad_value);
283389857Sobrien		    }
283489857Sobrien
283589857Sobrien		  dynobj = htab->elf.dynobj;
283689857Sobrien		  sreloc = bfd_get_section_by_name (dynobj, name);
283789857Sobrien		  if (sreloc == NULL)
283889857Sobrien		    {
283989857Sobrien		      flagword flags;
284089857Sobrien
284189857Sobrien		      sreloc = bfd_make_section (dynobj, name);
284289857Sobrien		      flags = (SEC_HAS_CONTENTS | SEC_READONLY
284389857Sobrien			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
284489857Sobrien		      if ((sec->flags & SEC_ALLOC) != 0)
284589857Sobrien			flags |= SEC_ALLOC | SEC_LOAD;
284689857Sobrien		      if (sreloc == NULL
284789857Sobrien			  || ! bfd_set_section_flags (dynobj, sreloc, flags)
284889857Sobrien			  || ! bfd_set_section_alignment (dynobj, sreloc, 3))
284989857Sobrien			return false;
285089857Sobrien		    }
285189857Sobrien		  elf_section_data (sec)->sreloc = sreloc;
285289857Sobrien		}
285389857Sobrien
285489857Sobrien	      /* If this is a global symbol, we count the number of
285589857Sobrien		 relocations we need for this symbol.  */
285689857Sobrien	      if (h != NULL)
285789857Sobrien		{
285889857Sobrien		  head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
285989857Sobrien		}
286089857Sobrien	      else
286189857Sobrien		{
286289857Sobrien		  /* Track dynamic relocs needed for local syms too.
286389857Sobrien		     We really need local syms available to do this
286489857Sobrien		     easily.  Oh well.  */
286589857Sobrien
286689857Sobrien		  asection *s;
286789857Sobrien		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
286889857Sobrien						 sec, r_symndx);
286989857Sobrien		  if (s == NULL)
287089857Sobrien		    return false;
287189857Sobrien
287289857Sobrien		  head = ((struct ppc_dyn_relocs **)
287389857Sobrien			  &elf_section_data (s)->local_dynrel);
287489857Sobrien		}
287589857Sobrien
287689857Sobrien	      p = *head;
287789857Sobrien	      if (p == NULL || p->sec != sec)
287889857Sobrien		{
287989857Sobrien		  p = ((struct ppc_dyn_relocs *)
288089857Sobrien		       bfd_alloc (htab->elf.dynobj,
288189857Sobrien				  (bfd_size_type) sizeof *p));
288289857Sobrien		  if (p == NULL)
288389857Sobrien		    return false;
288489857Sobrien		  p->next = *head;
288589857Sobrien		  *head = p;
288689857Sobrien		  p->sec = sec;
288789857Sobrien		  p->count = 0;
288889857Sobrien		  p->pc_count = 0;
288989857Sobrien		}
289089857Sobrien
289189857Sobrien	      p->count += 1;
289289857Sobrien	      if (!IS_ABSOLUTE_RELOC (r_type))
289389857Sobrien		p->pc_count += 1;
289489857Sobrien	    }
289589857Sobrien	  break;
289689857Sobrien
289789857Sobrien	default:
289892828Sobrien	  break;
289989857Sobrien	}
290089857Sobrien    }
290189857Sobrien
290289857Sobrien  return true;
290389857Sobrien}
290489857Sobrien
290589857Sobrien/* Return the section that should be marked against GC for a given
290689857Sobrien   relocation.  */
290789857Sobrien
290889857Sobrienstatic asection *
2909104834Sobrienppc64_elf_gc_mark_hook (sec, info, rel, h, sym)
2910104834Sobrien     asection *sec;
291189857Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
291289857Sobrien     Elf_Internal_Rela *rel;
291389857Sobrien     struct elf_link_hash_entry *h;
291489857Sobrien     Elf_Internal_Sym *sym;
291589857Sobrien{
2916104834Sobrien  asection *rsec = NULL;
2917104834Sobrien
291889857Sobrien  if (h != NULL)
291989857Sobrien    {
292089857Sobrien      enum elf_ppc_reloc_type r_type;
2921104834Sobrien      struct ppc_link_hash_entry *fdh;
292289857Sobrien
292389857Sobrien      r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info);
292489857Sobrien      switch (r_type)
292589857Sobrien	{
292689857Sobrien	case R_PPC64_GNU_VTINHERIT:
292789857Sobrien	case R_PPC64_GNU_VTENTRY:
292889857Sobrien	  break;
292989857Sobrien
293089857Sobrien	default:
293189857Sobrien	  switch (h->root.type)
293289857Sobrien	    {
293389857Sobrien	    case bfd_link_hash_defined:
293489857Sobrien	    case bfd_link_hash_defweak:
2935104834Sobrien	      fdh = (struct ppc_link_hash_entry *) h;
293689857Sobrien
2937104834Sobrien	      /* Function descriptor syms cause the associated
2938104834Sobrien		 function code sym section to be marked.  */
2939104834Sobrien	      if (fdh->is_func_descriptor)
2940104834Sobrien		rsec = fdh->oh->root.u.def.section;
2941104834Sobrien
2942104834Sobrien	      /* Function entry syms return NULL if they are in .opd
2943104834Sobrien		 and are not ._start (or others undefined on the ld
2944104834Sobrien		 command line).  Thus we avoid marking all function
2945104834Sobrien		 sections, as all functions are referenced in .opd.  */
2946104834Sobrien	      else if ((fdh->oh != NULL
2947104834Sobrien			&& ((struct ppc_link_hash_entry *) fdh->oh)->is_entry)
2948104834Sobrien		       || elf_section_data (sec)->tdata == NULL)
2949104834Sobrien		rsec = h->root.u.def.section;
2950104834Sobrien	      break;
2951104834Sobrien
295289857Sobrien	    case bfd_link_hash_common:
2953104834Sobrien	      rsec = h->root.u.c.p->section;
2954104834Sobrien	      break;
295589857Sobrien
295689857Sobrien	    default:
295789857Sobrien	      break;
295889857Sobrien	    }
295989857Sobrien	}
296089857Sobrien    }
296189857Sobrien  else
296289857Sobrien    {
2963104834Sobrien      asection **opd_sym_section;
2964104834Sobrien
2965104834Sobrien      rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
2966104834Sobrien      opd_sym_section = (asection **) elf_section_data (rsec)->tdata;
2967104834Sobrien      if (opd_sym_section != NULL)
2968104834Sobrien	rsec = opd_sym_section[sym->st_value / 24];
2969104834Sobrien      else if (elf_section_data (sec)->tdata != NULL)
2970104834Sobrien	rsec = NULL;
297189857Sobrien    }
297289857Sobrien
2973104834Sobrien  return rsec;
297489857Sobrien}
297589857Sobrien
297689857Sobrien/* Update the .got, .plt. and dynamic reloc reference counts for the
297789857Sobrien   section being removed.  */
297889857Sobrien
297989857Sobrienstatic boolean
298089857Sobrienppc64_elf_gc_sweep_hook (abfd, info, sec, relocs)
298189857Sobrien     bfd *abfd;
298289857Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
298389857Sobrien     asection *sec;
298489857Sobrien     const Elf_Internal_Rela *relocs;
298589857Sobrien{
298689857Sobrien  Elf_Internal_Shdr *symtab_hdr;
298789857Sobrien  struct elf_link_hash_entry **sym_hashes;
298889857Sobrien  bfd_signed_vma *local_got_refcounts;
298989857Sobrien  const Elf_Internal_Rela *rel, *relend;
299089857Sobrien
299189857Sobrien  elf_section_data (sec)->local_dynrel = NULL;
299289857Sobrien
299389857Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
299489857Sobrien  sym_hashes = elf_sym_hashes (abfd);
299589857Sobrien  local_got_refcounts = elf_local_got_refcounts (abfd);
299689857Sobrien
299789857Sobrien  relend = relocs + sec->reloc_count;
299889857Sobrien  for (rel = relocs; rel < relend; rel++)
299989857Sobrien    {
300089857Sobrien      unsigned long r_symndx;
300189857Sobrien      enum elf_ppc_reloc_type r_type;
300289857Sobrien      struct elf_link_hash_entry *h;
300389857Sobrien
300489857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
300589857Sobrien      r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info);
300689857Sobrien      switch (r_type)
300789857Sobrien	{
300889857Sobrien	case R_PPC64_GOT16:
300989857Sobrien	case R_PPC64_GOT16_DS:
301089857Sobrien	case R_PPC64_GOT16_HA:
301189857Sobrien	case R_PPC64_GOT16_HI:
301289857Sobrien	case R_PPC64_GOT16_LO:
301389857Sobrien	case R_PPC64_GOT16_LO_DS:
301489857Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
301589857Sobrien	    {
301689857Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
301789857Sobrien	      if (h->got.refcount > 0)
301889857Sobrien		h->got.refcount--;
301989857Sobrien	    }
302089857Sobrien	  else
302189857Sobrien	    {
302289857Sobrien	      if (local_got_refcounts[r_symndx] > 0)
302389857Sobrien		local_got_refcounts[r_symndx]--;
302489857Sobrien	    }
302589857Sobrien	  break;
302689857Sobrien
302789857Sobrien	case R_PPC64_PLT16_HA:
302889857Sobrien	case R_PPC64_PLT16_HI:
302989857Sobrien	case R_PPC64_PLT16_LO:
303089857Sobrien	case R_PPC64_PLT32:
303189857Sobrien	case R_PPC64_PLT64:
303289857Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
303389857Sobrien	    {
303489857Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
303589857Sobrien	      if (h->plt.refcount > 0)
303689857Sobrien		h->plt.refcount--;
303789857Sobrien	    }
303889857Sobrien	  break;
303989857Sobrien
3040104834Sobrien	case R_PPC64_REL14:
3041104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
3042104834Sobrien	case R_PPC64_REL14_BRTAKEN:
304389857Sobrien	case R_PPC64_REL24:
304489857Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
304589857Sobrien	    {
304689857Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
304789857Sobrien	      if (h->plt.refcount > 0)
304889857Sobrien		h->plt.refcount--;
304989857Sobrien	    }
305089857Sobrien	  break;
305189857Sobrien
305289857Sobrien	case R_PPC64_REL32:
305389857Sobrien	case R_PPC64_REL64:
305489857Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
305589857Sobrien	    {
305689857Sobrien	      struct ppc_link_hash_entry *eh;
305789857Sobrien	      struct ppc_dyn_relocs **pp;
305889857Sobrien	      struct ppc_dyn_relocs *p;
305989857Sobrien
306089857Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
306189857Sobrien	      eh = (struct ppc_link_hash_entry *) h;
306289857Sobrien
306389857Sobrien	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
306489857Sobrien		if (p->sec == sec)
306589857Sobrien		  {
306689857Sobrien		    p->pc_count -= 1;
306789857Sobrien		    p->count -= 1;
306889857Sobrien		    if (p->count == 0)
306989857Sobrien		      *pp = p->next;
307089857Sobrien		    break;
307189857Sobrien		  }
307289857Sobrien	    }
307389857Sobrien	  break;
307489857Sobrien
307589857Sobrien	case R_PPC64_ADDR14:
307689857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
307789857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
307889857Sobrien	case R_PPC64_ADDR16:
307989857Sobrien	case R_PPC64_ADDR16_DS:
308089857Sobrien	case R_PPC64_ADDR16_HA:
308189857Sobrien	case R_PPC64_ADDR16_HI:
308289857Sobrien	case R_PPC64_ADDR16_HIGHER:
308389857Sobrien	case R_PPC64_ADDR16_HIGHERA:
308489857Sobrien	case R_PPC64_ADDR16_HIGHEST:
308589857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
308689857Sobrien	case R_PPC64_ADDR16_LO:
308789857Sobrien	case R_PPC64_ADDR16_LO_DS:
308889857Sobrien	case R_PPC64_ADDR24:
308989857Sobrien	case R_PPC64_ADDR30:
309089857Sobrien	case R_PPC64_ADDR32:
309189857Sobrien	case R_PPC64_ADDR64:
309289857Sobrien	case R_PPC64_UADDR16:
309389857Sobrien	case R_PPC64_UADDR32:
309489857Sobrien	case R_PPC64_UADDR64:
309589857Sobrien	case R_PPC64_TOC:
309689857Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
309789857Sobrien	    {
309889857Sobrien	      struct ppc_link_hash_entry *eh;
309989857Sobrien	      struct ppc_dyn_relocs **pp;
310089857Sobrien	      struct ppc_dyn_relocs *p;
310189857Sobrien
310289857Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
310389857Sobrien	      eh = (struct ppc_link_hash_entry *) h;
310489857Sobrien
310589857Sobrien	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
310689857Sobrien		if (p->sec == sec)
310789857Sobrien		  {
310889857Sobrien		    p->count -= 1;
310989857Sobrien		    if (p->count == 0)
311089857Sobrien		      *pp = p->next;
311189857Sobrien		    break;
311289857Sobrien		  }
311389857Sobrien	    }
311489857Sobrien	  break;
311589857Sobrien
311689857Sobrien	default:
311789857Sobrien	  break;
311889857Sobrien	}
311989857Sobrien    }
312089857Sobrien  return true;
312189857Sobrien}
312289857Sobrien
312389857Sobrien/* Called via elf_link_hash_traverse to transfer dynamic linking
312489857Sobrien   information on function code symbol entries to their corresponding
312589857Sobrien   function descriptor symbol entries.  */
312689857Sobrienstatic boolean
312789857Sobrienfunc_desc_adjust (h, inf)
312889857Sobrien     struct elf_link_hash_entry *h;
312989857Sobrien     PTR inf;
313089857Sobrien{
313189857Sobrien  struct bfd_link_info *info;
313289857Sobrien  struct ppc_link_hash_table *htab;
313389857Sobrien
313494536Sobrien  if (h->root.type == bfd_link_hash_indirect)
313589857Sobrien    return true;
313689857Sobrien
313794536Sobrien  if (h->root.type == bfd_link_hash_warning)
313894536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
313994536Sobrien
314089857Sobrien  info = (struct bfd_link_info *) inf;
314189857Sobrien  htab = ppc_hash_table (info);
314289857Sobrien
314389857Sobrien  /* If this is a function code symbol, transfer dynamic linking
314489857Sobrien     information to the function descriptor symbol.  */
314589857Sobrien  if (!((struct ppc_link_hash_entry *) h)->is_func)
314689857Sobrien    return true;
314789857Sobrien
314899461Sobrien  if (h->root.type == bfd_link_hash_undefweak
314999461Sobrien      && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR))
315099461Sobrien    htab->have_undefweak = true;
315199461Sobrien
315289857Sobrien  if (h->plt.refcount > 0
315389857Sobrien      && h->root.root.string[0] == '.'
315489857Sobrien      && h->root.root.string[1] != '\0')
315589857Sobrien    {
3156104834Sobrien      struct elf_link_hash_entry *fdh = ((struct ppc_link_hash_entry *) h)->oh;
315789857Sobrien      boolean force_local;
315889857Sobrien
315989857Sobrien      /* Find the corresponding function descriptor symbol.  Create it
316089857Sobrien	 as undefined if necessary.  */
316189857Sobrien
3162104834Sobrien      if (fdh == NULL)
3163104834Sobrien	fdh = elf_link_hash_lookup (&htab->elf, h->root.root.string + 1,
3164104834Sobrien				    false, false, true);
316589857Sobrien
316691041Sobrien      if (fdh == NULL
316791041Sobrien	  && info->shared
316891041Sobrien	  && (h->root.type == bfd_link_hash_undefined
316991041Sobrien	      || h->root.type == bfd_link_hash_undefweak))
317089857Sobrien	{
317189857Sobrien	  bfd *abfd;
317289857Sobrien	  asymbol *newsym;
3173107492Sobrien	  struct bfd_link_hash_entry *bh;
317489857Sobrien
317591041Sobrien	  abfd = h->root.u.undef.abfd;
317689857Sobrien	  newsym = bfd_make_empty_symbol (abfd);
317789857Sobrien	  newsym->name = h->root.root.string + 1;
317889857Sobrien	  newsym->section = bfd_und_section_ptr;
317989857Sobrien	  newsym->value = 0;
318089857Sobrien	  newsym->flags = BSF_OBJECT;
318189857Sobrien	  if (h->root.type == bfd_link_hash_undefweak)
318289857Sobrien	    newsym->flags |= BSF_WEAK;
318389857Sobrien
3184107492Sobrien	  bh = &fdh->root;
318589857Sobrien	  if ( !(_bfd_generic_link_add_one_symbol
318689857Sobrien		 (info, abfd, newsym->name, newsym->flags,
3187107492Sobrien		  newsym->section, newsym->value, NULL, false, false, &bh)))
318889857Sobrien	    {
318989857Sobrien	      return false;
319089857Sobrien	    }
3191107492Sobrien	  fdh = (struct elf_link_hash_entry *) bh;
319291041Sobrien	  fdh->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
319389857Sobrien	}
319489857Sobrien
319589857Sobrien      if (fdh != NULL
319689857Sobrien	  && (fdh->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0
319789857Sobrien	  && (info->shared
319889857Sobrien	      || (fdh->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
319989857Sobrien	      || (fdh->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0))
320089857Sobrien	{
320189857Sobrien	  if (fdh->dynindx == -1)
320289857Sobrien	    if (! bfd_elf64_link_record_dynamic_symbol (info, fdh))
320389857Sobrien	      return false;
320489857Sobrien	  fdh->elf_link_hash_flags |= (h->elf_link_hash_flags
320589857Sobrien				       & (ELF_LINK_HASH_REF_REGULAR
320689857Sobrien					  | ELF_LINK_HASH_REF_DYNAMIC
320789857Sobrien					  | ELF_LINK_HASH_REF_REGULAR_NONWEAK
320889857Sobrien					  | ELF_LINK_NON_GOT_REF));
320991041Sobrien	  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
321091041Sobrien	    {
321191041Sobrien	      fdh->plt.refcount = h->plt.refcount;
321291041Sobrien	      fdh->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
321391041Sobrien	    }
321489857Sobrien	  ((struct ppc_link_hash_entry *) fdh)->is_func_descriptor = 1;
3215104834Sobrien	  ((struct ppc_link_hash_entry *) fdh)->oh = h;
3216104834Sobrien	  ((struct ppc_link_hash_entry *) h)->oh = fdh;
321789857Sobrien	}
321889857Sobrien
321989857Sobrien      /* Now that the info is on the function descriptor, clear the
322089857Sobrien	 function code sym info.  Any function code syms for which we
322189857Sobrien	 don't have a definition in a regular file, we force local.
322289857Sobrien	 This prevents a shared library from exporting syms that have
322389857Sobrien	 been imported from another library.  Function code syms that
322489857Sobrien	 are really in the library we must leave global to prevent the
322591041Sobrien	 linker dragging in a definition from a static library.  */
3226104834Sobrien      force_local = (info->shared
3227104834Sobrien		     && ((h->elf_link_hash_flags
3228104834Sobrien			  & ELF_LINK_HASH_DEF_REGULAR) == 0
3229104834Sobrien			 || fdh == NULL
3230104834Sobrien			 || (fdh->elf_link_hash_flags
3231104834Sobrien			     & ELF_LINK_HASH_DEF_REGULAR) == 0
3232104834Sobrien			 || (fdh->elf_link_hash_flags
3233104834Sobrien			     & ELF_LINK_FORCED_LOCAL) != 0));
323489857Sobrien      _bfd_elf_link_hash_hide_symbol (info, h, force_local);
323589857Sobrien    }
323689857Sobrien
323789857Sobrien  return true;
323889857Sobrien}
323989857Sobrien
324092828Sobrien#define MIN_SAVE_FPR 14
324192828Sobrien#define MAX_SAVE_FPR 31
324292828Sobrien
324389857Sobrien/* Called near the start of bfd_elf_size_dynamic_sections.  We use
324492828Sobrien   this hook to a) provide some gcc support functions, and b) transfer
324592828Sobrien   dynamic linking information gathered so far on function code symbol
324692828Sobrien   entries, to their corresponding function descriptor symbol entries.  */
324789857Sobrienstatic boolean
324889857Sobrienppc64_elf_func_desc_adjust (obfd, info)
324989857Sobrien     bfd *obfd ATTRIBUTE_UNUSED;
325089857Sobrien     struct bfd_link_info *info;
325189857Sobrien{
325289857Sobrien  struct ppc_link_hash_table *htab;
325392828Sobrien  unsigned int lowest_savef = MAX_SAVE_FPR + 2;
325492828Sobrien  unsigned int lowest_restf = MAX_SAVE_FPR + 2;
325592828Sobrien  unsigned int i;
325692828Sobrien  struct elf_link_hash_entry *h;
325799461Sobrien  bfd_byte *p;
325892828Sobrien  char sym[10];
325989857Sobrien
326089857Sobrien  htab = ppc_hash_table (info);
326192828Sobrien
326292828Sobrien  if (htab->sfpr == NULL)
326392828Sobrien    /* We don't have any relocs.  */
326492828Sobrien    return true;
326592828Sobrien
326692828Sobrien  /* First provide any missing ._savef* and ._restf* functions.  */
326792828Sobrien  memcpy (sym, "._savef14", 10);
326892828Sobrien  for (i = MIN_SAVE_FPR; i <= MAX_SAVE_FPR; i++)
326992828Sobrien    {
327092828Sobrien      sym[7] = i / 10 + '0';
327192828Sobrien      sym[8] = i % 10 + '0';
327292828Sobrien      h = elf_link_hash_lookup (&htab->elf, sym, false, false, true);
327392828Sobrien      if (h != NULL
327492828Sobrien	  && h->root.type == bfd_link_hash_undefined)
327592828Sobrien	{
327692828Sobrien	  if (lowest_savef > i)
327792828Sobrien	    lowest_savef = i;
327892828Sobrien	  h->root.type = bfd_link_hash_defined;
327992828Sobrien	  h->root.u.def.section = htab->sfpr;
328092828Sobrien	  h->root.u.def.value = (i - lowest_savef) * 4;
328192828Sobrien	  h->type = STT_FUNC;
328292828Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
328392828Sobrien	  _bfd_elf_link_hash_hide_symbol (info, h, info->shared);
328492828Sobrien	}
328592828Sobrien    }
328692828Sobrien
328792828Sobrien  memcpy (sym, "._restf14", 10);
328892828Sobrien  for (i = MIN_SAVE_FPR; i <= MAX_SAVE_FPR; i++)
328992828Sobrien    {
329092828Sobrien      sym[7] = i / 10 + '0';
329192828Sobrien      sym[8] = i % 10 + '0';
329292828Sobrien      h = elf_link_hash_lookup (&htab->elf, sym, false, false, true);
329392828Sobrien      if (h != NULL
329492828Sobrien	  && h->root.type == bfd_link_hash_undefined)
329592828Sobrien	{
329692828Sobrien	  if (lowest_restf > i)
329792828Sobrien	    lowest_restf = i;
329892828Sobrien	  h->root.type = bfd_link_hash_defined;
329992828Sobrien	  h->root.u.def.section = htab->sfpr;
330092828Sobrien	  h->root.u.def.value = ((MAX_SAVE_FPR + 2 - lowest_savef) * 4
330192828Sobrien				 + (i - lowest_restf) * 4);
330292828Sobrien	  h->type = STT_FUNC;
330392828Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
330492828Sobrien	  _bfd_elf_link_hash_hide_symbol (info, h, info->shared);
330592828Sobrien	}
330692828Sobrien    }
330792828Sobrien
330899461Sobrien  elf_link_hash_traverse (&htab->elf, func_desc_adjust, (PTR) info);
330999461Sobrien
331092828Sobrien  htab->sfpr->_raw_size = ((MAX_SAVE_FPR + 2 - lowest_savef) * 4
331192828Sobrien			   + (MAX_SAVE_FPR + 2 - lowest_restf) * 4);
331292828Sobrien
331392828Sobrien  if (htab->sfpr->_raw_size == 0)
331492828Sobrien    {
331599461Sobrien      if (!htab->have_undefweak)
331699461Sobrien	{
331799461Sobrien	  _bfd_strip_section_from_output (info, htab->sfpr);
331899461Sobrien	  return true;
331999461Sobrien	}
332099461Sobrien
332199461Sobrien      htab->sfpr->_raw_size = 4;
332292828Sobrien    }
332399461Sobrien
332499461Sobrien  p = (bfd_byte *) bfd_alloc (htab->elf.dynobj, htab->sfpr->_raw_size);
332599461Sobrien  if (p == NULL)
332699461Sobrien    return false;
332799461Sobrien  htab->sfpr->contents = p;
332899461Sobrien
332999461Sobrien  for (i = lowest_savef; i <= MAX_SAVE_FPR; i++)
333092828Sobrien    {
333199461Sobrien      unsigned int fpr = i << 21;
333299461Sobrien      unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8;
333399461Sobrien      bfd_put_32 (htab->elf.dynobj, STFD_FR0_0R1 + fpr + stackoff, p);
333499461Sobrien      p += 4;
333599461Sobrien    }
333699461Sobrien  if (lowest_savef <= MAX_SAVE_FPR)
333799461Sobrien    {
333892828Sobrien      bfd_put_32 (htab->elf.dynobj, BLR, p);
333992828Sobrien      p += 4;
334099461Sobrien    }
334192828Sobrien
334299461Sobrien  for (i = lowest_restf; i <= MAX_SAVE_FPR; i++)
334399461Sobrien    {
334499461Sobrien      unsigned int fpr = i << 21;
334599461Sobrien      unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8;
334699461Sobrien      bfd_put_32 (htab->elf.dynobj, LFD_FR0_0R1 + fpr + stackoff, p);
334792828Sobrien      p += 4;
334892828Sobrien    }
334999461Sobrien  if (lowest_restf <= MAX_SAVE_FPR
335099461Sobrien      || htab->sfpr->_raw_size == 4)
335199461Sobrien    {
335299461Sobrien      bfd_put_32 (htab->elf.dynobj, BLR, p);
335399461Sobrien    }
335492828Sobrien
335589857Sobrien  return true;
335689857Sobrien}
335789857Sobrien
335889857Sobrien/* Adjust a symbol defined by a dynamic object and referenced by a
335989857Sobrien   regular object.  The current definition is in some section of the
336089857Sobrien   dynamic object, but we're not including those sections.  We have to
336189857Sobrien   change the definition to something the rest of the link can
336289857Sobrien   understand.  */
336389857Sobrien
336489857Sobrienstatic boolean
336589857Sobrienppc64_elf_adjust_dynamic_symbol (info, h)
336689857Sobrien     struct bfd_link_info *info;
336789857Sobrien     struct elf_link_hash_entry *h;
336889857Sobrien{
336989857Sobrien  struct ppc_link_hash_table *htab;
337089857Sobrien  struct ppc_link_hash_entry * eh;
337189857Sobrien  struct ppc_dyn_relocs *p;
337289857Sobrien  asection *s;
337389857Sobrien  unsigned int power_of_two;
337489857Sobrien
337589857Sobrien  htab = ppc_hash_table (info);
337689857Sobrien
337789857Sobrien  /* Deal with function syms.  */
337889857Sobrien  if (h->type == STT_FUNC
337989857Sobrien      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
338089857Sobrien    {
338189857Sobrien      /* Clear procedure linkage table information for any symbol that
338289857Sobrien	 won't need a .plt entry.  */
338389857Sobrien      if (!((struct ppc_link_hash_entry *) h)->is_func_descriptor
338489857Sobrien	  || h->plt.refcount <= 0
338589857Sobrien	  || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
338689857Sobrien	  || (! info->shared
338789857Sobrien	      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
338889857Sobrien	      && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0))
338989857Sobrien	{
339089857Sobrien	  h->plt.offset = (bfd_vma) -1;
339189857Sobrien	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
339289857Sobrien	}
339389857Sobrien      return true;
339489857Sobrien    }
339589857Sobrien  else
339689857Sobrien    h->plt.offset = (bfd_vma) -1;
339789857Sobrien
339889857Sobrien  /* If this is a weak symbol, and there is a real definition, the
339989857Sobrien     processor independent code will have arranged for us to see the
340089857Sobrien     real definition first, and we can just use the same value.  */
340189857Sobrien  if (h->weakdef != NULL)
340289857Sobrien    {
340389857Sobrien      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
340489857Sobrien		  || h->weakdef->root.type == bfd_link_hash_defweak);
340589857Sobrien      h->root.u.def.section = h->weakdef->root.u.def.section;
340689857Sobrien      h->root.u.def.value = h->weakdef->root.u.def.value;
340789857Sobrien      return true;
340889857Sobrien    }
340989857Sobrien
341089857Sobrien  /* This is a reference to a symbol defined by a dynamic object which
341189857Sobrien     is not a function.  */
341289857Sobrien
341389857Sobrien  /* If we are creating a shared library, we must presume that the
341489857Sobrien     only references to the symbol are via the global offset table.
341589857Sobrien     For such cases we need not do anything here; the relocations will
341689857Sobrien     be handled correctly by relocate_section.  */
341789857Sobrien  if (info->shared)
341889857Sobrien    return true;
341989857Sobrien
342089857Sobrien  /* If there are no references to this symbol that do not use the
342189857Sobrien     GOT, we don't need to generate a copy reloc.  */
342289857Sobrien  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
342389857Sobrien    return true;
342489857Sobrien
342589857Sobrien  eh = (struct ppc_link_hash_entry *) h;
342689857Sobrien  for (p = eh->dyn_relocs; p != NULL; p = p->next)
342789857Sobrien    {
342889857Sobrien      s = p->sec->output_section;
342989857Sobrien      if (s != NULL && (s->flags & SEC_READONLY) != 0)
343089857Sobrien	break;
343189857Sobrien    }
343289857Sobrien
343389857Sobrien  /* If we didn't find any dynamic relocs in read-only sections, then
343489857Sobrien     we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
343589857Sobrien  if (p == NULL)
343689857Sobrien    {
343789857Sobrien      h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
343889857Sobrien      return true;
343989857Sobrien    }
344089857Sobrien
344189857Sobrien  /* We must allocate the symbol in our .dynbss section, which will
344289857Sobrien     become part of the .bss section of the executable.  There will be
344389857Sobrien     an entry for this symbol in the .dynsym section.  The dynamic
344489857Sobrien     object will contain position independent code, so all references
344589857Sobrien     from the dynamic object to this symbol will go through the global
344689857Sobrien     offset table.  The dynamic linker will use the .dynsym entry to
344789857Sobrien     determine the address it must put in the global offset table, so
344889857Sobrien     both the dynamic object and the regular object will refer to the
344989857Sobrien     same memory location for the variable.  */
345089857Sobrien
345189857Sobrien  /* We must generate a R_PPC_COPY reloc to tell the dynamic linker to
345289857Sobrien     copy the initial value out of the dynamic object and into the
345389857Sobrien     runtime process image.  We need to remember the offset into the
345489857Sobrien     .rela.bss section we are going to use.  */
345589857Sobrien  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
345689857Sobrien    {
345789857Sobrien      htab->srelbss->_raw_size += sizeof (Elf64_External_Rela);
345889857Sobrien      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
345989857Sobrien    }
346089857Sobrien
346189857Sobrien  /* We need to figure out the alignment required for this symbol.  I
346289857Sobrien     have no idea how ELF linkers handle this.  */
346389857Sobrien  power_of_two = bfd_log2 (h->size);
346489857Sobrien  if (power_of_two > 4)
346589857Sobrien    power_of_two = 4;
346689857Sobrien
346789857Sobrien  /* Apply the required alignment.  */
346889857Sobrien  s = htab->sdynbss;
346989857Sobrien  s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two));
347089857Sobrien  if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
347189857Sobrien    {
347289857Sobrien      if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
347389857Sobrien	return false;
347489857Sobrien    }
347589857Sobrien
347689857Sobrien  /* Define the symbol as being at this point in the section.  */
347789857Sobrien  h->root.u.def.section = s;
347889857Sobrien  h->root.u.def.value = s->_raw_size;
347989857Sobrien
348089857Sobrien  /* Increment the section size to make room for the symbol.  */
348189857Sobrien  s->_raw_size += h->size;
348289857Sobrien
348389857Sobrien  return true;
348489857Sobrien}
348589857Sobrien
348689857Sobrien/* If given a function descriptor symbol, hide both the function code
348789857Sobrien   sym and the descriptor.  */
348889857Sobrienstatic void
348989857Sobrienppc64_elf_hide_symbol (info, h, force_local)
349089857Sobrien     struct bfd_link_info *info;
349189857Sobrien     struct elf_link_hash_entry *h;
349289857Sobrien     boolean force_local;
349389857Sobrien{
349489857Sobrien  _bfd_elf_link_hash_hide_symbol (info, h, force_local);
349589857Sobrien
349689857Sobrien  if (((struct ppc_link_hash_entry *) h)->is_func_descriptor)
349789857Sobrien    {
3498104834Sobrien      struct elf_link_hash_entry *fh = ((struct ppc_link_hash_entry *) h)->oh;
349989857Sobrien
3500104834Sobrien      if (fh == NULL)
3501104834Sobrien	{
3502104834Sobrien	  const char *p, *q;
3503104834Sobrien	  struct ppc_link_hash_table *htab;
3504104834Sobrien	  char save;
3505104834Sobrien
3506104834Sobrien	  /* We aren't supposed to use alloca in BFD because on
3507104834Sobrien	     systems which do not have alloca the version in libiberty
3508104834Sobrien	     calls xmalloc, which might cause the program to crash
3509104834Sobrien	     when it runs out of memory.  This function doesn't have a
3510104834Sobrien	     return status, so there's no way to gracefully return an
3511104834Sobrien	     error.  So cheat.  We know that string[-1] can be safely
3512104834Sobrien	     dereferenced;  It's either a string in an ELF string
3513104834Sobrien	     table, or allocated in an objalloc structure.  */
3514104834Sobrien
3515104834Sobrien	  p = h->root.root.string - 1;
3516104834Sobrien	  save = *p;
3517104834Sobrien	  *(char *) p = '.';
3518104834Sobrien	  htab = ppc_hash_table (info);
3519104834Sobrien	  fh = elf_link_hash_lookup (&htab->elf, p, false, false, false);
3520104834Sobrien	  *(char *) p = save;
3521104834Sobrien
3522104834Sobrien	  /* Unfortunately, if it so happens that the string we were
3523104834Sobrien	     looking for was allocated immediately before this string,
3524104834Sobrien	     then we overwrote the string terminator.  That's the only
3525104834Sobrien	     reason the lookup should fail.  */
3526104834Sobrien	  if (fh == NULL)
3527104834Sobrien	    {
3528104834Sobrien	      q = h->root.root.string + strlen (h->root.root.string);
3529104834Sobrien	      while (q >= h->root.root.string && *q == *p)
3530104834Sobrien		--q, --p;
3531104834Sobrien	      if (q < h->root.root.string && *p == '.')
3532104834Sobrien		fh = elf_link_hash_lookup (&htab->elf, p, false, false, false);
3533104834Sobrien	    }
3534104834Sobrien	  if (fh != NULL)
3535104834Sobrien	    {
3536104834Sobrien	      ((struct ppc_link_hash_entry *) h)->oh = fh;
3537104834Sobrien	      ((struct ppc_link_hash_entry *) fh)->oh = h;
3538104834Sobrien	    }
3539104834Sobrien	}
354089857Sobrien      if (fh != NULL)
354189857Sobrien	_bfd_elf_link_hash_hide_symbol (info, fh, force_local);
354289857Sobrien    }
354389857Sobrien}
354489857Sobrien
3545104834Sobrienstatic boolean
3546104834Sobrienedit_opd (obfd, info)
3547104834Sobrien     bfd *obfd;
3548104834Sobrien     struct bfd_link_info *info;
3549104834Sobrien{
3550104834Sobrien  bfd *ibfd;
3551104834Sobrien  unsigned int bfd_indx;
3552104834Sobrien
3553104834Sobrien  for (bfd_indx = 0, ibfd = info->input_bfds;
3554104834Sobrien       ibfd != NULL;
3555104834Sobrien       ibfd = ibfd->link_next, bfd_indx++)
3556104834Sobrien    {
3557104834Sobrien      asection *sec;
3558104834Sobrien      Elf_Internal_Rela *relstart, *rel, *relend;
3559104834Sobrien      Elf_Internal_Shdr *symtab_hdr;
3560104834Sobrien      Elf_Internal_Sym *local_syms;
3561104834Sobrien      struct elf_link_hash_entry **sym_hashes;
3562104834Sobrien      bfd_vma offset;
3563104834Sobrien      long *adjust;
3564104834Sobrien      boolean need_edit;
3565104834Sobrien
3566104834Sobrien      sec = bfd_get_section_by_name (ibfd, ".opd");
3567104834Sobrien      if (sec == NULL)
3568104834Sobrien	continue;
3569104834Sobrien
3570104834Sobrien      adjust = (long *) elf_section_data (sec)->tdata;
3571104834Sobrien      BFD_ASSERT (adjust != NULL);
3572104834Sobrien      memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24);
3573104834Sobrien
3574104834Sobrien      if (sec->output_section == bfd_abs_section_ptr)
3575104834Sobrien	continue;
3576104834Sobrien
3577104834Sobrien      /* Look through the section relocs.  */
3578104834Sobrien      if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0)
3579104834Sobrien	continue;
3580104834Sobrien
3581104834Sobrien      local_syms = NULL;
3582104834Sobrien      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3583104834Sobrien      sym_hashes = elf_sym_hashes (ibfd);
3584104834Sobrien
3585104834Sobrien      /* Read the relocations.  */
3586104834Sobrien      relstart = _bfd_elf64_link_read_relocs (obfd, sec, (PTR) NULL,
3587104834Sobrien					      (Elf_Internal_Rela *) NULL,
3588104834Sobrien					      info->keep_memory);
3589104834Sobrien      if (relstart == NULL)
3590104834Sobrien	return false;
3591104834Sobrien
3592104834Sobrien      /* First run through the relocs to check they are sane, and to
3593104834Sobrien	 determine whether we need to edit this opd section.  */
3594104834Sobrien      need_edit = false;
3595104834Sobrien      offset = 0;
3596104834Sobrien      relend = relstart + sec->reloc_count;
3597104834Sobrien      for (rel = relstart; rel < relend; rel++)
3598104834Sobrien	{
3599104834Sobrien	  enum elf_ppc_reloc_type r_type;
3600104834Sobrien	  unsigned long r_symndx;
3601104834Sobrien	  asection *sym_sec;
3602104834Sobrien	  struct elf_link_hash_entry *h;
3603104834Sobrien	  Elf_Internal_Sym *sym;
3604104834Sobrien
3605104834Sobrien	  /* .opd contains a regular array of 24 byte entries.  We're
3606104834Sobrien	     only interested in the reloc pointing to a function entry
3607104834Sobrien	     point.  */
3608104834Sobrien	  r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info);
3609104834Sobrien	  if (r_type == R_PPC64_TOC)
3610104834Sobrien	    continue;
3611104834Sobrien
3612104834Sobrien	  if (r_type != R_PPC64_ADDR64)
3613104834Sobrien	    {
3614104834Sobrien	      (*_bfd_error_handler)
3615104834Sobrien		(_("%s: unexpected reloc type %u in .opd section"),
3616104834Sobrien		 bfd_archive_filename (ibfd), r_type);
3617104834Sobrien	      need_edit = false;
3618104834Sobrien	      break;
3619104834Sobrien	    }
3620104834Sobrien
3621104834Sobrien	  if (rel + 1 >= relend)
3622104834Sobrien	    continue;
3623104834Sobrien	  r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE ((rel + 1)->r_info);
3624104834Sobrien	  if (r_type != R_PPC64_TOC)
3625104834Sobrien	    continue;
3626104834Sobrien
3627104834Sobrien	  if (rel->r_offset != offset)
3628104834Sobrien	    {
3629104834Sobrien	      /* If someone messes with .opd alignment then after a
3630104834Sobrien		 "ld -r" we might have padding in the middle of .opd.
3631104834Sobrien		 Also, there's nothing to prevent someone putting
3632104834Sobrien		 something silly in .opd with the assembler.  No .opd
3633104834Sobrien		 optimization for them!  */
3634104834Sobrien	      (*_bfd_error_handler)
3635104834Sobrien		(_("%s: .opd is not a regular array of opd entries"),
3636104834Sobrien		 bfd_archive_filename (ibfd));
3637104834Sobrien	      need_edit = false;
3638104834Sobrien	      break;
3639104834Sobrien	    }
3640104834Sobrien
3641104834Sobrien	  r_symndx = ELF64_R_SYM (rel->r_info);
3642104834Sobrien	  sym_sec = NULL;
3643104834Sobrien	  h = NULL;
3644104834Sobrien	  sym = NULL;
3645104834Sobrien	  if (r_symndx >= symtab_hdr->sh_info)
3646104834Sobrien	    {
3647104834Sobrien	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3648104834Sobrien	      while (h->root.type == bfd_link_hash_indirect
3649104834Sobrien		     || h->root.type == bfd_link_hash_warning)
3650104834Sobrien		h = (struct elf_link_hash_entry *) h->root.u.i.link;
3651104834Sobrien	      if (h->root.type == bfd_link_hash_defined
3652104834Sobrien		  || h->root.type == bfd_link_hash_defweak)
3653104834Sobrien		sym_sec = h->root.u.def.section;
3654104834Sobrien	    }
3655104834Sobrien	  else
3656104834Sobrien	    {
3657104834Sobrien	      if (local_syms == NULL)
3658104834Sobrien		{
3659104834Sobrien		  local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
3660104834Sobrien		  if (local_syms == NULL)
3661104834Sobrien		    local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
3662104834Sobrien						       symtab_hdr->sh_info, 0,
3663104834Sobrien						       NULL, NULL, NULL);
3664104834Sobrien		  if (local_syms == NULL)
3665104834Sobrien		    goto error_free_rel;
3666104834Sobrien		}
3667104834Sobrien	      sym = local_syms + r_symndx;
3668104834Sobrien	      if ((sym->st_shndx != SHN_UNDEF
3669104834Sobrien		   && sym->st_shndx < SHN_LORESERVE)
3670104834Sobrien		  || sym->st_shndx > SHN_HIRESERVE)
3671104834Sobrien		sym_sec = bfd_section_from_elf_index (ibfd, sym->st_shndx);
3672104834Sobrien	    }
3673104834Sobrien
3674104834Sobrien	  if (sym_sec == NULL || sym_sec->owner == NULL)
3675104834Sobrien	    {
3676104834Sobrien	      (*_bfd_error_handler)
3677104834Sobrien		(_("%s: undefined sym `%s' in .opd section"),
3678104834Sobrien		 bfd_archive_filename (ibfd),
3679104834Sobrien		 h != NULL ? h->root.root.string : "<local symbol>");
3680104834Sobrien	      need_edit = false;
3681104834Sobrien	      break;
3682104834Sobrien	    }
3683104834Sobrien
3684104834Sobrien	  /* opd entries are always for functions defined in the
3685104834Sobrien	     current input bfd.  If the symbol isn't defined in the
3686104834Sobrien	     input bfd, then we won't be using the function in this
3687104834Sobrien	     bfd;  It must be defined in a linkonce section in another
3688104834Sobrien	     bfd, or is weak.  It's also possible that we are
3689104834Sobrien	     discarding the function due to a linker script /DISCARD/,
3690104834Sobrien	     which we test for via the output_section.  */
3691104834Sobrien	  if (sym_sec->owner != ibfd
3692104834Sobrien	      || sym_sec->output_section == bfd_abs_section_ptr)
3693104834Sobrien	    need_edit = true;
3694104834Sobrien
3695104834Sobrien	  offset += 24;
3696104834Sobrien	}
3697104834Sobrien
3698104834Sobrien      if (need_edit)
3699104834Sobrien	{
3700104834Sobrien	  Elf_Internal_Rela *write_rel;
3701104834Sobrien	  bfd_byte *rptr, *wptr;
3702104834Sobrien	  boolean skip;
3703104834Sobrien
3704104834Sobrien	  /* This seems a waste of time as input .opd sections are all
3705104834Sobrien	     zeros as generated by gcc, but I suppose there's no reason
3706104834Sobrien	     this will always be so.  We might start putting something in
3707104834Sobrien	     the third word of .opd entries.  */
3708104834Sobrien	  if ((sec->flags & SEC_IN_MEMORY) == 0)
3709104834Sobrien	    {
3710104834Sobrien	      bfd_byte *loc = bfd_alloc (ibfd, sec->_raw_size);
3711104834Sobrien	      if (loc == NULL
3712104834Sobrien		  || !bfd_get_section_contents (ibfd, sec, loc, (bfd_vma) 0,
3713104834Sobrien						sec->_raw_size))
3714104834Sobrien		{
3715104834Sobrien		  if (local_syms != NULL
3716104834Sobrien		      && symtab_hdr->contents != (unsigned char *) local_syms)
3717104834Sobrien		    free (local_syms);
3718104834Sobrien		error_free_rel:
3719104834Sobrien		  if (elf_section_data (sec)->relocs != relstart)
3720104834Sobrien		    free (relstart);
3721104834Sobrien		  return false;
3722104834Sobrien		}
3723104834Sobrien	      sec->contents = loc;
3724104834Sobrien	      sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
3725104834Sobrien	    }
3726104834Sobrien
3727104834Sobrien	  elf_section_data (sec)->relocs = relstart;
3728104834Sobrien
3729104834Sobrien	  wptr = sec->contents;
3730104834Sobrien	  rptr = sec->contents;
3731104834Sobrien	  write_rel = relstart;
3732104834Sobrien	  skip = false;
3733104834Sobrien	  offset = 0;
3734104834Sobrien	  for (rel = relstart; rel < relend; rel++)
3735104834Sobrien	    {
3736104834Sobrien	      if (rel->r_offset == offset)
3737104834Sobrien		{
3738104834Sobrien		  unsigned long r_symndx;
3739104834Sobrien		  asection *sym_sec;
3740104834Sobrien		  struct elf_link_hash_entry *h;
3741104834Sobrien		  Elf_Internal_Sym *sym;
3742104834Sobrien
3743104834Sobrien		  r_symndx = ELF64_R_SYM (rel->r_info);
3744104834Sobrien		  sym_sec = NULL;
3745104834Sobrien		  h = NULL;
3746104834Sobrien		  sym = NULL;
3747104834Sobrien		  if (r_symndx >= symtab_hdr->sh_info)
3748104834Sobrien		    {
3749104834Sobrien		      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3750104834Sobrien		      while (h->root.type == bfd_link_hash_indirect
3751104834Sobrien			     || h->root.type == bfd_link_hash_warning)
3752104834Sobrien			h = (struct elf_link_hash_entry *) h->root.u.i.link;
3753104834Sobrien		      if (h->root.type == bfd_link_hash_defined
3754104834Sobrien			  || h->root.type == bfd_link_hash_defweak)
3755104834Sobrien			sym_sec = h->root.u.def.section;
3756104834Sobrien		    }
3757104834Sobrien		  else
3758104834Sobrien		    {
3759104834Sobrien		      sym = local_syms + r_symndx;
3760104834Sobrien		      if ((sym->st_shndx != SHN_UNDEF
3761104834Sobrien			   && sym->st_shndx < SHN_LORESERVE)
3762104834Sobrien			  || sym->st_shndx > SHN_HIRESERVE)
3763104834Sobrien			sym_sec = bfd_section_from_elf_index (ibfd,
3764104834Sobrien							      sym->st_shndx);
3765104834Sobrien		    }
3766104834Sobrien
3767104834Sobrien		  skip = (sym_sec->owner != ibfd
3768104834Sobrien			  || sym_sec->output_section == bfd_abs_section_ptr);
3769104834Sobrien		  if (skip)
3770104834Sobrien		    {
3771104834Sobrien		      if (h != NULL && sym_sec->owner == ibfd)
3772104834Sobrien			{
3773104834Sobrien			  /* Arrange for the function descriptor sym
3774104834Sobrien			     to be dropped.  */
3775104834Sobrien			  struct elf_link_hash_entry *fdh;
3776104834Sobrien			  struct ppc_link_hash_entry *fh;
3777104834Sobrien
3778104834Sobrien			  fh = (struct ppc_link_hash_entry *) h;
3779104834Sobrien			  BFD_ASSERT (fh->is_func);
3780104834Sobrien			  fdh = fh->oh;
3781104834Sobrien			  fdh->root.u.def.value = 0;
3782104834Sobrien			  fdh->root.u.def.section = sym_sec;
3783104834Sobrien			}
3784104834Sobrien		    }
3785104834Sobrien		  else
3786104834Sobrien		    {
3787104834Sobrien		      /* We'll be keeping this opd entry.  */
3788104834Sobrien
3789104834Sobrien		      if (h != NULL)
3790104834Sobrien			{
3791104834Sobrien			  /* Redefine the function descriptor symbol
3792104834Sobrien			     to this location in the opd section.
3793104834Sobrien			     We've checked above that opd relocs are
3794104834Sobrien			     ordered.  */
3795104834Sobrien			  struct elf_link_hash_entry *fdh;
3796104834Sobrien			  struct ppc_link_hash_entry *fh;
3797104834Sobrien
3798104834Sobrien			  fh = (struct ppc_link_hash_entry *) h;
3799104834Sobrien			  BFD_ASSERT (fh->is_func);
3800104834Sobrien			  fdh = fh->oh;
3801104834Sobrien			  fdh->root.u.def.value = wptr - sec->contents;
3802104834Sobrien			}
3803104834Sobrien		      else
3804104834Sobrien			{
3805104834Sobrien			  /* Local syms are a bit tricky.  We could
3806104834Sobrien			     tweak them as they can be cached, but
3807104834Sobrien			     we'd need to look through the local syms
3808104834Sobrien			     for the function descriptor sym which we
3809104834Sobrien			     don't have at the moment.  So keep an
3810104834Sobrien			     array of adjustments.  */
3811107492Sobrien			  adjust[rel->r_offset / 24] = wptr - rptr;
3812104834Sobrien			}
3813104834Sobrien
3814104834Sobrien		      if (wptr != rptr)
3815104834Sobrien			memcpy (wptr, rptr, 24);
3816104834Sobrien		      wptr += 24;
3817104834Sobrien		    }
3818104834Sobrien		  rptr += 24;
3819104834Sobrien		  offset += 24;
3820104834Sobrien		}
3821104834Sobrien
3822104834Sobrien	      /* We need to adjust any reloc offsets to point to the
3823104834Sobrien		 new opd entries.  While we're at it, we may as well
3824104834Sobrien		 remove redundant relocs.  */
3825104834Sobrien	      if (!skip)
3826104834Sobrien		{
3827104834Sobrien		  rel->r_offset += wptr - rptr;
3828104834Sobrien		  if (write_rel != rel)
3829104834Sobrien		    memcpy (write_rel, rel, sizeof (*rel));
3830104834Sobrien		  ++write_rel;
3831104834Sobrien		}
3832104834Sobrien	    }
3833104834Sobrien
3834104834Sobrien	  sec->_cooked_size = wptr - sec->contents;
3835104834Sobrien	  sec->reloc_count = write_rel - relstart;
3836104834Sobrien	}
3837104834Sobrien      else if (elf_section_data (sec)->relocs != relstart)
3838104834Sobrien	free (relstart);
3839104834Sobrien
3840104834Sobrien      if (local_syms != NULL
3841104834Sobrien	  && symtab_hdr->contents != (unsigned char *) local_syms)
3842104834Sobrien	{
3843104834Sobrien	  if (!info->keep_memory)
3844104834Sobrien	    free (local_syms);
3845104834Sobrien	  else
3846104834Sobrien	    symtab_hdr->contents = (unsigned char *) local_syms;
3847104834Sobrien	}
3848104834Sobrien    }
3849104834Sobrien
3850104834Sobrien  return true;
3851104834Sobrien}
3852104834Sobrien
385389857Sobrien/* This is the condition under which ppc64_elf_finish_dynamic_symbol
385489857Sobrien   will be called from elflink.h.  If elflink.h doesn't call our
385589857Sobrien   finish_dynamic_symbol routine, we'll need to do something about
385689857Sobrien   initializing any .plt and .got entries in ppc64_elf_relocate_section.  */
385789857Sobrien#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \
385889857Sobrien  ((DYN)								\
385989857Sobrien   && ((INFO)->shared							\
386089857Sobrien       || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)	\
386189857Sobrien   && ((H)->dynindx != -1						\
386289857Sobrien       || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
386389857Sobrien
386489857Sobrien/* Allocate space in .plt, .got and associated reloc sections for
386589857Sobrien   dynamic relocs.  */
386689857Sobrien
386789857Sobrienstatic boolean
386889857Sobrienallocate_dynrelocs (h, inf)
386989857Sobrien     struct elf_link_hash_entry *h;
387089857Sobrien     PTR inf;
387189857Sobrien{
387289857Sobrien  struct bfd_link_info *info;
387389857Sobrien  struct ppc_link_hash_table *htab;
387489857Sobrien  asection *s;
387589857Sobrien  struct ppc_link_hash_entry *eh;
387689857Sobrien  struct ppc_dyn_relocs *p;
387789857Sobrien
387894536Sobrien  if (h->root.type == bfd_link_hash_indirect)
387989857Sobrien    return true;
388089857Sobrien
388194536Sobrien  if (h->root.type == bfd_link_hash_warning)
388294536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
388394536Sobrien
388489857Sobrien  info = (struct bfd_link_info *) inf;
388589857Sobrien  htab = ppc_hash_table (info);
388689857Sobrien
388789857Sobrien  if (htab->elf.dynamic_sections_created
388889857Sobrien      && h->plt.refcount > 0
388989857Sobrien      && h->dynindx != -1)
389089857Sobrien    {
389189857Sobrien      BFD_ASSERT (((struct ppc_link_hash_entry *) h)->is_func_descriptor);
389289857Sobrien
389389857Sobrien      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
389489857Sobrien	{
389589857Sobrien	  /* If this is the first .plt entry, make room for the special
389689857Sobrien	     first entry.  */
389789857Sobrien	  s = htab->splt;
389889857Sobrien	  if (s->_raw_size == 0)
389989857Sobrien	    s->_raw_size += PLT_INITIAL_ENTRY_SIZE;
390089857Sobrien
390189857Sobrien	  h->plt.offset = s->_raw_size;
390289857Sobrien
390389857Sobrien	  /* Make room for this entry.  */
390489857Sobrien	  s->_raw_size += PLT_ENTRY_SIZE;
390589857Sobrien
3906104834Sobrien	  /* Make room for the .glink code.  */
390789857Sobrien	  s = htab->sglink;
390889857Sobrien	  if (s->_raw_size == 0)
390989857Sobrien	    s->_raw_size += GLINK_CALL_STUB_SIZE;
391089857Sobrien	  /* We need bigger stubs past index 32767.  */
391189857Sobrien	  if (s->_raw_size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
391289857Sobrien	    s->_raw_size += 4;
391389857Sobrien	  s->_raw_size += 2*4;
391489857Sobrien
391589857Sobrien	  /* We also need to make an entry in the .rela.plt section.  */
391689857Sobrien	  s = htab->srelplt;
391789857Sobrien	  s->_raw_size += sizeof (Elf64_External_Rela);
391889857Sobrien	}
391989857Sobrien      else
392089857Sobrien	{
392189857Sobrien	  h->plt.offset = (bfd_vma) -1;
392289857Sobrien	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
392389857Sobrien	}
392489857Sobrien    }
392589857Sobrien  else
392689857Sobrien    {
392789857Sobrien      h->plt.offset = (bfd_vma) -1;
392889857Sobrien      h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
392989857Sobrien    }
393089857Sobrien
393189857Sobrien  if (h->got.refcount > 0)
393289857Sobrien    {
393389857Sobrien      boolean dyn;
393489857Sobrien
393589857Sobrien      /* Make sure this symbol is output as a dynamic symbol.
393689857Sobrien	 Undefined weak syms won't yet be marked as dynamic.  */
393789857Sobrien      if (h->dynindx == -1
393889857Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
393989857Sobrien	{
394089857Sobrien	  if (! bfd_elf64_link_record_dynamic_symbol (info, h))
394189857Sobrien	    return false;
394289857Sobrien	}
394389857Sobrien
394489857Sobrien      s = htab->sgot;
394589857Sobrien      h->got.offset = s->_raw_size;
394689857Sobrien      s->_raw_size += 8;
394789857Sobrien      dyn = htab->elf.dynamic_sections_created;
394889857Sobrien      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
394989857Sobrien	htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
395089857Sobrien    }
395189857Sobrien  else
395289857Sobrien    h->got.offset = (bfd_vma) -1;
395389857Sobrien
395489857Sobrien  eh = (struct ppc_link_hash_entry *) h;
395589857Sobrien  if (eh->dyn_relocs == NULL)
395689857Sobrien    return true;
395789857Sobrien
395889857Sobrien  /* In the shared -Bsymbolic case, discard space allocated for
395989857Sobrien     dynamic pc-relative relocs against symbols which turn out to be
396089857Sobrien     defined in regular objects.  For the normal shared case, discard
396189857Sobrien     space for relocs that have become local due to symbol visibility
396289857Sobrien     changes.  */
396389857Sobrien
396489857Sobrien  if (info->shared)
396589857Sobrien    {
396689857Sobrien      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
396789857Sobrien	  && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
396889857Sobrien	      || info->symbolic))
396989857Sobrien	{
397089857Sobrien	  struct ppc_dyn_relocs **pp;
397189857Sobrien
397289857Sobrien	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
397389857Sobrien	    {
397489857Sobrien	      p->count -= p->pc_count;
397589857Sobrien	      p->pc_count = 0;
397689857Sobrien	      if (p->count == 0)
397789857Sobrien		*pp = p->next;
397889857Sobrien	      else
397989857Sobrien		pp = &p->next;
398089857Sobrien	    }
398189857Sobrien	}
398289857Sobrien    }
398389857Sobrien  else
398489857Sobrien    {
398589857Sobrien      /* For the non-shared case, discard space for relocs against
398689857Sobrien	 symbols which turn out to need copy relocs or are not
398789857Sobrien	 dynamic.  */
398889857Sobrien
398989857Sobrien      if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
399089857Sobrien	  && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
399189857Sobrien	       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
399289857Sobrien	      || (htab->elf.dynamic_sections_created
399389857Sobrien		  && (h->root.type == bfd_link_hash_undefweak
399489857Sobrien		      || h->root.type == bfd_link_hash_undefined))))
399589857Sobrien	{
399689857Sobrien	  /* Make sure this symbol is output as a dynamic symbol.
399789857Sobrien	     Undefined weak syms won't yet be marked as dynamic.  */
399889857Sobrien	  if (h->dynindx == -1
399989857Sobrien	      && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
400089857Sobrien	    {
400189857Sobrien	      if (! bfd_elf64_link_record_dynamic_symbol (info, h))
400289857Sobrien		return false;
400389857Sobrien	    }
400489857Sobrien
400589857Sobrien	  /* If that succeeded, we know we'll be keeping all the
400689857Sobrien	     relocs.  */
400789857Sobrien	  if (h->dynindx != -1)
400889857Sobrien	    goto keep;
400989857Sobrien	}
401089857Sobrien
401189857Sobrien      eh->dyn_relocs = NULL;
401289857Sobrien
401389857Sobrien    keep: ;
401489857Sobrien    }
401589857Sobrien
401689857Sobrien  /* Finally, allocate space.  */
401789857Sobrien  for (p = eh->dyn_relocs; p != NULL; p = p->next)
401889857Sobrien    {
401989857Sobrien      asection *sreloc = elf_section_data (p->sec)->sreloc;
402089857Sobrien      sreloc->_raw_size += p->count * sizeof (Elf64_External_Rela);
402189857Sobrien    }
402289857Sobrien
402389857Sobrien  return true;
402489857Sobrien}
402589857Sobrien
402689857Sobrien/* Find any dynamic relocs that apply to read-only sections.  */
402789857Sobrien
402889857Sobrienstatic boolean
402989857Sobrienreadonly_dynrelocs (h, inf)
403089857Sobrien     struct elf_link_hash_entry *h;
403189857Sobrien     PTR inf;
403289857Sobrien{
403389857Sobrien  struct ppc_link_hash_entry *eh;
403489857Sobrien  struct ppc_dyn_relocs *p;
403589857Sobrien
403694536Sobrien  if (h->root.type == bfd_link_hash_warning)
403794536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
403894536Sobrien
403989857Sobrien  eh = (struct ppc_link_hash_entry *) h;
404089857Sobrien  for (p = eh->dyn_relocs; p != NULL; p = p->next)
404189857Sobrien    {
404289857Sobrien      asection *s = p->sec->output_section;
404389857Sobrien
404489857Sobrien      if (s != NULL && (s->flags & SEC_READONLY) != 0)
404589857Sobrien	{
404689857Sobrien	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
404789857Sobrien
404889857Sobrien	  info->flags |= DF_TEXTREL;
404989857Sobrien
405089857Sobrien	  /* Not an error, just cut short the traversal.  */
405189857Sobrien	  return false;
405289857Sobrien	}
405389857Sobrien    }
405489857Sobrien  return true;
405589857Sobrien}
405689857Sobrien
405789857Sobrien/* Set the sizes of the dynamic sections.  */
405889857Sobrien
405989857Sobrienstatic boolean
406089857Sobrienppc64_elf_size_dynamic_sections (output_bfd, info)
406189857Sobrien     bfd *output_bfd ATTRIBUTE_UNUSED;
406289857Sobrien     struct bfd_link_info *info;
406389857Sobrien{
406489857Sobrien  struct ppc_link_hash_table *htab;
406589857Sobrien  bfd *dynobj;
406689857Sobrien  asection *s;
406789857Sobrien  boolean relocs;
406889857Sobrien  bfd *ibfd;
406989857Sobrien
407089857Sobrien  htab = ppc_hash_table (info);
407189857Sobrien  dynobj = htab->elf.dynobj;
407289857Sobrien  if (dynobj == NULL)
407389857Sobrien    abort ();
407489857Sobrien
407589857Sobrien  if (htab->elf.dynamic_sections_created)
407689857Sobrien    {
407789857Sobrien      /* Set the contents of the .interp section to the interpreter.  */
407889857Sobrien      if (! info->shared)
407989857Sobrien	{
408089857Sobrien	  s = bfd_get_section_by_name (dynobj, ".interp");
408189857Sobrien	  if (s == NULL)
408289857Sobrien	    abort ();
408389857Sobrien	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
408489857Sobrien	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
408589857Sobrien	}
408689857Sobrien    }
408789857Sobrien
408889857Sobrien  /* Set up .got offsets for local syms, and space for local dynamic
408989857Sobrien     relocs.  */
409089857Sobrien  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
409189857Sobrien    {
409289857Sobrien      bfd_signed_vma *local_got;
409389857Sobrien      bfd_signed_vma *end_local_got;
409489857Sobrien      bfd_size_type locsymcount;
409589857Sobrien      Elf_Internal_Shdr *symtab_hdr;
409689857Sobrien      asection *srel;
409789857Sobrien
409889857Sobrien      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
409989857Sobrien	continue;
410089857Sobrien
410189857Sobrien      for (s = ibfd->sections; s != NULL; s = s->next)
410289857Sobrien	{
410389857Sobrien	  struct ppc_dyn_relocs *p;
410489857Sobrien
410589857Sobrien	  for (p = *((struct ppc_dyn_relocs **)
410689857Sobrien		     &elf_section_data (s)->local_dynrel);
410789857Sobrien	       p != NULL;
410889857Sobrien	       p = p->next)
410989857Sobrien	    {
411089857Sobrien	      if (!bfd_is_abs_section (p->sec)
411189857Sobrien		  && bfd_is_abs_section (p->sec->output_section))
411289857Sobrien		{
411389857Sobrien		  /* Input section has been discarded, either because
411489857Sobrien		     it is a copy of a linkonce section or due to
411589857Sobrien		     linker script /DISCARD/, so we'll be discarding
411689857Sobrien		     the relocs too.  */
411789857Sobrien		}
411891041Sobrien	      else if (p->count != 0)
411989857Sobrien		{
412089857Sobrien		  srel = elf_section_data (p->sec)->sreloc;
412189857Sobrien		  srel->_raw_size += p->count * sizeof (Elf64_External_Rela);
412291041Sobrien		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
412391041Sobrien		    info->flags |= DF_TEXTREL;
412489857Sobrien		}
412589857Sobrien	    }
412689857Sobrien	}
412789857Sobrien
412889857Sobrien      local_got = elf_local_got_refcounts (ibfd);
412989857Sobrien      if (!local_got)
413089857Sobrien	continue;
413189857Sobrien
413289857Sobrien      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
413389857Sobrien      locsymcount = symtab_hdr->sh_info;
413489857Sobrien      end_local_got = local_got + locsymcount;
413589857Sobrien      s = htab->sgot;
413689857Sobrien      srel = htab->srelgot;
413789857Sobrien      for (; local_got < end_local_got; ++local_got)
413889857Sobrien	{
413989857Sobrien	  if (*local_got > 0)
414089857Sobrien	    {
414189857Sobrien	      *local_got = s->_raw_size;
414289857Sobrien	      s->_raw_size += 8;
414389857Sobrien	      if (info->shared)
414489857Sobrien		srel->_raw_size += sizeof (Elf64_External_Rela);
414589857Sobrien	    }
414689857Sobrien	  else
414789857Sobrien	    *local_got = (bfd_vma) -1;
414889857Sobrien	}
414989857Sobrien    }
415089857Sobrien
4151104834Sobrien  if (!edit_opd (output_bfd, info))
4152104834Sobrien    return false;
4153104834Sobrien
415489857Sobrien  /* Allocate global sym .plt and .got entries, and space for global
415589857Sobrien     sym dynamic relocs.  */
415689857Sobrien  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
415789857Sobrien
415889857Sobrien  /* We now have determined the sizes of the various dynamic sections.
415989857Sobrien     Allocate memory for them.  */
416089857Sobrien  relocs = false;
416189857Sobrien  for (s = dynobj->sections; s != NULL; s = s->next)
416289857Sobrien    {
416389857Sobrien      if ((s->flags & SEC_LINKER_CREATED) == 0)
416489857Sobrien	continue;
416589857Sobrien
4166104834Sobrien      if (s == htab->sbrlt || s == htab->srelbrlt)
4167104834Sobrien	/* These haven't been allocated yet;  don't strip.  */
4168104834Sobrien	continue;
4169104834Sobrien      else if (s == htab->splt
4170104834Sobrien	       || s == htab->sgot
4171104834Sobrien	       || s == htab->sglink)
417289857Sobrien	{
417389857Sobrien	  /* Strip this section if we don't need it; see the
417489857Sobrien	     comment below.  */
417589857Sobrien	}
417689857Sobrien      else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
417789857Sobrien	{
417889857Sobrien	  if (s->_raw_size == 0)
417989857Sobrien	    {
418089857Sobrien	      /* If we don't need this section, strip it from the
418189857Sobrien		 output file.  This is mostly to handle .rela.bss and
418289857Sobrien		 .rela.plt.  We must create both sections in
418389857Sobrien		 create_dynamic_sections, because they must be created
418489857Sobrien		 before the linker maps input sections to output
418589857Sobrien		 sections.  The linker does that before
418689857Sobrien		 adjust_dynamic_symbol is called, and it is that
418789857Sobrien		 function which decides whether anything needs to go
418889857Sobrien		 into these sections.  */
418989857Sobrien	    }
419089857Sobrien	  else
419189857Sobrien	    {
419289857Sobrien	      if (s != htab->srelplt)
419389857Sobrien		relocs = true;
419489857Sobrien
419589857Sobrien	      /* We use the reloc_count field as a counter if we need
419689857Sobrien		 to copy relocs into the output file.  */
419789857Sobrien	      s->reloc_count = 0;
419889857Sobrien	    }
419989857Sobrien	}
420089857Sobrien      else
420189857Sobrien	{
420289857Sobrien	  /* It's not one of our sections, so don't allocate space.  */
420389857Sobrien	  continue;
420489857Sobrien	}
420589857Sobrien
420689857Sobrien      if (s->_raw_size == 0)
420789857Sobrien	{
420889857Sobrien	  _bfd_strip_section_from_output (info, s);
420989857Sobrien	  continue;
421089857Sobrien	}
421189857Sobrien
4212104834Sobrien      /* .plt is in the bss section.  We don't initialise it.  */
4213104834Sobrien      if ((s->flags & SEC_LOAD) == 0)
4214104834Sobrien	continue;
4215104834Sobrien
421689857Sobrien      /* Allocate memory for the section contents.  We use bfd_zalloc
421789857Sobrien	 here in case unused entries are not reclaimed before the
421889857Sobrien	 section's contents are written out.  This should not happen,
421989857Sobrien	 but this way if it does, we get a R_PPC64_NONE reloc instead
422089857Sobrien	 of garbage.  */
4221104834Sobrien      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
422289857Sobrien      if (s->contents == NULL)
422389857Sobrien	return false;
422489857Sobrien    }
422589857Sobrien
422689857Sobrien  if (htab->elf.dynamic_sections_created)
422789857Sobrien    {
422889857Sobrien      /* Add some entries to the .dynamic section.  We fill in the
422989857Sobrien	 values later, in ppc64_elf_finish_dynamic_sections, but we
423089857Sobrien	 must add the entries now so that we get the correct size for
423189857Sobrien	 the .dynamic section.  The DT_DEBUG entry is filled in by the
423289857Sobrien	 dynamic linker and used by the debugger.  */
423389857Sobrien#define add_dynamic_entry(TAG, VAL) \
423489857Sobrien  bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
423589857Sobrien
423689857Sobrien      if (!info->shared)
423789857Sobrien	{
423889857Sobrien	  if (!add_dynamic_entry (DT_DEBUG, 0))
423989857Sobrien	    return false;
424089857Sobrien	}
424189857Sobrien
4242104834Sobrien      if (htab->splt != NULL && htab->splt->_raw_size != 0)
424389857Sobrien	{
424489857Sobrien	  if (!add_dynamic_entry (DT_PLTGOT, 0)
424589857Sobrien	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
424689857Sobrien	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
424789857Sobrien	      || !add_dynamic_entry (DT_JMPREL, 0)
424889857Sobrien	      || !add_dynamic_entry (DT_PPC64_GLINK, 0))
424989857Sobrien	    return false;
425089857Sobrien	}
425189857Sobrien
425291041Sobrien      if (NO_OPD_RELOCS)
425391041Sobrien	{
425491041Sobrien	  if (!add_dynamic_entry (DT_PPC64_OPD, 0)
425591041Sobrien	      || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
425691041Sobrien	    return false;
425791041Sobrien	}
425891041Sobrien
425989857Sobrien      if (relocs)
426089857Sobrien	{
426189857Sobrien	  if (!add_dynamic_entry (DT_RELA, 0)
426289857Sobrien	      || !add_dynamic_entry (DT_RELASZ, 0)
426389857Sobrien	      || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
426489857Sobrien	    return false;
426589857Sobrien
426689857Sobrien	  /* If any dynamic relocs apply to a read-only section,
426789857Sobrien	     then we need a DT_TEXTREL entry.  */
426891041Sobrien	  if ((info->flags & DF_TEXTREL) == 0)
426991041Sobrien	    elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
427091041Sobrien				    (PTR) info);
427189857Sobrien
427289857Sobrien	  if ((info->flags & DF_TEXTREL) != 0)
427389857Sobrien	    {
427489857Sobrien	      if (!add_dynamic_entry (DT_TEXTREL, 0))
427589857Sobrien		return false;
427689857Sobrien	    }
427789857Sobrien	}
427889857Sobrien    }
427989857Sobrien#undef add_dynamic_entry
428089857Sobrien
428189857Sobrien  return true;
428289857Sobrien}
428389857Sobrien
4284104834Sobrien/* Determine the type of stub needed, if any, for a call.  */
428589857Sobrien
4286104834Sobrienstatic INLINE enum ppc_stub_type
4287104834Sobrienppc_type_of_stub (input_sec, rel, hash, destination)
4288104834Sobrien     asection *input_sec;
4289104834Sobrien     const Elf_Internal_Rela *rel;
4290104834Sobrien     struct ppc_link_hash_entry **hash;
4291104834Sobrien     bfd_vma destination;
429289857Sobrien{
4293104834Sobrien  struct ppc_link_hash_entry *h = *hash;
4294104834Sobrien  bfd_vma location;
4295104834Sobrien  bfd_vma branch_offset;
4296104834Sobrien  bfd_vma max_branch_offset;
4297104834Sobrien  unsigned int r_type;
429899461Sobrien
4299104834Sobrien  if (h != NULL)
430089857Sobrien    {
4301104834Sobrien      if (h->oh != NULL
4302104834Sobrien	  && h->oh->plt.offset != (bfd_vma) -1
4303104834Sobrien	  && h->oh->dynindx != -1)
4304104834Sobrien	{
4305104834Sobrien	  *hash = (struct ppc_link_hash_entry *) h->oh;
4306104834Sobrien	  return ppc_stub_plt_call;
4307104834Sobrien	}
430889857Sobrien
4309104834Sobrien      if (h->elf.root.type == bfd_link_hash_undefweak
4310104834Sobrien	  || h->elf.root.type == bfd_link_hash_undefined)
4311104834Sobrien	return ppc_stub_none;
431299461Sobrien    }
431389857Sobrien
4314104834Sobrien  /* Determine where the call point is.  */
4315104834Sobrien  location = (input_sec->output_offset
4316104834Sobrien	      + input_sec->output_section->vma
4317104834Sobrien	      + rel->r_offset);
431889857Sobrien
4319104834Sobrien  branch_offset = destination - location;
4320104834Sobrien  r_type = ELF64_R_TYPE (rel->r_info);
432189857Sobrien
4322104834Sobrien  /* Determine if a long branch stub is needed.  */
4323104834Sobrien  max_branch_offset = 1 << 25;
4324104834Sobrien  if (r_type != (unsigned int) R_PPC64_REL24)
4325104834Sobrien    max_branch_offset = 1 << 15;
432689857Sobrien
4327104834Sobrien  if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
4328104834Sobrien    /* We need a stub.  Figure out whether a long_branch or plt_branch
4329104834Sobrien       is needed later.  */
4330104834Sobrien    return ppc_stub_long_branch;
433189857Sobrien
4332104834Sobrien  return ppc_stub_none;
433389857Sobrien}
433489857Sobrien
433589857Sobrien/* Build a .plt call stub.  */
433689857Sobrien
433789857Sobrienstatic bfd_byte *
433889857Sobrienbuild_plt_stub (obfd, p, offset, glink)
433989857Sobrien     bfd *obfd;
434089857Sobrien     bfd_byte *p;
434189857Sobrien     int offset;
434289857Sobrien     int glink;
434389857Sobrien{
434489857Sobrien#define PPC_LO(v) ((v) & 0xffff)
434589857Sobrien#define PPC_HI(v) (((v) >> 16) & 0xffff)
434689857Sobrien#define PPC_HA(v) PPC_HI ((v) + 0x8000)
434789857Sobrien
434889857Sobrien  if (glink)
434989857Sobrien    bfd_put_32 (obfd, LD_R2_40R1, p),			p += 4;
435089857Sobrien  bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),	p += 4;
435189857Sobrien  if (!glink)
435289857Sobrien    bfd_put_32 (obfd, STD_R2_40R1, p),			p += 4;
435389857Sobrien  bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),	p += 4;
435489857Sobrien  if (PPC_HA (offset + 8) != PPC_HA (offset))
435589857Sobrien    bfd_put_32 (obfd, ADDIS_R12_R12_1, p),		p += 4;
435689857Sobrien  offset += 8;
435789857Sobrien  bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset), p),	p += 4;
435889857Sobrien  if (PPC_HA (offset + 8) != PPC_HA (offset))
435989857Sobrien    bfd_put_32 (obfd, ADDIS_R12_R12_1, p),		p += 4;
436089857Sobrien  offset += 8;
436189857Sobrien  bfd_put_32 (obfd, MTCTR_R11, p),			p += 4;
436289857Sobrien  bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),	p += 4;
436389857Sobrien  bfd_put_32 (obfd, BCTR, p),				p += 4;
436489857Sobrien  return p;
436589857Sobrien}
436689857Sobrien
436789857Sobrienstatic boolean
4368104834Sobrienppc_build_one_stub (gen_entry, in_arg)
4369104834Sobrien     struct bfd_hash_entry *gen_entry;
4370104834Sobrien     PTR in_arg;
437189857Sobrien{
4372104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
4373104834Sobrien  struct ppc_branch_hash_entry *br_entry;
437489857Sobrien  struct bfd_link_info *info;
437589857Sobrien  struct ppc_link_hash_table *htab;
4376104834Sobrien  asection *stub_sec;
4377104834Sobrien  bfd *stub_bfd;
4378104834Sobrien  bfd_byte *loc;
4379104834Sobrien  bfd_byte *p;
4380104834Sobrien  unsigned int indx;
4381104834Sobrien  bfd_vma off;
4382104834Sobrien  int size;
438389857Sobrien
4384104834Sobrien  /* Massage our args to the form they really have.  */
4385104834Sobrien  stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
4386104834Sobrien  info = (struct bfd_link_info *) in_arg;
438789857Sobrien
438889857Sobrien  htab = ppc_hash_table (info);
4389104834Sobrien  stub_sec = stub_entry->stub_sec;
439089857Sobrien
4391104834Sobrien  /* Make a note of the offset within the stubs for this entry.  */
4392104834Sobrien  stub_entry->stub_offset = stub_sec->_cooked_size;
4393104834Sobrien  loc = stub_sec->contents + stub_entry->stub_offset;
4394104834Sobrien
4395104834Sobrien  stub_bfd = stub_sec->owner;
4396104834Sobrien
4397104834Sobrien  switch (stub_entry->stub_type)
439889857Sobrien    {
4399104834Sobrien    case ppc_stub_long_branch:
4400104834Sobrien      /* Branches are relative.  This is where we are going to.  */
4401104834Sobrien      off = (stub_entry->target_value
4402104834Sobrien	     + stub_entry->target_section->output_offset
4403104834Sobrien	     + stub_entry->target_section->output_section->vma);
440489857Sobrien
4405104834Sobrien      /* And this is where we are coming from.  */
4406104834Sobrien      off -= (stub_entry->stub_offset
4407104834Sobrien	      + stub_sec->output_offset
4408104834Sobrien	      + stub_sec->output_section->vma);
440989857Sobrien
4410104834Sobrien      BFD_ASSERT (off + (1 << 25) < (bfd_vma) (1 << 26));
441189857Sobrien
4412104834Sobrien      bfd_put_32 (stub_bfd, (bfd_vma) B_DOT | (off & 0x3fffffc), loc);
4413104834Sobrien      size = 4;
4414104834Sobrien      break;
441589857Sobrien
4416104834Sobrien    case ppc_stub_plt_branch:
4417104834Sobrien      br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
4418104834Sobrien					 stub_entry->root.string + 9,
4419104834Sobrien					 false, false);
4420104834Sobrien      if (br_entry == NULL)
4421104834Sobrien	{
4422104834Sobrien	  (*_bfd_error_handler) (_("can't find branch stub `%s'"),
4423104834Sobrien				 stub_entry->root.string + 9);
4424104834Sobrien	  htab->stub_error = true;
4425104834Sobrien	  return false;
4426104834Sobrien	}
442789857Sobrien
4428104834Sobrien      off = (stub_entry->target_value
4429104834Sobrien	     + stub_entry->target_section->output_offset
4430104834Sobrien	     + stub_entry->target_section->output_section->vma);
4431104834Sobrien
4432104834Sobrien      bfd_put_64 (htab->sbrlt->owner, off,
4433104834Sobrien		  htab->sbrlt->contents + br_entry->offset);
4434104834Sobrien
4435104834Sobrien      if (info->shared)
443689857Sobrien	{
4437104834Sobrien	  /* Create a reloc for the branch lookup table entry.  */
4438104834Sobrien	  Elf_Internal_Rela rela;
4439104834Sobrien	  Elf64_External_Rela *r;
4440104834Sobrien
4441104834Sobrien	  rela.r_offset = (br_entry->offset
4442104834Sobrien			   + htab->sbrlt->output_offset
4443104834Sobrien			   + htab->sbrlt->output_section->vma);
4444104834Sobrien	  rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
4445104834Sobrien	  rela.r_addend = off;
4446104834Sobrien
4447104834Sobrien	  r = (Elf64_External_Rela *) htab->srelbrlt->contents;
4448104834Sobrien	  r += htab->srelbrlt->reloc_count++;
4449104834Sobrien	  bfd_elf64_swap_reloca_out (htab->srelbrlt->owner, &rela, r);
4450104834Sobrien	}
4451104834Sobrien
4452104834Sobrien      off = (br_entry->offset
4453104834Sobrien	     + htab->sbrlt->output_offset
4454104834Sobrien	     + htab->sbrlt->output_section->vma
4455104834Sobrien	     - elf_gp (htab->sbrlt->output_section->owner)
4456104834Sobrien	     - TOC_BASE_OFF);
4457104834Sobrien
4458104834Sobrien      if (off + 0x80000000 > 0xffffffff || (off & 7) != 0)
4459104834Sobrien	{
446089857Sobrien	  (*_bfd_error_handler)
446189857Sobrien	    (_("linkage table error against `%s'"),
4462104834Sobrien	     stub_entry->root.string);
446389857Sobrien	  bfd_set_error (bfd_error_bad_value);
4464104834Sobrien	  htab->stub_error = true;
446589857Sobrien	  return false;
446689857Sobrien	}
446789857Sobrien
4468104834Sobrien      indx = off;
4469104834Sobrien      bfd_put_32 (stub_bfd, (bfd_vma) ADDIS_R12_R2 | PPC_HA (indx), loc);
4470104834Sobrien      bfd_put_32 (stub_bfd, (bfd_vma) LD_R11_0R12 | PPC_LO (indx), loc + 4);
4471104834Sobrien      bfd_put_32 (stub_bfd, (bfd_vma) MTCTR_R11, loc + 8);
4472104834Sobrien      bfd_put_32 (stub_bfd, (bfd_vma) BCTR, loc + 12);
4473104834Sobrien      size = 16;
4474104834Sobrien      break;
447589857Sobrien
4476104834Sobrien    case ppc_stub_plt_call:
4477104834Sobrien      /* Do the best we can for shared libraries built without
4478104834Sobrien	 exporting ".foo" for each "foo".  This can happen when symbol
4479104834Sobrien	 versioning scripts strip all bar a subset of symbols.  */
4480104834Sobrien      if (stub_entry->h->oh->root.type != bfd_link_hash_defined
4481104834Sobrien	  && stub_entry->h->oh->root.type != bfd_link_hash_defweak)
448289857Sobrien	{
4483104834Sobrien	  /* Point the symbol at the stub.  There may be multiple stubs,
4484104834Sobrien	     we don't really care;  The main thing is to make this sym
4485104834Sobrien	     defined somewhere.  */
4486104834Sobrien	  stub_entry->h->oh->root.type = bfd_link_hash_defined;
4487104834Sobrien	  stub_entry->h->oh->root.u.def.section = stub_entry->stub_sec;
4488104834Sobrien	  stub_entry->h->oh->root.u.def.value = stub_entry->stub_offset;
448989857Sobrien	}
4490104834Sobrien
4491104834Sobrien      /* Now build the stub.  */
4492104834Sobrien      off = stub_entry->h->elf.plt.offset;
4493104834Sobrien      if (off >= (bfd_vma) -2)
4494104834Sobrien	abort ();
4495104834Sobrien
4496104834Sobrien      off &= ~ (bfd_vma) 1;
4497104834Sobrien      off += (htab->splt->output_offset
4498104834Sobrien	      + htab->splt->output_section->vma
4499104834Sobrien	      - elf_gp (htab->splt->output_section->owner)
4500104834Sobrien	      - TOC_BASE_OFF);
4501104834Sobrien
4502104834Sobrien      if (off + 0x80000000 > 0xffffffff || (off & 7) != 0)
450389857Sobrien	{
4504104834Sobrien	  (*_bfd_error_handler)
4505104834Sobrien	    (_("linkage table error against `%s'"),
4506104834Sobrien	     stub_entry->h->elf.root.root.string);
4507104834Sobrien	  bfd_set_error (bfd_error_bad_value);
4508104834Sobrien	  htab->stub_error = true;
4509104834Sobrien	  return false;
451089857Sobrien	}
4511104834Sobrien
4512104834Sobrien      p = build_plt_stub (stub_bfd, loc, (int) off, 0);
4513104834Sobrien      size = p - loc;
4514104834Sobrien      break;
4515104834Sobrien
4516104834Sobrien    default:
4517104834Sobrien      BFD_FAIL ();
4518104834Sobrien      return false;
451989857Sobrien    }
4520104834Sobrien
4521104834Sobrien  stub_sec->_cooked_size += size;
452289857Sobrien  return true;
452389857Sobrien}
452489857Sobrien
4525104834Sobrien/* As above, but don't actually build the stub.  Just bump offset so
4526104834Sobrien   we know stub section sizes, and select plt_branch stubs where
4527104834Sobrien   long_branch stubs won't do.  */
4528104834Sobrien
4529104834Sobrienstatic boolean
4530104834Sobrienppc_size_one_stub (gen_entry, in_arg)
4531104834Sobrien     struct bfd_hash_entry *gen_entry;
4532104834Sobrien     PTR in_arg;
4533104834Sobrien{
4534104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
4535104834Sobrien  struct ppc_link_hash_table *htab;
4536104834Sobrien  bfd_vma off;
4537104834Sobrien  int size;
4538104834Sobrien
4539104834Sobrien  /* Massage our args to the form they really have.  */
4540104834Sobrien  stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
4541104834Sobrien  htab = (struct ppc_link_hash_table *) in_arg;
4542104834Sobrien
4543104834Sobrien  if (stub_entry->stub_type == ppc_stub_plt_call)
4544104834Sobrien    {
4545104834Sobrien      off = stub_entry->h->elf.plt.offset & ~(bfd_vma) 1;
4546104834Sobrien      off += (htab->splt->output_offset
4547104834Sobrien	      + htab->splt->output_section->vma
4548104834Sobrien	      - elf_gp (htab->splt->output_section->owner)
4549104834Sobrien	      - TOC_BASE_OFF);
4550104834Sobrien
4551104834Sobrien      size = 28;
4552104834Sobrien      if (PPC_HA ((int) off + 16) != PPC_HA ((int) off))
4553104834Sobrien	size += 4;
4554104834Sobrien    }
4555104834Sobrien  else
4556104834Sobrien    {
4557104834Sobrien      /* ppc_stub_long_branch or ppc_stub_plt_branch.  */
4558104834Sobrien      stub_entry->stub_type = ppc_stub_long_branch;
4559104834Sobrien      size = 4;
4560104834Sobrien
4561104834Sobrien      off = (stub_entry->target_value
4562104834Sobrien	     + stub_entry->target_section->output_offset
4563104834Sobrien	     + stub_entry->target_section->output_section->vma);
4564104834Sobrien      off -= (stub_entry->stub_sec->_raw_size
4565104834Sobrien	      + stub_entry->stub_sec->output_offset
4566104834Sobrien	      + stub_entry->stub_sec->output_section->vma);
4567104834Sobrien
4568104834Sobrien      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
4569104834Sobrien	{
4570104834Sobrien	  struct ppc_branch_hash_entry *br_entry;
4571104834Sobrien
4572104834Sobrien	  br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
4573104834Sobrien					     stub_entry->root.string + 9,
4574104834Sobrien					     true, false);
4575104834Sobrien	  if (br_entry == NULL)
4576104834Sobrien	    {
4577104834Sobrien	      (*_bfd_error_handler) (_("can't build branch stub `%s'"),
4578104834Sobrien				     stub_entry->root.string + 9);
4579104834Sobrien	      htab->stub_error = true;
4580104834Sobrien	      return false;
4581104834Sobrien	    }
4582104834Sobrien
4583104834Sobrien	  if (br_entry->iter != htab->stub_iteration)
4584104834Sobrien	    {
4585104834Sobrien	      br_entry->iter = htab->stub_iteration;
4586104834Sobrien	      br_entry->offset = htab->sbrlt->_raw_size;
4587104834Sobrien	      htab->sbrlt->_raw_size += 8;
4588104834Sobrien	    }
4589104834Sobrien	  stub_entry->stub_type = ppc_stub_plt_branch;
4590104834Sobrien	  size = 16;
4591104834Sobrien	}
4592104834Sobrien    }
4593104834Sobrien
4594104834Sobrien  stub_entry->stub_sec->_raw_size += size;
4595104834Sobrien  return true;
4596104834Sobrien}
4597104834Sobrien
4598104834Sobrien/* Set up various things so that we can make a list of input sections
4599104834Sobrien   for each output section included in the link.  Returns -1 on error,
4600104834Sobrien   0 when no stubs will be needed, and 1 on success.  */
4601104834Sobrien
4602104834Sobrienint
4603104834Sobrienppc64_elf_setup_section_lists (output_bfd, info)
4604104834Sobrien     bfd *output_bfd;
460589857Sobrien     struct bfd_link_info *info;
460689857Sobrien{
4607104834Sobrien  bfd *input_bfd;
4608104834Sobrien  int top_id, top_index;
4609104834Sobrien  asection *section;
4610104834Sobrien  asection **input_list, **list;
4611104834Sobrien  bfd_size_type amt;
461289857Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
461389857Sobrien
4614104834Sobrien  if (htab->elf.root.creator->flavour != bfd_target_elf_flavour
4615104834Sobrien      || htab->sbrlt == NULL)
4616104834Sobrien    return 0;
461789857Sobrien
4618104834Sobrien  /* Find the top input section id.  */
4619104834Sobrien  for (input_bfd = info->input_bfds, top_id = 0;
4620104834Sobrien       input_bfd != NULL;
4621104834Sobrien       input_bfd = input_bfd->link_next)
4622104834Sobrien    {
4623104834Sobrien      for (section = input_bfd->sections;
4624104834Sobrien	   section != NULL;
4625104834Sobrien	   section = section->next)
4626104834Sobrien	{
4627104834Sobrien	  if (top_id < section->id)
4628104834Sobrien	    top_id = section->id;
4629104834Sobrien	}
4630104834Sobrien    }
463189857Sobrien
4632104834Sobrien  amt = sizeof (struct map_stub) * (top_id + 1);
4633104834Sobrien  htab->stub_group = (struct map_stub *) bfd_zmalloc (amt);
4634104834Sobrien  if (htab->stub_group == NULL)
4635104834Sobrien    return -1;
4636104834Sobrien
4637104834Sobrien  /* We can't use output_bfd->section_count here to find the top output
4638104834Sobrien     section index as some sections may have been removed, and
4639104834Sobrien     _bfd_strip_section_from_output doesn't renumber the indices.  */
4640104834Sobrien  for (section = output_bfd->sections, top_index = 0;
4641104834Sobrien       section != NULL;
4642104834Sobrien       section = section->next)
464389857Sobrien    {
4644104834Sobrien      if (top_index < section->index)
4645104834Sobrien	top_index = section->index;
464689857Sobrien    }
464789857Sobrien
4648104834Sobrien  htab->top_index = top_index;
4649104834Sobrien  amt = sizeof (asection *) * (top_index + 1);
4650104834Sobrien  input_list = (asection **) bfd_malloc (amt);
4651104834Sobrien  htab->input_list = input_list;
4652104834Sobrien  if (input_list == NULL)
4653104834Sobrien    return -1;
465489857Sobrien
4655104834Sobrien  /* For sections we aren't interested in, mark their entries with a
4656104834Sobrien     value we can check later.  */
4657104834Sobrien  list = input_list + top_index;
4658104834Sobrien  do
4659104834Sobrien    *list = bfd_abs_section_ptr;
4660104834Sobrien  while (list-- != input_list);
466189857Sobrien
4662104834Sobrien  for (section = output_bfd->sections;
4663104834Sobrien       section != NULL;
4664104834Sobrien       section = section->next)
4665104834Sobrien    {
4666104834Sobrien      if ((section->flags & SEC_CODE) != 0)
4667104834Sobrien	input_list[section->index] = NULL;
4668104834Sobrien    }
466989857Sobrien
4670104834Sobrien  return 1;
4671104834Sobrien}
4672104834Sobrien
4673104834Sobrien/* The linker repeatedly calls this function for each input section,
4674104834Sobrien   in the order that input sections are linked into output sections.
4675104834Sobrien   Build lists of input sections to determine groupings between which
4676104834Sobrien   we may insert linker stubs.  */
4677104834Sobrien
4678104834Sobrienvoid
4679104834Sobrienppc64_elf_next_input_section (info, isec)
4680104834Sobrien     struct bfd_link_info *info;
4681104834Sobrien     asection *isec;
4682104834Sobrien{
4683104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
4684104834Sobrien
4685104834Sobrien  if (isec->output_section->index <= htab->top_index)
468689857Sobrien    {
4687104834Sobrien      asection **list = htab->input_list + isec->output_section->index;
4688104834Sobrien      if (*list != bfd_abs_section_ptr)
4689104834Sobrien	{
4690104834Sobrien	  /* Steal the link_sec pointer for our list.  */
4691104834Sobrien#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
4692104834Sobrien	  /* This happens to make the list in reverse order,
4693104834Sobrien	     which is what we want.  */
4694104834Sobrien	  PREV_SEC (isec) = *list;
4695104834Sobrien	  *list = isec;
4696104834Sobrien	}
469789857Sobrien    }
469889857Sobrien}
469989857Sobrien
4700104834Sobrien/* See whether we can group stub sections together.  Grouping stub
4701104834Sobrien   sections may result in fewer stubs.  More importantly, we need to
4702104834Sobrien   put all .init* and .fini* stubs at the beginning of the .init or
4703104834Sobrien   .fini output sections respectively, because glibc splits the
4704104834Sobrien   _init and _fini functions into multiple parts.  Putting a stub in
4705104834Sobrien   the middle of a function is not a good idea.  */
470689857Sobrien
4707104834Sobrienstatic void
4708104834Sobriengroup_sections (htab, stub_group_size, stubs_always_before_branch)
4709104834Sobrien     struct ppc_link_hash_table *htab;
4710104834Sobrien     bfd_size_type stub_group_size;
4711104834Sobrien     boolean stubs_always_before_branch;
471289857Sobrien{
4713104834Sobrien  asection **list = htab->input_list + htab->top_index;
4714104834Sobrien  do
4715104834Sobrien    {
4716104834Sobrien      asection *tail = *list;
4717104834Sobrien      if (tail == bfd_abs_section_ptr)
4718104834Sobrien	continue;
4719104834Sobrien      while (tail != NULL)
4720104834Sobrien	{
4721104834Sobrien	  asection *curr;
4722104834Sobrien	  asection *prev;
4723104834Sobrien	  bfd_size_type total;
472489857Sobrien
4725104834Sobrien	  curr = tail;
4726104834Sobrien	  if (tail->_cooked_size)
4727104834Sobrien	    total = tail->_cooked_size;
4728104834Sobrien	  else
4729104834Sobrien	    total = tail->_raw_size;
4730104834Sobrien	  while ((prev = PREV_SEC (curr)) != NULL
4731104834Sobrien		 && ((total += curr->output_offset - prev->output_offset)
4732104834Sobrien		     < stub_group_size))
4733104834Sobrien	    curr = prev;
473489857Sobrien
4735104834Sobrien	  /* OK, the size from the start of CURR to the end is less
4736104834Sobrien	     than stub_group_size and thus can be handled by one stub
4737104834Sobrien	     section.  (or the tail section is itself larger than
4738104834Sobrien	     stub_group_size, in which case we may be toast.)  We
4739104834Sobrien	     should really be keeping track of the total size of stubs
4740104834Sobrien	     added here, as stubs contribute to the final output
4741104834Sobrien	     section size.  That's a little tricky, and this way will
4742104834Sobrien	     only break if stubs added make the total size more than
4743104834Sobrien	     2^25, ie. for the default stub_group_size, if stubs total
4744104834Sobrien	     more than 2834432 bytes, or over 100000 plt call stubs.  */
4745104834Sobrien	  do
4746104834Sobrien	    {
4747104834Sobrien	      prev = PREV_SEC (tail);
4748104834Sobrien	      /* Set up this stub group.  */
4749104834Sobrien	      htab->stub_group[tail->id].link_sec = curr;
4750104834Sobrien	    }
4751104834Sobrien	  while (tail != curr && (tail = prev) != NULL);
4752104834Sobrien
4753104834Sobrien	  /* But wait, there's more!  Input sections up to stub_group_size
4754104834Sobrien	     bytes before the stub section can be handled by it too.  */
4755104834Sobrien	  if (!stubs_always_before_branch)
4756104834Sobrien	    {
4757104834Sobrien	      total = 0;
4758104834Sobrien	      while (prev != NULL
4759104834Sobrien		     && ((total += tail->output_offset - prev->output_offset)
4760104834Sobrien			 < stub_group_size))
4761104834Sobrien		{
4762104834Sobrien		  tail = prev;
4763104834Sobrien		  prev = PREV_SEC (tail);
4764104834Sobrien		  htab->stub_group[tail->id].link_sec = curr;
4765104834Sobrien		}
4766104834Sobrien	    }
4767104834Sobrien	  tail = prev;
4768104834Sobrien	}
4769104834Sobrien    }
4770104834Sobrien  while (list-- != htab->input_list);
4771104834Sobrien  free (htab->input_list);
4772104834Sobrien#undef PREV_SEC
4773104834Sobrien}
4774104834Sobrien
4775104834Sobrien/* Determine and set the size of the stub section for a final link.
4776104834Sobrien
4777104834Sobrien   The basic idea here is to examine all the relocations looking for
4778104834Sobrien   PC-relative calls to a target that is unreachable with a "bl"
4779104834Sobrien   instruction.  */
4780104834Sobrien
4781104834Sobrienboolean
4782104834Sobrienppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
4783104834Sobrien		      add_stub_section, layout_sections_again)
4784104834Sobrien     bfd *output_bfd;
4785104834Sobrien     bfd *stub_bfd;
4786104834Sobrien     struct bfd_link_info *info;
4787104834Sobrien     bfd_signed_vma group_size;
4788104834Sobrien     asection * (*add_stub_section) PARAMS ((const char *, asection *));
4789104834Sobrien     void (*layout_sections_again) PARAMS ((void));
4790104834Sobrien{
4791104834Sobrien  bfd_size_type stub_group_size;
4792104834Sobrien  boolean stubs_always_before_branch;
4793104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
4794104834Sobrien
4795104834Sobrien  /* Stash our params away.  */
4796104834Sobrien  htab->stub_bfd = stub_bfd;
4797104834Sobrien  htab->add_stub_section = add_stub_section;
4798104834Sobrien  htab->layout_sections_again = layout_sections_again;
4799104834Sobrien  stubs_always_before_branch = group_size < 0;
4800104834Sobrien  if (group_size < 0)
4801104834Sobrien    stub_group_size = -group_size;
4802104834Sobrien  else
4803104834Sobrien    stub_group_size = group_size;
4804104834Sobrien  if (stub_group_size == 1)
4805104834Sobrien    {
4806104834Sobrien      /* Default values.  */
4807104834Sobrien      stub_group_size = 30720000;
4808104834Sobrien      if (htab->has_14bit_branch)
4809104834Sobrien	stub_group_size = 30000;
4810104834Sobrien    }
4811104834Sobrien
4812104834Sobrien  group_sections (htab, stub_group_size, stubs_always_before_branch);
4813104834Sobrien
4814104834Sobrien  while (1)
4815104834Sobrien    {
4816104834Sobrien      bfd *input_bfd;
4817104834Sobrien      unsigned int bfd_indx;
4818104834Sobrien      asection *stub_sec;
4819104834Sobrien      boolean stub_changed;
4820104834Sobrien
4821104834Sobrien      htab->stub_iteration += 1;
4822104834Sobrien      stub_changed = false;
4823104834Sobrien
4824104834Sobrien      for (input_bfd = info->input_bfds, bfd_indx = 0;
4825104834Sobrien	   input_bfd != NULL;
4826104834Sobrien	   input_bfd = input_bfd->link_next, bfd_indx++)
4827104834Sobrien	{
4828104834Sobrien	  Elf_Internal_Shdr *symtab_hdr;
4829104834Sobrien	  asection *section;
4830104834Sobrien	  Elf_Internal_Sym *local_syms = NULL;
4831104834Sobrien
4832104834Sobrien	  /* We'll need the symbol table in a second.  */
4833104834Sobrien	  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4834104834Sobrien	  if (symtab_hdr->sh_info == 0)
4835104834Sobrien	    continue;
4836104834Sobrien
4837104834Sobrien	  /* Walk over each section attached to the input bfd.  */
4838104834Sobrien	  for (section = input_bfd->sections;
4839104834Sobrien	       section != NULL;
4840104834Sobrien	       section = section->next)
4841104834Sobrien	    {
4842104834Sobrien	      Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
4843104834Sobrien
4844104834Sobrien	      /* If there aren't any relocs, then there's nothing more
4845104834Sobrien		 to do.  */
4846104834Sobrien	      if ((section->flags & SEC_RELOC) == 0
4847104834Sobrien		  || section->reloc_count == 0)
4848104834Sobrien		continue;
4849104834Sobrien
4850104834Sobrien	      /* If this section is a link-once section that will be
4851104834Sobrien		 discarded, then don't create any stubs.  */
4852104834Sobrien	      if (section->output_section == NULL
4853104834Sobrien		  || section->output_section->owner != output_bfd)
4854104834Sobrien		continue;
4855104834Sobrien
4856104834Sobrien	      /* Get the relocs.  */
4857104834Sobrien	      internal_relocs
4858104834Sobrien		= _bfd_elf64_link_read_relocs (input_bfd, section, NULL,
4859104834Sobrien					       (Elf_Internal_Rela *) NULL,
4860104834Sobrien					       info->keep_memory);
4861104834Sobrien	      if (internal_relocs == NULL)
4862104834Sobrien		goto error_ret_free_local;
4863104834Sobrien
4864104834Sobrien	      /* Now examine each relocation.  */
4865104834Sobrien	      irela = internal_relocs;
4866104834Sobrien	      irelaend = irela + section->reloc_count;
4867104834Sobrien	      for (; irela < irelaend; irela++)
4868104834Sobrien		{
4869104834Sobrien		  unsigned int r_type, r_indx;
4870104834Sobrien		  enum ppc_stub_type stub_type;
4871104834Sobrien		  struct ppc_stub_hash_entry *stub_entry;
4872104834Sobrien		  asection *sym_sec;
4873104834Sobrien		  bfd_vma sym_value;
4874104834Sobrien		  bfd_vma destination;
4875104834Sobrien		  struct ppc_link_hash_entry *hash;
4876104834Sobrien		  char *stub_name;
4877104834Sobrien		  const asection *id_sec;
4878104834Sobrien
4879104834Sobrien		  r_type = ELF64_R_TYPE (irela->r_info);
4880104834Sobrien		  r_indx = ELF64_R_SYM (irela->r_info);
4881104834Sobrien
4882104834Sobrien		  if (r_type >= (unsigned int) R_PPC_max)
4883104834Sobrien		    {
4884104834Sobrien		      bfd_set_error (bfd_error_bad_value);
4885104834Sobrien		      goto error_ret_free_internal;
4886104834Sobrien		    }
4887104834Sobrien
4888104834Sobrien		  /* Only look for stubs on branch instructions.  */
4889104834Sobrien		  if (r_type != (unsigned int) R_PPC64_REL24
4890104834Sobrien		      && r_type != (unsigned int) R_PPC64_REL14
4891104834Sobrien		      && r_type != (unsigned int) R_PPC64_REL14_BRTAKEN
4892104834Sobrien		      && r_type != (unsigned int) R_PPC64_REL14_BRNTAKEN)
4893104834Sobrien		    continue;
4894104834Sobrien
4895104834Sobrien		  /* Now determine the call target, its name, value,
4896104834Sobrien		     section.  */
4897104834Sobrien		  sym_sec = NULL;
4898104834Sobrien		  sym_value = 0;
4899104834Sobrien		  destination = 0;
4900104834Sobrien		  hash = NULL;
4901104834Sobrien		  if (r_indx < symtab_hdr->sh_info)
4902104834Sobrien		    {
4903104834Sobrien		      /* It's a local symbol.  */
4904104834Sobrien		      Elf_Internal_Sym *sym;
4905104834Sobrien		      Elf_Internal_Shdr *hdr;
4906104834Sobrien
4907104834Sobrien		      if (local_syms == NULL)
4908104834Sobrien			{
4909104834Sobrien			  local_syms
4910104834Sobrien			    = (Elf_Internal_Sym *) symtab_hdr->contents;
4911104834Sobrien			  if (local_syms == NULL)
4912104834Sobrien			    local_syms
4913104834Sobrien			      = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
4914104834Sobrien						      symtab_hdr->sh_info, 0,
4915104834Sobrien						      NULL, NULL, NULL);
4916104834Sobrien			  if (local_syms == NULL)
4917104834Sobrien			    goto error_ret_free_internal;
4918104834Sobrien			}
4919104834Sobrien		      sym = local_syms + r_indx;
4920104834Sobrien		      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
4921104834Sobrien		      sym_sec = hdr->bfd_section;
4922104834Sobrien		      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
4923104834Sobrien			sym_value = sym->st_value;
4924104834Sobrien		      destination = (sym_value + irela->r_addend
4925104834Sobrien				     + sym_sec->output_offset
4926104834Sobrien				     + sym_sec->output_section->vma);
4927104834Sobrien		    }
4928104834Sobrien		  else
4929104834Sobrien		    {
4930104834Sobrien		      /* It's an external symbol.  */
4931104834Sobrien		      int e_indx;
4932104834Sobrien
4933104834Sobrien		      e_indx = r_indx - symtab_hdr->sh_info;
4934104834Sobrien		      hash = ((struct ppc_link_hash_entry *)
4935104834Sobrien			      elf_sym_hashes (input_bfd)[e_indx]);
4936104834Sobrien
4937104834Sobrien		      while (hash->elf.root.type == bfd_link_hash_indirect
4938104834Sobrien			     || hash->elf.root.type == bfd_link_hash_warning)
4939104834Sobrien			hash = ((struct ppc_link_hash_entry *)
4940104834Sobrien				hash->elf.root.u.i.link);
4941104834Sobrien
4942104834Sobrien		      if (hash->elf.root.type == bfd_link_hash_defined
4943104834Sobrien			  || hash->elf.root.type == bfd_link_hash_defweak)
4944104834Sobrien			{
4945104834Sobrien			  sym_sec = hash->elf.root.u.def.section;
4946104834Sobrien			  sym_value = hash->elf.root.u.def.value;
4947104834Sobrien			  if (sym_sec->output_section != NULL)
4948104834Sobrien			    destination = (sym_value + irela->r_addend
4949104834Sobrien					   + sym_sec->output_offset
4950104834Sobrien					   + sym_sec->output_section->vma);
4951104834Sobrien			}
4952104834Sobrien		      else if (hash->elf.root.type == bfd_link_hash_undefweak)
4953104834Sobrien			;
4954104834Sobrien		      else if (hash->elf.root.type == bfd_link_hash_undefined)
4955104834Sobrien			;
4956104834Sobrien		      else
4957104834Sobrien			{
4958104834Sobrien			  bfd_set_error (bfd_error_bad_value);
4959104834Sobrien			  goto error_ret_free_internal;
4960104834Sobrien			}
4961104834Sobrien		    }
4962104834Sobrien
4963104834Sobrien		  /* Determine what (if any) linker stub is needed.  */
4964104834Sobrien		  stub_type = ppc_type_of_stub (section, irela, &hash,
4965104834Sobrien						destination);
4966104834Sobrien		  if (stub_type == ppc_stub_none)
4967104834Sobrien		    continue;
4968104834Sobrien
4969104834Sobrien		  /* Support for grouping stub sections.  */
4970104834Sobrien		  id_sec = htab->stub_group[section->id].link_sec;
4971104834Sobrien
4972104834Sobrien		  /* Get the name of this stub.  */
4973104834Sobrien		  stub_name = ppc_stub_name (id_sec, sym_sec, hash, irela);
4974104834Sobrien		  if (!stub_name)
4975104834Sobrien		    goto error_ret_free_internal;
4976104834Sobrien
4977104834Sobrien		  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
4978104834Sobrien						     stub_name, false, false);
4979104834Sobrien		  if (stub_entry != NULL)
4980104834Sobrien		    {
4981104834Sobrien		      /* The proper stub has already been created.  */
4982104834Sobrien		      free (stub_name);
4983104834Sobrien		      continue;
4984104834Sobrien		    }
4985104834Sobrien
4986104834Sobrien		  stub_entry = ppc_add_stub (stub_name, section, htab);
4987104834Sobrien		  if (stub_entry == NULL)
4988104834Sobrien		    {
4989104834Sobrien		      free (stub_name);
4990104834Sobrien		    error_ret_free_internal:
4991104834Sobrien		      if (elf_section_data (section)->relocs == NULL)
4992104834Sobrien			free (internal_relocs);
4993104834Sobrien		    error_ret_free_local:
4994104834Sobrien		      if (local_syms != NULL
4995104834Sobrien			  && (symtab_hdr->contents
4996104834Sobrien			      != (unsigned char *) local_syms))
4997104834Sobrien			free (local_syms);
4998104834Sobrien		      return false;
4999104834Sobrien		    }
5000104834Sobrien
5001104834Sobrien		  stub_entry->target_value = sym_value;
5002104834Sobrien		  stub_entry->target_section = sym_sec;
5003104834Sobrien		  stub_entry->stub_type = stub_type;
5004104834Sobrien		  stub_entry->h = hash;
5005104834Sobrien		  stub_changed = true;
5006104834Sobrien		}
5007104834Sobrien
5008104834Sobrien	      /* We're done with the internal relocs, free them.  */
5009104834Sobrien	      if (elf_section_data (section)->relocs != internal_relocs)
5010104834Sobrien		free (internal_relocs);
5011104834Sobrien	    }
5012104834Sobrien
5013104834Sobrien	  if (local_syms != NULL
5014104834Sobrien	      && symtab_hdr->contents != (unsigned char *) local_syms)
5015104834Sobrien	    {
5016104834Sobrien	      if (!info->keep_memory)
5017104834Sobrien		free (local_syms);
5018104834Sobrien	      else
5019104834Sobrien		symtab_hdr->contents = (unsigned char *) local_syms;
5020104834Sobrien	    }
5021104834Sobrien	}
5022104834Sobrien
5023104834Sobrien      if (!stub_changed)
5024104834Sobrien	break;
5025104834Sobrien
5026104834Sobrien      /* OK, we've added some stubs.  Find out the new size of the
5027104834Sobrien	 stub sections.  */
5028104834Sobrien      for (stub_sec = htab->stub_bfd->sections;
5029104834Sobrien	   stub_sec != NULL;
5030104834Sobrien	   stub_sec = stub_sec->next)
5031104834Sobrien	{
5032104834Sobrien	  stub_sec->_raw_size = 0;
5033104834Sobrien	  stub_sec->_cooked_size = 0;
5034104834Sobrien	}
5035104834Sobrien      htab->sbrlt->_raw_size = 0;
5036104834Sobrien      htab->sbrlt->_cooked_size = 0;
5037104834Sobrien
5038104834Sobrien      bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, htab);
5039104834Sobrien
5040104834Sobrien      /* Ask the linker to do its stuff.  */
5041104834Sobrien      (*htab->layout_sections_again) ();
5042104834Sobrien    }
5043104834Sobrien
5044104834Sobrien  /* It would be nice to strip .branch_lt from the output if the
5045104834Sobrien     section is empty, but it's too late.  If we strip sections here,
5046104834Sobrien     the dynamic symbol table is corrupted since the section symbol
5047104834Sobrien     for the stripped section isn't written.  */
5048104834Sobrien
504989857Sobrien  return true;
505089857Sobrien}
505189857Sobrien
5052104834Sobrien/* Called after we have determined section placement.  If sections
5053104834Sobrien   move, we'll be called again.  Provide a value for TOCstart.  */
5054104834Sobrien
5055104834Sobrienbfd_vma
5056104834Sobrienppc64_elf_toc (obfd)
5057104834Sobrien     bfd *obfd;
5058104834Sobrien{
5059104834Sobrien  asection *s;
5060104834Sobrien  bfd_vma TOCstart;
5061104834Sobrien
5062104834Sobrien  /* The TOC consists of sections .got, .toc, .tocbss, .plt in that
5063104834Sobrien     order.  The TOC starts where the first of these sections starts.  */
5064104834Sobrien  s = bfd_get_section_by_name (obfd, ".got");
5065104834Sobrien  if (s == NULL)
5066104834Sobrien    s = bfd_get_section_by_name (obfd, ".toc");
5067104834Sobrien  if (s == NULL)
5068104834Sobrien    s = bfd_get_section_by_name (obfd, ".tocbss");
5069104834Sobrien  if (s == NULL)
5070104834Sobrien    s = bfd_get_section_by_name (obfd, ".plt");
5071104834Sobrien  if (s == NULL)
5072104834Sobrien    {
5073104834Sobrien      /* This may happen for
5074104834Sobrien	 o  references to TOC base (SYM@toc / TOC[tc0]) without a
5075104834Sobrien	 .toc directive
5076104834Sobrien	 o  bad linker script
5077104834Sobrien	 o --gc-sections and empty TOC sections
5078104834Sobrien
5079104834Sobrien	 FIXME: Warn user?  */
5080104834Sobrien
5081104834Sobrien      /* Look for a likely section.  We probably won't even be
5082104834Sobrien	 using TOCstart.  */
5083104834Sobrien      for (s = obfd->sections; s != NULL; s = s->next)
5084104834Sobrien	if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY))
5085104834Sobrien	    == (SEC_ALLOC | SEC_SMALL_DATA))
5086104834Sobrien	  break;
5087104834Sobrien      if (s == NULL)
5088104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
5089104834Sobrien	  if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA))
5090104834Sobrien	      == (SEC_ALLOC | SEC_SMALL_DATA))
5091104834Sobrien	    break;
5092104834Sobrien      if (s == NULL)
5093104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
5094104834Sobrien	  if ((s->flags & (SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
5095104834Sobrien	    break;
5096104834Sobrien      if (s == NULL)
5097104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
5098104834Sobrien	  if ((s->flags & SEC_ALLOC) == SEC_ALLOC)
5099104834Sobrien	    break;
5100104834Sobrien    }
5101104834Sobrien
5102104834Sobrien  TOCstart = 0;
5103104834Sobrien  if (s != NULL)
5104104834Sobrien    TOCstart = s->output_section->vma + s->output_offset;
5105104834Sobrien
5106104834Sobrien  return TOCstart;
5107104834Sobrien}
5108104834Sobrien
5109104834Sobrien/* Build all the stubs associated with the current output file.
5110104834Sobrien   The stubs are kept in a hash table attached to the main linker
5111104834Sobrien   hash table.  This function is called via gldelf64ppc_finish.  */
5112104834Sobrien
5113104834Sobrienboolean
5114104834Sobrienppc64_elf_build_stubs (info)
5115104834Sobrien     struct bfd_link_info *info;
5116104834Sobrien{
5117104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
5118104834Sobrien  asection *stub_sec;
5119104834Sobrien  bfd_vma plt_r2;
5120104834Sobrien  bfd_byte *p;
5121104834Sobrien
5122104834Sobrien  for (stub_sec = htab->stub_bfd->sections;
5123104834Sobrien       stub_sec != NULL;
5124104834Sobrien       stub_sec = stub_sec->next)
5125104834Sobrien    {
5126104834Sobrien      bfd_size_type size;
5127104834Sobrien
5128104834Sobrien      /* Allocate memory to hold the linker stubs.  */
5129104834Sobrien      size = stub_sec->_raw_size;
5130104834Sobrien      if (size != 0)
5131104834Sobrien	{
5132104834Sobrien	  stub_sec->contents = (bfd_byte *) bfd_zalloc (htab->stub_bfd, size);
5133104834Sobrien	  if (stub_sec->contents == NULL)
5134104834Sobrien	    return false;
5135104834Sobrien	}
5136104834Sobrien      stub_sec->_cooked_size = 0;
5137104834Sobrien    }
5138104834Sobrien
5139104834Sobrien  if (htab->splt != NULL)
5140104834Sobrien    {
5141104834Sobrien      unsigned int indx;
5142104834Sobrien
5143104834Sobrien      /* Build the .glink plt call stub.  */
5144104834Sobrien      plt_r2 = (htab->splt->output_offset
5145104834Sobrien		+ htab->splt->output_section->vma
5146104834Sobrien		- elf_gp (htab->splt->output_section->owner)
5147104834Sobrien		- TOC_BASE_OFF);
5148104834Sobrien      p = htab->sglink->contents;
5149104834Sobrien      p = build_plt_stub (htab->sglink->owner, p, (int) plt_r2, 1);
5150104834Sobrien      while (p < htab->sglink->contents + GLINK_CALL_STUB_SIZE)
5151104834Sobrien	{
5152104834Sobrien	  bfd_put_32 (htab->sglink->owner, NOP, p);
5153104834Sobrien	  p += 4;
5154104834Sobrien	}
5155104834Sobrien
5156104834Sobrien      /* Build the .glink lazy link call stubs.  */
5157104834Sobrien      indx = 0;
5158104834Sobrien      while (p < htab->sglink->contents + htab->sglink->_raw_size)
5159104834Sobrien	{
5160104834Sobrien	  if (indx < 0x8000)
5161104834Sobrien	    {
5162104834Sobrien	      bfd_put_32 (htab->sglink->owner, LI_R0_0 | indx, p);
5163104834Sobrien	      p += 4;
5164104834Sobrien	    }
5165104834Sobrien	  else
5166104834Sobrien	    {
5167104834Sobrien	      bfd_put_32 (htab->sglink->owner, LIS_R0_0 | PPC_HI (indx), p);
5168104834Sobrien	      p += 4;
5169104834Sobrien	      bfd_put_32 (htab->sglink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
5170104834Sobrien	      p += 4;
5171104834Sobrien	    }
5172104834Sobrien	  bfd_put_32 (htab->sglink->owner,
5173104834Sobrien		      B_DOT | ((htab->sglink->contents - p) & 0x3fffffc), p);
5174104834Sobrien	  indx++;
5175104834Sobrien	  p += 4;
5176104834Sobrien	}
5177104834Sobrien      htab->sglink->_cooked_size = p - htab->sglink->contents;
5178104834Sobrien    }
5179104834Sobrien
5180104834Sobrien  if (htab->sbrlt->_raw_size != 0)
5181104834Sobrien    {
5182104834Sobrien      htab->sbrlt->contents = (bfd_byte *) bfd_zalloc (htab->sbrlt->owner,
5183104834Sobrien						       htab->sbrlt->_raw_size);
5184104834Sobrien      if (htab->sbrlt->contents == NULL)
5185104834Sobrien	return false;
5186104834Sobrien    }
5187104834Sobrien
5188104834Sobrien  /* Build the stubs as directed by the stub hash table.  */
5189104834Sobrien  bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
5190104834Sobrien
5191104834Sobrien  for (stub_sec = htab->stub_bfd->sections;
5192104834Sobrien       stub_sec != NULL;
5193104834Sobrien       stub_sec = stub_sec->next)
5194104834Sobrien    {
5195104834Sobrien      if (stub_sec->_raw_size != stub_sec->_cooked_size)
5196104834Sobrien	break;
5197104834Sobrien    }
5198104834Sobrien
5199104834Sobrien  if (stub_sec != NULL
5200104834Sobrien      || htab->sglink->_raw_size != htab->sglink->_cooked_size)
5201104834Sobrien    {
5202104834Sobrien      htab->stub_error = true;
5203104834Sobrien      (*_bfd_error_handler) (_("stubs don't match calculated size"));
5204104834Sobrien    }
5205104834Sobrien
5206104834Sobrien  return !htab->stub_error;
5207104834Sobrien}
5208104834Sobrien
520989857Sobrien/* The RELOCATE_SECTION function is called by the ELF backend linker
521089857Sobrien   to handle the relocations for a section.
521189857Sobrien
521289857Sobrien   The relocs are always passed as Rela structures; if the section
521389857Sobrien   actually uses Rel structures, the r_addend field will always be
521489857Sobrien   zero.
521589857Sobrien
521689857Sobrien   This function is responsible for adjust the section contents as
521789857Sobrien   necessary, and (if using Rela relocs and generating a
521889857Sobrien   relocateable output file) adjusting the reloc addend as
521989857Sobrien   necessary.
522089857Sobrien
522189857Sobrien   This function does not have to worry about setting the reloc
522289857Sobrien   address or the reloc symbol index.
522389857Sobrien
522489857Sobrien   LOCAL_SYMS is a pointer to the swapped in local symbols.
522589857Sobrien
522689857Sobrien   LOCAL_SECTIONS is an array giving the section in the input file
522789857Sobrien   corresponding to the st_shndx field of each local symbol.
522889857Sobrien
522989857Sobrien   The global hash table entry for the global symbols can be found
523089857Sobrien   via elf_sym_hashes (input_bfd).
523189857Sobrien
523289857Sobrien   When generating relocateable output, this function must handle
523389857Sobrien   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
523489857Sobrien   going to be the section symbol corresponding to the output
523589857Sobrien   section, which means that the addend must be adjusted
523689857Sobrien   accordingly.  */
523789857Sobrien
523889857Sobrienstatic boolean
523989857Sobrienppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
524089857Sobrien			    contents, relocs, local_syms, local_sections)
524189857Sobrien     bfd *output_bfd;
524289857Sobrien     struct bfd_link_info *info;
524389857Sobrien     bfd *input_bfd;
524489857Sobrien     asection *input_section;
524589857Sobrien     bfd_byte *contents;
524689857Sobrien     Elf_Internal_Rela *relocs;
524789857Sobrien     Elf_Internal_Sym *local_syms;
524889857Sobrien     asection **local_sections;
524989857Sobrien{
525089857Sobrien  struct ppc_link_hash_table *htab;
525189857Sobrien  Elf_Internal_Shdr *symtab_hdr;
525289857Sobrien  struct elf_link_hash_entry **sym_hashes;
525389857Sobrien  Elf_Internal_Rela *rel;
525489857Sobrien  Elf_Internal_Rela *relend;
525589857Sobrien  bfd_vma *local_got_offsets;
525689857Sobrien  bfd_vma TOCstart;
525789857Sobrien  boolean ret = true;
525889857Sobrien  boolean is_opd;
525992828Sobrien  /* Disabled until we sort out how ld should choose 'y' vs 'at'.  */
526092828Sobrien  boolean is_power4 = false;
526189857Sobrien
526299461Sobrien  if (info->relocateable)
526399461Sobrien    return true;
526499461Sobrien
526589857Sobrien  /* Initialize howto table if needed.  */
526689857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
526789857Sobrien    ppc_howto_init ();
526889857Sobrien
526989857Sobrien  htab = ppc_hash_table (info);
527089857Sobrien  local_got_offsets = elf_local_got_offsets (input_bfd);
527189857Sobrien  TOCstart = elf_gp (output_bfd);
527289857Sobrien  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
527389857Sobrien  sym_hashes = elf_sym_hashes (input_bfd);
5274104834Sobrien  is_opd = elf_section_data (input_section)->tdata != NULL;
527589857Sobrien
527689857Sobrien  rel = relocs;
527789857Sobrien  relend = relocs + input_section->reloc_count;
527889857Sobrien  for (; rel < relend; rel++)
527989857Sobrien    {
528089857Sobrien      enum elf_ppc_reloc_type r_type;
528189857Sobrien      bfd_vma offset;
528289857Sobrien      bfd_vma addend;
528389857Sobrien      bfd_reloc_status_type r;
528489857Sobrien      Elf_Internal_Sym *sym;
528589857Sobrien      asection *sec;
528689857Sobrien      struct elf_link_hash_entry *h;
5287104834Sobrien      struct elf_link_hash_entry *fdh;
528889857Sobrien      const char *sym_name;
528989857Sobrien      unsigned long r_symndx;
529089857Sobrien      bfd_vma relocation;
529189857Sobrien      boolean unresolved_reloc;
5292104834Sobrien      boolean warned;
529389857Sobrien      long insn;
5294104834Sobrien      struct ppc_stub_hash_entry *stub_entry;
5295104834Sobrien      bfd_vma max_br_offset;
529699461Sobrien      bfd_vma from;
529789857Sobrien
529889857Sobrien      r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info);
529989857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
530089857Sobrien      offset = rel->r_offset;
530189857Sobrien      addend = rel->r_addend;
530289857Sobrien      r = bfd_reloc_other;
530389857Sobrien      sym = (Elf_Internal_Sym *) 0;
530489857Sobrien      sec = (asection *) 0;
530589857Sobrien      h = (struct elf_link_hash_entry *) 0;
530689857Sobrien      sym_name = (const char *) 0;
530789857Sobrien      unresolved_reloc = false;
5308104834Sobrien      warned = false;
530989857Sobrien
531089857Sobrien      if (r_type == R_PPC64_TOC)
531189857Sobrien	{
531289857Sobrien	  /* Relocation value is TOC base.  Symbol is ignored.  */
531389857Sobrien	  relocation = TOCstart + TOC_BASE_OFF;
531489857Sobrien	}
531589857Sobrien      else if (r_symndx < symtab_hdr->sh_info)
531689857Sobrien	{
531789857Sobrien	  /* It's a local symbol.  */
531889857Sobrien	  sym = local_syms + r_symndx;
531989857Sobrien	  sec = local_sections[r_symndx];
532089857Sobrien	  sym_name = "<local symbol>";
532189857Sobrien
532289857Sobrien	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
532399461Sobrien	  /* rel may have changed, update our copy of addend.  */
532489857Sobrien	  addend = rel->r_addend;
5325104834Sobrien
5326104834Sobrien	  if (elf_section_data (sec) != NULL)
5327104834Sobrien	    {
5328104834Sobrien	      long *opd_sym_adjust;
5329104834Sobrien
5330104834Sobrien	      opd_sym_adjust = (long *) elf_section_data (sec)->tdata;
5331104834Sobrien	      if (opd_sym_adjust != NULL && sym->st_value % 24 == 0)
5332104834Sobrien		relocation += opd_sym_adjust[sym->st_value / 24];
5333104834Sobrien	    }
533489857Sobrien	}
533589857Sobrien      else
533689857Sobrien	{
533789857Sobrien	  /* It's a global symbol.  */
533889857Sobrien	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
533989857Sobrien	  while (h->root.type == bfd_link_hash_indirect
534089857Sobrien		 || h->root.type == bfd_link_hash_warning)
534189857Sobrien	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
534289857Sobrien	  sym_name = h->root.root.string;
534389857Sobrien	  relocation = 0;
534489857Sobrien	  if (h->root.type == bfd_link_hash_defined
534589857Sobrien	      || h->root.type == bfd_link_hash_defweak)
534689857Sobrien	    {
534789857Sobrien	      sec = h->root.u.def.section;
534889857Sobrien	      if (sec->output_section == NULL)
534989857Sobrien		/* Set a flag that will be cleared later if we find a
535089857Sobrien		   relocation value for this symbol.  output_section
535189857Sobrien		   is typically NULL for symbols satisfied by a shared
535289857Sobrien		   library.  */
535389857Sobrien		unresolved_reloc = true;
535489857Sobrien	      else
535589857Sobrien		relocation = (h->root.u.def.value
535689857Sobrien			      + sec->output_section->vma
535789857Sobrien			      + sec->output_offset);
535889857Sobrien	    }
535989857Sobrien	  else if (h->root.type == bfd_link_hash_undefweak)
536089857Sobrien	    ;
536189857Sobrien	  else if (info->shared
536289857Sobrien		   && (!info->symbolic || info->allow_shlib_undefined)
536389857Sobrien		   && !info->no_undefined
536489857Sobrien		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
536589857Sobrien	    ;
536689857Sobrien	  else
536789857Sobrien	    {
536889857Sobrien	      if (! ((*info->callbacks->undefined_symbol)
536989857Sobrien		     (info, h->root.root.string, input_bfd, input_section,
537089857Sobrien		      offset, (!info->shared
537189857Sobrien			       || info->no_undefined
537289857Sobrien			       || ELF_ST_VISIBILITY (h->other)))))
537389857Sobrien		return false;
5374104834Sobrien	      warned = true;
537589857Sobrien	    }
537689857Sobrien	}
537789857Sobrien
537889857Sobrien      /* First handle relocations that tweak non-addend part of insn.  */
537989857Sobrien      insn = 0;
538089857Sobrien      switch (r_type)
538189857Sobrien	{
538289857Sobrien	default:
538389857Sobrien	  break;
538489857Sobrien
538589857Sobrien	  /* Branch taken prediction relocations.  */
538689857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
538789857Sobrien	case R_PPC64_REL14_BRTAKEN:
5388104834Sobrien	  insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field.  */
5389104834Sobrien	  /* Fall thru.  */
539089857Sobrien
539189857Sobrien	  /* Branch not taken prediction relocations.  */
539289857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
539389857Sobrien	case R_PPC64_REL14_BRNTAKEN:
539489857Sobrien	  insn |= bfd_get_32 (output_bfd, contents + offset) & ~(0x01 << 21);
539592828Sobrien	  if (is_power4)
539692828Sobrien	    {
539792828Sobrien	      /* Set 'a' bit.  This is 0b00010 in BO field for branch
539892828Sobrien		 on CR(BI) insns (BO == 001at or 011at), and 0b01000
539992828Sobrien		 for branch on CTR insns (BO == 1a00t or 1a01t).  */
540092828Sobrien	      if ((insn & (0x14 << 21)) == (0x04 << 21))
540192828Sobrien		insn |= 0x02 << 21;
540292828Sobrien	      else if ((insn & (0x14 << 21)) == (0x10 << 21))
540392828Sobrien		insn |= 0x08 << 21;
540492828Sobrien	      else
540592828Sobrien		break;
540692828Sobrien	    }
540789857Sobrien	  else
540892828Sobrien	    {
540999461Sobrien	      from = (offset
541099461Sobrien		      + input_section->output_offset
541199461Sobrien		      + input_section->output_section->vma);
541299461Sobrien
541392828Sobrien	      /* Invert 'y' bit if not the default.  */
541499461Sobrien	      if ((bfd_signed_vma) (relocation + addend - from) < 0)
541592828Sobrien		insn ^= 0x01 << 21;
541692828Sobrien	    }
541789857Sobrien
541889857Sobrien	  bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
541989857Sobrien	  break;
542089857Sobrien
542189857Sobrien	case R_PPC64_REL24:
542299461Sobrien	  /* A REL24 branching to a linkage function is followed by a
542399461Sobrien	     nop.  We replace the nop with a ld in order to restore
542499461Sobrien	     the TOC base pointer.  Only calls to shared objects need
542599461Sobrien	     to alter the TOC base.  These are recognized by their
542699461Sobrien	     need for a PLT entry.  */
542789857Sobrien	  if (h != NULL
5428104834Sobrien	      && (fdh = ((struct ppc_link_hash_entry *) h)->oh) != NULL
5429104834Sobrien	      && fdh->plt.offset != (bfd_vma) -1
5430104834Sobrien	      && (stub_entry = ppc_get_stub_entry (input_section, sec, fdh,
5431104834Sobrien						   rel, htab)) != NULL)
543289857Sobrien	    {
543399461Sobrien	      boolean can_plt_call = 0;
543489857Sobrien
543589857Sobrien	      if (offset + 8 <= input_section->_cooked_size)
543689857Sobrien		{
543799461Sobrien		  insn = bfd_get_32 (input_bfd, contents + offset + 4);
543899461Sobrien		  if (insn == NOP
543999461Sobrien		      || insn == CROR_151515 || insn == CROR_313131)
544089857Sobrien		    {
544199461Sobrien		      bfd_put_32 (input_bfd, (bfd_vma) LD_R2_40R1,
544299461Sobrien				  contents + offset + 4);
544399461Sobrien		      can_plt_call = 1;
544489857Sobrien		    }
544589857Sobrien		}
544699461Sobrien
544799461Sobrien	      if (!can_plt_call)
544899461Sobrien		{
544999461Sobrien		  /* If this is a plain branch rather than a branch
545099461Sobrien		     and link, don't require a nop.  */
545199461Sobrien		  insn = bfd_get_32 (input_bfd, contents + offset);
545299461Sobrien		  if ((insn & 1) == 0)
545399461Sobrien		    can_plt_call = 1;
545499461Sobrien		}
545599461Sobrien
545699461Sobrien	      if (can_plt_call)
545799461Sobrien		{
5458104834Sobrien		  relocation = (stub_entry->stub_offset
5459104834Sobrien				+ stub_entry->stub_sec->output_offset
5460104834Sobrien				+ stub_entry->stub_sec->output_section->vma);
546199461Sobrien		  addend = 0;
546299461Sobrien		  unresolved_reloc = false;
546399461Sobrien		}
546489857Sobrien	    }
546589857Sobrien
546689857Sobrien	  if (h != NULL
546789857Sobrien	      && h->root.type == bfd_link_hash_undefweak
546899461Sobrien	      && relocation == 0
546999461Sobrien	      && addend == 0)
547089857Sobrien	    {
547199461Sobrien	      /* Tweak calls to undefined weak functions to point at a
547299461Sobrien		 blr.  We can thus call a weak function without first
547399461Sobrien		 checking whether the function is defined.  We have a
547499461Sobrien		 blr at the end of .sfpr.  */
547599461Sobrien	      BFD_ASSERT (htab->sfpr->_raw_size != 0);
547699461Sobrien	      relocation = (htab->sfpr->_raw_size - 4
547799461Sobrien			    + htab->sfpr->output_offset
547899461Sobrien			    + htab->sfpr->output_section->vma);
547999461Sobrien	      from = (offset
548099461Sobrien		      + input_section->output_offset
548199461Sobrien		      + input_section->output_section->vma);
548299461Sobrien
548399461Sobrien	      /* But let's not be silly about it.  If the blr isn't in
548499461Sobrien		 reach, just go to the next instruction.  */
548599461Sobrien	      if (relocation - from + (1 << 25) >= (1 << 26)
548699461Sobrien		  || htab->sfpr->_raw_size == 0)
548799461Sobrien		relocation = from + 4;
548889857Sobrien	    }
548989857Sobrien	  break;
549089857Sobrien	}
549189857Sobrien
549289857Sobrien      /* Set `addend'.  */
549389857Sobrien      switch (r_type)
549489857Sobrien	{
549589857Sobrien	default:
549689857Sobrien	  (*_bfd_error_handler)
549789857Sobrien	    (_("%s: unknown relocation type %d for symbol %s"),
549889857Sobrien	     bfd_archive_filename (input_bfd), (int) r_type, sym_name);
549989857Sobrien
550089857Sobrien	  bfd_set_error (bfd_error_bad_value);
550189857Sobrien	  ret = false;
550289857Sobrien	  continue;
550389857Sobrien
550489857Sobrien	case R_PPC64_NONE:
550589857Sobrien	case R_PPC_GNU_VTINHERIT:
550689857Sobrien	case R_PPC_GNU_VTENTRY:
550789857Sobrien	  continue;
550889857Sobrien
550989857Sobrien	  /* GOT16 relocations.  Like an ADDR16 using the symbol's
551089857Sobrien	     address in the GOT as relocation value instead of the
551189857Sobrien	     symbols value itself.  Also, create a GOT entry for the
551289857Sobrien	     symbol and put the symbol value there.  */
551389857Sobrien	case R_PPC64_GOT16:
551489857Sobrien	case R_PPC64_GOT16_LO:
551589857Sobrien	case R_PPC64_GOT16_HI:
551689857Sobrien	case R_PPC64_GOT16_HA:
551789857Sobrien	case R_PPC64_GOT16_DS:
551889857Sobrien	case R_PPC64_GOT16_LO_DS:
551989857Sobrien	  {
552089857Sobrien	    /* Relocation is to the entry for this symbol in the global
552189857Sobrien	       offset table.  */
552289857Sobrien	    bfd_vma off;
552389857Sobrien
552489857Sobrien	    if (htab->sgot == NULL)
552589857Sobrien	      abort ();
552689857Sobrien
552789857Sobrien	    if (h != NULL)
552889857Sobrien	      {
552989857Sobrien		boolean dyn;
553089857Sobrien
553189857Sobrien		off = h->got.offset;
553289857Sobrien		dyn = htab->elf.dynamic_sections_created;
553389857Sobrien		if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
553489857Sobrien		    || (info->shared
553589857Sobrien			&& (info->symbolic
553689857Sobrien			    || h->dynindx == -1
553789857Sobrien			    || (h->elf_link_hash_flags
553889857Sobrien				& ELF_LINK_FORCED_LOCAL))
553989857Sobrien			&& (h->elf_link_hash_flags
554089857Sobrien			    & ELF_LINK_HASH_DEF_REGULAR)))
554189857Sobrien		  {
554289857Sobrien		    /* This is actually a static link, or it is a
554389857Sobrien		       -Bsymbolic link and the symbol is defined
554489857Sobrien		       locally, or the symbol was forced to be local
554589857Sobrien		       because of a version file.  We must initialize
554689857Sobrien		       this entry in the global offset table.  Since the
554789857Sobrien		       offset must always be a multiple of 8, we use the
554889857Sobrien		       least significant bit to record whether we have
554989857Sobrien		       initialized it already.
555089857Sobrien
555189857Sobrien		       When doing a dynamic link, we create a .rel.got
555289857Sobrien		       relocation entry to initialize the value.  This
555389857Sobrien		       is done in the finish_dynamic_symbol routine.  */
555489857Sobrien		    if ((off & 1) != 0)
555589857Sobrien		      off &= ~1;
555689857Sobrien		    else
555789857Sobrien		      {
555889857Sobrien			bfd_put_64 (output_bfd, relocation,
555989857Sobrien				    htab->sgot->contents + off);
556089857Sobrien			h->got.offset |= 1;
556189857Sobrien		      }
556289857Sobrien		  }
556389857Sobrien		else
556489857Sobrien		  unresolved_reloc = false;
556589857Sobrien	      }
556689857Sobrien	    else
556789857Sobrien	      {
556889857Sobrien		if (local_got_offsets == NULL)
556989857Sobrien		  abort ();
557089857Sobrien
557189857Sobrien		off = local_got_offsets[r_symndx];
557289857Sobrien
557389857Sobrien		/* The offset must always be a multiple of 8.  We use
557489857Sobrien		   the least significant bit to record whether we have
557589857Sobrien		   already processed this entry.  */
557689857Sobrien		if ((off & 1) != 0)
557789857Sobrien		  off &= ~1;
557889857Sobrien		else
557989857Sobrien		  {
558089857Sobrien		    bfd_put_64 (output_bfd, relocation,
558189857Sobrien				htab->sgot->contents + off);
558289857Sobrien
558389857Sobrien		    if (info->shared)
558489857Sobrien		      {
558589857Sobrien			Elf_Internal_Rela outrel;
558689857Sobrien			Elf64_External_Rela *loc;
558789857Sobrien
558889857Sobrien			/* We need to generate a R_PPC64_RELATIVE reloc
558989857Sobrien			   for the dynamic linker.  */
559089857Sobrien			outrel.r_offset = (htab->sgot->output_section->vma
559189857Sobrien					   + htab->sgot->output_offset
559289857Sobrien					   + off);
559389857Sobrien			outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
559489857Sobrien			outrel.r_addend = relocation;
559589857Sobrien			loc = (Elf64_External_Rela *) htab->srelgot->contents;
559689857Sobrien			loc += htab->srelgot->reloc_count++;
559789857Sobrien			bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
559889857Sobrien		      }
559989857Sobrien
560089857Sobrien		    local_got_offsets[r_symndx] |= 1;
560189857Sobrien		  }
560289857Sobrien	      }
560389857Sobrien
560489857Sobrien	    if (off >= (bfd_vma) -2)
560589857Sobrien	      abort ();
560689857Sobrien
560789857Sobrien	    relocation = htab->sgot->output_offset + off;
560889857Sobrien
560989857Sobrien	    /* TOC base (r2) is TOC start plus 0x8000.  */
561089857Sobrien	    addend -= TOC_BASE_OFF;
561189857Sobrien	  }
561289857Sobrien	  break;
561389857Sobrien
561489857Sobrien	case R_PPC64_PLT16_HA:
561589857Sobrien	case R_PPC64_PLT16_HI:
561689857Sobrien	case R_PPC64_PLT16_LO:
561789857Sobrien	case R_PPC64_PLT32:
561889857Sobrien	case R_PPC64_PLT64:
561989857Sobrien	  /* Relocation is to the entry for this symbol in the
562089857Sobrien	     procedure linkage table.  */
562189857Sobrien
562289857Sobrien	  /* Resolve a PLT reloc against a local symbol directly,
562389857Sobrien	     without using the procedure linkage table.  */
562489857Sobrien	  if (h == NULL)
562589857Sobrien	    break;
562689857Sobrien
562789857Sobrien	  if (h->plt.offset == (bfd_vma) -1
562889857Sobrien	      || htab->splt == NULL)
562989857Sobrien	    {
563089857Sobrien	      /* We didn't make a PLT entry for this symbol.  This
563189857Sobrien		 happens when statically linking PIC code, or when
563289857Sobrien		 using -Bsymbolic.  */
563389857Sobrien	      break;
563489857Sobrien	    }
563589857Sobrien
563689857Sobrien	  relocation = (htab->splt->output_section->vma
563789857Sobrien			+ htab->splt->output_offset
563889857Sobrien			+ h->plt.offset);
563989857Sobrien	  unresolved_reloc = false;
564089857Sobrien	  break;
564189857Sobrien
564289857Sobrien	  /* TOC16 relocs.  We want the offset relative to the TOC base,
564389857Sobrien	     which is the address of the start of the TOC plus 0x8000.
564489857Sobrien	     The TOC consists of sections .got, .toc, .tocbss, and .plt,
564589857Sobrien	     in this order.  */
564689857Sobrien	case R_PPC64_TOC16:
564789857Sobrien	case R_PPC64_TOC16_LO:
564889857Sobrien	case R_PPC64_TOC16_HI:
564989857Sobrien	case R_PPC64_TOC16_DS:
565089857Sobrien	case R_PPC64_TOC16_LO_DS:
565189857Sobrien	case R_PPC64_TOC16_HA:
565289857Sobrien	  addend -= TOCstart + TOC_BASE_OFF;
565389857Sobrien	  break;
565489857Sobrien
565589857Sobrien	  /* Relocate against the beginning of the section.  */
565689857Sobrien	case R_PPC64_SECTOFF:
565789857Sobrien	case R_PPC64_SECTOFF_LO:
565889857Sobrien	case R_PPC64_SECTOFF_HI:
565989857Sobrien	case R_PPC64_SECTOFF_DS:
566089857Sobrien	case R_PPC64_SECTOFF_LO_DS:
566189857Sobrien	case R_PPC64_SECTOFF_HA:
566289857Sobrien	  if (sec != (asection *) 0)
566389857Sobrien	    addend -= sec->output_section->vma;
566489857Sobrien	  break;
566589857Sobrien
5666104834Sobrien	case R_PPC64_REL14:
5667104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
5668104834Sobrien	case R_PPC64_REL14_BRTAKEN:
566989857Sobrien	case R_PPC64_REL24:
567089857Sobrien	  break;
567189857Sobrien
567289857Sobrien	  /* Relocations that may need to be propagated if this is a
567389857Sobrien	     dynamic object.  */
567489857Sobrien	case R_PPC64_REL32:
567589857Sobrien	case R_PPC64_REL64:
567689857Sobrien	case R_PPC64_ADDR14:
567789857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
567889857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
567989857Sobrien	case R_PPC64_ADDR16:
568089857Sobrien	case R_PPC64_ADDR16_DS:
568189857Sobrien	case R_PPC64_ADDR16_HA:
568289857Sobrien	case R_PPC64_ADDR16_HI:
568389857Sobrien	case R_PPC64_ADDR16_HIGHER:
568489857Sobrien	case R_PPC64_ADDR16_HIGHERA:
568589857Sobrien	case R_PPC64_ADDR16_HIGHEST:
568689857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
568789857Sobrien	case R_PPC64_ADDR16_LO:
568889857Sobrien	case R_PPC64_ADDR16_LO_DS:
568989857Sobrien	case R_PPC64_ADDR24:
569089857Sobrien	case R_PPC64_ADDR30:
569189857Sobrien	case R_PPC64_ADDR32:
569289857Sobrien	case R_PPC64_ADDR64:
569389857Sobrien	case R_PPC64_UADDR16:
569489857Sobrien	case R_PPC64_UADDR32:
569589857Sobrien	case R_PPC64_UADDR64:
569689857Sobrien	  /* r_symndx will be zero only for relocs against symbols
569789857Sobrien	     from removed linkonce sections, or sections discarded by
569889857Sobrien	     a linker script.  */
569989857Sobrien	  if (r_symndx == 0)
570089857Sobrien	    break;
570189857Sobrien	  /* Fall thru.  */
570289857Sobrien
570389857Sobrien	case R_PPC64_TOC:
570489857Sobrien	  if ((input_section->flags & SEC_ALLOC) == 0)
570589857Sobrien	    break;
570689857Sobrien
570789857Sobrien	  if (NO_OPD_RELOCS && is_opd)
570889857Sobrien	    break;
570989857Sobrien
571089857Sobrien	  if ((info->shared
571189857Sobrien	       && (IS_ABSOLUTE_RELOC (r_type)
571289857Sobrien		   || (h != NULL
571389857Sobrien		       && h->dynindx != -1
571489857Sobrien		       && (! info->symbolic
571589857Sobrien			   || (h->elf_link_hash_flags
571689857Sobrien			       & ELF_LINK_HASH_DEF_REGULAR) == 0))))
571789857Sobrien	      || (!info->shared
571889857Sobrien		  && h != NULL
571989857Sobrien		  && h->dynindx != -1
572089857Sobrien		  && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
572189857Sobrien		  && (((h->elf_link_hash_flags
572289857Sobrien			& ELF_LINK_HASH_DEF_DYNAMIC) != 0
572389857Sobrien		       && (h->elf_link_hash_flags
572489857Sobrien			   & ELF_LINK_HASH_DEF_REGULAR) == 0)
572589857Sobrien		      || h->root.type == bfd_link_hash_undefweak
572689857Sobrien		      || h->root.type == bfd_link_hash_undefined)))
572789857Sobrien	    {
572889857Sobrien	      Elf_Internal_Rela outrel;
572989857Sobrien	      boolean skip, relocate;
573089857Sobrien	      asection *sreloc;
573189857Sobrien	      Elf64_External_Rela *loc;
573289857Sobrien
573389857Sobrien	      /* When generating a dynamic object, these relocations
573489857Sobrien		 are copied into the output file to be resolved at run
573589857Sobrien		 time.  */
573689857Sobrien
573789857Sobrien	      skip = false;
573891041Sobrien	      relocate = false;
573989857Sobrien
574089857Sobrien	      outrel.r_offset =
574189857Sobrien		_bfd_elf_section_offset (output_bfd, info, input_section,
574289857Sobrien					 rel->r_offset);
574389857Sobrien	      if (outrel.r_offset == (bfd_vma) -1)
574489857Sobrien		skip = true;
574591041Sobrien	      else if (outrel.r_offset == (bfd_vma) -2)
574691041Sobrien		skip = true, relocate = true;
574789857Sobrien	      outrel.r_offset += (input_section->output_section->vma
574889857Sobrien				  + input_section->output_offset);
574989857Sobrien	      outrel.r_addend = addend;
575089857Sobrien
575189857Sobrien	      if (skip)
575291041Sobrien		memset (&outrel, 0, sizeof outrel);
575389857Sobrien	      else if (h != NULL
575489857Sobrien		       && h->dynindx != -1
575589857Sobrien		       && !is_opd
575689857Sobrien		       && (!IS_ABSOLUTE_RELOC (r_type)
575789857Sobrien			   || !info->shared
575889857Sobrien			   || !info->symbolic
575989857Sobrien			   || (h->elf_link_hash_flags
576089857Sobrien			       & ELF_LINK_HASH_DEF_REGULAR) == 0))
576191041Sobrien		outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
576289857Sobrien	      else
576389857Sobrien		{
576489857Sobrien		  /* This symbol is local, or marked to become local,
576589857Sobrien		     or this is an opd section reloc which must point
576689857Sobrien		     at a local function.  */
576789857Sobrien		  outrel.r_addend += relocation;
576889857Sobrien		  relocate = true;
576989857Sobrien		  if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC)
577089857Sobrien		    {
5771104834Sobrien		      if (is_opd && h != NULL)
5772104834Sobrien			{
5773104834Sobrien			  /* Lie about opd entries.  This case occurs
5774104834Sobrien			     when building shared libraries and we
5775104834Sobrien			     reference a function in another shared
5776104834Sobrien			     lib.  The same thing happens for a weak
5777104834Sobrien			     definition in an application that's
5778104834Sobrien			     overridden by a strong definition in a
5779104834Sobrien			     shared lib.  (I believe this is a generic
5780104834Sobrien			     bug in binutils handling of weak syms.)
5781104834Sobrien			     In these cases we won't use the opd
5782104834Sobrien			     entry in this lib.  */
5783104834Sobrien			  unresolved_reloc = false;
5784104834Sobrien			}
578589857Sobrien		      outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
578689857Sobrien		    }
578789857Sobrien		  else
578889857Sobrien		    {
578989857Sobrien		      long indx = 0;
579089857Sobrien
579189857Sobrien		      if (bfd_is_abs_section (sec))
579289857Sobrien			;
579389857Sobrien		      else if (sec == NULL || sec->owner == NULL)
579489857Sobrien			{
579589857Sobrien			  bfd_set_error (bfd_error_bad_value);
579689857Sobrien			  return false;
579789857Sobrien			}
579889857Sobrien		      else
579989857Sobrien			{
580089857Sobrien			  asection *osec;
580189857Sobrien
580289857Sobrien			  osec = sec->output_section;
580389857Sobrien			  indx = elf_section_data (osec)->dynindx;
580489857Sobrien
580589857Sobrien			  /* We are turning this relocation into one
580689857Sobrien			     against a section symbol, so subtract out
580789857Sobrien			     the output section's address but not the
580889857Sobrien			     offset of the input section in the output
580989857Sobrien			     section.  */
581089857Sobrien			  outrel.r_addend -= osec->vma;
581189857Sobrien			}
581289857Sobrien
581389857Sobrien		      outrel.r_info = ELF64_R_INFO (indx, r_type);
581489857Sobrien		    }
581589857Sobrien		}
581689857Sobrien
581789857Sobrien	      sreloc = elf_section_data (input_section)->sreloc;
581889857Sobrien	      if (sreloc == NULL)
581989857Sobrien		abort ();
582089857Sobrien
582189857Sobrien	      loc = (Elf64_External_Rela *) sreloc->contents;
582289857Sobrien	      loc += sreloc->reloc_count++;
582389857Sobrien	      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
582489857Sobrien
582589857Sobrien	      /* If this reloc is against an external symbol, it will
582689857Sobrien		 be computed at runtime, so there's no need to do
582789857Sobrien		 anything now.  */
582889857Sobrien	      if (! relocate)
582989857Sobrien		continue;
583089857Sobrien	    }
583189857Sobrien	  break;
583289857Sobrien
583389857Sobrien	case R_PPC64_COPY:
583489857Sobrien	case R_PPC64_GLOB_DAT:
583589857Sobrien	case R_PPC64_JMP_SLOT:
583689857Sobrien	case R_PPC64_RELATIVE:
583789857Sobrien	  /* We shouldn't ever see these dynamic relocs in relocatable
583889857Sobrien	     files.  */
583989857Sobrien	  /* Fall thru */
584089857Sobrien
584189857Sobrien	case R_PPC64_PLTGOT16:
584289857Sobrien	case R_PPC64_PLTGOT16_DS:
584389857Sobrien	case R_PPC64_PLTGOT16_HA:
584489857Sobrien	case R_PPC64_PLTGOT16_HI:
584589857Sobrien	case R_PPC64_PLTGOT16_LO:
584689857Sobrien	case R_PPC64_PLTGOT16_LO_DS:
584789857Sobrien	case R_PPC64_PLTREL32:
584889857Sobrien	case R_PPC64_PLTREL64:
584989857Sobrien	  /* These ones haven't been implemented yet.  */
585089857Sobrien
585189857Sobrien	  (*_bfd_error_handler)
585289857Sobrien	    (_("%s: Relocation %s is not supported for symbol %s."),
585389857Sobrien	     bfd_archive_filename (input_bfd),
585489857Sobrien	     ppc64_elf_howto_table[(int) r_type]->name, sym_name);
585589857Sobrien
585689857Sobrien	  bfd_set_error (bfd_error_invalid_operation);
585789857Sobrien	  ret = false;
585889857Sobrien	  continue;
585989857Sobrien	}
586089857Sobrien
586189857Sobrien      /* Do any further special processing.  */
586289857Sobrien      switch (r_type)
586389857Sobrien	{
586489857Sobrien	default:
586589857Sobrien	  break;
586689857Sobrien
586789857Sobrien	case R_PPC64_ADDR16_HA:
586889857Sobrien	case R_PPC64_ADDR16_HIGHERA:
586989857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
587089857Sobrien	case R_PPC64_PLT16_HA:
587189857Sobrien	case R_PPC64_TOC16_HA:
587289857Sobrien	case R_PPC64_SECTOFF_HA:
587389857Sobrien	  /* It's just possible that this symbol is a weak symbol
587489857Sobrien	     that's not actually defined anywhere. In that case,
587589857Sobrien	     'sec' would be NULL, and we should leave the symbol
587689857Sobrien	     alone (it will be set to zero elsewhere in the link).  */
587789857Sobrien	  if (sec != NULL)
587889857Sobrien	    /* Add 0x10000 if sign bit in 0:15 is set.  */
587989857Sobrien	    addend += ((relocation + addend) & 0x8000) << 1;
588089857Sobrien	  break;
588189857Sobrien
588289857Sobrien	case R_PPC64_ADDR16_DS:
588389857Sobrien	case R_PPC64_ADDR16_LO_DS:
588489857Sobrien	case R_PPC64_GOT16_DS:
588589857Sobrien	case R_PPC64_GOT16_LO_DS:
588689857Sobrien	case R_PPC64_PLT16_LO_DS:
588789857Sobrien	case R_PPC64_SECTOFF_DS:
588889857Sobrien	case R_PPC64_SECTOFF_LO_DS:
588989857Sobrien	case R_PPC64_TOC16_DS:
589089857Sobrien	case R_PPC64_TOC16_LO_DS:
589189857Sobrien	case R_PPC64_PLTGOT16_DS:
589289857Sobrien	case R_PPC64_PLTGOT16_LO_DS:
589389857Sobrien	  if (((relocation + addend) & 3) != 0)
589489857Sobrien	    {
589589857Sobrien	      (*_bfd_error_handler)
589689857Sobrien		(_("%s: error: relocation %s not a multiple of 4"),
589789857Sobrien		 bfd_archive_filename (input_bfd),
589889857Sobrien		 ppc64_elf_howto_table[(int) r_type]->name);
589989857Sobrien	      bfd_set_error (bfd_error_bad_value);
590089857Sobrien	      ret = false;
590189857Sobrien	      continue;
590289857Sobrien	    }
590389857Sobrien	  break;
5904104834Sobrien
5905104834Sobrien	case R_PPC64_REL14:
5906104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
5907104834Sobrien	case R_PPC64_REL14_BRTAKEN:
5908104834Sobrien	  max_br_offset = 1 << 15;
5909104834Sobrien	  goto branch_check;
5910104834Sobrien
5911104834Sobrien	case R_PPC64_REL24:
5912104834Sobrien	  max_br_offset = 1 << 25;
5913104834Sobrien
5914104834Sobrien	branch_check:
5915104834Sobrien	  /* If the branch is out of reach, then redirect the
5916104834Sobrien	     call to the local stub for this function.  */
5917104834Sobrien	  from = (offset
5918104834Sobrien		  + input_section->output_offset
5919104834Sobrien		  + input_section->output_section->vma);
5920104834Sobrien	  if (relocation + addend - from + max_br_offset >= 2 * max_br_offset
5921104834Sobrien	      && (stub_entry = ppc_get_stub_entry (input_section, sec, h,
5922104834Sobrien						   rel, htab)) != NULL)
5923104834Sobrien	    {
5924104834Sobrien	      /* Munge up the value and addend so that we call the stub
5925104834Sobrien		 rather than the procedure directly.  */
5926104834Sobrien	      relocation = (stub_entry->stub_offset
5927104834Sobrien			    + stub_entry->stub_sec->output_offset
5928104834Sobrien			    + stub_entry->stub_sec->output_section->vma);
5929104834Sobrien	      addend = 0;
5930104834Sobrien	    }
5931104834Sobrien	  break;
593289857Sobrien	}
593389857Sobrien
5934104834Sobrien      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
5935104834Sobrien	 because such sections are not SEC_ALLOC and thus ld.so will
5936104834Sobrien	 not process them.  */
593789857Sobrien      if (unresolved_reloc
5938104834Sobrien	  && !((input_section->flags & SEC_DEBUGGING) != 0
593989857Sobrien	       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
5940104834Sobrien	{
5941104834Sobrien	  (*_bfd_error_handler)
5942104834Sobrien	    (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
5943104834Sobrien	     bfd_archive_filename (input_bfd),
5944104834Sobrien	     bfd_get_section_name (input_bfd, input_section),
5945104834Sobrien	     (long) rel->r_offset,
5946104834Sobrien	     h->root.root.string);
5947104834Sobrien	  ret = false;
5948104834Sobrien	}
594989857Sobrien
595089857Sobrien      r = _bfd_final_link_relocate (ppc64_elf_howto_table[(int) r_type],
595189857Sobrien				    input_bfd,
595289857Sobrien				    input_section,
595389857Sobrien				    contents,
595489857Sobrien				    offset,
595589857Sobrien				    relocation,
595689857Sobrien				    addend);
595789857Sobrien
5958104834Sobrien      if (r != bfd_reloc_ok)
595989857Sobrien	{
596089857Sobrien	  const char *name;
596189857Sobrien
596289857Sobrien	  if (h != NULL)
596389857Sobrien	    {
596489857Sobrien	      if (h->root.type == bfd_link_hash_undefweak
596589857Sobrien		  && ppc64_elf_howto_table[(int) r_type]->pc_relative)
596689857Sobrien		{
596789857Sobrien		  /* Assume this is a call protected by other code that
596889857Sobrien		     detects the symbol is undefined.  If this is the case,
596989857Sobrien		     we can safely ignore the overflow.  If not, the
597089857Sobrien		     program is hosed anyway, and a little warning isn't
597189857Sobrien		     going to help.  */
597289857Sobrien
597389857Sobrien		  continue;
597489857Sobrien		}
597589857Sobrien
597689857Sobrien	      name = h->root.root.string;
597789857Sobrien	    }
597889857Sobrien	  else
597989857Sobrien	    {
598089857Sobrien	      name = bfd_elf_string_from_elf_section (input_bfd,
598189857Sobrien						      symtab_hdr->sh_link,
598289857Sobrien						      sym->st_name);
598389857Sobrien	      if (name == NULL)
598489857Sobrien		continue;
598589857Sobrien	      if (*name == '\0')
598689857Sobrien		name = bfd_section_name (input_bfd, sec);
598789857Sobrien	    }
598889857Sobrien
5989104834Sobrien	  if (r == bfd_reloc_overflow)
5990104834Sobrien	    {
5991104834Sobrien	      if (warned)
5992104834Sobrien		continue;
5993104834Sobrien	      if (!((*info->callbacks->reloc_overflow)
5994104834Sobrien		    (info, name, ppc64_elf_howto_table[(int) r_type]->name,
5995104834Sobrien		     rel->r_addend, input_bfd, input_section, offset)))
5996104834Sobrien		return false;
5997104834Sobrien	    }
5998104834Sobrien	  else
5999104834Sobrien	    {
6000104834Sobrien	      (*_bfd_error_handler)
6001104834Sobrien		(_("%s(%s+0x%lx): reloc against `%s': error %d"),
6002104834Sobrien		 bfd_archive_filename (input_bfd),
6003104834Sobrien		 bfd_get_section_name (input_bfd, input_section),
6004104834Sobrien		 (long) rel->r_offset, name, (int) r);
6005104834Sobrien	      ret = false;
6006104834Sobrien	    }
600789857Sobrien	}
600889857Sobrien    }
600989857Sobrien
601089857Sobrien  return ret;
601189857Sobrien}
601289857Sobrien
601389857Sobrien/* Finish up dynamic symbol handling.  We set the contents of various
601489857Sobrien   dynamic sections here.  */
601589857Sobrien
601689857Sobrienstatic boolean
601789857Sobrienppc64_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
601889857Sobrien     bfd *output_bfd;
601989857Sobrien     struct bfd_link_info *info;
602089857Sobrien     struct elf_link_hash_entry *h;
602189857Sobrien     Elf_Internal_Sym *sym;
602289857Sobrien{
602389857Sobrien  struct ppc_link_hash_table *htab;
602489857Sobrien  bfd *dynobj;
602589857Sobrien
602689857Sobrien  htab = ppc_hash_table (info);
602789857Sobrien  dynobj = htab->elf.dynobj;
602889857Sobrien
602989857Sobrien  if (h->plt.offset != (bfd_vma) -1
603089857Sobrien      && ((struct ppc_link_hash_entry *) h)->is_func_descriptor)
603189857Sobrien    {
603289857Sobrien      Elf_Internal_Rela rela;
603389857Sobrien      Elf64_External_Rela *loc;
603489857Sobrien
603589857Sobrien      /* This symbol has an entry in the procedure linkage table.  Set
6036104834Sobrien	 it up.  */
603789857Sobrien
603889857Sobrien      if (htab->splt == NULL
603989857Sobrien	  || htab->srelplt == NULL
604089857Sobrien	  || htab->sglink == NULL)
604189857Sobrien	abort ();
604289857Sobrien
604389857Sobrien      /* Create a JMP_SLOT reloc to inform the dynamic linker to
604489857Sobrien	 fill in the PLT entry.  */
604589857Sobrien
604689857Sobrien      rela.r_offset = (htab->splt->output_section->vma
604789857Sobrien		       + htab->splt->output_offset
604889857Sobrien		       + h->plt.offset);
604989857Sobrien      rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
605089857Sobrien      rela.r_addend = 0;
605189857Sobrien
605289857Sobrien      loc = (Elf64_External_Rela *) htab->srelplt->contents;
605389857Sobrien      loc += (h->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE;
605489857Sobrien      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
605589857Sobrien    }
605689857Sobrien
605789857Sobrien  if (h->got.offset != (bfd_vma) -1)
605889857Sobrien    {
605989857Sobrien      Elf_Internal_Rela rela;
606089857Sobrien      Elf64_External_Rela *loc;
606189857Sobrien
606289857Sobrien      /* This symbol has an entry in the global offset table.  Set it
6063104834Sobrien	 up.  */
606489857Sobrien
606589857Sobrien      if (htab->sgot == NULL || htab->srelgot == NULL)
606689857Sobrien	abort ();
606789857Sobrien
606889857Sobrien      rela.r_offset = (htab->sgot->output_section->vma
606989857Sobrien		       + htab->sgot->output_offset
607089857Sobrien		       + (h->got.offset &~ (bfd_vma) 1));
607189857Sobrien
607289857Sobrien      /* If this is a static link, or it is a -Bsymbolic link and the
607389857Sobrien	 symbol is defined locally or was forced to be local because
607489857Sobrien	 of a version file, we just want to emit a RELATIVE reloc.
607589857Sobrien	 The entry in the global offset table will already have been
607689857Sobrien	 initialized in the relocate_section function.  */
607789857Sobrien      if (info->shared
607889857Sobrien	  && (info->symbolic
607989857Sobrien	      || h->dynindx == -1
608089857Sobrien	      || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
608189857Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
608289857Sobrien	{
608389857Sobrien	  BFD_ASSERT((h->got.offset & 1) != 0);
608489857Sobrien	  rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
608589857Sobrien	  rela.r_addend = (h->root.u.def.value
608689857Sobrien			   + h->root.u.def.section->output_section->vma
608789857Sobrien			   + h->root.u.def.section->output_offset);
608889857Sobrien	}
608989857Sobrien      else
609089857Sobrien	{
609189857Sobrien	  BFD_ASSERT ((h->got.offset & 1) == 0);
609289857Sobrien	  bfd_put_64 (output_bfd, (bfd_vma) 0,
609389857Sobrien		      htab->sgot->contents + h->got.offset);
609489857Sobrien	  rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_GLOB_DAT);
609589857Sobrien	  rela.r_addend = 0;
609689857Sobrien	}
609789857Sobrien
609889857Sobrien      loc = (Elf64_External_Rela *) htab->srelgot->contents;
609989857Sobrien      loc += htab->srelgot->reloc_count++;
610089857Sobrien      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
610189857Sobrien    }
610289857Sobrien
610389857Sobrien  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
610489857Sobrien    {
610589857Sobrien      Elf_Internal_Rela rela;
610689857Sobrien      Elf64_External_Rela *loc;
610789857Sobrien
610889857Sobrien      /* This symbol needs a copy reloc.  Set it up.  */
610989857Sobrien
611089857Sobrien      if (h->dynindx == -1
611189857Sobrien	  || (h->root.type != bfd_link_hash_defined
611289857Sobrien	      && h->root.type != bfd_link_hash_defweak)
611389857Sobrien	  || htab->srelbss == NULL)
611489857Sobrien	abort ();
611589857Sobrien
611689857Sobrien      rela.r_offset = (h->root.u.def.value
611789857Sobrien		       + h->root.u.def.section->output_section->vma
611889857Sobrien		       + h->root.u.def.section->output_offset);
611989857Sobrien      rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_COPY);
612089857Sobrien      rela.r_addend = 0;
612189857Sobrien      loc = (Elf64_External_Rela *) htab->srelbss->contents;
612289857Sobrien      loc += htab->srelbss->reloc_count++;
612389857Sobrien      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
612489857Sobrien    }
612589857Sobrien
612689857Sobrien  /* Mark some specially defined symbols as absolute.  */
612789857Sobrien  if (strcmp (h->root.root.string, "_DYNAMIC") == 0)
612889857Sobrien    sym->st_shndx = SHN_ABS;
612989857Sobrien
613089857Sobrien  return true;
613189857Sobrien}
613289857Sobrien
613389857Sobrien/* Used to decide how to sort relocs in an optimal manner for the
613489857Sobrien   dynamic linker, before writing them out.  */
613589857Sobrien
613689857Sobrienstatic enum elf_reloc_type_class
613789857Sobrienppc64_elf_reloc_type_class (rela)
613889857Sobrien     const Elf_Internal_Rela *rela;
613989857Sobrien{
614089857Sobrien  enum elf_ppc_reloc_type r_type;
614189857Sobrien
614289857Sobrien  r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rela->r_info);
614389857Sobrien  switch (r_type)
614489857Sobrien    {
614589857Sobrien    case R_PPC64_RELATIVE:
614689857Sobrien      return reloc_class_relative;
614789857Sobrien    case R_PPC64_JMP_SLOT:
614889857Sobrien      return reloc_class_plt;
614989857Sobrien    case R_PPC64_COPY:
615089857Sobrien      return reloc_class_copy;
615189857Sobrien    default:
615289857Sobrien      return reloc_class_normal;
615389857Sobrien    }
615489857Sobrien}
615589857Sobrien
615689857Sobrien/* Finish up the dynamic sections.  */
615789857Sobrien
615889857Sobrienstatic boolean
615989857Sobrienppc64_elf_finish_dynamic_sections (output_bfd, info)
616089857Sobrien     bfd *output_bfd;
616189857Sobrien     struct bfd_link_info *info;
616289857Sobrien{
616389857Sobrien  struct ppc_link_hash_table *htab;
616489857Sobrien  bfd *dynobj;
616589857Sobrien  asection *sdyn;
616689857Sobrien
616789857Sobrien  htab = ppc_hash_table (info);
616889857Sobrien  dynobj = htab->elf.dynobj;
616989857Sobrien  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
617089857Sobrien
617189857Sobrien  if (htab->elf.dynamic_sections_created)
617289857Sobrien    {
617389857Sobrien      Elf64_External_Dyn *dyncon, *dynconend;
617489857Sobrien
617589857Sobrien      if (sdyn == NULL || htab->sgot == NULL)
617689857Sobrien	abort ();
617789857Sobrien
617889857Sobrien      dyncon = (Elf64_External_Dyn *) sdyn->contents;
617989857Sobrien      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
618089857Sobrien      for (; dyncon < dynconend; dyncon++)
618189857Sobrien	{
618289857Sobrien	  Elf_Internal_Dyn dyn;
618391041Sobrien	  asection *s;
618489857Sobrien
618589857Sobrien	  bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
618689857Sobrien
618789857Sobrien	  switch (dyn.d_tag)
618889857Sobrien	    {
618989857Sobrien	    default:
619089857Sobrien	      continue;
619189857Sobrien
619289857Sobrien	    case DT_PPC64_GLINK:
619389857Sobrien	      dyn.d_un.d_ptr = (htab->sglink->output_section->vma
619489857Sobrien				+ htab->sglink->output_offset);
619589857Sobrien	      break;
619689857Sobrien
619791041Sobrien	    case DT_PPC64_OPD:
619891041Sobrien	      s = bfd_get_section_by_name (output_bfd, ".opd");
619991041Sobrien	      if (s != NULL)
620091041Sobrien		dyn.d_un.d_ptr = s->vma;
620191041Sobrien	      break;
620291041Sobrien
620391041Sobrien	    case DT_PPC64_OPDSZ:
620491041Sobrien	      s = bfd_get_section_by_name (output_bfd, ".opd");
620591041Sobrien	      if (s != NULL)
620691041Sobrien		dyn.d_un.d_val = s->_raw_size;
620791041Sobrien	      break;
620891041Sobrien
620989857Sobrien	    case DT_PLTGOT:
621089857Sobrien	      dyn.d_un.d_ptr = (htab->splt->output_section->vma
621189857Sobrien				+ htab->splt->output_offset);
621289857Sobrien	      break;
621389857Sobrien
621489857Sobrien	    case DT_JMPREL:
621589857Sobrien	      dyn.d_un.d_ptr = (htab->srelplt->output_section->vma
621689857Sobrien				+ htab->srelplt->output_offset);
621789857Sobrien	      break;
621889857Sobrien
621989857Sobrien	    case DT_PLTRELSZ:
622089857Sobrien	      dyn.d_un.d_val = htab->srelplt->_raw_size;
622189857Sobrien	      break;
622289857Sobrien
622389857Sobrien	    case DT_RELASZ:
622489857Sobrien	      /* Don't count procedure linkage table relocs in the
622589857Sobrien		 overall reloc count.  */
622689857Sobrien	      if (htab->srelplt != NULL)
622789857Sobrien		dyn.d_un.d_val -= htab->srelplt->_raw_size;
622889857Sobrien	      break;
622989857Sobrien	    }
623089857Sobrien
623189857Sobrien	  bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
623289857Sobrien	}
623389857Sobrien    }
623489857Sobrien
623589857Sobrien  if (htab->sgot != NULL && htab->sgot->_raw_size != 0)
623689857Sobrien    {
623789857Sobrien      /* Fill in the first entry in the global offset table.
623889857Sobrien	 We use it to hold the link-time TOCbase.  */
623989857Sobrien      bfd_put_64 (output_bfd,
624089857Sobrien		  elf_gp (output_bfd) + TOC_BASE_OFF,
624189857Sobrien		  htab->sgot->contents);
624289857Sobrien
624389857Sobrien      /* Set .got entry size.  */
624489857Sobrien      elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 8;
624589857Sobrien    }
624689857Sobrien
624789857Sobrien  if (htab->splt != NULL && htab->splt->_raw_size != 0)
624889857Sobrien    {
624989857Sobrien      /* Set .plt entry size.  */
625089857Sobrien      elf_section_data (htab->splt->output_section)->this_hdr.sh_entsize
625189857Sobrien	= PLT_ENTRY_SIZE;
625289857Sobrien    }
625389857Sobrien
625489857Sobrien  return true;
625589857Sobrien}
625689857Sobrien
625789857Sobrien#define TARGET_LITTLE_SYM	bfd_elf64_powerpcle_vec
625889857Sobrien#define TARGET_LITTLE_NAME	"elf64-powerpcle"
625989857Sobrien#define TARGET_BIG_SYM		bfd_elf64_powerpc_vec
626089857Sobrien#define TARGET_BIG_NAME		"elf64-powerpc"
626189857Sobrien#define ELF_ARCH		bfd_arch_powerpc
626289857Sobrien#define ELF_MACHINE_CODE	EM_PPC64
626389857Sobrien#define ELF_MAXPAGESIZE		0x10000
626489857Sobrien#define elf_info_to_howto	ppc64_elf_info_to_howto
626589857Sobrien
626689857Sobrien#ifdef  EM_CYGNUS_POWERPC
626789857Sobrien#define ELF_MACHINE_ALT1	EM_CYGNUS_POWERPC
626889857Sobrien#endif
626989857Sobrien
627089857Sobrien#ifdef EM_PPC_OLD
627189857Sobrien#define ELF_MACHINE_ALT2	EM_PPC_OLD
627289857Sobrien#endif
627389857Sobrien
627489857Sobrien#define elf_backend_want_got_sym 0
627589857Sobrien#define elf_backend_want_plt_sym 0
627689857Sobrien#define elf_backend_plt_alignment 3
627789857Sobrien#define elf_backend_plt_not_loaded 1
627889857Sobrien#define elf_backend_got_symbol_offset 0
627989857Sobrien#define elf_backend_got_header_size 8
628089857Sobrien#define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE
628189857Sobrien#define elf_backend_can_gc_sections 1
628289857Sobrien#define elf_backend_can_refcount 1
628399461Sobrien#define elf_backend_rela_normal 1
628489857Sobrien
628589857Sobrien#define bfd_elf64_bfd_reloc_type_lookup	      ppc64_elf_reloc_type_lookup
628689857Sobrien#define bfd_elf64_bfd_merge_private_bfd_data  ppc64_elf_merge_private_bfd_data
628789857Sobrien#define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
6288104834Sobrien#define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
628989857Sobrien
6290104834Sobrien#define elf_backend_object_p		      ppc64_elf_object_p
629189857Sobrien#define elf_backend_create_dynamic_sections   ppc64_elf_create_dynamic_sections
629289857Sobrien#define elf_backend_copy_indirect_symbol      ppc64_elf_copy_indirect_symbol
629389857Sobrien#define elf_backend_check_relocs	      ppc64_elf_check_relocs
629489857Sobrien#define elf_backend_gc_mark_hook	      ppc64_elf_gc_mark_hook
629589857Sobrien#define elf_backend_gc_sweep_hook	      ppc64_elf_gc_sweep_hook
629689857Sobrien#define elf_backend_adjust_dynamic_symbol     ppc64_elf_adjust_dynamic_symbol
629789857Sobrien#define elf_backend_hide_symbol		      ppc64_elf_hide_symbol
629889857Sobrien#define elf_backend_always_size_sections      ppc64_elf_func_desc_adjust
629989857Sobrien#define elf_backend_size_dynamic_sections     ppc64_elf_size_dynamic_sections
630089857Sobrien#define elf_backend_relocate_section	      ppc64_elf_relocate_section
630189857Sobrien#define elf_backend_finish_dynamic_symbol     ppc64_elf_finish_dynamic_symbol
630289857Sobrien#define elf_backend_reloc_type_class	      ppc64_elf_reloc_type_class
630389857Sobrien#define elf_backend_finish_dynamic_sections   ppc64_elf_finish_dynamic_sections
630489857Sobrien
630589857Sobrien#include "elf64-target.h"
6306