elf32-ppc.c revision 104834
118334Speter/* PowerPC-specific support for 32-bit ELF
272562Sobrien   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3169689Skan   Free Software Foundation, Inc.
4169689Skan   Written by Ian Lance Taylor, Cygnus Support.
518334Speter
690075SobrienThis file is part of BFD, the Binary File Descriptor library.
718334Speter
890075SobrienThis program is free software; you can redistribute it and/or modify
990075Sobrienit under the terms of the GNU General Public License as published by
1090075Sobrienthe Free Software Foundation; either version 2 of the License, or
1190075Sobrien(at your option) any later version.
1218334Speter
1390075SobrienThis program is distributed in the hope that it will be useful,
1490075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1590075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1690075SobrienGNU General Public License for more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1990075Sobrienalong with this program; if not, write to the Free Software
20169689SkanFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21169689Skan
2218334Speter/* This file is based on a preliminary PowerPC ELF ABI.  The
2352284Sobrien   information may not match the final PowerPC ELF ABI.  It includes
2452284Sobrien   suggestions from the in-progress Embedded PowerPC ABI, and that
2552284Sobrien   information may also not match.  */
2618334Speter
2752284Sobrien#include "bfd.h"
2852284Sobrien#include "sysdep.h"
2952284Sobrien#include "bfdlink.h"
3018334Speter#include "libbfd.h"
3118334Speter#include "elf-bfd.h"
3218334Speter#include "elf/ppc.h"
3318334Speter
3418334Speter#define USE_RELA		/* we want RELA relocations, not REL */
3518334Speter
3618334Speterstatic reloc_howto_type *ppc_elf_reloc_type_lookup
3752284Sobrien  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
3852284Sobrienstatic void ppc_elf_info_to_howto
3952284Sobrien  PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
4052284Sobrienstatic void ppc_elf_howto_init PARAMS ((void));
4118334Speterstatic int ppc_elf_sort_rela PARAMS ((const PTR, const PTR));
4252284Sobrienstatic boolean ppc_elf_relax_section
4318334Speter  PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
4418334Speterstatic bfd_reloc_status_type ppc_elf_addr16_ha_reloc
4518334Speter  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
4618334Speterstatic boolean ppc_elf_object_p PARAMS ((bfd *));
4718334Speterstatic boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword));
4818334Speterstatic boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
4918334Speter
5018334Speterstatic int ppc_elf_additional_program_headers PARAMS ((bfd *));
5118334Speterstatic boolean ppc_elf_modify_segment_map PARAMS ((bfd *));
5218334Speter
5352284Sobrienstatic asection *ppc_elf_create_got
5418334Speter  PARAMS ((bfd *, struct bfd_link_info *));
5552284Sobrienstatic boolean ppc_elf_create_dynamic_sections
5652284Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
5752284Sobrien
5852284Sobrienstatic boolean ppc_elf_section_from_shdr PARAMS ((bfd *,
5918334Speter						  Elf32_Internal_Shdr *,
6090075Sobrien						  const char *));
6118334Speterstatic boolean ppc_elf_fake_sections
6218334Speter  PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
6318334Speter
6418334Speterstatic elf_linker_section_t *ppc_elf_create_linker_section
6518334Speter  PARAMS ((bfd *abfd,
6618334Speter	   struct bfd_link_info *info,
6718334Speter	   enum elf_linker_section_enum));
6818334Speter
6918334Speterstatic boolean ppc_elf_check_relocs PARAMS ((bfd *,
7018334Speter					     struct bfd_link_info *,
7118334Speter					     asection *,
7218334Speter					     const Elf_Internal_Rela *));
7318334Speter
7418334Speterstatic asection * ppc_elf_gc_mark_hook PARAMS ((asection *sec,
7518334Speter						struct bfd_link_info *info,
7618334Speter						Elf_Internal_Rela *rel,
7718334Speter						struct elf_link_hash_entry *h,
7818334Speter						Elf_Internal_Sym *sym));
7918334Speter
8018334Speterstatic boolean ppc_elf_gc_sweep_hook PARAMS ((bfd *abfd,
8118334Speter					      struct bfd_link_info *info,
8218334Speter					      asection *sec,
8318334Speter					      const Elf_Internal_Rela *relocs));
8418334Speter
8518334Speterstatic boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,
8618334Speter						      struct elf_link_hash_entry *));
8718334Speter
8818334Speterstatic boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
8918334Speter
9018334Speterstatic boolean ppc_elf_relocate_section PARAMS ((bfd *,
9118334Speter						 struct bfd_link_info *info,
9218334Speter						 bfd *,
9318334Speter						 asection *,
9418334Speter						 bfd_byte *,
9518334Speter						 Elf_Internal_Rela *relocs,
9618334Speter						 Elf_Internal_Sym *local_syms,
9718334Speter						 asection **));
9818334Speter
9918334Speterstatic boolean ppc_elf_add_symbol_hook  PARAMS ((bfd *,
10018334Speter						 struct bfd_link_info *,
10118334Speter						 const Elf_Internal_Sym *,
10218334Speter						 const char **,
10318334Speter						 flagword *,
10418334Speter						 asection **,
10518334Speter						 bfd_vma *));
10618334Speter
10790075Sobrienstatic boolean ppc_elf_finish_dynamic_symbol PARAMS ((bfd *,
108161651Skan						      struct bfd_link_info *,
10952284Sobrien						      struct elf_link_hash_entry *,
11052284Sobrien						      Elf_Internal_Sym *));
11152284Sobrien
11252284Sobrienstatic boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
11390075Sobrienstatic enum elf_reloc_type_class ppc_elf_reloc_type_class
11452284Sobrien  PARAMS ((const Elf_Internal_Rela *));
11552284Sobrienstatic boolean ppc_elf_grok_prstatus
116169689Skan  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
11752284Sobrienstatic boolean ppc_elf_grok_psinfo
11852284Sobrien  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
11952284Sobrien
12052284Sobrien#define BRANCH_PREDICT_BIT 0x200000		/* branch prediction bit for branch taken relocs */
12118334Speter#define RA_REGISTER_MASK 0x001f0000		/* mask to set RA in memory instructions */
12218334Speter#define RA_REGISTER_SHIFT 16			/* value to shift register by to insert RA */
12350397Sobrien
124132718Skan/* The name of the dynamic interpreter.  This is put in the .interp
125132718Skan   section.  */
12690075Sobrien
12718334Speter#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
12890075Sobrien
12990075Sobrien/* The size in bytes of an entry in the procedure linkage table.  */
13018334Speter#define PLT_ENTRY_SIZE 12
13118334Speter/* The initial size of the plt reserved for the dynamic linker.  */
13218334Speter#define PLT_INITIAL_ENTRY_SIZE 72
13318334Speter/* The size of the gap between entries in the PLT.  */
13418334Speter#define PLT_SLOT_SIZE 8
13590075Sobrien/* The number of single-slot PLT entries (the rest use two slots).  */
13650397Sobrien#define PLT_NUM_SINGLE_ENTRIES 8192
13750397Sobrien
13852284Sobrien/* Will references to this symbol always reference the symbol
13990075Sobrien   in this object?  */
14090075Sobrien#define SYMBOL_REFERENCES_LOCAL(INFO, H)				\
14118334Speter  ((! INFO->shared							\
14218334Speter    || INFO->symbolic							\
14390075Sobrien    || H->dynindx == -1							\
144169689Skan    || ELF_ST_VISIBILITY (H->other) == STV_INTERNAL			\
145169689Skan    || ELF_ST_VISIBILITY (H->other) == STV_HIDDEN)			\
14690075Sobrien   && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
14790075Sobrien
14890075Sobrien/* Will _calls_ to this symbol always call the version in this object?  */
14990075Sobrien#define SYMBOL_CALLS_LOCAL(INFO, H)				\
15090075Sobrien  ((! INFO->shared							\
15190075Sobrien    || INFO->symbolic							\
15290075Sobrien    || H->dynindx == -1							\
15390075Sobrien    || ELF_ST_VISIBILITY (H->other) != STV_DEFAULT)			\
15490075Sobrien   && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
15590075Sobrien
15652284Sobrienstatic reloc_howto_type *ppc_elf_howto_table[(int) R_PPC_max];
15790075Sobrien
15890075Sobrienstatic reloc_howto_type ppc_elf_howto_raw[] = {
15990075Sobrien  /* This reloc does nothing.  */
16096263Sobrien  HOWTO (R_PPC_NONE,		/* type */
16196263Sobrien	 0,			/* rightshift */
16296263Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
16350397Sobrien	 32,			/* bitsize */
16490075Sobrien	 false,			/* pc_relative */
16590075Sobrien	 0,			/* bitpos */
166169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
167169689Skan	 bfd_elf_generic_reloc,	/* special_function */
16890075Sobrien	 "R_PPC_NONE",		/* name */
16990075Sobrien	 false,			/* partial_inplace */
17050397Sobrien	 0,			/* src_mask */
171169689Skan	 0,			/* dst_mask */
172169689Skan	 false),		/* pcrel_offset */
173169689Skan
174169689Skan  /* A standard 32 bit relocation.  */
175169689Skan  HOWTO (R_PPC_ADDR32,		/* type */
17652284Sobrien	 0,			/* rightshift */
17752284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
17818334Speter	 32,			/* bitsize */
17918334Speter	 false,			/* pc_relative */
18018334Speter	 0,			/* bitpos */
18118334Speter	 complain_overflow_bitfield, /* complain_on_overflow */
18218334Speter	 bfd_elf_generic_reloc,	/* special_function */
18350397Sobrien	 "R_PPC_ADDR32",	/* name */
18418334Speter	 false,			/* partial_inplace */
185169689Skan	 0,			/* src_mask */
18618334Speter	 0xffffffff,		/* dst_mask */
18718334Speter	 false),		/* pcrel_offset */
18852284Sobrien
18918334Speter  /* An absolute 26 bit branch; the lower two bits must be zero.
190169689Skan     FIXME: we don't check that, we just clear them.  */
19118334Speter  HOWTO (R_PPC_ADDR24,		/* type */
19218334Speter	 0,			/* rightshift */
19318334Speter	 2,			/* size (0 = byte, 1 = short, 2 = long) */
19418334Speter	 26,			/* bitsize */
19518334Speter	 false,			/* pc_relative */
19618334Speter	 0,			/* bitpos */
19718334Speter	 complain_overflow_bitfield, /* complain_on_overflow */
19818334Speter	 bfd_elf_generic_reloc,	/* special_function */
19918334Speter	 "R_PPC_ADDR24",	/* name */
20018334Speter	 false,			/* partial_inplace */
20118334Speter	 0,			/* src_mask */
20218334Speter	 0x3fffffc,		/* dst_mask */
20390075Sobrien	 false),		/* pcrel_offset */
20490075Sobrien
20590075Sobrien  /* A standard 16 bit relocation.  */
20690075Sobrien  HOWTO (R_PPC_ADDR16,		/* type */
20790075Sobrien	 0,			/* rightshift */
20890075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
20990075Sobrien	 16,			/* bitsize */
21052284Sobrien	 false,			/* pc_relative */
21190075Sobrien	 0,			/* bitpos */
21290075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
21390075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
21452284Sobrien	 "R_PPC_ADDR16",	/* name */
21590075Sobrien	 false,			/* partial_inplace */
21690075Sobrien	 0,			/* src_mask */
21790075Sobrien	 0xffff,		/* dst_mask */
21852284Sobrien	 false),		/* pcrel_offset */
21990075Sobrien
22090075Sobrien  /* A 16 bit relocation without overflow.  */
22152284Sobrien  HOWTO (R_PPC_ADDR16_LO,	/* type */
22290075Sobrien	 0,			/* rightshift */
22318334Speter	 1,			/* size (0 = byte, 1 = short, 2 = long) */
22490075Sobrien	 16,			/* bitsize */
22590075Sobrien	 false,			/* pc_relative */
22618334Speter	 0,			/* bitpos */
22790075Sobrien	 complain_overflow_dont,/* complain_on_overflow */
22890075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
22918334Speter	 "R_PPC_ADDR16_LO",	/* name */
23090075Sobrien	 false,			/* partial_inplace */
23190075Sobrien	 0,			/* src_mask */
23218334Speter	 0xffff,		/* dst_mask */
23390075Sobrien	 false),		/* pcrel_offset */
23490075Sobrien
23590075Sobrien  /* The high order 16 bits of an address.  */
23618334Speter  HOWTO (R_PPC_ADDR16_HI,	/* type */
23790075Sobrien	 16,			/* rightshift */
23890075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
23990075Sobrien	 16,			/* bitsize */
24050397Sobrien	 false,			/* pc_relative */
24190075Sobrien	 0,			/* bitpos */
24290075Sobrien	 complain_overflow_dont, /* complain_on_overflow */
24390075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
24450397Sobrien	 "R_PPC_ADDR16_HI",	/* name */
24590075Sobrien	 false,			/* partial_inplace */
24690075Sobrien	 0,			/* src_mask */
24790075Sobrien	 0xffff,		/* dst_mask */
24850397Sobrien	 false),		/* pcrel_offset */
24990075Sobrien
25090075Sobrien  /* The high order 16 bits of an address, plus 1 if the contents of
25190075Sobrien     the low 16 bits, treated as a signed number, is negative.  */
25290075Sobrien  HOWTO (R_PPC_ADDR16_HA,	/* type */
25350397Sobrien	 16,			/* rightshift */
25490075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
25590075Sobrien	 16,			/* bitsize */
25618334Speter	 false,			/* pc_relative */
25718334Speter	 0,			/* bitpos */
25890075Sobrien	 complain_overflow_dont, /* complain_on_overflow */
25990075Sobrien	 ppc_elf_addr16_ha_reloc, /* special_function */
26018334Speter	 "R_PPC_ADDR16_HA",	/* name */
261117395Skan	 false,			/* partial_inplace */
26290075Sobrien	 0,			/* src_mask */
26318334Speter	 0xffff,		/* dst_mask */
264132718Skan	 false),		/* pcrel_offset */
26590075Sobrien
266169689Skan  /* An absolute 16 bit branch; the lower two bits must be zero.
267169689Skan     FIXME: we don't check that, we just clear them.  */
26890075Sobrien  HOWTO (R_PPC_ADDR14,		/* type */
26952284Sobrien	 0,			/* rightshift */
270117395Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
271117395Skan	 16,			/* bitsize */
272117395Skan	 false,			/* pc_relative */
273169689Skan	 0,			/* bitpos */
274169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
275169689Skan	 bfd_elf_generic_reloc,	/* special_function */
276169689Skan	 "R_PPC_ADDR14",	/* name */
277169689Skan	 false,			/* partial_inplace */
278169689Skan	 0,			/* src_mask */
279169689Skan	 0xfffc,		/* dst_mask */
280169689Skan	 false),		/* pcrel_offset */
281169689Skan
282169689Skan  /* An absolute 16 bit branch, for which bit 10 should be set to
283169689Skan     indicate that the branch is expected to be taken.	The lower two
284169689Skan     bits must be zero.  */
28552284Sobrien  HOWTO (R_PPC_ADDR14_BRTAKEN,	/* type */
286169689Skan	 0,			/* rightshift */
287169689Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
28890075Sobrien	 16,			/* bitsize */
289132718Skan	 false,			/* pc_relative */
290132718Skan	 0,			/* bitpos */
291132718Skan	 complain_overflow_bitfield, /* complain_on_overflow */
292132718Skan	 bfd_elf_generic_reloc,	/* special_function */
293169689Skan	 "R_PPC_ADDR14_BRTAKEN",/* name */
294132718Skan	 false,			/* partial_inplace */
295132718Skan	 0,			/* src_mask */
296132718Skan	 0xfffc,		/* dst_mask */
297132718Skan	 false),		/* pcrel_offset */
298132718Skan
299132718Skan  /* An absolute 16 bit branch, for which bit 10 should be set to
300132718Skan     indicate that the branch is not expected to be taken.  The lower
301132718Skan     two bits must be zero.  */
302132718Skan  HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
303132718Skan	 0,			/* rightshift */
304132718Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
30552284Sobrien	 16,			/* bitsize */
30690075Sobrien	 false,			/* pc_relative */
307132718Skan	 0,			/* bitpos */
308132718Skan	 complain_overflow_bitfield, /* complain_on_overflow */
309132718Skan	 bfd_elf_generic_reloc,	/* special_function */
310132718Skan	 "R_PPC_ADDR14_BRNTAKEN",/* name */
311132718Skan	 false,			/* partial_inplace */
312132718Skan	 0,			/* src_mask */
313132718Skan	 0xfffc,		/* dst_mask */
314132718Skan	 false),		/* pcrel_offset */
31552284Sobrien
31690075Sobrien  /* A relative 26 bit branch; the lower two bits must be zero.  */
317132718Skan  HOWTO (R_PPC_REL24,		/* type */
318132718Skan	 0,			/* rightshift */
319132718Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
320132718Skan	 26,			/* bitsize */
321132718Skan	 true,			/* pc_relative */
32290075Sobrien	 0,			/* bitpos */
323132718Skan	 complain_overflow_signed, /* complain_on_overflow */
324132718Skan	 bfd_elf_generic_reloc,	/* special_function */
325132718Skan	 "R_PPC_REL24",		/* name */
326132718Skan	 false,			/* partial_inplace */
327132718Skan	 0,			/* src_mask */
328132718Skan	 0x3fffffc,		/* dst_mask */
329132718Skan	 true),			/* pcrel_offset */
330132718Skan
331169689Skan  /* A relative 16 bit branch; the lower two bits must be zero.  */
33290075Sobrien  HOWTO (R_PPC_REL14,		/* type */
33390075Sobrien	 0,			/* rightshift */
33490075Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
33552284Sobrien	 16,			/* bitsize */
33690075Sobrien	 true,			/* pc_relative */
337132718Skan	 0,			/* bitpos */
33890075Sobrien	 complain_overflow_signed, /* complain_on_overflow */
33990075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
34052284Sobrien	 "R_PPC_REL14",		/* name */
34190075Sobrien	 false,			/* partial_inplace */
342132718Skan	 0,			/* src_mask */
34352284Sobrien	 0xfffc,		/* dst_mask */
34490075Sobrien	 true),			/* pcrel_offset */
34590075Sobrien
346169689Skan  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
34790075Sobrien     the branch is expected to be taken.  The lower two bits must be
348169689Skan     zero.  */
34952284Sobrien  HOWTO (R_PPC_REL14_BRTAKEN,	/* type */
35090075Sobrien	 0,			/* rightshift */
35152284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
35290075Sobrien	 16,			/* bitsize */
353169689Skan	 true,			/* pc_relative */
354169689Skan	 0,			/* bitpos */
35552284Sobrien	 complain_overflow_signed, /* complain_on_overflow */
35690075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
357169689Skan	 "R_PPC_REL14_BRTAKEN",	/* name */
35852284Sobrien	 false,			/* partial_inplace */
35990075Sobrien	 0,			/* src_mask */
36090075Sobrien	 0xfffc,		/* dst_mask */
36190075Sobrien	 true),			/* pcrel_offset */
36290075Sobrien
36352284Sobrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
36490075Sobrien     the branch is not expected to be taken.  The lower two bits must
36590075Sobrien     be zero.  */
36652284Sobrien  HOWTO (R_PPC_REL14_BRNTAKEN,	/* type */
36790075Sobrien	 0,			/* rightshift */
36852284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
36990075Sobrien	 16,			/* bitsize */
37090075Sobrien	 true,			/* pc_relative */
37190075Sobrien	 0,			/* bitpos */
37290075Sobrien	 complain_overflow_signed, /* complain_on_overflow */
37390075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
37490075Sobrien	 "R_PPC_REL14_BRNTAKEN",/* name */
37552284Sobrien	 false,			/* partial_inplace */
376117395Skan	 0,			/* src_mask */
377117395Skan	 0xfffc,		/* dst_mask */
378132718Skan	 true),			/* pcrel_offset */
379146895Skan
380117395Skan  /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
381117395Skan     symbol.  */
38290075Sobrien  HOWTO (R_PPC_GOT16,		/* type */
38390075Sobrien	 0,			/* rightshift */
38452284Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
38590075Sobrien	 16,			/* bitsize */
38690075Sobrien	 false,			/* pc_relative */
38790075Sobrien	 0,			/* bitpos */
38852284Sobrien	 complain_overflow_signed, /* complain_on_overflow */
38990075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
39090075Sobrien	 "R_PPC_GOT16",		/* name */
39152284Sobrien	 false,			/* partial_inplace */
39290075Sobrien	 0,			/* src_mask */
39390075Sobrien	 0xffff,		/* dst_mask */
39490075Sobrien	 false),		/* pcrel_offset */
39590075Sobrien
39690075Sobrien  /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
39752284Sobrien     the symbol.  */
39890075Sobrien  HOWTO (R_PPC_GOT16_LO,	/* type */
399117395Skan	 0,			/* rightshift */
40090075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
40152284Sobrien	 16,			/* bitsize */
40290075Sobrien	 false,			/* pc_relative */
40390075Sobrien	 0,			/* bitpos */
404169689Skan	 complain_overflow_dont, /* complain_on_overflow */
40552284Sobrien	 bfd_elf_generic_reloc,	/* special_function */
40690075Sobrien	 "R_PPC_GOT16_LO",	/* name */
40790075Sobrien	 false,			/* partial_inplace */
40890075Sobrien	 0,			/* src_mask */
40990075Sobrien	 0xffff,		/* dst_mask */
410169689Skan	 false),		/* pcrel_offset */
41152284Sobrien
41290075Sobrien  /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
41390075Sobrien     the symbol.  */
41490075Sobrien  HOWTO (R_PPC_GOT16_HI,	/* type */
41590075Sobrien	 16,			/* rightshift */
41652284Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
41790075Sobrien	 16,			/* bitsize */
418169689Skan	 false,			/* pc_relative */
41952284Sobrien	 0,			/* bitpos */
42090075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
42190075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
42290075Sobrien	 "R_PPC_GOT16_HI",	/* name */
42352284Sobrien	 false,			/* partial_inplace */
42490075Sobrien	 0,			/* src_mask */
425132718Skan	 0xffff,		/* dst_mask */
426132718Skan	 false),		 /* pcrel_offset */
427132718Skan
428132718Skan  /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
42990075Sobrien     the symbol.  */
430169689Skan  HOWTO (R_PPC_GOT16_HA,	/* type */
431169689Skan	 16,			/* rightshift */
432169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
433169689Skan	 16,			/* bitsize */
434169689Skan	 false,			/* pc_relative */
43552284Sobrien	 0,			/* bitpos */
43690075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
437117395Skan	 ppc_elf_addr16_ha_reloc, /* special_function */
43890075Sobrien	 "R_PPC_GOT16_HA",	/* name */
43952284Sobrien	 false,			/* partial_inplace */
440169689Skan	 0,			/* src_mask */
441169689Skan	 0xffff,		/* dst_mask */
44252284Sobrien	 false),		/* pcrel_offset */
443169689Skan
44490075Sobrien  /* Like R_PPC_REL24, but referring to the procedure linkage table
44590075Sobrien     entry for the symbol.  */
44652284Sobrien  HOWTO (R_PPC_PLTREL24,	/* type */
44790075Sobrien	 0,			/* rightshift */
44890075Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
44990075Sobrien	 26,			/* bitsize */
45052284Sobrien	 true,			/* pc_relative */
45190075Sobrien	 0,			/* bitpos */
452132718Skan	 complain_overflow_signed,  /* complain_on_overflow */
45390075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
45490075Sobrien	 "R_PPC_PLTREL24",	/* name */
45590075Sobrien	 false,			/* partial_inplace */
45652284Sobrien	 0,			/* src_mask */
457169689Skan	 0x3fffffc,		/* dst_mask */
45852284Sobrien	 true),			/* pcrel_offset */
45990075Sobrien
46090075Sobrien  /* This is used only by the dynamic linker.  The symbol should exist
46190075Sobrien     both in the object being run and in some shared library.  The
46252284Sobrien     dynamic linker copies the data addressed by the symbol from the
46390075Sobrien     shared library into the object, because the object being
46452284Sobrien     run has to have the data at some particular address.  */
46552284Sobrien  HOWTO (R_PPC_COPY,		/* type */
46690075Sobrien	 0,			/* rightshift */
46790075Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
46852284Sobrien	 32,			/* bitsize */
46918334Speter	 false,			/* pc_relative */
470132718Skan	 0,			/* bitpos */
47118334Speter	 complain_overflow_bitfield, /* complain_on_overflow */
472132718Skan	 bfd_elf_generic_reloc,	 /* special_function */
47318334Speter	 "R_PPC_COPY",		/* name */
47490075Sobrien	 false,			/* partial_inplace */
47552284Sobrien	 0,			/* src_mask */
47690075Sobrien	 0,			/* dst_mask */
47752284Sobrien	 false),		/* pcrel_offset */
47890075Sobrien
47990075Sobrien  /* Like R_PPC_ADDR32, but used when setting global offset table
48090075Sobrien     entries.  */
48190075Sobrien  HOWTO (R_PPC_GLOB_DAT,	/* type */
48290075Sobrien	 0,			/* rightshift */
48352284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
48490075Sobrien	 32,			/* bitsize */
48590075Sobrien	 false,			/* pc_relative */
48690075Sobrien	 0,			/* bitpos */
48752284Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
488169689Skan	 bfd_elf_generic_reloc,	 /* special_function */
48952284Sobrien	 "R_PPC_GLOB_DAT",	/* name */
490169689Skan	 false,			/* partial_inplace */
491169689Skan	 0,			/* src_mask */
49252284Sobrien	 0xffffffff,		/* dst_mask */
493169689Skan	 false),		/* pcrel_offset */
49490075Sobrien
49518334Speter  /* Marks a procedure linkage table entry for a symbol.  */
49690075Sobrien  HOWTO (R_PPC_JMP_SLOT,	/* type */
49790075Sobrien	 0,			/* rightshift */
49852284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
49952284Sobrien	 32,			/* bitsize */
500132718Skan	 false,			/* pc_relative */
50152284Sobrien	 0,			/* bitpos */
50290075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
50318334Speter	 bfd_elf_generic_reloc,	 /* special_function */
50490075Sobrien	 "R_PPC_JMP_SLOT",	/* name */
50590075Sobrien	 false,			/* partial_inplace */
506169689Skan	 0,			/* src_mask */
507169689Skan	 0,			/* dst_mask */
50852284Sobrien	 false),		/* pcrel_offset */
509169689Skan
51090075Sobrien  /* Used only by the dynamic linker.  When the object is run, this
511169689Skan     longword is set to the load address of the object, plus the
51290075Sobrien     addend.  */
51390075Sobrien  HOWTO (R_PPC_RELATIVE,	/* type */
514169689Skan	 0,			/* rightshift */
515169689Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
516169689Skan	 32,			/* bitsize */
51790075Sobrien	 false,			/* pc_relative */
518169689Skan	 0,			/* bitpos */
51952284Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
52052284Sobrien	 bfd_elf_generic_reloc,	 /* special_function */
52190075Sobrien	 "R_PPC_RELATIVE",	/* name */
52290075Sobrien	 false,			/* partial_inplace */
523169689Skan	 0,			/* src_mask */
524169689Skan	 0xffffffff,		/* dst_mask */
52550397Sobrien	 false),		/* pcrel_offset */
52690075Sobrien
527169689Skan  /* Like R_PPC_REL24, but uses the value of the symbol within the
52852284Sobrien     object rather than the final value.  Normally used for
529169689Skan     _GLOBAL_OFFSET_TABLE_.  */
53018334Speter  HOWTO (R_PPC_LOCAL24PC,	/* type */
531117395Skan	 0,			/* rightshift */
532169689Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
53390075Sobrien	 26,			/* bitsize */
534169689Skan	 true,			/* pc_relative */
53590075Sobrien	 0,			/* bitpos */
536169689Skan	 complain_overflow_signed, /* complain_on_overflow */
53790075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
538169689Skan	 "R_PPC_LOCAL24PC",	/* name */
53990075Sobrien	 false,			/* partial_inplace */
540169689Skan	 0,			/* src_mask */
54190075Sobrien	 0x3fffffc,		/* dst_mask */
542117395Skan	 true),			/* pcrel_offset */
54390075Sobrien
544169689Skan  /* Like R_PPC_ADDR32, but may be unaligned.  */
54552284Sobrien  HOWTO (R_PPC_UADDR32,		/* type */
54690075Sobrien	 0,			/* rightshift */
54752284Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
54890075Sobrien	 32,			/* bitsize */
54990075Sobrien	 false,			/* pc_relative */
55052284Sobrien	 0,			/* bitpos */
551132718Skan	 complain_overflow_bitfield, /* complain_on_overflow */
55290075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
55390075Sobrien	 "R_PPC_UADDR32",	/* name */
55490075Sobrien	 false,			/* partial_inplace */
55590075Sobrien	 0,			/* src_mask */
55690075Sobrien	 0xffffffff,		/* dst_mask */
55752284Sobrien	 false),		/* pcrel_offset */
55890075Sobrien
55990075Sobrien  /* Like R_PPC_ADDR16, but may be unaligned.  */
56090075Sobrien  HOWTO (R_PPC_UADDR16,		/* type */
56152284Sobrien	 0,			/* rightshift */
562132718Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
563132718Skan	 16,			/* bitsize */
564132718Skan	 false,			/* pc_relative */
56590075Sobrien	 0,			/* bitpos */
56690075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
56752284Sobrien	 bfd_elf_generic_reloc,	/* special_function */
568117395Skan	 "R_PPC_UADDR16",	/* name */
569169689Skan	 false,			/* partial_inplace */
570169689Skan	 0,			/* src_mask */
57152284Sobrien	 0xffff,		/* dst_mask */
57290075Sobrien	 false),		/* pcrel_offset */
573169689Skan
57496263Sobrien  /* 32-bit PC relative */
575117395Skan  HOWTO (R_PPC_REL32,		/* type */
57652284Sobrien	 0,			/* rightshift */
577169689Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
578117395Skan	 32,			/* bitsize */
57952284Sobrien	 true,			/* pc_relative */
580169689Skan	 0,			/* bitpos */
581169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
582169689Skan	 bfd_elf_generic_reloc,	/* special_function */
58390075Sobrien	 "R_PPC_REL32",		/* name */
58490075Sobrien	 false,			/* partial_inplace */
58552284Sobrien	 0,			/* src_mask */
58690075Sobrien	 0xffffffff,		/* dst_mask */
58790075Sobrien	 true),			/* pcrel_offset */
588169689Skan
589169689Skan  /* 32-bit relocation to the symbol's procedure linkage table.
59052284Sobrien     FIXME: not supported.  */
59190075Sobrien  HOWTO (R_PPC_PLT32,		/* type */
59290075Sobrien	 0,			/* rightshift */
59390075Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
59490075Sobrien	 32,			/* bitsize */
59518334Speter	 false,			/* pc_relative */
59690075Sobrien	 0,			/* bitpos */
59718334Speter	 complain_overflow_bitfield, /* complain_on_overflow */
59890075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
59990075Sobrien	 "R_PPC_PLT32",		/* name */
600117395Skan	 false,			/* partial_inplace */
60190075Sobrien	 0,			/* src_mask */
60252284Sobrien	 0,			/* dst_mask */
60390075Sobrien	 false),		/* pcrel_offset */
60490075Sobrien
60590075Sobrien  /* 32-bit PC relative relocation to the symbol's procedure linkage table.
60652284Sobrien     FIXME: not supported.  */
60790075Sobrien  HOWTO (R_PPC_PLTREL32,	/* type */
60890075Sobrien	 0,			/* rightshift */
609117395Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
61018334Speter	 32,			/* bitsize */
611169689Skan	 true,			/* pc_relative */
61290075Sobrien	 0,			/* bitpos */
61390075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
614117395Skan	 bfd_elf_generic_reloc,	/* special_function */
61590075Sobrien	 "R_PPC_PLTREL32",	/* name */
61652284Sobrien	 false,			/* partial_inplace */
61752284Sobrien	 0,			/* src_mask */
61896263Sobrien	 0,			/* dst_mask */
61996263Sobrien	 true),			/* pcrel_offset */
62096263Sobrien
62196263Sobrien  /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
62296263Sobrien     the symbol.  */
623117395Skan  HOWTO (R_PPC_PLT16_LO,	/* type */
624117395Skan	 0,			/* rightshift */
62596263Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
62696263Sobrien	 16,			/* bitsize */
62790075Sobrien	 false,			/* pc_relative */
62896263Sobrien	 0,			/* bitpos */
62996263Sobrien	 complain_overflow_dont, /* complain_on_overflow */
63096263Sobrien	 bfd_elf_generic_reloc,	/* special_function */
631169689Skan	 "R_PPC_PLT16_LO",	/* name */
63296263Sobrien	 false,			/* partial_inplace */
63396263Sobrien	 0,			/* src_mask */
634132718Skan	 0xffff,		/* dst_mask */
635132718Skan	 false),		/* pcrel_offset */
636132718Skan
637169689Skan  /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
638132718Skan     the symbol.  */
639132718Skan  HOWTO (R_PPC_PLT16_HI,	/* type */
640169689Skan	 16,			/* rightshift */
641169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
642132718Skan	 16,			/* bitsize */
64318334Speter	 false,			/* pc_relative */
64418334Speter	 0,			/* bitpos */
64590075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
64690075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
647169689Skan	 "R_PPC_PLT16_HI",	/* name */
648169689Skan	 false,			/* partial_inplace */
64990075Sobrien	 0,			/* src_mask */
650169689Skan	 0xffff,		/* dst_mask */
651169689Skan	 false),		 /* pcrel_offset */
652169689Skan
653169689Skan  /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
654169689Skan     the symbol.  */
655169689Skan  HOWTO (R_PPC_PLT16_HA,	/* type */
656169689Skan	 16,			/* rightshift */
657169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
658169689Skan	 16,			/* bitsize */
659169689Skan	 false,			/* pc_relative */
660169689Skan	 0,			/* bitpos */
66152284Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
662117395Skan	 ppc_elf_addr16_ha_reloc, /* special_function */
663117395Skan	 "R_PPC_PLT16_HA",	/* name */
664117395Skan	 false,			/* partial_inplace */
665117395Skan	 0,			/* src_mask */
66690075Sobrien	 0xffff,		/* dst_mask */
66790075Sobrien	 false),		/* pcrel_offset */
668169689Skan
669169689Skan  /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
670169689Skan     small data items.  */
67118334Speter  HOWTO (R_PPC_SDAREL16,	/* type */
672117395Skan	 0,			/* rightshift */
673169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
674169689Skan	 16,			/* bitsize */
675169689Skan	 false,			/* pc_relative */
676169689Skan	 0,			/* bitpos */
677169689Skan	 complain_overflow_signed, /* complain_on_overflow */
678169689Skan	 bfd_elf_generic_reloc,	/* special_function */
679169689Skan	 "R_PPC_SDAREL16",	/* name */
680169689Skan	 false,			/* partial_inplace */
681169689Skan	 0,			/* src_mask */
682169689Skan	 0xffff,		/* dst_mask */
683169689Skan	 false),		/* pcrel_offset */
68490075Sobrien
68590075Sobrien  /* 16-bit section relative relocation.  */
68690075Sobrien  HOWTO (R_PPC_SECTOFF,		/* type */
687117395Skan	 0,			/* rightshift */
68890075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
689169689Skan	 16,			/* bitsize */
69052284Sobrien	 false,			/* pc_relative */
69196263Sobrien	 0,			/* bitpos */
69296263Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
69390075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
69490075Sobrien	 "R_PPC_SECTOFF",	/* name */
69518334Speter	 false,			/* partial_inplace */
69652284Sobrien	 0,			/* src_mask */
69718334Speter	 0xffff,		/* dst_mask */
69890075Sobrien	 false),		/* pcrel_offset */
69952284Sobrien
70090075Sobrien  /* 16-bit lower half section relative relocation.  */
70190075Sobrien  HOWTO (R_PPC_SECTOFF_LO,	  /* type */
702169689Skan	 0,			/* rightshift */
703169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
70490075Sobrien	 16,			/* bitsize */
70590075Sobrien	 false,			/* pc_relative */
70690075Sobrien	 0,			/* bitpos */
70790075Sobrien	 complain_overflow_dont, /* complain_on_overflow */
708169689Skan	 bfd_elf_generic_reloc,	/* special_function */
709169689Skan	 "R_PPC_SECTOFF_LO",	/* name */
710169689Skan	 false,			/* partial_inplace */
71152284Sobrien	 0,			/* src_mask */
71290075Sobrien	 0xffff,		/* dst_mask */
71390075Sobrien	 false),		/* pcrel_offset */
71490075Sobrien
71590075Sobrien  /* 16-bit upper half section relative relocation.  */
71690075Sobrien  HOWTO (R_PPC_SECTOFF_HI,	/* type */
71790075Sobrien	 16,			/* rightshift */
71890075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
71990075Sobrien	 16,			/* bitsize */
72090075Sobrien	 false,			/* pc_relative */
721169689Skan	 0,			/* bitpos */
722169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
723169689Skan	 bfd_elf_generic_reloc,	/* special_function */
724169689Skan	 "R_PPC_SECTOFF_HI",	/* name */
725169689Skan	 false,			/* partial_inplace */
726169689Skan	 0,			/* src_mask */
727169689Skan	 0xffff,		/* dst_mask */
728169689Skan	 false),		 /* pcrel_offset */
72990075Sobrien
730169689Skan  /* 16-bit upper half adjusted section relative relocation.  */
731169689Skan  HOWTO (R_PPC_SECTOFF_HA,	/* type */
732169689Skan	 16,			/* rightshift */
733169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
734169689Skan	 16,			/* bitsize */
73590075Sobrien	 false,			/* pc_relative */
73690075Sobrien	 0,			/* bitpos */
737169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
738169689Skan	 ppc_elf_addr16_ha_reloc, /* special_function */
739117395Skan	 "R_PPC_SECTOFF_HA",	/* name */
74052284Sobrien	 false,			/* partial_inplace */
74152284Sobrien	 0,			/* src_mask */
742117395Skan	 0xffff,		/* dst_mask */
743117395Skan	 false),		/* pcrel_offset */
744117395Skan
745132718Skan  /* The remaining relocs are from the Embedded ELF ABI, and are not
746117395Skan     in the SVR4 ELF ABI.  */
747117395Skan
748117395Skan  /* 32 bit value resulting from the addend minus the symbol */
749117395Skan  HOWTO (R_PPC_EMB_NADDR32,	/* type */
750117395Skan	 0,			/* rightshift */
751117395Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
752117395Skan	 32,			/* bitsize */
753117395Skan	 false,			/* pc_relative */
754117395Skan	 0,			/* bitpos */
755169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
756117395Skan	 bfd_elf_generic_reloc,	/* special_function */
757117395Skan	 "R_PPC_EMB_NADDR32",	/* name */
758169689Skan	 false,			/* partial_inplace */
759117395Skan	 0,			/* src_mask */
760117395Skan	 0xffffffff,		/* dst_mask */
761117395Skan	 false),		/* pcrel_offset */
762117395Skan
763117395Skan  /* 16 bit value resulting from the addend minus the symbol */
764117395Skan  HOWTO (R_PPC_EMB_NADDR16,	/* type */
765117395Skan	 0,			/* rightshift */
766117395Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
767117395Skan	 16,			/* bitsize */
768117395Skan	 false,			/* pc_relative */
769169689Skan	 0,			/* bitpos */
77052284Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
77190075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
772169689Skan	 "R_PPC_EMB_NADDR16",	/* name */
77352284Sobrien	 false,			/* partial_inplace */
774169689Skan	 0,			/* src_mask */
77552284Sobrien	 0xffff,		/* dst_mask */
776169689Skan	 false),		/* pcrel_offset */
777169689Skan
778169689Skan  /* 16 bit value resulting from the addend minus the symbol */
779169689Skan  HOWTO (R_PPC_EMB_NADDR16_LO,	/* type */
780169689Skan	 0,			/* rightshift */
781169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
78250397Sobrien	 16,			/* bitsize */
783169689Skan	 false,			/* pc_relative */
784169689Skan	 0,			/* bitpos */
785169689Skan	 complain_overflow_dont,/* complain_on_overflow */
786169689Skan	 bfd_elf_generic_reloc,	/* special_function */
787169689Skan	 "R_PPC_EMB_ADDR16_LO",	/* name */
788169689Skan	 false,			/* partial_inplace */
78952284Sobrien	 0,			/* src_mask */
79018334Speter	 0xffff,		/* dst_mask */
79190075Sobrien	 false),		/* pcrel_offset */
79250397Sobrien
793117395Skan  /* The high order 16 bits of the addend minus the symbol */
794169689Skan  HOWTO (R_PPC_EMB_NADDR16_HI,	/* type */
79552284Sobrien	 16,			/* rightshift */
79690075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
79790075Sobrien	 16,			/* bitsize */
798117395Skan	 false,			/* pc_relative */
79952284Sobrien	 0,			/* bitpos */
800117395Skan	 complain_overflow_dont, /* complain_on_overflow */
80152284Sobrien	 bfd_elf_generic_reloc,	/* special_function */
802132718Skan	 "R_PPC_EMB_NADDR16_HI", /* name */
80352284Sobrien	 false,			/* partial_inplace */
80490075Sobrien	 0,			/* src_mask */
80590075Sobrien	 0xffff,		/* dst_mask */
80652284Sobrien	 false),		/* pcrel_offset */
80790075Sobrien
80852284Sobrien  /* The high order 16 bits of the result of the addend minus the address,
80990075Sobrien     plus 1 if the contents of the low 16 bits, treated as a signed number,
81090075Sobrien     is negative.  */
81190075Sobrien  HOWTO (R_PPC_EMB_NADDR16_HA,	/* type */
81290075Sobrien	 16,			/* rightshift */
81390075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
81490075Sobrien	 16,			/* bitsize */
81590075Sobrien	 false,			/* pc_relative */
81690075Sobrien	 0,			/* bitpos */
81790075Sobrien	 complain_overflow_dont, /* complain_on_overflow */
81890075Sobrien	 ppc_elf_addr16_ha_reloc, /* special_function */
81990075Sobrien	 "R_PPC_EMB_NADDR16_HA", /* name */
82090075Sobrien	 false,			/* partial_inplace */
82190075Sobrien	 0,			/* src_mask */
82290075Sobrien	 0xffff,		/* dst_mask */
82352284Sobrien	 false),		/* pcrel_offset */
824117395Skan
825117395Skan  /* 16 bit value resulting from allocating a 4 byte word to hold an
82690075Sobrien     address in the .sdata section, and returning the offset from
82752284Sobrien     _SDA_BASE_ for that relocation */
82818334Speter  HOWTO (R_PPC_EMB_SDAI16,	/* type */
829169689Skan	 0,			/* rightshift */
830169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
831169689Skan	 16,			/* bitsize */
832169689Skan	 false,			/* pc_relative */
833117395Skan	 0,			/* bitpos */
83490075Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
83518334Speter	 bfd_elf_generic_reloc,	/* special_function */
83690075Sobrien	 "R_PPC_EMB_SDAI16",	/* name */
83790075Sobrien	 false,			/* partial_inplace */
83890075Sobrien	 0,			/* src_mask */
83990075Sobrien	 0xffff,		/* dst_mask */
840117395Skan	 false),		/* pcrel_offset */
841132718Skan
84290075Sobrien  /* 16 bit value resulting from allocating a 4 byte word to hold an
843169689Skan     address in the .sdata2 section, and returning the offset from
844169689Skan     _SDA2_BASE_ for that relocation */
845169689Skan  HOWTO (R_PPC_EMB_SDA2I16,	/* type */
846169689Skan	 0,			/* rightshift */
847169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
84852284Sobrien	 16,			/* bitsize */
849169689Skan	 false,			/* pc_relative */
850169689Skan	 0,			/* bitpos */
851169689Skan	 complain_overflow_bitfield, /* complain_on_overflow */
852169689Skan	 bfd_elf_generic_reloc,	/* special_function */
853169689Skan	 "R_PPC_EMB_SDA2I16",	/* name */
85418334Speter	 false,			/* partial_inplace */
855169689Skan	 0,			/* src_mask */
856169689Skan	 0xffff,		/* dst_mask */
857169689Skan	 false),		/* pcrel_offset */
858169689Skan
859169689Skan  /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with
860169689Skan     small data items.	 */
861169689Skan  HOWTO (R_PPC_EMB_SDA2REL,	/* type */
862169689Skan	 0,			/* rightshift */
863169689Skan	 1,			/* size (0 = byte, 1 = short, 2 = long) */
864169689Skan	 16,			/* bitsize */
865169689Skan	 false,			/* pc_relative */
866169689Skan	 0,			/* bitpos */
867169689Skan	 complain_overflow_signed, /* complain_on_overflow */
868169689Skan	 bfd_elf_generic_reloc,	/* special_function */
869169689Skan	 "R_PPC_EMB_SDA2REL",	/* name */
870169689Skan	 false,			/* partial_inplace */
871169689Skan	 0,			/* src_mask */
87252284Sobrien	 0xffff,		/* dst_mask */
87352284Sobrien	 false),		/* pcrel_offset */
87452284Sobrien
87550397Sobrien  /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit
87690075Sobrien     signed offset from the appropriate base, and filling in the register
87790075Sobrien     field with the appropriate register (0, 2, or 13).  */
87850397Sobrien  HOWTO (R_PPC_EMB_SDA21,	/* type */
87990075Sobrien	 0,			/* rightshift */
880132718Skan	 2,			/* size (0 = byte, 1 = short, 2 = long) */
881132718Skan	 16,			/* bitsize */
88252284Sobrien	 false,			/* pc_relative */
88390075Sobrien	 0,			/* bitpos */
88490075Sobrien	 complain_overflow_signed, /* complain_on_overflow */
88590075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
88690075Sobrien	 "R_PPC_EMB_SDA21",	/* name */
887169689Skan	 false,			/* partial_inplace */
888169689Skan	 0,			/* src_mask */
88990075Sobrien	 0xffff,		/* dst_mask */
89090075Sobrien	 false),		/* pcrel_offset */
89152284Sobrien
89252284Sobrien  /* Relocation not handled: R_PPC_EMB_MRKREF */
89352284Sobrien  /* Relocation not handled: R_PPC_EMB_RELSEC16 */
894169689Skan  /* Relocation not handled: R_PPC_EMB_RELST_LO */
89552284Sobrien  /* Relocation not handled: R_PPC_EMB_RELST_HI */
896169689Skan  /* Relocation not handled: R_PPC_EMB_RELST_HA */
89790075Sobrien  /* Relocation not handled: R_PPC_EMB_BIT_FLD */
89852284Sobrien
89990075Sobrien  /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling
90090075Sobrien     in the 16 bit signed offset from the appropriate base, and filling in the
90190075Sobrien     register field with the appropriate register (0, 2, or 13).  */
90290075Sobrien  HOWTO (R_PPC_EMB_RELSDA,	/* type */
90390075Sobrien	 0,			/* rightshift */
90452284Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
905169689Skan	 16,			/* bitsize */
906169689Skan	 true,			/* pc_relative */
907169689Skan	 0,			/* bitpos */
908169689Skan	 complain_overflow_signed, /* complain_on_overflow */
909169689Skan	 bfd_elf_generic_reloc,	/* special_function */
910169689Skan	 "R_PPC_EMB_RELSDA",	/* name */
911169689Skan	 false,			/* partial_inplace */
912169689Skan	 0,			/* src_mask */
913169689Skan	 0xffff,		/* dst_mask */
914169689Skan	 false),		/* pcrel_offset */
915169689Skan
916169689Skan  /* GNU extension to record C++ vtable hierarchy */
917169689Skan  HOWTO (R_PPC_GNU_VTINHERIT,	/* type */
91852284Sobrien	 0,			/* rightshift */
91918334Speter	 0,			/* size (0 = byte, 1 = short, 2 = long) */
92090075Sobrien	 0,			/* bitsize */
92190075Sobrien	 false,			/* pc_relative */
92252284Sobrien	 0,			/* bitpos */
92390075Sobrien	 complain_overflow_dont, /* complain_on_overflow */
924132718Skan	 NULL,			/* special_function */
92552284Sobrien	 "R_PPC_GNU_VTINHERIT",	/* name */
92690075Sobrien	 false,			/* partial_inplace */
92790075Sobrien	 0,			/* src_mask */
92852284Sobrien	 0,			/* dst_mask */
929169689Skan	 false),		/* pcrel_offset */
93090075Sobrien
93190075Sobrien  /* GNU extension to record C++ vtable member usage */
93290075Sobrien  HOWTO (R_PPC_GNU_VTENTRY,	/* type */
93352284Sobrien	 0,			/* rightshift */
934169689Skan	 0,			/* size (0 = byte, 1 = short, 2 = long) */
93590075Sobrien	 0,			/* bitsize */
93690075Sobrien	 false,			/* pc_relative */
93752284Sobrien	 0,			/* bitpos */
93852284Sobrien	 complain_overflow_dont, /* complain_on_overflow */
93952284Sobrien	 NULL,			/* special_function */
94090075Sobrien	 "R_PPC_GNU_VTENTRY",	/* name */
94190075Sobrien	 false,			/* partial_inplace */
94290075Sobrien	 0,			/* src_mask */
94352284Sobrien	 0,			/* dst_mask */
944132718Skan	 false),		/* pcrel_offset */
94552284Sobrien
94690075Sobrien  /* Phony reloc to handle AIX style TOC entries */
94752284Sobrien  HOWTO (R_PPC_TOC16,		/* type */
94890075Sobrien	 0,			/* rightshift */
94990075Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
950132718Skan	 16,			/* bitsize */
95190075Sobrien	 false,			/* pc_relative */
95290075Sobrien	 0,			/* bitpos */
95390075Sobrien	 complain_overflow_signed, /* complain_on_overflow */
95490075Sobrien	 bfd_elf_generic_reloc,	/* special_function */
95590075Sobrien	 "R_PPC_TOC16",		/* name */
95652284Sobrien	 false,			/* partial_inplace */
95790075Sobrien	 0,			/* src_mask */
95852284Sobrien	 0xffff,		/* dst_mask */
95952284Sobrien	 false),		/* pcrel_offset */
96090075Sobrien};
96190075Sobrien
96290075Sobrien/* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
96390075Sobrien
96490075Sobrienstatic void
96552284Sobrienppc_elf_howto_init ()
96690075Sobrien{
96790075Sobrien  unsigned int i, type;
96890075Sobrien
96990075Sobrien  for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++)
970117395Skan    {
97190075Sobrien      type = ppc_elf_howto_raw[i].type;
97252284Sobrien      BFD_ASSERT (type < sizeof (ppc_elf_howto_table) / sizeof (ppc_elf_howto_table[0]));
97318334Speter      ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
97490075Sobrien    }
97590075Sobrien}
97690075Sobrien
97790075Sobrien/* This function handles relaxing for the PPC with option --mpc860c0[=<n>].
978132718Skan
97990075Sobrien   The MPC860, revision C0 or earlier contains a bug in the die.
98090075Sobrien   If all of the following conditions are true, the next instruction
98190075Sobrien   to be executed *may* be treated as a no-op.
98250397Sobrien   1/ A forward branch is executed.
98390075Sobrien   2/ The branch is predicted as not taken.
98490075Sobrien   3/ The branch is taken.
98590075Sobrien   4/ The branch is located in the last 5 words of a page.
98690075Sobrien      (The EOP limit is 5 by default but may be specified as any value from 1-10.)
98790075Sobrien
98890075Sobrien   Our software solution is to detect these problematic branches in a
98950397Sobrien   linker pass and modify them as follows:
990132718Skan   1/ Unconditional branches - Since these are always predicted taken,
99152284Sobrien      there is no problem and no action is required.
99290075Sobrien   2/ Conditional backward branches - No problem, no action required.
99390075Sobrien   3/ Conditional forward branches - Ensure that the "inverse prediction
99490075Sobrien      bit" is set (ensure it is predicted taken).
99590075Sobrien   4/ Conditional register branches - Ensure that the "y bit" is set
99690075Sobrien      (ensure it is predicted taken).
99752284Sobrien*/
99850397Sobrien
99990075Sobrien/* Sort sections by address.  */
100090075Sobrien
100190075Sobrienstatic int
100290075Sobrienppc_elf_sort_rela (arg1, arg2)
100390075Sobrien     const PTR arg1;
100490075Sobrien     const PTR arg2;
100590075Sobrien{
100690075Sobrien  const Elf_Internal_Rela **rela1 = (const Elf_Internal_Rela**) arg1;
100790075Sobrien  const Elf_Internal_Rela **rela2 = (const Elf_Internal_Rela**) arg2;
100890075Sobrien
100990075Sobrien  /* Sort by offset.  */
101090075Sobrien  return ((*rela1)->r_offset - (*rela2)->r_offset);
1011132718Skan}
101290075Sobrien
101352284Sobrienstatic boolean
101490075Sobrienppc_elf_relax_section (abfd, isec, link_info, again)
101590075Sobrien     bfd *abfd;
101690075Sobrien     asection *isec;
101752284Sobrien     struct bfd_link_info *link_info;
101890075Sobrien     boolean *again;
101990075Sobrien{
1020132718Skan#define PAGESIZE 0x1000
102190075Sobrien
102252284Sobrien  bfd_byte *contents = NULL;
102390075Sobrien  bfd_byte *free_contents = NULL;
102490075Sobrien  Elf_Internal_Rela *internal_relocs = NULL;
102590075Sobrien  Elf_Internal_Rela *free_relocs = NULL;
102652284Sobrien  Elf_Internal_Rela **rela_comb = NULL;
102790075Sobrien  int comb_curr, comb_count;
102852284Sobrien
102990075Sobrien  /* We never have to do this more than once per input section.  */
103090075Sobrien  *again = false;
103152284Sobrien
103252284Sobrien  /* If needed, initialize this section's cooked size.  */
103390075Sobrien  if (isec->_cooked_size == 0)
103490075Sobrien      isec->_cooked_size = isec->_raw_size;
103590075Sobrien
103618334Speter  /* We're only interested in text sections which overlap the
103790075Sobrien     troublesome area at the end of a page.  */
103850397Sobrien  if (link_info->mpc860c0 && (isec->flags & SEC_CODE) && isec->_cooked_size)
103952284Sobrien    {
1040132718Skan      bfd_vma dot, end_page, end_section;
104152284Sobrien      boolean section_modified;
1042117395Skan
1043169689Skan      /* Get the section contents.  */
1044169689Skan      /* Get cached copy if it exists.  */
1045169689Skan      if (elf_section_data (isec)->this_hdr.contents != NULL)
1046169689Skan	  contents = elf_section_data (isec)->this_hdr.contents;
104718334Speter      else
1048169689Skan	{
1049169689Skan	  /* Go get them off disk.  */
1050169689Skan	  contents = (bfd_byte *) bfd_malloc (isec->_raw_size);
1051169689Skan	  if (contents == NULL)
1052169689Skan	    goto error_return;
1053169689Skan	  free_contents = contents;
1054169689Skan
1055169689Skan	  if (! bfd_get_section_contents (abfd, isec, contents,
1056169689Skan					  (file_ptr) 0, isec->_raw_size))
1057117395Skan	    goto error_return;
1058117395Skan	}
1059117395Skan
1060117395Skan      comb_curr = 0;
1061169689Skan      comb_count = 0;
1062117395Skan      if (isec->reloc_count)
1063117395Skan	{
1064169689Skan          unsigned n;
1065169689Skan	  bfd_size_type amt;
1066169689Skan
1067169689Skan          /* Get a copy of the native relocations.  */
106852284Sobrien          internal_relocs = _bfd_elf32_link_read_relocs (
106990075Sobrien    	    abfd, isec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
107090075Sobrien    	    link_info->keep_memory);
1071117395Skan          if (internal_relocs == NULL)
1072169689Skan    	      goto error_return;
107352284Sobrien          if (! link_info->keep_memory)
1074169689Skan    	      free_relocs = internal_relocs;
1075169689Skan
1076169689Skan          /* Setup a faster access method for the reloc info we need.  */
1077169689Skan	  amt = isec->reloc_count;
1078169689Skan	  amt *= sizeof (Elf_Internal_Rela*);
1079169689Skan          rela_comb = (Elf_Internal_Rela**) bfd_malloc (amt);
1080169689Skan          if (rela_comb == NULL)
1081169689Skan              goto error_return;
1082169689Skan          for (n = 0; n < isec->reloc_count; ++n)
1083169689Skan            {
1084169689Skan              long r_type;
1085169689Skan
1086169689Skan              r_type = ELF32_R_TYPE (internal_relocs[n].r_info);
1087169689Skan              if (r_type < 0 || r_type >= (int) R_PPC_max)
1088169689Skan                  goto error_return;
1089169689Skan
1090169689Skan              /* Prologue constants are sometimes present in the ".text"
1091169689Skan              sections and they can be identified by their associated relocation.
109290075Sobrien              We don't want to process those words and some others which
1093169689Skan              can also be identified by their relocations.  However, not all
109452284Sobrien              conditional branches will have a relocation so we will
109590075Sobrien              only ignore words that 1) have a reloc, and 2) the reloc
109690075Sobrien              is not applicable to a conditional branch.
109790075Sobrien              The array rela_comb is built here for use in the EOP scan loop.  */
109890075Sobrien              switch (r_type)
109952284Sobrien                {
1100117395Skan                case R_PPC_ADDR14_BRNTAKEN:     /* absolute, predicted not taken */
1101117395Skan                case R_PPC_REL14:               /* relative cond. br.  */
1102117395Skan                case R_PPC_REL14_BRNTAKEN:      /* rel. cond. br., predicted not taken */
1103117395Skan                  /* We should check the instruction.  */
1104117395Skan                  break;
1105117395Skan                default:
110690075Sobrien                  /* The word is not a conditional branch - ignore it.  */
110790075Sobrien                  rela_comb[comb_count++] = &internal_relocs[n];
110890075Sobrien                  break;
1109117395Skan                }
111052284Sobrien            }
111190075Sobrien          if (comb_count > 1)
111290075Sobrien	    qsort (rela_comb, (size_t) comb_count, sizeof (int), ppc_elf_sort_rela);
111352284Sobrien	}
111418334Speter
111552284Sobrien      /* Enumerate each EOP region that overlaps this section.  */
1116169689Skan      end_section = isec->vma + isec->_cooked_size;
1117169689Skan      dot = end_page = (isec->vma | (PAGESIZE - 1)) + 1;
111896263Sobrien      dot -= link_info->mpc860c0;
111996263Sobrien      section_modified = false;
112096263Sobrien      if (dot < isec->vma)      /* Increment the start position if this section */
112196263Sobrien          dot = isec->vma;      /* begins in the middle of its first EOP region.  */
112296263Sobrien      for (;
112390075Sobrien           dot < end_section;
112490075Sobrien           dot += PAGESIZE, end_page += PAGESIZE)
112570635Sobrien        {
112690075Sobrien
112790075Sobrien          /* Check each word in this EOP region.  */
112890075Sobrien          for (; dot < end_page; dot += 4)
112990075Sobrien            {
113090075Sobrien              bfd_vma isec_offset;
113190075Sobrien              unsigned long insn;
113290075Sobrien              boolean skip, modified;
113390075Sobrien
113490075Sobrien              /* Don't process this word if there is a relocation for it and
113570635Sobrien              the relocation indicates the word is not a conditional branch.  */
113690075Sobrien              skip = false;
113790075Sobrien              isec_offset = dot - isec->vma;
113890075Sobrien              for (; comb_curr<comb_count; ++comb_curr)
113990075Sobrien                {
114090075Sobrien                  bfd_vma r_offset;
114190075Sobrien
114290075Sobrien                  r_offset = rela_comb[comb_curr]->r_offset;
1143169689Skan                  if (r_offset >= isec_offset)
1144169689Skan                    {
1145169689Skan                      if (r_offset == isec_offset) skip = true;
1146169689Skan                      break;
1147169689Skan                    }
1148169689Skan                }
1149169689Skan              if (skip) continue;
1150169689Skan
1151169689Skan              /* Check the current word for a problematic conditional branch.  */
1152169689Skan#define BO0(insn) ((insn) & 0x02000000)
1153169689Skan#define BO2(insn) ((insn) & 0x00800000)
1154169689Skan#define BO4(insn) ((insn) & 0x00200000)
1155169689Skan              insn = (unsigned long) bfd_get_32 (abfd, contents + isec_offset);
1156169689Skan              modified = false;
1157169689Skan              if ((insn & 0xFc000000) == 0x40000000)
1158169689Skan                {
1159169689Skan                  /* Instruction is BCx */
1160169689Skan                  if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
1161169689Skan                    {
1162169689Skan                      bfd_vma target;
1163169689Skan                      /* This branch is predicted as "normal".
1164169689Skan                      If this is a forward branch, it is problematic.  */
1165169689Skan
1166169689Skan                      target = insn & 0x0000Fffc;               /*extract*/
1167169689Skan                      target = (target ^ 0x8000) - 0x8000;      /*sign extend*/
1168169689Skan                      if ((insn & 0x00000002) == 0)
1169169689Skan                          target += dot;                        /*convert to abs*/
1170169689Skan                      if (target > dot)
1171169689Skan                        {
1172169689Skan                          insn |= 0x00200000;   /* set the prediction bit */
1173169689Skan                          modified = true;
1174169689Skan                        }
1175169689Skan                    }
1176169689Skan                }
1177169689Skan              else if ((insn & 0xFc00Fffe) == 0x4c000420)
117890075Sobrien                {
117918334Speter                  /* Instruction is BCCTRx */
118090075Sobrien                  if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
118190075Sobrien		    {
118290075Sobrien		      /* This branch is predicted as not-taken.
1183169689Skan		      If this is a forward branch, it is problematic.
118452284Sobrien                      Since we can't tell statically if it will branch forward,
118590075Sobrien                      always set the prediction bit.  */
118690075Sobrien                      insn |= 0x00200000;   /* set the prediction bit */
118790075Sobrien                      modified = true;
118890075Sobrien		    }
118918334Speter                }
1190169689Skan              else if ((insn & 0xFc00Fffe) == 0x4c000020)
1191169689Skan                {
1192169689Skan                  /* Instruction is BCLRx */
1193169689Skan                  if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
1194169689Skan		    {
1195169689Skan		      /* This branch is predicted as not-taken.
1196169689Skan		      If this is a forward branch, it is problematic.
1197169689Skan                      Since we can't tell statically if it will branch forward,
1198169689Skan                      always set the prediction bit.  */
1199169689Skan                      insn |= 0x00200000;   /* set the prediction bit */
1200169689Skan                      modified = true;
120190075Sobrien		    }
120290075Sobrien                }
120396263Sobrien#undef BO0
1204169689Skan#undef BO2
1205169689Skan#undef BO4
120696263Sobrien              if (modified)
120796263Sobrien	        {
120896263Sobrien                  bfd_put_32 (abfd, (bfd_vma) insn, contents + isec_offset);
120996263Sobrien		  section_modified = true;
121096263Sobrien	        }
121196263Sobrien            }
121296263Sobrien        }
121396263Sobrien      if (section_modified)
1214169689Skan	{
1215169689Skan	  elf_section_data (isec)->this_hdr.contents = contents;
1216169689Skan	  free_contents = NULL;
121796263Sobrien	}
1218169689Skan    }
121996263Sobrien
122096263Sobrien  if (rela_comb != NULL)
122196263Sobrien    {
122296263Sobrien      free (rela_comb);
122396263Sobrien      rela_comb = NULL;
122496263Sobrien    }
122596263Sobrien
122696263Sobrien  if (free_relocs != NULL)
122796263Sobrien    {
122890075Sobrien      free (free_relocs);
122996263Sobrien      free_relocs = NULL;
123096263Sobrien    }
123196263Sobrien
123296263Sobrien  if (free_contents != NULL)
123396263Sobrien    {
123496263Sobrien      if (! link_info->keep_memory)
123590075Sobrien	free (free_contents);
123618334Speter      else
123790075Sobrien	{
123890075Sobrien	  /* Cache the section contents for elf_link_input_bfd.  */
123918334Speter	  elf_section_data (isec)->this_hdr.contents = contents;
124090075Sobrien	}
124190075Sobrien      free_contents = NULL;
124290075Sobrien    }
124390075Sobrien
124490075Sobrien  return true;
124590075Sobrien
124690075Sobrienerror_return:
124790075Sobrien  if (rela_comb != NULL)
124852284Sobrien    free (rela_comb);
124990075Sobrien  if (free_relocs != NULL)
125090075Sobrien    free (free_relocs);
125190075Sobrien  if (free_contents != NULL)
125290075Sobrien    free (free_contents);
125390075Sobrien  return false;
125490075Sobrien}
125552284Sobrien
125690075Sobrienstatic reloc_howto_type *
125790075Sobrienppc_elf_reloc_type_lookup (abfd, code)
1258132718Skan     bfd *abfd ATTRIBUTE_UNUSED;
125990075Sobrien     bfd_reloc_code_real_type code;
126090075Sobrien{
126190075Sobrien  enum elf_ppc_reloc_type ppc_reloc = R_PPC_NONE;
126252284Sobrien
126390075Sobrien  if (!ppc_elf_howto_table[R_PPC_ADDR32])
126490075Sobrien    /* Initialize howto table if needed.  */
1265169689Skan    ppc_elf_howto_init ();
126690075Sobrien
126790075Sobrien  switch ((int) code)
126852284Sobrien    {
126990075Sobrien    default:
1270169689Skan      return (reloc_howto_type *) NULL;
1271169689Skan
1272169689Skan    case BFD_RELOC_NONE:		ppc_reloc = R_PPC_NONE;			break;
127352284Sobrien    case BFD_RELOC_32:			ppc_reloc = R_PPC_ADDR32;		break;
1274169689Skan    case BFD_RELOC_PPC_BA26:		ppc_reloc = R_PPC_ADDR24;		break;
127590075Sobrien    case BFD_RELOC_16:			ppc_reloc = R_PPC_ADDR16;		break;
1276169689Skan    case BFD_RELOC_LO16:		ppc_reloc = R_PPC_ADDR16_LO;		break;
1277169689Skan    case BFD_RELOC_HI16:		ppc_reloc = R_PPC_ADDR16_HI;		break;
127890075Sobrien    case BFD_RELOC_HI16_S:		ppc_reloc = R_PPC_ADDR16_HA;		break;
127990075Sobrien    case BFD_RELOC_PPC_BA16:		ppc_reloc = R_PPC_ADDR14;		break;
128090075Sobrien    case BFD_RELOC_PPC_BA16_BRTAKEN:	ppc_reloc = R_PPC_ADDR14_BRTAKEN;	break;
128190075Sobrien    case BFD_RELOC_PPC_BA16_BRNTAKEN:	ppc_reloc = R_PPC_ADDR14_BRNTAKEN;	break;
128290075Sobrien    case BFD_RELOC_PPC_B26:		ppc_reloc = R_PPC_REL24;		break;
128390075Sobrien    case BFD_RELOC_PPC_B16:		ppc_reloc = R_PPC_REL14;		break;
128490075Sobrien    case BFD_RELOC_PPC_B16_BRTAKEN:	ppc_reloc = R_PPC_REL14_BRTAKEN;	break;
128590075Sobrien    case BFD_RELOC_PPC_B16_BRNTAKEN:	ppc_reloc = R_PPC_REL14_BRNTAKEN;	break;
1286169689Skan    case BFD_RELOC_16_GOTOFF:		ppc_reloc = R_PPC_GOT16;		break;
1287169689Skan    case BFD_RELOC_LO16_GOTOFF:		ppc_reloc = R_PPC_GOT16_LO;		break;
128852284Sobrien    case BFD_RELOC_HI16_GOTOFF:		ppc_reloc = R_PPC_GOT16_HI;		break;
1289169689Skan    case BFD_RELOC_HI16_S_GOTOFF:	ppc_reloc = R_PPC_GOT16_HA;		break;
129090075Sobrien    case BFD_RELOC_24_PLT_PCREL:	ppc_reloc = R_PPC_PLTREL24;		break;
1291169689Skan    case BFD_RELOC_PPC_COPY:		ppc_reloc = R_PPC_COPY;			break;
1292169689Skan    case BFD_RELOC_PPC_GLOB_DAT:	ppc_reloc = R_PPC_GLOB_DAT;		break;
1293169689Skan    case BFD_RELOC_PPC_LOCAL24PC:	ppc_reloc = R_PPC_LOCAL24PC;		break;
1294169689Skan    case BFD_RELOC_32_PCREL:		ppc_reloc = R_PPC_REL32;		break;
1295169689Skan    case BFD_RELOC_32_PLTOFF:		ppc_reloc = R_PPC_PLT32;		break;
1296169689Skan    case BFD_RELOC_32_PLT_PCREL:	ppc_reloc = R_PPC_PLTREL32;		break;
1297169689Skan    case BFD_RELOC_LO16_PLTOFF:		ppc_reloc = R_PPC_PLT16_LO;		break;
1298169689Skan    case BFD_RELOC_HI16_PLTOFF:		ppc_reloc = R_PPC_PLT16_HI;		break;
1299169689Skan    case BFD_RELOC_HI16_S_PLTOFF:	ppc_reloc = R_PPC_PLT16_HA;		break;
1300169689Skan    case BFD_RELOC_GPREL16:		ppc_reloc = R_PPC_SDAREL16;		break;
1301169689Skan    case BFD_RELOC_16_BASEREL:		ppc_reloc = R_PPC_SECTOFF;		break;
1302169689Skan    case BFD_RELOC_LO16_BASEREL:	ppc_reloc = R_PPC_SECTOFF_LO;		break;
130390075Sobrien    case BFD_RELOC_HI16_BASEREL:	ppc_reloc = R_PPC_SECTOFF_HI;		break;
130452284Sobrien    case BFD_RELOC_HI16_S_BASEREL:	ppc_reloc = R_PPC_SECTOFF_HA;		break;
1305169689Skan    case BFD_RELOC_CTOR:		ppc_reloc = R_PPC_ADDR32;		break;
130690075Sobrien    case BFD_RELOC_PPC_TOC16:		ppc_reloc = R_PPC_TOC16;		break;
1307169689Skan    case BFD_RELOC_PPC_EMB_NADDR32:	ppc_reloc = R_PPC_EMB_NADDR32;		break;
1308169689Skan    case BFD_RELOC_PPC_EMB_NADDR16:	ppc_reloc = R_PPC_EMB_NADDR16;		break;
130990075Sobrien    case BFD_RELOC_PPC_EMB_NADDR16_LO:	ppc_reloc = R_PPC_EMB_NADDR16_LO;	break;
131090075Sobrien    case BFD_RELOC_PPC_EMB_NADDR16_HI:	ppc_reloc = R_PPC_EMB_NADDR16_HI;	break;
1311169689Skan    case BFD_RELOC_PPC_EMB_NADDR16_HA:	ppc_reloc = R_PPC_EMB_NADDR16_HA;	break;
1312169689Skan    case BFD_RELOC_PPC_EMB_SDAI16:	ppc_reloc = R_PPC_EMB_SDAI16;		break;
131390075Sobrien    case BFD_RELOC_PPC_EMB_SDA2I16:	ppc_reloc = R_PPC_EMB_SDA2I16;		break;
1314169689Skan    case BFD_RELOC_PPC_EMB_SDA2REL:	ppc_reloc = R_PPC_EMB_SDA2REL;		break;
1315169689Skan    case BFD_RELOC_PPC_EMB_SDA21:	ppc_reloc = R_PPC_EMB_SDA21;		break;
1316169689Skan    case BFD_RELOC_PPC_EMB_MRKREF:	ppc_reloc = R_PPC_EMB_MRKREF;		break;
1317169689Skan    case BFD_RELOC_PPC_EMB_RELSEC16:	ppc_reloc = R_PPC_EMB_RELSEC16;		break;
1318169689Skan    case BFD_RELOC_PPC_EMB_RELST_LO:	ppc_reloc = R_PPC_EMB_RELST_LO;		break;
131990075Sobrien    case BFD_RELOC_PPC_EMB_RELST_HI:	ppc_reloc = R_PPC_EMB_RELST_HI;		break;
132090075Sobrien    case BFD_RELOC_PPC_EMB_RELST_HA:	ppc_reloc = R_PPC_EMB_RELST_HA;		break;
132152284Sobrien    case BFD_RELOC_PPC_EMB_BIT_FLD:	ppc_reloc = R_PPC_EMB_BIT_FLD;		break;
132290075Sobrien    case BFD_RELOC_PPC_EMB_RELSDA:	ppc_reloc = R_PPC_EMB_RELSDA;		break;
132390075Sobrien    case BFD_RELOC_VTABLE_INHERIT:	ppc_reloc = R_PPC_GNU_VTINHERIT;	break;
132490075Sobrien    case BFD_RELOC_VTABLE_ENTRY:	ppc_reloc = R_PPC_GNU_VTENTRY;		break;
132590075Sobrien    }
132652284Sobrien
132790075Sobrien  return ppc_elf_howto_table[(int) ppc_reloc];
132890075Sobrien};
132990075Sobrien
133090075Sobrien/* Set the howto pointer for a PowerPC ELF reloc.  */
1331169689Skan
1332169689Skanstatic void
1333169689Skanppc_elf_info_to_howto (abfd, cache_ptr, dst)
1334169689Skan     bfd *abfd ATTRIBUTE_UNUSED;
1335169689Skan     arelent *cache_ptr;
133690075Sobrien     Elf32_Internal_Rela *dst;
133790075Sobrien{
133890075Sobrien  if (!ppc_elf_howto_table[R_PPC_ADDR32])
133990075Sobrien    /* Initialize howto table if needed.  */
134090075Sobrien    ppc_elf_howto_init ();
1341169689Skan
134218334Speter  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
134390075Sobrien  cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
134490075Sobrien}
1345169689Skan
1346169689Skan/* Handle the R_PPC_ADDR16_HA reloc.  */
1347169689Skan
1348169689Skanstatic bfd_reloc_status_type
134952284Sobrienppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
135090075Sobrien			 output_bfd, error_message)
1351169689Skan     bfd *abfd ATTRIBUTE_UNUSED;
1352169689Skan     arelent *reloc_entry;
135390075Sobrien     asymbol *symbol;
135452284Sobrien     PTR data ATTRIBUTE_UNUSED;
1355169689Skan     asection *input_section;
1356169689Skan     bfd *output_bfd;
1357169689Skan     char **error_message ATTRIBUTE_UNUSED;
1358169689Skan{
1359169689Skan  bfd_vma relocation;
1360169689Skan
1361169689Skan  if (output_bfd != NULL)
1362169689Skan    {
1363169689Skan      reloc_entry->address += input_section->output_offset;
1364169689Skan      return bfd_reloc_ok;
1365169689Skan    }
1366169689Skan
1367169689Skan  if (reloc_entry->address > input_section->_cooked_size)
1368169689Skan    return bfd_reloc_outofrange;
1369169689Skan
1370169689Skan  if (bfd_is_com_section (symbol->section))
1371169689Skan    relocation = 0;
1372169689Skan  else
1373169689Skan    relocation = symbol->value;
1374169689Skan
1375169689Skan  relocation += symbol->section->output_section->vma;
1376169689Skan  relocation += symbol->section->output_offset;
1377169689Skan  relocation += reloc_entry->addend;
1378169689Skan
1379169689Skan  reloc_entry->addend += (relocation & 0x8000) << 1;
1380169689Skan
1381169689Skan  return bfd_reloc_continue;
1382169689Skan}
1383169689Skan
1384169689Skan/* Fix bad default arch selected for a 32 bit input bfd when the
1385169689Skan   default is 64 bit.  */
1386169689Skan
1387169689Skanstatic boolean
1388169689Skanppc_elf_object_p (abfd)
1389169689Skan     bfd *abfd;
1390169689Skan{
1391169689Skan  if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
1392169689Skan    {
1393169689Skan      Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
1394169689Skan
1395169689Skan      if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1396169689Skan	{
1397169689Skan	  /* Relies on arch after 64 bit default being 32 bit default.  */
1398169689Skan	  abfd->arch_info = abfd->arch_info->next;
1399169689Skan	  BFD_ASSERT (abfd->arch_info->bits_per_word == 32);
1400169689Skan	}
1401169689Skan    }
1402169689Skan  return true;
1403169689Skan}
1404169689Skan
1405169689Skan/* Function to set whether a module needs the -mrelocatable bit set.  */
1406169689Skan
1407169689Skanstatic boolean
1408169689Skanppc_elf_set_private_flags (abfd, flags)
1409169689Skan     bfd *abfd;
1410169689Skan     flagword flags;
1411169689Skan{
1412169689Skan  BFD_ASSERT (!elf_flags_init (abfd)
1413169689Skan	      || elf_elfheader (abfd)->e_flags == flags);
141490075Sobrien
141552284Sobrien  elf_elfheader (abfd)->e_flags = flags;
141690075Sobrien  elf_flags_init (abfd) = true;
141790075Sobrien  return true;
1418169689Skan}
141918334Speter
142090075Sobrien/* Merge backend specific data from an object file to the output
1421169689Skan   object file when linking */
1422169689Skanstatic boolean
1423169689Skanppc_elf_merge_private_bfd_data (ibfd, obfd)
142490075Sobrien     bfd *ibfd;
142590075Sobrien     bfd *obfd;
142690075Sobrien{
142790075Sobrien  flagword old_flags;
142890075Sobrien  flagword new_flags;
142990075Sobrien  boolean error;
143090075Sobrien
143118334Speter  /* Check if we have the same endianess */
143218334Speter  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
143352284Sobrien    return false;
143490075Sobrien
143590075Sobrien  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1436169689Skan      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1437169689Skan    return true;
143852284Sobrien
143990075Sobrien  new_flags = elf_elfheader (ibfd)->e_flags;
144052284Sobrien  old_flags = elf_elfheader (obfd)->e_flags;
1441169689Skan  if (!elf_flags_init (obfd))	/* First call, no flags set */
1442169689Skan    {
1443169689Skan      elf_flags_init (obfd) = true;
144452284Sobrien      elf_elfheader (obfd)->e_flags = new_flags;
144590075Sobrien    }
1446169689Skan
1447169689Skan  else if (new_flags == old_flags)	/* Compatible flags are ok */
1448169689Skan    ;
144952284Sobrien
145090075Sobrien  else					/* Incompatible flags */
145152284Sobrien    {
1452117395Skan      /* Warn about -mrelocatable mismatch.  Allow -mrelocatable-lib to be linked
145390075Sobrien         with either.  */
1454169689Skan      error = false;
1455169689Skan      if ((new_flags & EF_PPC_RELOCATABLE) != 0
145690075Sobrien	  && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0)
145752284Sobrien	{
145852284Sobrien	  error = true;
1459169689Skan	  (*_bfd_error_handler)
146090075Sobrien	    (_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
1461169689Skan	     bfd_archive_filename (ibfd));
1462169689Skan	}
146318334Speter      else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
146452284Sobrien	       && (old_flags & EF_PPC_RELOCATABLE) != 0)
146590075Sobrien	{
1466117395Skan	  error = true;
146790075Sobrien	  (*_bfd_error_handler)
146890075Sobrien	    (_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
146990075Sobrien	     bfd_archive_filename (ibfd));
147052284Sobrien	}
147190075Sobrien
147290075Sobrien      /* The output is -mrelocatable-lib iff both the input files are.  */
147390075Sobrien      if (! (new_flags & EF_PPC_RELOCATABLE_LIB))
147490075Sobrien	elf_elfheader (obfd)->e_flags &= ~EF_PPC_RELOCATABLE_LIB;
147552284Sobrien
147652284Sobrien      /* The output is -mrelocatable iff it can't be -mrelocatable-lib,
147790075Sobrien         but each input file is either -mrelocatable or -mrelocatable-lib.  */
147890075Sobrien      if (! (elf_elfheader (obfd)->e_flags & EF_PPC_RELOCATABLE_LIB)
147990075Sobrien	  && (new_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE))
148090075Sobrien	  && (old_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE)))
1481132718Skan	elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE;
148290075Sobrien
148390075Sobrien      /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if any module uses it */
148490075Sobrien      elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB);
148590075Sobrien
148652284Sobrien      new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
148790075Sobrien      old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
148890075Sobrien
148952284Sobrien      /* Warn about any other mismatches */
149090075Sobrien      if (new_flags != old_flags)
149152284Sobrien	{
149290075Sobrien	  error = true;
149390075Sobrien	  (*_bfd_error_handler)
149490075Sobrien	    (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1495169689Skan	     bfd_archive_filename (ibfd), (long) new_flags, (long) old_flags);
149690075Sobrien	}
149790075Sobrien
149890075Sobrien      if (error)
149990075Sobrien	{
150090075Sobrien	  bfd_set_error (bfd_error_bad_value);
150152284Sobrien	  return false;
150290075Sobrien	}
1503169689Skan    }
150490075Sobrien
150552284Sobrien  return true;
150690075Sobrien}
150790075Sobrien
150852284Sobrien/* Handle a PowerPC specific section when reading an object file.  This
150990075Sobrien   is called when elfcode.h finds a section with an unknown type.  */
151090075Sobrien
151190075Sobrienstatic boolean
151290075Sobrienppc_elf_section_from_shdr (abfd, hdr, name)
151352284Sobrien     bfd *abfd;
151452284Sobrien     Elf32_Internal_Shdr *hdr;
151590075Sobrien     const char *name;
151652284Sobrien{
151752284Sobrien  asection *newsect;
151890075Sobrien  flagword flags;
151990075Sobrien
152090075Sobrien  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
152190075Sobrien    return false;
152290075Sobrien
152390075Sobrien  newsect = hdr->bfd_section;
152452284Sobrien  flags = bfd_get_section_flags (abfd, newsect);
1525169689Skan  if (hdr->sh_flags & SHF_EXCLUDE)
1526132718Skan    flags |= SEC_EXCLUDE;
152752284Sobrien
152852284Sobrien  if (hdr->sh_type == SHT_ORDERED)
152990075Sobrien    flags |= SEC_SORT_ENTRIES;
1530169689Skan
153190075Sobrien  bfd_set_section_flags (abfd, newsect, flags);
1532169689Skan  return true;
153352284Sobrien}
1534169689Skan
153552284Sobrien/* Set up any other section flags and such that may be necessary.  */
153690075Sobrien
1537169689Skanstatic boolean
1538169689Skanppc_elf_fake_sections (abfd, shdr, asect)
1539169689Skan     bfd *abfd ATTRIBUTE_UNUSED;
1540169689Skan     Elf32_Internal_Shdr *shdr;
154152284Sobrien     asection *asect;
154290075Sobrien{
154390075Sobrien  if ((asect->flags & SEC_EXCLUDE) != 0)
154452284Sobrien    shdr->sh_flags |= SHF_EXCLUDE;
154590075Sobrien
154690075Sobrien  if ((asect->flags & SEC_SORT_ENTRIES) != 0)
154790075Sobrien    shdr->sh_type = SHT_ORDERED;
154890075Sobrien
154990075Sobrien  return true;
155090075Sobrien}
155190075Sobrien
155290075Sobrien/* Create a special linker section */
155390075Sobrienstatic elf_linker_section_t *
155490075Sobrienppc_elf_create_linker_section (abfd, info, which)
155590075Sobrien     bfd *abfd;
155690075Sobrien     struct bfd_link_info *info;
155790075Sobrien     enum elf_linker_section_enum which;
155890075Sobrien{
1559117395Skan  bfd *dynobj = elf_hash_table (info)->dynobj;
1560117395Skan  elf_linker_section_t *lsect;
1561117395Skan
1562117395Skan  /* Record the first bfd section that needs the special section */
1563117395Skan  if (!dynobj)
156490075Sobrien    dynobj = elf_hash_table (info)->dynobj = abfd;
156590075Sobrien
156690075Sobrien  /* If this is the first time, create the section */
156790075Sobrien  lsect = elf_linker_section (dynobj, which);
1568169689Skan  if (!lsect)
156990075Sobrien    {
157052284Sobrien      elf_linker_section_t defaults;
157190075Sobrien      static elf_linker_section_t zero_section;
157290075Sobrien
157390075Sobrien      defaults = zero_section;
157452284Sobrien      defaults.which = which;
157590075Sobrien      defaults.hole_written_p = false;
157618334Speter      defaults.alignment = 2;
157790075Sobrien
157850397Sobrien      /* Both of these sections are (technically) created by the user
157990075Sobrien	 putting data in them, so they shouldn't be marked
1580169689Skan	 SEC_LINKER_CREATED.
158190075Sobrien
1582169689Skan	 The linker creates them so it has somewhere to attach their
1583132718Skan	 respective symbols. In fact, if they were empty it would
158450397Sobrien	 be OK to leave the symbol set to 0 (or any random number), because
1585117395Skan	 the appropriate register should never be used.  */
158650397Sobrien      defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1587117395Skan			| SEC_IN_MEMORY);
158890075Sobrien
1589169689Skan      switch (which)
1590169689Skan	{
1591169689Skan	default:
1592169689Skan	  (*_bfd_error_handler) (_("%s: Unknown special linker type %d"),
1593169689Skan				 bfd_get_filename (abfd),
1594169689Skan				 (int) which);
1595169689Skan
1596169689Skan	  bfd_set_error (bfd_error_bad_value);
1597169689Skan	  return (elf_linker_section_t *) 0;
1598169689Skan
159990075Sobrien	case LINKER_SECTION_SDATA:	/* .sdata/.sbss section */
160050397Sobrien	  defaults.name		  = ".sdata";
1601169689Skan	  defaults.rel_name	  = ".rela.sdata";
160250397Sobrien	  defaults.bss_name	  = ".sbss";
160350397Sobrien	  defaults.sym_name	  = "_SDA_BASE_";
160450397Sobrien	  defaults.sym_offset	  = 32768;
1605132718Skan	  break;
160650397Sobrien
160790075Sobrien	case LINKER_SECTION_SDATA2:	/* .sdata2/.sbss2 section */
160852284Sobrien	  defaults.name		  = ".sdata2";
160990075Sobrien	  defaults.rel_name	  = ".rela.sdata2";
1610169689Skan	  defaults.bss_name	  = ".sbss2";
1611169689Skan	  defaults.sym_name	  = "_SDA2_BASE_";
161290075Sobrien	  defaults.sym_offset	  = 32768;
161390075Sobrien	  defaults.flags	 |= SEC_READONLY;
161490075Sobrien	  break;
161590075Sobrien	}
161690075Sobrien
161790075Sobrien      lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
161890075Sobrien    }
161990075Sobrien
162050397Sobrien  return lsect;
162190075Sobrien}
162290075Sobrien
162390075Sobrien/* If we have a non-zero sized .sbss2 or .PPC.EMB.sbss0 sections, we
162490075Sobrien   need to bump up the number of section headers.  */
1625161651Skan
162690075Sobrienstatic int
1627132718Skanppc_elf_additional_program_headers (abfd)
162890075Sobrien     bfd *abfd;
162950397Sobrien{
163050397Sobrien  asection *s;
163150397Sobrien  int ret;
163290075Sobrien
163318334Speter  ret = 0;
163490075Sobrien
1635132718Skan  s = bfd_get_section_by_name (abfd, ".interp");
163618334Speter  if (s != NULL)
163790075Sobrien    ++ret;
163818334Speter
163990075Sobrien  s = bfd_get_section_by_name (abfd, ".sbss2");
164090075Sobrien  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
164190075Sobrien    ++ret;
164290075Sobrien
164318334Speter  s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
164490075Sobrien  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
164590075Sobrien    ++ret;
164690075Sobrien
1647117395Skan  return ret;
164818334Speter}
1649169689Skan
165052284Sobrien/* Modify the segment map if needed.  */
165190075Sobrien
165290075Sobrienstatic boolean
165390075Sobrienppc_elf_modify_segment_map (abfd)
165490075Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
165590075Sobrien{
165690075Sobrien  return true;
165790075Sobrien}
165890075Sobrien
1659169689Skan/* The powerpc .got has a blrl instruction in it.  Mark it executable.  */
166090075Sobrien
166190075Sobrienstatic asection *
166252284Sobrienppc_elf_create_got (abfd, info)
166390075Sobrien     bfd *abfd;
166490075Sobrien     struct bfd_link_info *info;
166590075Sobrien{
166690075Sobrien  register asection *s;
166718334Speter  flagword flags;
166890075Sobrien
166990075Sobrien  if (!_bfd_elf_create_got_section (abfd, info))
167018334Speter    return NULL;
1671117395Skan
1672117395Skan  s = bfd_get_section_by_name (abfd, ".got");
167352284Sobrien  if (s == NULL)
167452284Sobrien    abort ();
167518334Speter
1676117395Skan  flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1677117395Skan	   | SEC_LINKER_CREATED);
167852284Sobrien  if (!bfd_set_section_flags (abfd, s, flags))
167918334Speter    return NULL;
168090075Sobrien  return s;
168190075Sobrien}
168290075Sobrien
168390075Sobrien/* We have to create .dynsbss and .rela.sbss here so that they get mapped
1684132718Skan   to output sections (just like _bfd_elf_create_dynamic_sections has
168552284Sobrien   to create .dynbss and .rela.bss).  */
168690075Sobrien
168790075Sobrienstatic boolean
168818334Speterppc_elf_create_dynamic_sections (abfd, info)
1689117395Skan     bfd *abfd;
1690117395Skan     struct bfd_link_info *info;
169190075Sobrien{
169290075Sobrien  register asection *s;
169352284Sobrien  flagword flags;
169490075Sobrien
169552284Sobrien  if (!ppc_elf_create_got (abfd, info))
169690075Sobrien    return false;
1697132718Skan
169852284Sobrien  if (!_bfd_elf_create_dynamic_sections (abfd, info))
169990075Sobrien    return false;
170090075Sobrien
170190075Sobrien  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
170290075Sobrien	   | SEC_LINKER_CREATED);
170390075Sobrien
1704169689Skan  s = bfd_make_section (abfd, ".dynsbss");
170518334Speter  if (s == NULL
170690075Sobrien      || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
170790075Sobrien    return false;
170818334Speter
170990075Sobrien  if (! info->shared)
171090075Sobrien    {
171118334Speter      s = bfd_make_section (abfd, ".rela.sbss");
171290075Sobrien      if (s == NULL
171390075Sobrien	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
171490075Sobrien	  || ! bfd_set_section_alignment (abfd, s, 2))
171552284Sobrien	return false;
171618334Speter    }
171790075Sobrien
171890075Sobrien  s = bfd_get_section_by_name (abfd, ".plt");
171990075Sobrien  if (s == NULL)
172090075Sobrien    abort ();
172190075Sobrien
172290075Sobrien  flags = SEC_ALLOC | SEC_CODE | SEC_IN_MEMORY | SEC_LINKER_CREATED;
172390075Sobrien  return bfd_set_section_flags (abfd, s, flags);
172490075Sobrien}
172590075Sobrien
172690075Sobrien/* Adjust a symbol defined by a dynamic object and referenced by a
172790075Sobrien   regular object.  The current definition is in some section of the
172890075Sobrien   dynamic object, but we're not including those sections.  We have to
172990075Sobrien   change the definition to something the rest of the link can
173090075Sobrien   understand.  */
173190075Sobrien
173290075Sobrienstatic boolean
173390075Sobrienppc_elf_adjust_dynamic_symbol (info, h)
173490075Sobrien     struct bfd_link_info *info;
173590075Sobrien     struct elf_link_hash_entry *h;
173618334Speter{
173790075Sobrien  bfd *dynobj = elf_hash_table (info)->dynobj;
1738169689Skan  asection *s;
1739169689Skan  unsigned int power_of_two;
1740169689Skan  bfd_vma plt_offset;
1741169689Skan
174290075Sobrien#ifdef DEBUG
1743169689Skan  fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called for %s\n", h->root.root.string);
174452284Sobrien#endif
174590075Sobrien
174690075Sobrien  /* Make sure we know what is going on here.  */
174790075Sobrien  BFD_ASSERT (dynobj != NULL
174890075Sobrien	      && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
174952284Sobrien		  || h->weakdef != NULL
175090075Sobrien		  || ((h->elf_link_hash_flags
1751146895Skan		       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
175290075Sobrien		      && (h->elf_link_hash_flags
1753102780Skan			  & ELF_LINK_HASH_REF_REGULAR) != 0
175452284Sobrien		      && (h->elf_link_hash_flags
1755117395Skan			  & ELF_LINK_HASH_DEF_REGULAR) == 0)));
1756117395Skan
1757117395Skan  /* If this is a function, put it in the procedure linkage table.  We
1758102780Skan     will fill in the contents of the procedure linkage table later,
1759132718Skan     when we know the address of the .got section.  */
1760117395Skan  if (h->type == STT_FUNC
1761117395Skan      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
1762132718Skan    {
1763102780Skan      if (! elf_hash_table (info)->dynamic_sections_created
1764117395Skan 	  || SYMBOL_CALLS_LOCAL (info, h)
1765102780Skan	  || (info->shared && h->plt.refcount <= 0))
1766102780Skan	{
1767102780Skan	  /* A PLT entry is not required/allowed when:
1768132718Skan
1769102780Skan	     1. We are not using ld.so; because then the PLT entry
1770102780Skan	     can't be set up, so we can't use one.
1771102780Skan
1772102780Skan	     2. We know for certain that a call to this symbol
1773102780Skan	     will go to this object.
1774102780Skan
1775132718Skan	     3. GC has rendered the entry unused.
1776102780Skan	     Note, however, that in an executable all references to the
1777102780Skan	     symbol go to the PLT, so we can't turn it off in that case.
1778102780Skan	     ??? The correct thing to do here is to reference count
1779102780Skan	     all uses of the symbol, not just those to the GOT or PLT.  */
1780102780Skan	  h->plt.offset = (bfd_vma) -1;
1781102780Skan	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1782102780Skan	  return true;
1783102780Skan	}
1784102780Skan
1785102780Skan      /* Make sure this symbol is output as a dynamic symbol.  */
1786102780Skan      if (h->dynindx == -1)
1787117395Skan	{
1788102780Skan	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
1789102780Skan	    return false;
179090075Sobrien	}
179190075Sobrien      BFD_ASSERT (h->dynindx != -1);
179252284Sobrien
179390075Sobrien      s = bfd_get_section_by_name (dynobj, ".plt");
179490075Sobrien      BFD_ASSERT (s != NULL);
179590075Sobrien
179690075Sobrien      /* If this is the first .plt entry, make room for the special
179790075Sobrien	 first entry.  */
179852284Sobrien      if (s->_raw_size == 0)
179990075Sobrien	s->_raw_size += PLT_INITIAL_ENTRY_SIZE;
180090075Sobrien
180190075Sobrien      /* The PowerPC PLT is actually composed of two parts, the first part
1802169689Skan	 is 2 words (for a load and a jump), and then there is a remaining
180390075Sobrien	 word available at the end.  */
180490075Sobrien      plt_offset = (PLT_INITIAL_ENTRY_SIZE
180590075Sobrien		    + (PLT_SLOT_SIZE
180690075Sobrien		       * ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE)
180790075Sobrien			  / PLT_ENTRY_SIZE)));
180890075Sobrien
180990075Sobrien      /* If this symbol is not defined in a regular file, and we are
181090075Sobrien	 not generating a shared library, then set the symbol to this
181190075Sobrien	 location in the .plt.  This is required to make function
181290075Sobrien	 pointers compare as equal between the normal executable and
181390075Sobrien	 the shared library.  */
181490075Sobrien      if (! info->shared
181552284Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
181690075Sobrien	{
181752284Sobrien	  h->root.u.def.section = s;
181890075Sobrien	  h->root.u.def.value = plt_offset;
181990075Sobrien	}
182090075Sobrien
182190075Sobrien      h->plt.offset = plt_offset;
182252284Sobrien
182390075Sobrien      /* Make room for this entry.  After the 8192nd entry, room
182490075Sobrien         for two entries is allocated.  */
182552284Sobrien      if ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
182690075Sobrien	  >= PLT_NUM_SINGLE_ENTRIES)
182790075Sobrien	s->_raw_size += 2 * PLT_ENTRY_SIZE;
182852284Sobrien      else
182990075Sobrien	s->_raw_size += PLT_ENTRY_SIZE;
183090075Sobrien
183190075Sobrien      /* We also need to make an entry in the .rela.plt section.  */
183290075Sobrien      s = bfd_get_section_by_name (dynobj, ".rela.plt");
183390075Sobrien      BFD_ASSERT (s != NULL);
1834169689Skan      s->_raw_size += sizeof (Elf32_External_Rela);
1835169689Skan
1836169689Skan      return true;
1837169689Skan    }
1838169689Skan  else
1839169689Skan    h->plt.offset = (bfd_vma) -1;
1840169689Skan
1841169689Skan  /* If this is a weak symbol, and there is a real definition, the
1842169689Skan     processor independent code will have arranged for us to see the
1843169689Skan     real definition first, and we can just use the same value.  */
1844169689Skan  if (h->weakdef != NULL)
1845169689Skan    {
184690075Sobrien      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
184790075Sobrien		  || h->weakdef->root.type == bfd_link_hash_defweak);
184890075Sobrien      h->root.u.def.section = h->weakdef->root.u.def.section;
184990075Sobrien      h->root.u.def.value = h->weakdef->root.u.def.value;
185090075Sobrien      return true;
185118334Speter    }
1852169689Skan
1853161651Skan  /* This is a reference to a symbol defined by a dynamic object which
1854169689Skan     is not a function.  */
1855169689Skan
1856169689Skan  /* If we are creating a shared library, we must presume that the
1857169689Skan     only references to the symbol are via the global offset table.
1858169689Skan     For such cases we need not do anything here; the relocations will
1859169689Skan     be handled correctly by relocate_section.  */
1860161651Skan  if (info->shared)
186152284Sobrien    return true;
186290075Sobrien
186390075Sobrien  /* We must allocate the symbol in our .dynbss section, which will
186490075Sobrien     become part of the .bss section of the executable.  There will be
186552284Sobrien     an entry for this symbol in the .dynsym section.  The dynamic
1866169689Skan     object will contain position independent code, so all references
186718334Speter     from the dynamic object to this symbol will go through the global
1868119256Skan     offset table.  The dynamic linker will use the .dynsym entry to
1869119256Skan     determine the address it must put in the global offset table, so
1870119256Skan     both the dynamic object and the regular object will refer to the
187190075Sobrien     same memory location for the variable.
187218334Speter
187390075Sobrien     Of course, if the symbol is sufficiently small, we must instead
187490075Sobrien     allocate it in .sbss.  FIXME: It would be better to do this if and
187590075Sobrien     only if there were actually SDAREL relocs for that symbol.  */
187618334Speter
1877117395Skan  if (h->size <= elf_gp_size (dynobj))
1878117395Skan    s = bfd_get_section_by_name (dynobj, ".dynsbss");
1879117395Skan  else
188090075Sobrien    s = bfd_get_section_by_name (dynobj, ".dynbss");
188118334Speter  BFD_ASSERT (s != NULL);
188290075Sobrien
188390075Sobrien  /* We must generate a R_PPC_COPY reloc to tell the dynamic linker to
188418334Speter     copy the initial value out of the dynamic object and into the
1885117395Skan     runtime process image.  We need to remember the offset into the
1886117395Skan     .rela.bss section we are going to use.  */
188718334Speter  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
188890075Sobrien    {
188990075Sobrien      asection *srel;
189090075Sobrien
189190075Sobrien      if (h->size <= elf_gp_size (dynobj))
189290075Sobrien	srel = bfd_get_section_by_name (dynobj, ".rela.sbss");
189390075Sobrien      else
189490075Sobrien	srel = bfd_get_section_by_name (dynobj, ".rela.bss");
189518334Speter      BFD_ASSERT (srel != NULL);
1896119256Skan      srel->_raw_size += sizeof (Elf32_External_Rela);
1897119256Skan      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
1898119256Skan    }
1899119256Skan
1900119256Skan  /* We need to figure out the alignment required for this symbol.  I
1901169689Skan     have no idea how ELF linkers handle this.  */
190290075Sobrien  power_of_two = bfd_log2 (h->size);
1903119256Skan  if (power_of_two > 4)
1904119256Skan    power_of_two = 4;
1905119256Skan
1906119256Skan  /* Apply the required alignment.  */
1907119256Skan  s->_raw_size = BFD_ALIGN (s->_raw_size,
1908119256Skan			    (bfd_size_type) (1 << power_of_two));
190990075Sobrien  if (power_of_two > bfd_get_section_alignment (dynobj, s))
1910132718Skan    {
191190075Sobrien      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
1912132718Skan	return false;
191390075Sobrien    }
191490075Sobrien
191518334Speter  /* Define the symbol as being at this point in the section.  */
191618334Speter  h->root.u.def.section = s;
191790075Sobrien  h->root.u.def.value = s->_raw_size;
191890075Sobrien
191990075Sobrien  /* Increment the section size to make room for the symbol.  */
192090075Sobrien  s->_raw_size += h->size;
192118334Speter
192290075Sobrien  return true;
192390075Sobrien}
192490075Sobrien
192518334Speter/* Set the sizes of the dynamic sections.  */
192690075Sobrien
192790075Sobrienstatic boolean
192890075Sobrienppc_elf_size_dynamic_sections (output_bfd, info)
192990075Sobrien     bfd *output_bfd ATTRIBUTE_UNUSED;
193018334Speter     struct bfd_link_info *info;
193118334Speter{
1932169689Skan  bfd *dynobj;
193390075Sobrien  asection *s;
193490075Sobrien  boolean plt;
193590075Sobrien  boolean relocs;
193618334Speter
193790075Sobrien#ifdef DEBUG
193890075Sobrien  fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
193990075Sobrien#endif
194050397Sobrien
1941132718Skan  dynobj = elf_hash_table (info)->dynobj;
1942132718Skan  BFD_ASSERT (dynobj != NULL);
194390075Sobrien
194490075Sobrien  if (elf_hash_table (info)->dynamic_sections_created)
194590075Sobrien    {
1946132718Skan      /* Set the contents of the .interp section to the interpreter.  */
1947132718Skan      if (! info->shared)
1948132718Skan	{
194950397Sobrien	  s = bfd_get_section_by_name (dynobj, ".interp");
195090075Sobrien	  BFD_ASSERT (s != NULL);
1951169689Skan	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
1952169689Skan	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
1953169689Skan	}
195490075Sobrien    }
195518334Speter  else
195690075Sobrien    {
195790075Sobrien      /* We may have created entries in the .rela.got, .rela.sdata, and
195890075Sobrien	 .rela.sdata2 sections.  However, if we are not creating the
195990075Sobrien	 dynamic sections, we will not actually use these entries.  Reset
1960117395Skan	 the size of .rela.got, et al, which will cause it to get
196190075Sobrien	 stripped from the output file below.  */
196252284Sobrien      static char *rela_sections[] = { ".rela.got", ".rela.sdata",
196352284Sobrien				       ".rela.sdata2", ".rela.sbss",
1964169689Skan				       (char *) 0 };
196552284Sobrien      char **p;
196690075Sobrien
196752284Sobrien      for (p = rela_sections; *p != (char *) 0; p++)
196852284Sobrien	{
196990075Sobrien	  s = bfd_get_section_by_name (dynobj, *p);
197090075Sobrien	  if (s != NULL)
197190075Sobrien	    s->_raw_size = 0;
197252284Sobrien	}
197390075Sobrien    }
1974132718Skan
1975132718Skan  /* The check_relocs and adjust_dynamic_symbol entry points have
197618334Speter     determined the sizes of the various dynamic sections.  Allocate
1977169689Skan     memory for them.  */
197818334Speter  plt = false;
197990075Sobrien  relocs = false;
198090075Sobrien  for (s = dynobj->sections; s != NULL; s = s->next)
198190075Sobrien    {
198290075Sobrien      const char *name;
198390075Sobrien      boolean strip;
198490075Sobrien
198590075Sobrien      if ((s->flags & SEC_LINKER_CREATED) == 0)
198690075Sobrien	continue;
1987169689Skan
198818334Speter      /* It's OK to base decisions on the section name, because none
198990075Sobrien	 of the dynobj section names depend upon the input files.  */
1990169689Skan      name = bfd_get_section_name (dynobj, s);
199190075Sobrien
199290075Sobrien      strip = false;
199350397Sobrien
1994169689Skan      if (strcmp (name, ".plt") == 0)
199550397Sobrien	{
199690075Sobrien	  if (s->_raw_size == 0)
199790075Sobrien	    {
199890075Sobrien	      /* Strip this section if we don't need it; see the
1999169689Skan                 comment below.  */
200050397Sobrien	      strip = true;
2001132718Skan	    }
2002132718Skan	  else
2003132718Skan	    {
2004169689Skan	      /* Remember whether there is a PLT.  */
2005132718Skan	      plt = true;
200618334Speter	    }
2007169689Skan	}
200890075Sobrien      else if (strncmp (name, ".rela", 5) == 0)
2009169689Skan	{
201018334Speter	  if (s->_raw_size == 0)
201190075Sobrien	    {
2012169689Skan	      /* If we don't need this section, strip it from the
2013169689Skan		 output file.  This is mostly to handle .rela.bss and
201490075Sobrien		 .rela.plt.  We must create both sections in
2015169689Skan		 create_dynamic_sections, because they must be created
201618334Speter		 before the linker maps input sections to output
2017169689Skan		 sections.  The linker does that before
201890075Sobrien		 adjust_dynamic_symbol is called, and it is that
201990075Sobrien		 function which decides whether anything needs to go
202090075Sobrien		 into these sections.  */
202190075Sobrien	      strip = true;
202290075Sobrien	    }
2023169689Skan	  else
2024169689Skan	    {
202590075Sobrien	      /* Remember whether there are any relocation sections.  */
202690075Sobrien	      relocs = true;
202790075Sobrien
202890075Sobrien	      /* We use the reloc_count field as a counter if we need
2029169689Skan		 to copy relocs into the output file.  */
203018334Speter	      s->reloc_count = 0;
203190075Sobrien	    }
203290075Sobrien	}
203390075Sobrien      else if (strcmp (name, ".got") != 0
203418334Speter	       && strcmp (name, ".sdata") != 0
203590075Sobrien	       && strcmp (name, ".sdata2") != 0)
2036169689Skan	{
2037169689Skan	  /* It's not one of our sections, so don't allocate space.  */
2038169689Skan	  continue;
2039169689Skan	}
2040169689Skan
2041132718Skan      if (strip)
2042132718Skan	{
2043132718Skan	  _bfd_strip_section_from_output (info, s);
204490075Sobrien	  continue;
2045169689Skan	}
204618334Speter
204790075Sobrien      /* Allocate memory for the section contents.  */
204890075Sobrien      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
204952284Sobrien      if (s->contents == NULL && s->_raw_size != 0)
2050132718Skan	return false;
2051169689Skan    }
2052169689Skan
2053169689Skan  if (elf_hash_table (info)->dynamic_sections_created)
2054169689Skan    {
2055169689Skan      /* Add some entries to the .dynamic section.  We fill in the
2056169689Skan	 values later, in ppc_elf_finish_dynamic_sections, but we
2057132718Skan	 must add the entries now so that we get the correct size for
2058132718Skan	 the .dynamic section.  The DT_DEBUG entry is filled in by the
2059132718Skan	 dynamic linker and used by the debugger.  */
2060169689Skan#define add_dynamic_entry(TAG, VAL) \
2061132718Skan  bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2062132718Skan
2063169689Skan      if (!info->shared)
2064169689Skan	{
2065132718Skan	  if (!add_dynamic_entry (DT_DEBUG, 0))
2066132718Skan	    return false;
2067132718Skan	}
2068132718Skan
2069132718Skan      if (plt)
2070132718Skan	{
207170635Sobrien	  if (!add_dynamic_entry (DT_PLTGOT, 0)
2072132718Skan	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
207370635Sobrien	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2074132718Skan	      || !add_dynamic_entry (DT_JMPREL, 0))
2075169689Skan	    return false;
2076169689Skan	}
2077169689Skan
2078169689Skan      if (relocs)
207970635Sobrien	{
2080169689Skan	  if (!add_dynamic_entry (DT_RELA, 0)
208118334Speter	      || !add_dynamic_entry (DT_RELASZ, 0)
2082169689Skan	      || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
2083169689Skan	    return false;
2084169689Skan	}
2085169689Skan
2086169689Skan      if ((info->flags & DF_TEXTREL) != 0)
2087169689Skan	{
2088169689Skan	  if (!add_dynamic_entry (DT_TEXTREL, 0))
2089169689Skan	    return false;
209018334Speter	  info->flags |= DF_TEXTREL;
2091169689Skan	}
2092169689Skan    }
2093169689Skan#undef add_dynamic_entry
2094132718Skan
209590075Sobrien  return true;
209618334Speter}
209790075Sobrien
209890075Sobrien/* Look through the relocs for a section during the first phase, and
209990075Sobrien   allocate space in the global offset table or procedure linkage
210018334Speter   table.  */
210190075Sobrien
210290075Sobrienstatic boolean
210390075Sobrienppc_elf_check_relocs (abfd, info, sec, relocs)
210490075Sobrien     bfd *abfd;
210590075Sobrien     struct bfd_link_info *info;
210690075Sobrien     asection *sec;
210790075Sobrien     const Elf_Internal_Rela *relocs;
210890075Sobrien{
2109117395Skan  bfd *dynobj;
2110169689Skan  Elf_Internal_Shdr *symtab_hdr;
2111169689Skan  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
2112169689Skan  const Elf_Internal_Rela *rel;
211390075Sobrien  const Elf_Internal_Rela *rel_end;
211490075Sobrien  bfd_signed_vma *local_got_refcounts;
211590075Sobrien  elf_linker_section_t *sdata;
2116132718Skan  elf_linker_section_t *sdata2;
2117169689Skan  asection *sreloc;
211890075Sobrien  asection *sgot = NULL;
2119169689Skan  asection *srelgot = NULL;
212018334Speter
212190075Sobrien  if (info->relocateable)
212290075Sobrien    return true;
212350397Sobrien
212490075Sobrien#ifdef DEBUG
212590075Sobrien  fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
212690075Sobrien	   bfd_get_section_name (abfd, sec),
212790075Sobrien	   bfd_archive_filename (abfd));
212890075Sobrien#endif
212918334Speter
213090075Sobrien  /* Create the linker generated sections all the time so that the
213118334Speter     special symbols are created.  */
213290075Sobrien
213390075Sobrien  if ((sdata = elf_linker_section (abfd, LINKER_SECTION_SDATA)) == NULL)
213418334Speter    {
213590075Sobrien      sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA);
213652284Sobrien      if (!sdata)
213790075Sobrien	return false;
2138132718Skan    }
213990075Sobrien
214090075Sobrien  if ((sdata2 = elf_linker_section (abfd, LINKER_SECTION_SDATA2)) == NULL)
214152284Sobrien    {
2142169689Skan      sdata2 = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA2);
214318334Speter      if (!sdata2)
214490075Sobrien	return false;
214590075Sobrien    }
2146169689Skan
214790075Sobrien  dynobj = elf_hash_table (info)->dynobj;
214818334Speter  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2149169689Skan  local_got_refcounts = elf_local_got_refcounts (abfd);
2150169689Skan
2151169689Skan  sym_hashes = elf_sym_hashes (abfd);
2152169689Skan  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
2153169689Skan  if (!elf_bad_symtab (abfd))
2154169689Skan    sym_hashes_end -= symtab_hdr->sh_info;
2155169689Skan
2156169689Skan  sreloc = NULL;
2157169689Skan
2158169689Skan  rel_end = relocs + sec->reloc_count;
2159169689Skan  for (rel = relocs; rel < rel_end; rel++)
2160169689Skan    {
216190075Sobrien      unsigned long r_symndx;
216290075Sobrien      struct elf_link_hash_entry *h;
216318334Speter
216490075Sobrien      r_symndx = ELF32_R_SYM (rel->r_info);
216590075Sobrien      if (r_symndx < symtab_hdr->sh_info)
216618334Speter	h = NULL;
216790075Sobrien      else
216890075Sobrien	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
216918334Speter
217090075Sobrien      /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
217190075Sobrien	 This shows up in particular in an R_PPC_ADDR32 in the eabi
217218334Speter	 startup code.  */
217390075Sobrien      if (h && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
217490075Sobrien	{
217590075Sobrien	  if (sgot == NULL)
217690075Sobrien	    {
217790075Sobrien	      if (dynobj == NULL)
217890075Sobrien		elf_hash_table (info)->dynobj = dynobj = abfd;
217990075Sobrien	      sgot = ppc_elf_create_got (dynobj, info);
218090075Sobrien	      if (sgot == NULL)
218190075Sobrien		return false;
218218334Speter	    }
2183117395Skan	}
218418334Speter
218590075Sobrien      switch (ELF32_R_TYPE (rel->r_info))
2186132718Skan	{
2187132718Skan	/* GOT16 relocations */
218890075Sobrien	case R_PPC_GOT16:
218990075Sobrien	case R_PPC_GOT16_LO:
219090075Sobrien	case R_PPC_GOT16_HI:
219190075Sobrien	case R_PPC_GOT16_HA:
219218334Speter	  /* This symbol requires a global offset table entry.  */
219390075Sobrien
219418334Speter	  if (sgot == NULL)
219590075Sobrien	    {
219690075Sobrien	      if (dynobj == NULL)
2197169689Skan		elf_hash_table (info)->dynobj = dynobj = abfd;
2198169689Skan	      sgot = ppc_elf_create_got (dynobj, info);
219918334Speter	      if (sgot == NULL)
220090075Sobrien		return false;
220190075Sobrien	    }
2202169689Skan
2203169689Skan	  if (srelgot == NULL
220490075Sobrien	      && (h != NULL || info->shared))
220518334Speter	    {
220690075Sobrien	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
220718334Speter	      if (srelgot == NULL)
220890075Sobrien		{
2209132718Skan		  srelgot = bfd_make_section (dynobj, ".rela.got");
221090075Sobrien		  if (srelgot == NULL
221190075Sobrien		      || ! bfd_set_section_flags (dynobj, srelgot,
221290075Sobrien						  (SEC_ALLOC
221390075Sobrien						   | SEC_LOAD
2214169689Skan						   | SEC_HAS_CONTENTS
221590075Sobrien						   | SEC_IN_MEMORY
221690075Sobrien						   | SEC_LINKER_CREATED
221718334Speter						   | SEC_READONLY))
221890075Sobrien		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
2219132718Skan		    return false;
2220132718Skan		}
2221132718Skan	    }
2222132718Skan
222318334Speter	  if (h != NULL)
2224132718Skan	    {
222518334Speter	      if (h->got.refcount == 0)
222618334Speter		{
222718334Speter		  /* Make sure this symbol is output as a dynamic symbol.  */
2228169689Skan		  if (h->dynindx == -1)
2229169689Skan		    if (!bfd_elf32_link_record_dynamic_symbol (info, h))
2230169689Skan		      return false;
2231169689Skan
2232169689Skan		  /* Allocate space in the .got.  */
2233169689Skan		  sgot->_raw_size += 4;
2234169689Skan		  /* Allocate relocation space.  */
2235169689Skan		  srelgot->_raw_size += sizeof (Elf32_External_Rela);
2236169689Skan		}
2237169689Skan	      h->got.refcount++;
2238169689Skan	    }
2239169689Skan	  else
2240169689Skan	    {
2241169689Skan	      /* This is a global offset table entry for a local symbol.  */
2242169689Skan	      if (local_got_refcounts == NULL)
2243169689Skan		{
2244169689Skan		  bfd_size_type size;
2245169689Skan
2246169689Skan		  size = symtab_hdr->sh_info;
2247169689Skan		  size *= sizeof (bfd_signed_vma);
2248169689Skan		  local_got_refcounts
2249169689Skan		    = (bfd_signed_vma *) bfd_zalloc (abfd, size);
225090075Sobrien		  if (local_got_refcounts == NULL)
225190075Sobrien		    return false;
225290075Sobrien		  elf_local_got_refcounts (abfd) = local_got_refcounts;
225318334Speter		}
225418334Speter	      if (local_got_refcounts[r_symndx] == 0)
225518334Speter		{
225618334Speter		  sgot->_raw_size += 4;
225718334Speter
225818334Speter		  /* If we are generating a shared object, we need to
2259117395Skan                     output a R_PPC_RELATIVE reloc so that the
226018334Speter                     dynamic linker can adjust this GOT entry.  */
226152284Sobrien		  if (info->shared)
226252284Sobrien		    srelgot->_raw_size += sizeof (Elf32_External_Rela);
226352284Sobrien		}
226418334Speter	      local_got_refcounts[r_symndx]++;
2265132718Skan	    }
2266132718Skan	  break;
226718334Speter
226850397Sobrien	/* Indirect .sdata relocation */
226950397Sobrien	case R_PPC_EMB_SDAI16:
2270117395Skan	  if (info->shared)
2271117395Skan	    {
2272117395Skan	      ((*_bfd_error_handler)
2273117395Skan	       (_("%s: relocation %s cannot be used when making a shared object"),
227452284Sobrien		bfd_archive_filename (abfd), "R_PPC_EMB_SDAI16"));
227590075Sobrien	      return false;
227690075Sobrien	    }
227790075Sobrien
227852284Sobrien	  if (srelgot == NULL && (h != NULL || info->shared))
227990075Sobrien	    {
228052284Sobrien	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
228190075Sobrien	      if (srelgot == NULL)
228252284Sobrien		{
228390075Sobrien		  srelgot = bfd_make_section (dynobj, ".rela.got");
228490075Sobrien		  if (srelgot == NULL
228590075Sobrien		      || ! bfd_set_section_flags (dynobj, srelgot,
228690075Sobrien						  (SEC_ALLOC
228752284Sobrien						   | SEC_LOAD
228852284Sobrien						   | SEC_HAS_CONTENTS
228952284Sobrien						   | SEC_IN_MEMORY
229052284Sobrien						   | SEC_LINKER_CREATED
229118334Speter						   | SEC_READONLY))
229218334Speter		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
229318334Speter		    return false;
229418334Speter		}
229518334Speter	    }
229650397Sobrien
229750397Sobrien	  if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata, h, rel))
229818334Speter	    return false;
229918334Speter
230090075Sobrien	  break;
230118334Speter
230290075Sobrien	/* Indirect .sdata2 relocation */
230390075Sobrien	case R_PPC_EMB_SDA2I16:
230490075Sobrien	  if (info->shared)
230552284Sobrien	    {
230690075Sobrien	      ((*_bfd_error_handler)
230790075Sobrien	       (_("%s: relocation %s cannot be used when making a shared object"),
230890075Sobrien		bfd_archive_filename (abfd), "R_PPC_EMB_SDA2I16"));
230990075Sobrien	      return false;
231090075Sobrien	    }
231190075Sobrien
231290075Sobrien	  if (srelgot == NULL && (h != NULL || info->shared))
231390075Sobrien	    {
2314169689Skan	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
231590075Sobrien	      if (srelgot == NULL)
231690075Sobrien		{
231790075Sobrien		  srelgot = bfd_make_section (dynobj, ".rela.got");
231890075Sobrien		  if (srelgot == NULL
231990075Sobrien		      || ! bfd_set_section_flags (dynobj, srelgot,
232090075Sobrien						  (SEC_ALLOC
232190075Sobrien						   | SEC_LOAD
232290075Sobrien						   | SEC_HAS_CONTENTS
232352284Sobrien						   | SEC_IN_MEMORY
232452284Sobrien						   | SEC_LINKER_CREATED
232552284Sobrien						   | SEC_READONLY))
232690075Sobrien		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
232790075Sobrien		    return false;
232890075Sobrien		}
232990075Sobrien	    }
2330169689Skan
233190075Sobrien	  if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata2, h, rel))
233290075Sobrien	    return false;
233318334Speter
233490075Sobrien	  break;
233590075Sobrien
233690075Sobrien	case R_PPC_SDAREL16:
233790075Sobrien	case R_PPC_EMB_SDA2REL:
233818334Speter	case R_PPC_EMB_SDA21:
233990075Sobrien	  if (info->shared)
234090075Sobrien	    {
234190075Sobrien	      ((*_bfd_error_handler)
234290075Sobrien	       (_("%s: relocation %s cannot be used when making a shared object"),
234390075Sobrien		bfd_archive_filename (abfd),
234490075Sobrien		ppc_elf_howto_table[(int) ELF32_R_TYPE (rel->r_info)]->name));
234590075Sobrien	      return false;
234690075Sobrien	    }
234790075Sobrien	  break;
234890075Sobrien
234990075Sobrien	case R_PPC_PLT32:
235090075Sobrien	case R_PPC_PLTREL24:
235190075Sobrien	case R_PPC_PLT16_LO:
235290075Sobrien	case R_PPC_PLT16_HI:
235318334Speter	case R_PPC_PLT16_HA:
235490075Sobrien#ifdef DEBUG
235590075Sobrien	  fprintf (stderr, "Reloc requires a PLT entry\n");
235690075Sobrien#endif
235790075Sobrien	  /* This symbol requires a procedure linkage table entry.  We
235818334Speter             actually build the entry in adjust_dynamic_symbol,
2359169689Skan             because this might be a case of linking PIC code without
236090075Sobrien             linking in any dynamic objects, in which case we don't
236190075Sobrien             need to generate a procedure linkage table after all.  */
236290075Sobrien
236390075Sobrien	  if (h == NULL)
236490075Sobrien	    {
236590075Sobrien	      /* It does not make sense to have a procedure linkage
236690075Sobrien                 table entry for a local symbol.  */
236790075Sobrien	      bfd_set_error (bfd_error_bad_value);
236890075Sobrien	      return false;
236990075Sobrien	    }
237090075Sobrien
2371169689Skan	  /* Make sure this symbol is output as a dynamic symbol.  */
237290075Sobrien	  if (h->dynindx == -1)
237390075Sobrien	    {
237490075Sobrien	      if (! bfd_elf32_link_record_dynamic_symbol (info, h))
237590075Sobrien		return false;
237690075Sobrien	    }
237790075Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
237890075Sobrien	  h->plt.refcount++;
237990075Sobrien	  break;
238090075Sobrien
238190075Sobrien	  /* The following relocations don't need to propagate the
238290075Sobrien	     relocation if linking a shared object since they are
238390075Sobrien	     section relative.  */
238490075Sobrien	case R_PPC_SECTOFF:
238590075Sobrien	case R_PPC_SECTOFF_LO:
238690075Sobrien	case R_PPC_SECTOFF_HI:
238790075Sobrien	case R_PPC_SECTOFF_HA:
238890075Sobrien	  break;
238990075Sobrien
239090075Sobrien	  /* This refers only to functions defined in the shared library */
239190075Sobrien	case R_PPC_LOCAL24PC:
239252284Sobrien	  break;
239390075Sobrien
239418334Speter	  /* This relocation describes the C++ object vtable hierarchy.
239590075Sobrien	     Reconstruct it for later use during GC.  */
239652284Sobrien	case R_PPC_GNU_VTINHERIT:
239790075Sobrien	  if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
239818334Speter	    return false;
239990075Sobrien	  break;
240018334Speter
240118334Speter	  /* This relocation describes which C++ vtable entries are actually
240290075Sobrien	     used.  Record for later use during GC.  */
240390075Sobrien	case R_PPC_GNU_VTENTRY:
240490075Sobrien	  if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
240590075Sobrien	    return false;
240618334Speter	  break;
240718334Speter
240890075Sobrien	  /* When creating a shared object, we must copy these
240990075Sobrien	     relocs into the output file.  We create a reloc
241018334Speter	     section in dynobj and make room for the reloc.  */
241118334Speter	case R_PPC_REL24:
241218334Speter	case R_PPC_REL14:
241350397Sobrien	case R_PPC_REL14_BRTAKEN:
241490075Sobrien	case R_PPC_REL14_BRNTAKEN:
241590075Sobrien	case R_PPC_REL32:
241690075Sobrien	  if (h == NULL
241790075Sobrien	      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
241818334Speter	      || SYMBOL_REFERENCES_LOCAL (info, h))
241918334Speter	    break;
242050397Sobrien	  /* fall through */
242150397Sobrien
242218334Speter	default:
242350397Sobrien	  if (info->shared)
242450397Sobrien	    {
242590075Sobrien#ifdef DEBUG
242650397Sobrien	      fprintf (stderr, "ppc_elf_check_relocs need to create relocation for %s\n",
242750397Sobrien		       (h && h->root.root.string) ? h->root.root.string : "<unknown>");
242818334Speter#endif
242918334Speter	      if (sreloc == NULL)
243050397Sobrien		{
243150397Sobrien		  const char *name;
2432132718Skan
2433132718Skan		  name = (bfd_elf_string_from_elf_section
2434132718Skan			  (abfd,
2435169689Skan			   elf_elfheader (abfd)->e_shstrndx,
2436132718Skan			   elf_section_data (sec)->rel_hdr.sh_name));
2437132718Skan		  if (name == NULL)
2438132718Skan		    return false;
2439132718Skan
2440132718Skan		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
244150397Sobrien			      && strcmp (bfd_get_section_name (abfd, sec),
2442132718Skan					 name + 5) == 0);
2443132718Skan
2444132718Skan		  sreloc = bfd_get_section_by_name (dynobj, name);
2445132718Skan		  if (sreloc == NULL)
2446132718Skan		    {
2447132718Skan		      flagword flags;
244818334Speter
244918334Speter		      sreloc = bfd_make_section (dynobj, name);
245018334Speter		      flags = (SEC_HAS_CONTENTS | SEC_READONLY
245190075Sobrien			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
245218334Speter		      if ((sec->flags & SEC_ALLOC) != 0)
245390075Sobrien			flags |= SEC_ALLOC | SEC_LOAD;
245490075Sobrien		      if (sreloc == NULL
245590075Sobrien			  || ! bfd_set_section_flags (dynobj, sreloc, flags)
245690075Sobrien			  || ! bfd_set_section_alignment (dynobj, sreloc, 2))
245718334Speter			return false;
245818334Speter		    }
245918334Speter		  if (sec->flags & SEC_READONLY)
246018334Speter		    info->flags |= DF_TEXTREL;
246118334Speter		}
246218334Speter
246390075Sobrien	      sreloc->_raw_size += sizeof (Elf32_External_Rela);
246490075Sobrien
246518334Speter	      /* FIXME: We should here do what the m68k and i386
246618334Speter		 backends do: if the reloc is pc-relative, record it
2467132718Skan		 in case it turns out that the reloc is unnecessary
246818334Speter		 because the symbol is forced local by versioning or
246990075Sobrien		 we are linking with -Bdynamic.  Fortunately this
247018334Speter		 case is not frequent.  */
247190075Sobrien	    }
247218334Speter
247390075Sobrien	  break;
247490075Sobrien	}
2475169689Skan    }
247618334Speter
247718334Speter  return true;
247852284Sobrien}
247990075Sobrien
248018334Speter/* Return the section that should be marked against GC for a given
248118334Speter   relocation.  */
2482169689Skan
248318334Speterstatic asection *
248418334Speterppc_elf_gc_mark_hook (sec, info, rel, h, sym)
248518334Speter     asection *sec;
248618334Speter     struct bfd_link_info *info ATTRIBUTE_UNUSED;
248718334Speter     Elf_Internal_Rela *rel;
248818334Speter     struct elf_link_hash_entry *h;
248918334Speter     Elf_Internal_Sym *sym;
249018334Speter{
249118334Speter  if (h != NULL)
249252284Sobrien    {
249352284Sobrien      switch (ELF32_R_TYPE (rel->r_info))
249418334Speter	{
249552284Sobrien	case R_PPC_GNU_VTINHERIT:
249652284Sobrien	case R_PPC_GNU_VTENTRY:
249752284Sobrien	  break;
249818334Speter
249918334Speter	default:
250018334Speter	  switch (h->root.type)
250118334Speter	    {
250218334Speter	    case bfd_link_hash_defined:
250318334Speter	    case bfd_link_hash_defweak:
250418334Speter	      return h->root.u.def.section;
250518334Speter
250652284Sobrien	    case bfd_link_hash_common:
250718334Speter	      return h->root.u.c.p->section;
250818334Speter
2509146895Skan	    default:
2510146895Skan	      break;
2511146895Skan	    }
2512146895Skan	}
2513146895Skan    }
2514146895Skan  else
2515146895Skan    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
2516146895Skan
2517146895Skan  return NULL;
2518146895Skan}
2519146895Skan
252018334Speter/* Update the got entry reference counts for the section being removed.  */
252118334Speter
2522146895Skanstatic boolean
252318334Speterppc_elf_gc_sweep_hook (abfd, info, sec, relocs)
252418334Speter     bfd *abfd;
252518334Speter     struct bfd_link_info *info ATTRIBUTE_UNUSED;
252618334Speter     asection *sec;
252718334Speter     const Elf_Internal_Rela *relocs;
252818334Speter{
252918334Speter  Elf_Internal_Shdr *symtab_hdr;
2530132718Skan  struct elf_link_hash_entry **sym_hashes;
253118334Speter  bfd_signed_vma *local_got_refcounts;
2532169689Skan  const Elf_Internal_Rela *rel, *relend;
253318334Speter  unsigned long r_symndx;
253418334Speter  struct elf_link_hash_entry *h;
253550397Sobrien
2536169689Skan  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2537169689Skan  sym_hashes = elf_sym_hashes (abfd);
253850397Sobrien  local_got_refcounts = elf_local_got_refcounts (abfd);
253918334Speter
254018334Speter  relend = relocs + sec->reloc_count;
254190075Sobrien  for (rel = relocs; rel < relend; rel++)
254290075Sobrien    switch (ELF32_R_TYPE (rel->r_info))
254352284Sobrien      {
2544132718Skan      case R_PPC_GOT16:
254552284Sobrien      case R_PPC_GOT16_LO:
254690075Sobrien      case R_PPC_GOT16_HI:
254790075Sobrien      case R_PPC_GOT16_HA:
254890075Sobrien	r_symndx = ELF32_R_SYM (rel->r_info);
254990075Sobrien	if (r_symndx >= symtab_hdr->sh_info)
255090075Sobrien	  {
255190075Sobrien	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
255290075Sobrien	    if (h->got.refcount > 0)
255390075Sobrien	      h->got.refcount--;
255452284Sobrien	  }
255590075Sobrien	else if (local_got_refcounts != NULL)
255690075Sobrien	  {
255790075Sobrien	    if (local_got_refcounts[r_symndx] > 0)
255890075Sobrien	      local_got_refcounts[r_symndx]--;
255952284Sobrien	  }
256090075Sobrien        break;
256190075Sobrien
256290075Sobrien      case R_PPC_PLT32:
256390075Sobrien      case R_PPC_PLTREL24:
256490075Sobrien      case R_PPC_PLT16_LO:
256552284Sobrien      case R_PPC_PLT16_HI:
256690075Sobrien      case R_PPC_PLT16_HA:
256790075Sobrien	r_symndx = ELF32_R_SYM (rel->r_info);
256852284Sobrien	if (r_symndx >= symtab_hdr->sh_info)
256990075Sobrien	  {
257052284Sobrien	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
257152284Sobrien	    if (h->plt.refcount > 0)
257290075Sobrien	      h->plt.refcount--;
2573169689Skan	  }
257490075Sobrien	break;
257590075Sobrien
257690075Sobrien      default:
257790075Sobrien	break;
257890075Sobrien      }
257990075Sobrien
258090075Sobrien  return true;
258190075Sobrien}
258290075Sobrien
258390075Sobrien/* Hook called by the linker routine which adds symbols from an object
258452284Sobrien   file.  We use it to put .comm items in .sbss, and not .bss.  */
258552284Sobrien
258690075Sobrienstatic boolean
258790075Sobrienppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
258890075Sobrien     bfd *abfd;
258918334Speter     struct bfd_link_info *info;
2590117395Skan     const Elf_Internal_Sym *sym;
2591132718Skan     const char **namep ATTRIBUTE_UNUSED;
259218334Speter     flagword *flagsp ATTRIBUTE_UNUSED;
2593117395Skan     asection **secp;
2594117395Skan     bfd_vma *valp;
2595117395Skan{
2596169689Skan  if (sym->st_shndx == SHN_COMMON
2597117395Skan      && !info->relocateable
2598117395Skan      && sym->st_size <= elf_gp_size (abfd)
2599117395Skan      && info->hash->creator->flavour == bfd_target_elf_flavour)
2600117395Skan    {
2601117395Skan      /* Common symbols less than or equal to -G nn bytes are automatically
2602117395Skan	 put into .sdata.  */
260390075Sobrien      elf_linker_section_t *sdata
260418334Speter	= ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA);
2605169689Skan
2606169689Skan      if (!sdata->bss_section)
260790075Sobrien	{
260890075Sobrien	  bfd_size_type amt;
2609132718Skan
261090075Sobrien	  /* We don't go through bfd_make_section, because we don't
261190075Sobrien             want to attach this common section to DYNOBJ.  The linker
261290075Sobrien             will move the symbols to the appropriate output section
261390075Sobrien             when it defines common symbols.  */
261490075Sobrien	  amt = sizeof (asection);
261590075Sobrien	  sdata->bss_section = (asection *) bfd_zalloc (abfd, amt);
261618334Speter	  if (sdata->bss_section == NULL)
261790075Sobrien	    return false;
2618169689Skan	  sdata->bss_section->name = sdata->bss_name;
2619169689Skan	  sdata->bss_section->flags = SEC_IS_COMMON;
2620169689Skan	  sdata->bss_section->output_section = sdata->bss_section;
2621169689Skan	  amt = sizeof (asymbol);
2622169689Skan	  sdata->bss_section->symbol = (asymbol *) bfd_zalloc (abfd, amt);
2623169689Skan	  amt = sizeof (asymbol *);
262418334Speter	  sdata->bss_section->symbol_ptr_ptr =
262590075Sobrien	    (asymbol **) bfd_zalloc (abfd, amt);
262690075Sobrien	  if (sdata->bss_section->symbol == NULL
262790075Sobrien	      || sdata->bss_section->symbol_ptr_ptr == NULL)
262890075Sobrien	    return false;
262990075Sobrien	  sdata->bss_section->symbol->name = sdata->bss_name;
263090075Sobrien	  sdata->bss_section->symbol->flags = BSF_SECTION_SYM;
263190075Sobrien	  sdata->bss_section->symbol->section = sdata->bss_section;
263218334Speter	  *sdata->bss_section->symbol_ptr_ptr = sdata->bss_section->symbol;
263390075Sobrien	}
263490075Sobrien
263590075Sobrien      *secp = sdata->bss_section;
263618334Speter      *valp = sym->st_size;
263718334Speter    }
263818334Speter
263990075Sobrien  return true;
264090075Sobrien}
264118334Speter
264290075Sobrien/* Finish up dynamic symbol handling.  We set the contents of various
264390075Sobrien   dynamic sections here.  */
264490075Sobrien
264590075Sobrienstatic boolean
264618334Speterppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
2647132718Skan     bfd *output_bfd;
264818334Speter     struct bfd_link_info *info;
264990075Sobrien     struct elf_link_hash_entry *h;
265090075Sobrien     Elf_Internal_Sym *sym;
265190075Sobrien{
2652132718Skan  bfd *dynobj;
265318334Speter
265490075Sobrien#ifdef DEBUG
265590075Sobrien  fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s",
265690075Sobrien	   h->root.root.string);
265790075Sobrien#endif
265890075Sobrien
265990075Sobrien  dynobj = elf_hash_table (info)->dynobj;
266090075Sobrien  BFD_ASSERT (dynobj != NULL);
2661132718Skan
266290075Sobrien  if (h->plt.offset != (bfd_vma) -1)
266390075Sobrien    {
266490075Sobrien      asection *splt;
266552284Sobrien      asection *srela;
266690075Sobrien      Elf_Internal_Rela rela;
2667132718Skan      bfd_vma reloc_index;
2668132718Skan
2669132718Skan#ifdef DEBUG
267090075Sobrien      fprintf (stderr, ", plt_offset = %d", h->plt.offset);
2671132718Skan#endif
267290075Sobrien
267352284Sobrien      /* This symbol has an entry in the procedure linkage table.  Set
267490075Sobrien         it up.  */
267590075Sobrien
267690075Sobrien      BFD_ASSERT (h->dynindx != -1);
267790075Sobrien
267890075Sobrien      splt = bfd_get_section_by_name (dynobj, ".plt");
267990075Sobrien      srela = bfd_get_section_by_name (dynobj, ".rela.plt");
268090075Sobrien      BFD_ASSERT (splt != NULL && srela != NULL);
268190075Sobrien
268290075Sobrien      /* We don't need to fill in the .plt.  The ppc dynamic linker
2683132718Skan	 will fill it in.  */
2684132718Skan
2685132718Skan      /* Fill in the entry in the .rela.plt section.  */
268690075Sobrien      rela.r_offset = (splt->output_section->vma
268790075Sobrien		       + splt->output_offset
268890075Sobrien		       + h->plt.offset);
268990075Sobrien      rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
269090075Sobrien      rela.r_addend = 0;
2691169689Skan
269290075Sobrien      reloc_index = (h->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_SLOT_SIZE;
269390075Sobrien      if (reloc_index > PLT_NUM_SINGLE_ENTRIES)
269490075Sobrien	reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
2695132718Skan      bfd_elf32_swap_reloca_out (output_bfd, &rela,
2696132718Skan				 ((Elf32_External_Rela *) srela->contents
2697132718Skan				  + reloc_index));
2698132718Skan
2699132718Skan      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
270090075Sobrien	{
270190075Sobrien	  /* Mark the symbol as undefined, rather than as defined in
2702132718Skan	     the .plt section.  Leave the value alone.  */
2703132718Skan	  sym->st_shndx = SHN_UNDEF;
2704132718Skan	  /* If the symbol is weak, we do need to clear the value.
2705132718Skan	     Otherwise, the PLT entry would provide a definition for
270690075Sobrien	     the symbol even if the symbol wasn't defined anywhere,
2707132718Skan	     and so the symbol would never be NULL.  */
2708132718Skan	  if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
270990075Sobrien	      == 0)
271090075Sobrien	    sym->st_value = 0;
2711132718Skan	}
2712132718Skan    }
2713132718Skan
2714132718Skan  if (h->got.offset != (bfd_vma) -1)
271590075Sobrien    {
271690075Sobrien      asection *sgot;
271790075Sobrien      asection *srela;
271890075Sobrien      Elf_Internal_Rela rela;
271990075Sobrien
272090075Sobrien      /* This symbol has an entry in the global offset table.  Set it
272190075Sobrien         up.  */
272290075Sobrien
272390075Sobrien      sgot = bfd_get_section_by_name (dynobj, ".got");
272452284Sobrien      srela = bfd_get_section_by_name (dynobj, ".rela.got");
272590075Sobrien      BFD_ASSERT (sgot != NULL && srela != NULL);
272652284Sobrien
272790075Sobrien      rela.r_offset = (sgot->output_section->vma
272890075Sobrien		       + sgot->output_offset
272990075Sobrien		       + (h->got.offset &~ (bfd_vma) 1));
273090075Sobrien
273190075Sobrien      /* If this is a -Bsymbolic link, and the symbol is defined
273218334Speter	 locally, we just want to emit a RELATIVE reloc.  The entry in
273390075Sobrien	 the global offset table will already have been initialized in
2734132718Skan	 the relocate_section function.  */
273590075Sobrien      if (info->shared
273690075Sobrien	  && SYMBOL_REFERENCES_LOCAL (info, h))
273790075Sobrien	{
273890075Sobrien	  rela.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
273918334Speter	  rela.r_addend = (h->root.u.def.value
274090075Sobrien			   + h->root.u.def.section->output_section->vma
274190075Sobrien			   + h->root.u.def.section->output_offset);
274290075Sobrien	}
274318334Speter      else
274490075Sobrien	{
274552284Sobrien	  BFD_ASSERT ((h->got.offset & 1) == 0);
274690075Sobrien	  rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_GLOB_DAT);
274790075Sobrien	  rela.r_addend = 0;
274890075Sobrien	}
274990075Sobrien
275090075Sobrien      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
275190075Sobrien      bfd_elf32_swap_reloca_out (output_bfd, &rela,
275290075Sobrien				 ((Elf32_External_Rela *) srela->contents
275390075Sobrien				  + srela->reloc_count));
275490075Sobrien      ++srela->reloc_count;
275552284Sobrien    }
2756169689Skan
2757169689Skan  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
2758169689Skan    {
2759169689Skan      asection *s;
276090075Sobrien      Elf_Internal_Rela rela;
276190075Sobrien
276290075Sobrien      /* This symbols needs a copy reloc.  Set it up.  */
276390075Sobrien
276490075Sobrien#ifdef DEBUG
276590075Sobrien      fprintf (stderr, ", copy");
276690075Sobrien#endif
276790075Sobrien
2768169689Skan      BFD_ASSERT (h->dynindx != -1);
276990075Sobrien
277090075Sobrien      if (h->size <= elf_gp_size (dynobj))
277190075Sobrien	s = bfd_get_section_by_name (h->root.u.def.section->owner,
277290075Sobrien				     ".rela.sbss");
277390075Sobrien      else
277490075Sobrien	s = bfd_get_section_by_name (h->root.u.def.section->owner,
277590075Sobrien				     ".rela.bss");
2776169689Skan      BFD_ASSERT (s != NULL);
277790075Sobrien
277890075Sobrien      rela.r_offset = (h->root.u.def.value
277990075Sobrien		       + h->root.u.def.section->output_section->vma
2780169689Skan		       + h->root.u.def.section->output_offset);
278152284Sobrien      rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
278290075Sobrien      rela.r_addend = 0;
278390075Sobrien      bfd_elf32_swap_reloca_out (output_bfd, &rela,
278490075Sobrien				 ((Elf32_External_Rela *) s->contents
278590075Sobrien				  + s->reloc_count));
278690075Sobrien      ++s->reloc_count;
278790075Sobrien    }
278890075Sobrien
278990075Sobrien#ifdef DEBUG
279052284Sobrien  fprintf (stderr, "\n");
279190075Sobrien#endif
279290075Sobrien
279390075Sobrien  /* Mark some specially defined symbols as absolute.  */
279490075Sobrien  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2795169689Skan      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
279690075Sobrien      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
279790075Sobrien    sym->st_shndx = SHN_ABS;
279890075Sobrien
279990075Sobrien  return true;
280090075Sobrien}
280190075Sobrien
280252284Sobrien/* Finish up the dynamic sections.  */
280352284Sobrien
280490075Sobrienstatic boolean
280590075Sobrienppc_elf_finish_dynamic_sections (output_bfd, info)
280690075Sobrien     bfd *output_bfd;
280790075Sobrien     struct bfd_link_info *info;
280890075Sobrien{
280990075Sobrien  asection *sdyn;
281090075Sobrien  bfd *dynobj = elf_hash_table (info)->dynobj;
281190075Sobrien  asection *sgot = bfd_get_section_by_name (dynobj, ".got");
281290075Sobrien
281390075Sobrien#ifdef DEBUG
281490075Sobrien  fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
281590075Sobrien#endif
281690075Sobrien
281790075Sobrien  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
281890075Sobrien
281990075Sobrien  if (elf_hash_table (info)->dynamic_sections_created)
282052284Sobrien    {
282190075Sobrien      asection *splt;
282290075Sobrien      Elf32_External_Dyn *dyncon, *dynconend;
282390075Sobrien
282490075Sobrien      splt = bfd_get_section_by_name (dynobj, ".plt");
282590075Sobrien      BFD_ASSERT (splt != NULL && sdyn != NULL);
282690075Sobrien
282752284Sobrien      dyncon = (Elf32_External_Dyn *) sdyn->contents;
282852284Sobrien      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
2829169689Skan      for (; dyncon < dynconend; dyncon++)
2830169689Skan	{
283190075Sobrien	  Elf_Internal_Dyn dyn;
2832117395Skan	  const char *name;
283390075Sobrien	  boolean size;
2834169689Skan
283590075Sobrien	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
283652284Sobrien
283790075Sobrien	  switch (dyn.d_tag)
2838169689Skan	    {
283990075Sobrien	    case DT_PLTGOT:   name = ".plt";	  size = false; break;
2840169689Skan	    case DT_PLTRELSZ: name = ".rela.plt"; size = true;  break;
2841117395Skan	    case DT_JMPREL:   name = ".rela.plt"; size = false; break;
284218334Speter	    default:	      name = NULL;	  size = false; break;
2843169689Skan	    }
284490075Sobrien
2845117395Skan	  if (name != NULL)
2846117395Skan	    {
284790075Sobrien	      asection *s;
284890075Sobrien
2849169689Skan	      s = bfd_get_section_by_name (output_bfd, name);
285090075Sobrien	      if (s == NULL)
285190075Sobrien		dyn.d_un.d_val = 0;
285218334Speter	      else
285390075Sobrien		{
285452284Sobrien		  if (! size)
285518334Speter		    dyn.d_un.d_ptr = s->vma;
285618334Speter		  else
285790075Sobrien		    {
285818334Speter		      if (s->_cooked_size != 0)
285990075Sobrien			dyn.d_un.d_val = s->_cooked_size;
286018334Speter		      else
286190075Sobrien			dyn.d_un.d_val = s->_raw_size;
286218334Speter		    }
286390075Sobrien		}
286490075Sobrien	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
286590075Sobrien	    }
286690075Sobrien	}
286790075Sobrien    }
286890075Sobrien
286990075Sobrien  /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4 so that a function can
287090075Sobrien     easily find the address of the _GLOBAL_OFFSET_TABLE_.  */
287190075Sobrien  if (sgot)
287290075Sobrien    {
287390075Sobrien      unsigned char *contents = sgot->contents;
287490075Sobrien      bfd_put_32 (output_bfd, (bfd_vma) 0x4e800021 /* blrl */, contents);
287590075Sobrien
287690075Sobrien      if (sdyn == NULL)
2877169689Skan	bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
287890075Sobrien      else
287918334Speter	bfd_put_32 (output_bfd,
288090075Sobrien		    sdyn->output_section->vma + sdyn->output_offset,
288190075Sobrien		    contents+4);
288290075Sobrien
288318334Speter      elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
288490075Sobrien    }
288590075Sobrien
288690075Sobrien  return true;
288790075Sobrien}
288890075Sobrien
288990075Sobrien/* The RELOCATE_SECTION function is called by the ELF backend linker
289090075Sobrien   to handle the relocations for a section.
289190075Sobrien
289290075Sobrien   The relocs are always passed as Rela structures; if the section
289318334Speter   actually uses Rel structures, the r_addend field will always be
289490075Sobrien   zero.
289590075Sobrien
289690075Sobrien   This function is responsible for adjust the section contents as
289790075Sobrien   necessary, and (if using Rela relocs and generating a
289890075Sobrien   relocateable output file) adjusting the reloc addend as
289918334Speter   necessary.
290090075Sobrien
290190075Sobrien   This function does not have to worry about setting the reloc
290290075Sobrien   address or the reloc symbol index.
290390075Sobrien
290490075Sobrien   LOCAL_SYMS is a pointer to the swapped in local symbols.
290590075Sobrien
290618334Speter   LOCAL_SECTIONS is an array giving the section in the input file
290790075Sobrien   corresponding to the st_shndx field of each local symbol.
290890075Sobrien
290918334Speter   The global hash table entry for the global symbols can be found
291090075Sobrien   via elf_sym_hashes (input_bfd).
291150397Sobrien
291290075Sobrien   When generating relocateable output, this function must handle
291390075Sobrien   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
291490075Sobrien   going to be the section symbol corresponding to the output
291518334Speter   section, which means that the addend must be adjusted
291618334Speter   accordingly.  */
291790075Sobrien
291818334Speterstatic boolean
291990075Sobrienppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
292018334Speter			  contents, relocs, local_syms, local_sections)
292190075Sobrien     bfd *output_bfd;
292290075Sobrien     struct bfd_link_info *info;
292390075Sobrien     bfd *input_bfd;
292490075Sobrien     asection *input_section;
292590075Sobrien     bfd_byte *contents;
292618334Speter     Elf_Internal_Rela *relocs;
292790075Sobrien     Elf_Internal_Sym *local_syms;
292890075Sobrien     asection **local_sections;
292990075Sobrien{
293090075Sobrien  Elf_Internal_Shdr *symtab_hdr		  = &elf_tdata (input_bfd)->symtab_hdr;
293190075Sobrien  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
293218334Speter  bfd *dynobj				  = elf_hash_table (info)->dynobj;
293318334Speter  elf_linker_section_t *sdata		  = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA)  : NULL;
293490075Sobrien  elf_linker_section_t *sdata2		  = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA2) : NULL;
293590075Sobrien  Elf_Internal_Rela *rel		  = relocs;
293690075Sobrien  Elf_Internal_Rela *relend		  = relocs + input_section->reloc_count;
293790075Sobrien  asection *sreloc			  = NULL;
293890075Sobrien  asection *splt;
2939132718Skan  asection *sgot;
2940132718Skan  bfd_vma *local_got_offsets;
2941132718Skan  boolean ret				  = true;
294290075Sobrien  long insn;
294390075Sobrien
294490075Sobrien#ifdef DEBUG
294590075Sobrien  fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
294690075Sobrien	   bfd_archive_filename (input_bfd),
294790075Sobrien	   bfd_section_name(input_bfd, input_section),
294890075Sobrien	   (long) input_section->reloc_count,
294990075Sobrien	   (info->relocateable) ? " (relocatable)" : "");
295090075Sobrien#endif
295118334Speter
295218334Speter  if (info->relocateable)
295390075Sobrien    return true;
295418334Speter
295590075Sobrien  if (!ppc_elf_howto_table[R_PPC_ADDR32])
295690075Sobrien    /* Initialize howto table if needed.  */
295790075Sobrien    ppc_elf_howto_init ();
295890075Sobrien
295990075Sobrien  local_got_offsets = elf_local_got_offsets (input_bfd);
296018334Speter
296190075Sobrien  splt = sgot = NULL;
296290075Sobrien  if (dynobj != NULL)
296390075Sobrien    {
296490075Sobrien      splt = bfd_get_section_by_name (dynobj, ".plt");
2965132718Skan      sgot = bfd_get_section_by_name (dynobj, ".got");
2966132718Skan    }
2967132718Skan
2968132718Skan  for (; rel < relend; rel++)
2969132718Skan    {
2970132718Skan      enum elf_ppc_reloc_type r_type	= (enum elf_ppc_reloc_type)ELF32_R_TYPE (rel->r_info);
297190075Sobrien      bfd_vma offset			= rel->r_offset;
297290075Sobrien      bfd_vma addend			= rel->r_addend;
2973132718Skan      bfd_reloc_status_type r		= bfd_reloc_other;
2974169689Skan      Elf_Internal_Sym *sym		= (Elf_Internal_Sym *) 0;
2975169689Skan      asection *sec			= (asection *) 0;
2976132718Skan      struct elf_link_hash_entry *h	= (struct elf_link_hash_entry *) 0;
297790075Sobrien      const char *sym_name		= (const char *) 0;
297890075Sobrien      reloc_howto_type *howto;
297918334Speter      unsigned long r_symndx;
298090075Sobrien      bfd_vma relocation;
298190075Sobrien      int will_become_local;
298290075Sobrien
298318334Speter      /* Unknown relocation handling */
298490075Sobrien      if ((unsigned) r_type >= (unsigned) R_PPC_max
298590075Sobrien	  || !ppc_elf_howto_table[(int) r_type])
298690075Sobrien	{
2987169689Skan	  (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
2988169689Skan				 bfd_archive_filename (input_bfd),
2989169689Skan				 (int) r_type);
2990169689Skan
2991169689Skan	  bfd_set_error (bfd_error_bad_value);
2992169689Skan	  ret = false;
2993169689Skan	  continue;
299490075Sobrien	}
299590075Sobrien
299690075Sobrien      howto = ppc_elf_howto_table[(int) r_type];
299790075Sobrien      r_symndx = ELF32_R_SYM (rel->r_info);
299890075Sobrien
299990075Sobrien      if (r_symndx < symtab_hdr->sh_info)
300090075Sobrien	{
300190075Sobrien	  sym = local_syms + r_symndx;
300290075Sobrien	  sec = local_sections[r_symndx];
300318334Speter	  sym_name = "<local symbol>";
300418334Speter
300518334Speter	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
3006169689Skan	  addend = rel->r_addend;
3007169689Skan	  /* Relocs to local symbols are always resolved.  */
3008169689Skan	  will_become_local = 1;
3009169689Skan	}
3010169689Skan      else
3011169689Skan	{
3012169689Skan	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
301390075Sobrien	  while (h->root.type == bfd_link_hash_indirect
301490075Sobrien		 || h->root.type == bfd_link_hash_warning)
301590075Sobrien	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
301690075Sobrien	  sym_name = h->root.root.string;
301790075Sobrien
301890075Sobrien	  /* Can this relocation be resolved immediately?  */
301918334Speter	  will_become_local = SYMBOL_REFERENCES_LOCAL (info, h);
302090075Sobrien
302190075Sobrien	  if (h->root.type == bfd_link_hash_defined
302290075Sobrien	      || h->root.type == bfd_link_hash_defweak)
302390075Sobrien	    {
3024117395Skan	      sec = h->root.u.def.section;
302590075Sobrien	      if (((r_type == R_PPC_PLT32
302690075Sobrien		    || r_type == R_PPC_PLTREL24)
302718334Speter		   && splt != NULL
302818334Speter		   && h->plt.offset != (bfd_vma) -1)
302990075Sobrien		  || (r_type == R_PPC_LOCAL24PC
303090075Sobrien		      && sec->output_section == NULL)
303190075Sobrien		  || ((r_type == R_PPC_GOT16
303290075Sobrien		       || r_type == R_PPC_GOT16_LO
303390075Sobrien		       || r_type == R_PPC_GOT16_HI
303490075Sobrien		       || r_type == R_PPC_GOT16_HA)
303590075Sobrien		      && elf_hash_table (info)->dynamic_sections_created
303690075Sobrien		      && (! info->shared || ! will_become_local))
303790075Sobrien		  || (info->shared
303890075Sobrien 		      && ! will_become_local
303990075Sobrien		      && ((input_section->flags & SEC_ALLOC) != 0
3040169689Skan			  /* Testing SEC_DEBUGGING here may be wrong.
3041169689Skan                             It's here to avoid a crash when
3042169689Skan                             generating a shared library with DWARF
3043169689Skan                             debugging information.  */
3044169689Skan			  || ((input_section->flags & SEC_DEBUGGING) != 0
3045169689Skan			      && (h->elf_link_hash_flags
3046169689Skan				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
3047169689Skan		      && (r_type == R_PPC_ADDR32
3048169689Skan			  || r_type == R_PPC_ADDR24
3049169689Skan			  || r_type == R_PPC_ADDR16
3050169689Skan			  || r_type == R_PPC_ADDR16_LO
305190075Sobrien			  || r_type == R_PPC_ADDR16_HI
305218334Speter			  || r_type == R_PPC_ADDR16_HA
3053169689Skan			  || r_type == R_PPC_ADDR14
305490075Sobrien			  || r_type == R_PPC_ADDR14_BRTAKEN
305590075Sobrien			  || r_type == R_PPC_ADDR14_BRNTAKEN
305690075Sobrien			  || r_type == R_PPC_COPY
3057132718Skan			  || r_type == R_PPC_GLOB_DAT
3058132718Skan			  || r_type == R_PPC_JMP_SLOT
3059132718Skan			  || r_type == R_PPC_UADDR32
3060132718Skan			  || r_type == R_PPC_UADDR16
3061132718Skan			  || r_type == R_PPC_SDAREL16
3062132718Skan			  || r_type == R_PPC_EMB_NADDR32
3063132718Skan			  || r_type == R_PPC_EMB_NADDR16
3064132718Skan			  || r_type == R_PPC_EMB_NADDR16_LO
306590075Sobrien			  || r_type == R_PPC_EMB_NADDR16_HI
306618334Speter			  || r_type == R_PPC_EMB_NADDR16_HA
306718334Speter			  || r_type == R_PPC_EMB_SDAI16
306818334Speter			  || r_type == R_PPC_EMB_SDA2I16
306990075Sobrien			  || r_type == R_PPC_EMB_SDA2REL
307018334Speter			  || r_type == R_PPC_EMB_SDA21
3071169689Skan			  || r_type == R_PPC_EMB_MRKREF
3072169689Skan			  || r_type == R_PPC_EMB_BIT_FLD
3073169689Skan			  || r_type == R_PPC_EMB_RELSDA
3074169689Skan			  || ((r_type == R_PPC_REL24
3075169689Skan			       || r_type == R_PPC_REL32
3076169689Skan			       || r_type == R_PPC_REL14
307790075Sobrien			       || r_type == R_PPC_REL14_BRTAKEN
307890075Sobrien			       || r_type == R_PPC_REL14_BRNTAKEN
307918334Speter			       || r_type == R_PPC_RELATIVE)
308018334Speter			      && strcmp (h->root.root.string,
308118334Speter					 "_GLOBAL_OFFSET_TABLE_") != 0))))
308290075Sobrien		{
308390075Sobrien		  /* In these cases, we don't need the relocation
308490075Sobrien                     value.  We check specially because in some
308590075Sobrien                     obscure cases sec->output_section will be NULL.  */
308690075Sobrien		  relocation = 0;
3087132718Skan		}
308890075Sobrien	      else if (sec->output_section == NULL)
308990075Sobrien		{
309090075Sobrien                  (*_bfd_error_handler)
309190075Sobrien                    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
309290075Sobrien                     bfd_archive_filename (input_bfd), h->root.root.string,
309390075Sobrien                     bfd_get_section_name (input_bfd, input_section));
309490075Sobrien		  relocation = 0;
309590075Sobrien		}
309690075Sobrien	      else
309790075Sobrien		relocation = (h->root.u.def.value
309890075Sobrien			      + sec->output_section->vma
309990075Sobrien			      + sec->output_offset);
310090075Sobrien	    }
310190075Sobrien	  else if (h->root.type == bfd_link_hash_undefweak)
310290075Sobrien	    relocation = 0;
310390075Sobrien	  else if (info->shared
310490075Sobrien		   && (!info->symbolic || info->allow_shlib_undefined)
310590075Sobrien		   && !info->no_undefined
310690075Sobrien		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
310790075Sobrien	    relocation = 0;
310890075Sobrien	  else
3109169689Skan	    {
311090075Sobrien	      if (! (*info->callbacks->undefined_symbol) (info,
311190075Sobrien							 h->root.root.string,
311290075Sobrien							 input_bfd,
311390075Sobrien							 input_section,
311490075Sobrien							 rel->r_offset,
311590075Sobrien							 (!info->shared
311690075Sobrien							  || info->no_undefined
3117169689Skan							  || ELF_ST_VISIBILITY (h->other))))
311890075Sobrien		return false;
311990075Sobrien	      relocation = 0;
312090075Sobrien	    }
312190075Sobrien	}
312290075Sobrien
312390075Sobrien      switch ((int) r_type)
312490075Sobrien	{
312590075Sobrien	default:
312690075Sobrien	  (*_bfd_error_handler) (_("%s: unknown relocation type %d for symbol %s"),
312790075Sobrien				 bfd_archive_filename (input_bfd),
312890075Sobrien				 (int) r_type, sym_name);
312990075Sobrien
313090075Sobrien	  bfd_set_error (bfd_error_bad_value);
313190075Sobrien	  ret = false;
313290075Sobrien	  continue;
313390075Sobrien
313490075Sobrien	case (int) R_PPC_NONE:
313590075Sobrien	  continue;
313690075Sobrien
313790075Sobrien	/* Relocations that need no special processing.  */
313890075Sobrien	case (int) R_PPC_LOCAL24PC:
313990075Sobrien	  /* It makes no sense to point a local relocation
314090075Sobrien	     at a symbol not in this object.  */
314190075Sobrien	  if (h != NULL
314290075Sobrien	      && (h->root.type == bfd_link_hash_defined
314390075Sobrien		  || h->root.type == bfd_link_hash_defweak)
314490075Sobrien	      && sec->output_section == NULL)
314590075Sobrien	    {
314690075Sobrien	      if (! (*info->callbacks->undefined_symbol) (info,
314790075Sobrien							  h->root.root.string,
314890075Sobrien							  input_bfd,
314990075Sobrien							  input_section,
315090075Sobrien							  rel->r_offset,
315190075Sobrien							  true))
315290075Sobrien		return false;
315390075Sobrien	      continue;
315490075Sobrien	    }
315590075Sobrien	  break;
315690075Sobrien
315790075Sobrien	/* Relocations that may need to be propagated if this is a shared
315890075Sobrien           object.  */
315990075Sobrien	case (int) R_PPC_REL24:
316090075Sobrien	case (int) R_PPC_REL32:
316190075Sobrien	case (int) R_PPC_REL14:
316290075Sobrien	  /* If these relocations are not to a named symbol, they can be
316390075Sobrien	     handled right here, no need to bother the dynamic linker.  */
316490075Sobrien	  if (h == NULL
316590075Sobrien	      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
316690075Sobrien	      || SYMBOL_REFERENCES_LOCAL (info, h))
316790075Sobrien	    break;
316890075Sobrien	/* fall through */
316990075Sobrien
3170132718Skan	/* Relocations that always need to be propagated if this is a shared
317190075Sobrien           object.  */
317290075Sobrien	case (int) R_PPC_ADDR32:
317390075Sobrien	case (int) R_PPC_ADDR24:
317490075Sobrien	case (int) R_PPC_ADDR16:
317590075Sobrien	case (int) R_PPC_ADDR16_LO:
317690075Sobrien	case (int) R_PPC_ADDR16_HI:
317790075Sobrien	case (int) R_PPC_ADDR16_HA:
317890075Sobrien	case (int) R_PPC_ADDR14:
3179132718Skan	case (int) R_PPC_UADDR32:
318090075Sobrien	case (int) R_PPC_UADDR16:
318190075Sobrien	  if (info->shared && r_symndx != 0)
318290075Sobrien	    {
318390075Sobrien	      Elf_Internal_Rela outrel;
318490075Sobrien	      int skip;
318590075Sobrien
318690075Sobrien#ifdef DEBUG
318790075Sobrien	      fprintf (stderr, "ppc_elf_relocate_section need to create relocation for %s\n",
318890075Sobrien		       (h && h->root.root.string) ? h->root.root.string : "<unknown>");
318990075Sobrien#endif
319090075Sobrien
319190075Sobrien	      /* When generating a shared object, these relocations
319290075Sobrien                 are copied into the output file to be resolved at run
319390075Sobrien                 time.  */
319490075Sobrien
319590075Sobrien	      if (sreloc == NULL)
319690075Sobrien		{
319790075Sobrien		  const char *name;
319890075Sobrien
319990075Sobrien		  name = (bfd_elf_string_from_elf_section
320090075Sobrien			  (input_bfd,
320190075Sobrien			   elf_elfheader (input_bfd)->e_shstrndx,
3202169689Skan			   elf_section_data (input_section)->rel_hdr.sh_name));
3203169689Skan		  if (name == NULL)
320490075Sobrien		    return false;
320590075Sobrien
320690075Sobrien		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
320790075Sobrien			      && strcmp (bfd_get_section_name (input_bfd,
320890075Sobrien							       input_section),
320990075Sobrien					 name + 5) == 0);
321090075Sobrien
3211132718Skan		  sreloc = bfd_get_section_by_name (dynobj, name);
321290075Sobrien		  BFD_ASSERT (sreloc != NULL);
321390075Sobrien		}
321490075Sobrien
321590075Sobrien	      skip = 0;
321690075Sobrien
321790075Sobrien	      outrel.r_offset =
321890075Sobrien		_bfd_elf_section_offset (output_bfd, info, input_section,
321990075Sobrien					 rel->r_offset);
322090075Sobrien	      if (outrel.r_offset == (bfd_vma) -1
322190075Sobrien		  || outrel.r_offset == (bfd_vma) -2)
322290075Sobrien		skip = (int) outrel.r_offset;
322390075Sobrien	      outrel.r_offset += (input_section->output_section->vma
322490075Sobrien				  + input_section->output_offset);
322590075Sobrien
322690075Sobrien	      if (skip)
322790075Sobrien		memset (&outrel, 0, sizeof outrel);
322890075Sobrien	      /* h->dynindx may be -1 if this symbol was marked to
322990075Sobrien                 become local.  */
323090075Sobrien	      else if (! will_become_local)
323190075Sobrien		{
323290075Sobrien		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
323390075Sobrien		  outrel.r_addend = rel->r_addend;
3234132718Skan		}
323590075Sobrien	      else
323690075Sobrien		{
323790075Sobrien		  if (r_type == R_PPC_ADDR32)
3238169689Skan		    {
323990075Sobrien		      outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
3240169689Skan		      outrel.r_addend = relocation + rel->r_addend;
3241169689Skan		    }
324290075Sobrien		  else
324390075Sobrien		    {
324490075Sobrien		      long indx;
324590075Sobrien
324690075Sobrien		      if (h == NULL)
324790075Sobrien			sec = local_sections[r_symndx];
324890075Sobrien		      else
324990075Sobrien			{
325090075Sobrien			  BFD_ASSERT (h->root.type == bfd_link_hash_defined
325190075Sobrien				      || (h->root.type
325290075Sobrien					  == bfd_link_hash_defweak));
325390075Sobrien			  sec = h->root.u.def.section;
325490075Sobrien			}
325590075Sobrien		      if (sec != NULL && bfd_is_abs_section (sec))
325690075Sobrien			indx = 0;
325790075Sobrien		      else if (sec == NULL || sec->owner == NULL)
325890075Sobrien			{
325990075Sobrien			  bfd_set_error (bfd_error_bad_value);
326090075Sobrien			  return false;
326190075Sobrien			}
326290075Sobrien		      else
326390075Sobrien			{
326490075Sobrien			  asection *osec;
326590075Sobrien
326690075Sobrien			  osec = sec->output_section;
326790075Sobrien			  indx = elf_section_data (osec)->dynindx;
326890075Sobrien			  BFD_ASSERT (indx > 0);
326990075Sobrien#ifdef DEBUG
327090075Sobrien			  if (indx <= 0)
327190075Sobrien			    {
327290075Sobrien			      printf ("indx=%d section=%s flags=%08x name=%s\n",
327390075Sobrien				     indx, osec->name, osec->flags,
327490075Sobrien				     h->root.root.string);
327590075Sobrien			    }
327690075Sobrien#endif
327790075Sobrien			}
327890075Sobrien
327990075Sobrien		      outrel.r_info = ELF32_R_INFO (indx, r_type);
328090075Sobrien		      outrel.r_addend = relocation + rel->r_addend;
328190075Sobrien		    }
328290075Sobrien		}
328390075Sobrien
328490075Sobrien	      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
328590075Sobrien					 (((Elf32_External_Rela *)
328690075Sobrien					   sreloc->contents)
328790075Sobrien					  + sreloc->reloc_count));
328890075Sobrien	      ++sreloc->reloc_count;
328990075Sobrien
329090075Sobrien	      if (skip == -1)
329190075Sobrien		continue;
329290075Sobrien
329390075Sobrien	      /* This reloc will be computed at runtime.  We clear the memory
329490075Sobrien		 so that it contains predictable value.  */
329590075Sobrien	      if (! skip
329690075Sobrien		  && ((input_section->flags & SEC_ALLOC) != 0
329790075Sobrien		      || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE))
329890075Sobrien		{
329990075Sobrien		  relocation = howto->pc_relative ? outrel.r_offset : 0;
330090075Sobrien		  addend = 0;
330190075Sobrien		  break;
330290075Sobrien		}
330390075Sobrien	    }
330490075Sobrien
330590075Sobrien	  /* Arithmetic adjust relocations that aren't going into a
330690075Sobrien	     shared object.  */
330790075Sobrien	  if (r_type == R_PPC_ADDR16_HA
330890075Sobrien	      /* It's just possible that this symbol is a weak symbol
330990075Sobrien		 that's not actually defined anywhere. In that case,
331090075Sobrien		 'sec' would be NULL, and we should leave the symbol
331190075Sobrien		 alone (it will be set to zero elsewhere in the link).  */
331290075Sobrien	      && sec != NULL)
331390075Sobrien	    {
331490075Sobrien	      addend += ((relocation + addend) & 0x8000) << 1;
331590075Sobrien	    }
331690075Sobrien	  break;
3317169689Skan
331890075Sobrien	/* branch taken prediction relocations */
331990075Sobrien	case (int) R_PPC_ADDR14_BRTAKEN:
332090075Sobrien	case (int) R_PPC_REL14_BRTAKEN:
332190075Sobrien	  insn = bfd_get_32 (output_bfd, contents + offset);
3322132718Skan	  if ((relocation - offset) & 0x8000)
332390075Sobrien	    insn &= ~BRANCH_PREDICT_BIT;
332490075Sobrien	  else
332590075Sobrien	    insn |= BRANCH_PREDICT_BIT;
332690075Sobrien	  bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
332790075Sobrien	  break;
3328169689Skan
332990075Sobrien	/* branch not taken predicition relocations */
3330169689Skan	case (int) R_PPC_ADDR14_BRNTAKEN:
3331169689Skan	case (int) R_PPC_REL14_BRNTAKEN:
333290075Sobrien	  insn = bfd_get_32 (output_bfd, contents + offset);
3333169689Skan	  if ((relocation - offset) & 0x8000)
333490075Sobrien	    insn |= BRANCH_PREDICT_BIT;
3335169689Skan	  else
333690075Sobrien	    insn &= ~BRANCH_PREDICT_BIT;
333790075Sobrien	  bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
333890075Sobrien	  break;
333990075Sobrien
334090075Sobrien	/* GOT16 relocations */
334190075Sobrien	case (int) R_PPC_GOT16:
3342132718Skan	case (int) R_PPC_GOT16_LO:
334390075Sobrien	case (int) R_PPC_GOT16_HI:
334490075Sobrien	case (int) R_PPC_GOT16_HA:
334590075Sobrien	  /* Relocation is to the entry for this symbol in the global
3346169689Skan             offset table.  */
334790075Sobrien	  BFD_ASSERT (sgot != NULL);
3348169689Skan
3349169689Skan	  if (h != NULL)
335090075Sobrien	    {
335190075Sobrien	      bfd_vma off;
335290075Sobrien
335390075Sobrien	      off = h->got.offset;
335490075Sobrien	      BFD_ASSERT (off != (bfd_vma) -1);
335590075Sobrien
335690075Sobrien	      if (! elf_hash_table (info)->dynamic_sections_created
335790075Sobrien		  || (info->shared
335890075Sobrien		      && SYMBOL_REFERENCES_LOCAL (info, h)))
335990075Sobrien		{
336090075Sobrien		  /* This is actually a static link, or it is a
336190075Sobrien                     -Bsymbolic link and the symbol is defined
336290075Sobrien                     locally.  We must initialize this entry in the
336390075Sobrien                     global offset table.  Since the offset must
336490075Sobrien                     always be a multiple of 4, we use the least
336590075Sobrien                     significant bit to record whether we have
336690075Sobrien                     initialized it already.
336790075Sobrien
336890075Sobrien		     When doing a dynamic link, we create a .rela.got
336990075Sobrien		     relocation entry to initialize the value.  This
337090075Sobrien		     is done in the finish_dynamic_symbol routine.  */
337190075Sobrien		  if ((off & 1) != 0)
337290075Sobrien		    off &= ~1;
337390075Sobrien		  else
337490075Sobrien		    {
337590075Sobrien		      bfd_put_32 (output_bfd, relocation,
337690075Sobrien				  sgot->contents + off);
337790075Sobrien		      h->got.offset |= 1;
337890075Sobrien		    }
337990075Sobrien		}
338090075Sobrien
338190075Sobrien	      relocation = sgot->output_offset + off - 4;
338290075Sobrien	    }
338390075Sobrien	  else
338490075Sobrien	    {
338590075Sobrien	      bfd_vma off;
338690075Sobrien
338790075Sobrien	      BFD_ASSERT (local_got_offsets != NULL
338890075Sobrien			  && local_got_offsets[r_symndx] != (bfd_vma) -1);
338990075Sobrien
339090075Sobrien	      off = local_got_offsets[r_symndx];
339190075Sobrien
339290075Sobrien	      /* The offset must always be a multiple of 4.  We use
339390075Sobrien		 the least significant bit to record whether we have
339490075Sobrien		 already processed this entry.  */
339590075Sobrien	      if ((off & 1) != 0)
339690075Sobrien		off &= ~1;
339790075Sobrien	      else
339890075Sobrien		{
339990075Sobrien
340090075Sobrien		  if (info->shared)
340190075Sobrien		    {
340290075Sobrien		      asection *srelgot;
340390075Sobrien		      Elf_Internal_Rela outrel;
340490075Sobrien
340590075Sobrien		      /* We need to generate a R_PPC_RELATIVE reloc
340690075Sobrien			 for the dynamic linker.  */
340790075Sobrien		      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
340890075Sobrien		      BFD_ASSERT (srelgot != NULL);
340990075Sobrien
341090075Sobrien		      outrel.r_offset = (sgot->output_section->vma
341190075Sobrien					 + sgot->output_offset
341290075Sobrien					 + off);
341390075Sobrien		      outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
341490075Sobrien		      outrel.r_addend = relocation;
341590075Sobrien		      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
341690075Sobrien						 (((Elf32_External_Rela *)
341790075Sobrien						   srelgot->contents)
341890075Sobrien						  + srelgot->reloc_count));
341990075Sobrien		      ++srelgot->reloc_count;
342090075Sobrien		      relocation = 0;
342190075Sobrien		    }
342290075Sobrien
342390075Sobrien		  bfd_put_32 (output_bfd, relocation, sgot->contents + off);
342490075Sobrien		  local_got_offsets[r_symndx] |= 1;
3425169689Skan		}
342690075Sobrien
342790075Sobrien	      relocation = sgot->output_offset + off - 4;
342890075Sobrien	    }
342990075Sobrien	  break;
343090075Sobrien
343190075Sobrien	/* Indirect .sdata relocation */
343290075Sobrien	case (int) R_PPC_EMB_SDAI16:
343390075Sobrien	  BFD_ASSERT (sdata != NULL);
343490075Sobrien	  relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info,
3435132718Skan								sdata, h, relocation, rel,
343690075Sobrien								R_PPC_RELATIVE);
343790075Sobrien	  break;
343890075Sobrien
3439169689Skan	/* Indirect .sdata2 relocation */
344090075Sobrien	case (int) R_PPC_EMB_SDA2I16:
344190075Sobrien	  BFD_ASSERT (sdata2 != NULL);
344290075Sobrien	  relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info,
344390075Sobrien								sdata2, h, relocation, rel,
344490075Sobrien								R_PPC_RELATIVE);
344590075Sobrien	  break;
344690075Sobrien
344790075Sobrien	/* Handle the TOC16 reloc.  We want to use the offset within the .got
344890075Sobrien	   section, not the actual VMA.  This is appropriate when generating
344990075Sobrien	   an embedded ELF object, for which the .got section acts like the
345090075Sobrien	   AIX .toc section.  */
345190075Sobrien	case (int) R_PPC_TOC16:			/* phony GOT16 relocations */
345290075Sobrien	  BFD_ASSERT (sec != (asection *) 0);
345390075Sobrien	  BFD_ASSERT (bfd_is_und_section (sec)
345490075Sobrien		      || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
345590075Sobrien		      || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0)
345690075Sobrien
345790075Sobrien	  addend -= sec->output_section->vma + sec->output_offset + 0x8000;
345890075Sobrien	  break;
345990075Sobrien
346090075Sobrien	case (int) R_PPC_PLTREL24:
346190075Sobrien	  /* Relocation is to the entry for this symbol in the
346290075Sobrien             procedure linkage table.  */
346390075Sobrien	  BFD_ASSERT (h != NULL);
346490075Sobrien
346590075Sobrien	  if (h->plt.offset == (bfd_vma) -1
346690075Sobrien	      || splt == NULL)
346790075Sobrien	    {
346890075Sobrien	      /* We didn't make a PLT entry for this symbol.  This
346990075Sobrien                 happens when statically linking PIC code, or when
347090075Sobrien                 using -Bsymbolic.  */
347190075Sobrien	      break;
347290075Sobrien	    }
347390075Sobrien
347490075Sobrien	  relocation = (splt->output_section->vma
347590075Sobrien			+ splt->output_offset
347690075Sobrien			+ h->plt.offset);
347790075Sobrien	  break;
347890075Sobrien
347990075Sobrien	/* relocate against _SDA_BASE_ */
348090075Sobrien	case (int) R_PPC_SDAREL16:
348190075Sobrien	  {
348290075Sobrien	    const char *name;
348390075Sobrien
348490075Sobrien	    BFD_ASSERT (sec != (asection *) 0);
3485169689Skan	    name = bfd_get_section_name (abfd, sec->output_section);
348690075Sobrien	    if (strcmp (name, ".sdata") != 0
348790075Sobrien		&& strcmp (name, ".sbss") != 0)
348890075Sobrien	      {
348990075Sobrien		(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
349018334Speter				       bfd_archive_filename (input_bfd),
349118334Speter				       sym_name,
349290075Sobrien				       ppc_elf_howto_table[(int) r_type]->name,
349390075Sobrien				       name);
349490075Sobrien	      }
349590075Sobrien	    addend -= (sdata->sym_hash->root.u.def.value
349690075Sobrien		       + sdata->sym_hash->root.u.def.section->output_section->vma
349790075Sobrien		       + sdata->sym_hash->root.u.def.section->output_offset);
349890075Sobrien	  }
3499132718Skan	  break;
3500132718Skan
350190075Sobrien	/* relocate against _SDA2_BASE_ */
350290075Sobrien	case (int) R_PPC_EMB_SDA2REL:
350390075Sobrien	  {
350490075Sobrien	    const char *name;
350590075Sobrien
350690075Sobrien	    BFD_ASSERT (sec != (asection *) 0);
3507169689Skan	    name = bfd_get_section_name (abfd, sec->output_section);
350890075Sobrien	    if (strcmp (name, ".sdata2") != 0 && strcmp (name, ".sbss2") != 0)
350990075Sobrien	      {
351090075Sobrien		(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
351190075Sobrien				       bfd_archive_filename (input_bfd),
351290075Sobrien				       sym_name,
351390075Sobrien				       ppc_elf_howto_table[(int) r_type]->name,
351490075Sobrien				       name);
351590075Sobrien
351690075Sobrien		bfd_set_error (bfd_error_bad_value);
351790075Sobrien		ret = false;
351890075Sobrien		continue;
351990075Sobrien	      }
352090075Sobrien	    addend -= (sdata2->sym_hash->root.u.def.value
352190075Sobrien		       + sdata2->sym_hash->root.u.def.section->output_section->vma
352290075Sobrien		       + sdata2->sym_hash->root.u.def.section->output_offset);
352390075Sobrien	  }
3524169689Skan	  break;
352590075Sobrien
352690075Sobrien	/* relocate against either _SDA_BASE_, _SDA2_BASE_, or 0 */
352790075Sobrien	case (int) R_PPC_EMB_SDA21:
352890075Sobrien	case (int) R_PPC_EMB_RELSDA:
352990075Sobrien	  {
353090075Sobrien	    const char *name;
353190075Sobrien	    int reg;
353290075Sobrien
353390075Sobrien	    BFD_ASSERT (sec != (asection *) 0);
353490075Sobrien	    name = bfd_get_section_name (abfd, sec->output_section);
353590075Sobrien	    if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0)
353690075Sobrien	      {
353790075Sobrien		reg = 13;
353890075Sobrien		addend -= (sdata->sym_hash->root.u.def.value
353990075Sobrien			   + sdata->sym_hash->root.u.def.section->output_section->vma
354090075Sobrien			   + sdata->sym_hash->root.u.def.section->output_offset);
354190075Sobrien	      }
354290075Sobrien
354390075Sobrien	    else if (strcmp (name, ".sdata2") == 0
354490075Sobrien		     || strcmp (name, ".sbss2") == 0)
354590075Sobrien	      {
354690075Sobrien		reg = 2;
354790075Sobrien		addend -= (sdata2->sym_hash->root.u.def.value
354890075Sobrien			   + sdata2->sym_hash->root.u.def.section->output_section->vma
354990075Sobrien			   + sdata2->sym_hash->root.u.def.section->output_offset);
355090075Sobrien	      }
355190075Sobrien
355290075Sobrien	    else if (strcmp (name, ".PPC.EMB.sdata0") == 0
355390075Sobrien		     || strcmp (name, ".PPC.EMB.sbss0") == 0)
355490075Sobrien	      {
355590075Sobrien		reg = 0;
355690075Sobrien	      }
355790075Sobrien
3558117395Skan	    else
355990075Sobrien	      {
3560132718Skan		(*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
3561132718Skan				       bfd_archive_filename (input_bfd),
356290075Sobrien				       sym_name,
356390075Sobrien				       ppc_elf_howto_table[(int) r_type]->name,
356490075Sobrien				       name);
356590075Sobrien
356690075Sobrien		bfd_set_error (bfd_error_bad_value);
3567169689Skan		ret = false;
356890075Sobrien		continue;
356990075Sobrien	      }
357090075Sobrien
357190075Sobrien	    if (r_type == R_PPC_EMB_SDA21)
357290075Sobrien	      {			/* fill in register field */
357390075Sobrien		insn = bfd_get_32 (output_bfd, contents + offset);
357490075Sobrien		insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
357590075Sobrien		bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
357690075Sobrien	      }
3577169689Skan	  }
3578169689Skan	  break;
3579169689Skan
3580169689Skan	/* Relocate against the beginning of the section */
358190075Sobrien	case (int) R_PPC_SECTOFF:
358290075Sobrien	case (int) R_PPC_SECTOFF_LO:
358390075Sobrien	case (int) R_PPC_SECTOFF_HI:
358490075Sobrien	  BFD_ASSERT (sec != (asection *) 0);
358590075Sobrien	  addend -= sec->output_section->vma;
358690075Sobrien	  break;
358790075Sobrien
358890075Sobrien	case (int) R_PPC_SECTOFF_HA:
358990075Sobrien	  BFD_ASSERT (sec != (asection *) 0);
3590169689Skan	  addend -= sec->output_section->vma;
3591161651Skan	  addend += ((relocation + addend) & 0x8000) << 1;
3592161651Skan	  break;
3593161651Skan
3594161651Skan	/* Negative relocations */
3595161651Skan	case (int) R_PPC_EMB_NADDR32:
359690075Sobrien	case (int) R_PPC_EMB_NADDR16:
359790075Sobrien	case (int) R_PPC_EMB_NADDR16_LO:
359890075Sobrien	case (int) R_PPC_EMB_NADDR16_HI:
359990075Sobrien	  addend -= 2 * relocation;
360090075Sobrien	  break;
360190075Sobrien
360290075Sobrien	case (int) R_PPC_EMB_NADDR16_HA:
360390075Sobrien	  addend -= 2 * relocation;
360490075Sobrien	  addend += ((relocation + addend) & 0x8000) << 1;
360590075Sobrien	  break;
360690075Sobrien
360790075Sobrien	/* NOP relocation that prevents garbage collecting linkers from omitting a
360890075Sobrien	   reference.  */
360990075Sobrien	case (int) R_PPC_EMB_MRKREF:
361090075Sobrien	  continue;
3611169689Skan
3612169689Skan	case (int) R_PPC_COPY:
361390075Sobrien	case (int) R_PPC_GLOB_DAT:
361490075Sobrien	case (int) R_PPC_JMP_SLOT:
361590075Sobrien	case (int) R_PPC_RELATIVE:
361690075Sobrien	case (int) R_PPC_PLT32:
361790075Sobrien	case (int) R_PPC_PLTREL32:
361890075Sobrien	case (int) R_PPC_PLT16_LO:
361990075Sobrien	case (int) R_PPC_PLT16_HI:
362090075Sobrien	case (int) R_PPC_PLT16_HA:
362190075Sobrien	case (int) R_PPC_EMB_RELSEC16:
362290075Sobrien	case (int) R_PPC_EMB_RELST_LO:
362390075Sobrien	case (int) R_PPC_EMB_RELST_HI:
362490075Sobrien	case (int) R_PPC_EMB_RELST_HA:
362590075Sobrien	case (int) R_PPC_EMB_BIT_FLD:
3626169689Skan	  (*_bfd_error_handler) (_("%s: Relocation %s is not yet supported for symbol %s."),
3627169689Skan				 bfd_archive_filename (input_bfd),
3628169689Skan				 ppc_elf_howto_table[(int) r_type]->name,
3629169689Skan				 sym_name);
3630169689Skan
3631169689Skan	  bfd_set_error (bfd_error_invalid_operation);
3632169689Skan	  ret = false;
3633169689Skan	  continue;
3634169689Skan
3635169689Skan	case (int) R_PPC_GNU_VTINHERIT:
3636169689Skan	case (int) R_PPC_GNU_VTENTRY:
363790075Sobrien	  /* These are no-ops in the end.  */
363890075Sobrien	  continue;
3639169689Skan	}
364090075Sobrien
364190075Sobrien#ifdef DEBUG
364290075Sobrien      fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",
364390075Sobrien	       howto->name,
364490075Sobrien	       (int) r_type,
364590075Sobrien	       sym_name,
364690075Sobrien	       r_symndx,
364790075Sobrien	       (long) offset,
364890075Sobrien	       (long) addend);
364990075Sobrien#endif
365090075Sobrien
365190075Sobrien      r = _bfd_final_link_relocate (howto,
365290075Sobrien				    input_bfd,
365390075Sobrien				    input_section,
365490075Sobrien				    contents,
365518334Speter				    offset,
365618334Speter				    relocation,
365718334Speter				    addend);
365818334Speter
3659132718Skan      if (r == bfd_reloc_ok)
366018334Speter	;
366118334Speter      else if (r == bfd_reloc_overflow)
366218334Speter	{
366390075Sobrien	  const char *name;
366490075Sobrien
366590075Sobrien	  if (h != NULL)
366618334Speter	    {
3667169689Skan	      if (h->root.type == bfd_link_hash_undefweak
366890075Sobrien		  && howto->pc_relative)
366990075Sobrien		{
367018334Speter		  /* Assume this is a call protected by other code that
367118334Speter		     detect the symbol is undefined.  If this is the case,
367218334Speter		     we can safely ignore the overflow.  If not, the
367318334Speter		     program is hosed anyway, and a little warning isn't
367418334Speter		     going to help.  */
367518334Speter
3676169689Skan		  continue;
367790075Sobrien		}
367890075Sobrien
367990075Sobrien	      name = h->root.root.string;
368090075Sobrien	    }
368190075Sobrien	  else
368290075Sobrien	    {
368390075Sobrien	      name = bfd_elf_string_from_elf_section (input_bfd,
368490075Sobrien						      symtab_hdr->sh_link,
368590075Sobrien						      sym->st_name);
368690075Sobrien	      if (name == NULL)
368790075Sobrien		continue;
368890075Sobrien	      if (*name == '\0')
368990075Sobrien		name = bfd_section_name (input_bfd, sec);
369090075Sobrien	    }
369190075Sobrien
369290075Sobrien	  if (! (*info->callbacks->reloc_overflow) (info,
369390075Sobrien						   name,
369490075Sobrien						   howto->name,
369590075Sobrien						   (bfd_vma) 0,
369690075Sobrien						   input_bfd,
369790075Sobrien						   input_section,
369890075Sobrien						   offset))
369990075Sobrien	    return false;
370090075Sobrien	}
370118334Speter      else
370290075Sobrien	ret = false;
370390075Sobrien    }
370490075Sobrien
370590075Sobrien#ifdef DEBUG
370690075Sobrien  fprintf (stderr, "\n");
370790075Sobrien#endif
370890075Sobrien
370990075Sobrien  return ret;
371090075Sobrien}
371190075Sobrien
371290075Sobrienstatic enum elf_reloc_type_class
371390075Sobrienppc_elf_reloc_type_class (rela)
371490075Sobrien     const Elf_Internal_Rela *rela;
371590075Sobrien{
371690075Sobrien  switch ((int) ELF32_R_TYPE (rela->r_info))
371790075Sobrien    {
371890075Sobrien    case R_PPC_RELATIVE:
371990075Sobrien      return reloc_class_relative;
372090075Sobrien    case R_PPC_REL24:
372190075Sobrien    case R_PPC_ADDR24:
372290075Sobrien    case R_PPC_JMP_SLOT:
372390075Sobrien      return reloc_class_plt;
3724132718Skan    case R_PPC_COPY:
3725132718Skan      return reloc_class_copy;
3726132718Skan    default:
3727132718Skan      return reloc_class_normal;
3728132718Skan    }
3729132718Skan}
373090075Sobrien
3731169689Skan/* Support for core dump NOTE sections */
373290075Sobrienstatic boolean
373390075Sobrienppc_elf_grok_prstatus (abfd, note)
373418334Speter     bfd *abfd;
373590075Sobrien     Elf_Internal_Note *note;
373690075Sobrien{
373790075Sobrien  int offset;
373890075Sobrien  unsigned int raw_size;
373990075Sobrien
374090075Sobrien  switch (note->descsz)
374190075Sobrien    {
374290075Sobrien      default:
374390075Sobrien	return false;
374418334Speter
374590075Sobrien      case 268:		/* Linux/PPC */
374690075Sobrien	/* pr_cursig */
374790075Sobrien	elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3748132718Skan
3749132718Skan	/* pr_pid */
375090075Sobrien	elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
375190075Sobrien
375290075Sobrien	/* pr_reg */
375318334Speter	offset = 72;
375490075Sobrien	raw_size = 192;
375590075Sobrien
3756169689Skan	break;
375718334Speter    }
375890075Sobrien
375990075Sobrien  /* Make a ".reg/999" section.  */
376090075Sobrien  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
376190075Sobrien					  raw_size, note->descpos + offset);
376290075Sobrien}
376390075Sobrien
376490075Sobrienstatic boolean
376590075Sobrienppc_elf_grok_psinfo (abfd, note)
376618334Speter     bfd *abfd;
376790075Sobrien     Elf_Internal_Note *note;
376890075Sobrien{
376990075Sobrien  switch (note->descsz)
377090075Sobrien    {
377118334Speter      default:
377290075Sobrien	return false;
377390075Sobrien
377490075Sobrien      case 128:		/* Linux/PPC elf_prpsinfo */
377590075Sobrien	elf_tdata (abfd)->core_program
377690075Sobrien	 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
377790075Sobrien	elf_tdata (abfd)->core_command
377818334Speter	 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
377990075Sobrien    }
378090075Sobrien
378190075Sobrien  /* Note that for some reason, a spurious space is tacked
378290075Sobrien     onto the end of the args in some (at least one anyway)
378390075Sobrien     implementations, so strip it off if it exists.  */
378490075Sobrien
378590075Sobrien  {
378690075Sobrien    char *command = elf_tdata (abfd)->core_command;
378790075Sobrien    int n = strlen (command);
378890075Sobrien
378918334Speter    if (0 < n && command[n - 1] == ' ')
379090075Sobrien      command[n - 1] = '\0';
379190075Sobrien  }
379290075Sobrien
379390075Sobrien  return true;
379418334Speter}
379590075Sobrien
379690075Sobrien#define TARGET_LITTLE_SYM	bfd_elf32_powerpcle_vec
379790075Sobrien#define TARGET_LITTLE_NAME	"elf32-powerpcle"
379890075Sobrien#define TARGET_BIG_SYM		bfd_elf32_powerpc_vec
379990075Sobrien#define TARGET_BIG_NAME		"elf32-powerpc"
380090075Sobrien#define ELF_ARCH		bfd_arch_powerpc
380190075Sobrien#define ELF_MACHINE_CODE	EM_PPC
380290075Sobrien#define ELF_MAXPAGESIZE		0x10000
380390075Sobrien#define elf_info_to_howto	ppc_elf_info_to_howto
380418334Speter
380590075Sobrien#ifdef  EM_CYGNUS_POWERPC
380690075Sobrien#define ELF_MACHINE_ALT1	EM_CYGNUS_POWERPC
380790075Sobrien#endif
380890075Sobrien
380990075Sobrien#ifdef EM_PPC_OLD
381018334Speter#define ELF_MACHINE_ALT2	EM_PPC_OLD
381190075Sobrien#endif
381290075Sobrien
381390075Sobrien#define elf_backend_plt_not_loaded	1
381490075Sobrien#define elf_backend_got_symbol_offset	4
3815169689Skan#define elf_backend_can_gc_sections	1
3816169689Skan#define elf_backend_can_refcount	1
3817169689Skan#define elf_backend_got_header_size	12
3818169689Skan#define elf_backend_plt_header_size	PLT_INITIAL_ENTRY_SIZE
3819169689Skan#define elf_backend_rela_normal		1
3820169689Skan
382190075Sobrien#define bfd_elf32_bfd_merge_private_bfd_data	ppc_elf_merge_private_bfd_data
382218334Speter#define bfd_elf32_bfd_relax_section             ppc_elf_relax_section
382390075Sobrien#define bfd_elf32_bfd_reloc_type_lookup		ppc_elf_reloc_type_lookup
382490075Sobrien#define bfd_elf32_bfd_set_private_flags		ppc_elf_set_private_flags
382590075Sobrien#define bfd_elf32_bfd_final_link		_bfd_elf32_gc_common_final_link
382690075Sobrien
382790075Sobrien#define elf_backend_object_p			ppc_elf_object_p
382890075Sobrien#define elf_backend_gc_mark_hook		ppc_elf_gc_mark_hook
382990075Sobrien#define elf_backend_gc_sweep_hook		ppc_elf_gc_sweep_hook
383090075Sobrien#define elf_backend_section_from_shdr		ppc_elf_section_from_shdr
383190075Sobrien#define elf_backend_relocate_section		ppc_elf_relocate_section
383290075Sobrien#define elf_backend_create_dynamic_sections	ppc_elf_create_dynamic_sections
383390075Sobrien#define elf_backend_check_relocs		ppc_elf_check_relocs
383490075Sobrien#define elf_backend_adjust_dynamic_symbol	ppc_elf_adjust_dynamic_symbol
383590075Sobrien#define elf_backend_add_symbol_hook		ppc_elf_add_symbol_hook
383618334Speter#define elf_backend_size_dynamic_sections	ppc_elf_size_dynamic_sections
383790075Sobrien#define elf_backend_finish_dynamic_symbol	ppc_elf_finish_dynamic_symbol
383890075Sobrien#define elf_backend_finish_dynamic_sections	ppc_elf_finish_dynamic_sections
383990075Sobrien#define elf_backend_fake_sections		ppc_elf_fake_sections
384090075Sobrien#define elf_backend_additional_program_headers	ppc_elf_additional_program_headers
384190075Sobrien#define elf_backend_modify_segment_map		ppc_elf_modify_segment_map
3842169689Skan#define elf_backend_grok_prstatus		ppc_elf_grok_prstatus
3843169689Skan#define elf_backend_grok_psinfo			ppc_elf_grok_psinfo
3844169689Skan#define elf_backend_reloc_type_class		ppc_elf_reloc_type_class
3845169689Skan
384690075Sobrien#include "elf32-target.h"
384790075Sobrien