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