159024Sobrien/* SPARC-specific support for 32-bit ELF 2130561Sobrien Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 3218822Sdim 2003, 2004, 2005, 2007 Free Software Foundation, Inc. 459024Sobrien 5130561Sobrien This file is part of BFD, the Binary File Descriptor library. 659024Sobrien 7130561Sobrien This program is free software; you can redistribute it and/or modify 8130561Sobrien it under the terms of the GNU General Public License as published by 9130561Sobrien the Free Software Foundation; either version 2 of the License, or 10130561Sobrien (at your option) any later version. 1159024Sobrien 12130561Sobrien This program is distributed in the hope that it will be useful, 13130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 14130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130561Sobrien GNU General Public License for more details. 1659024Sobrien 17130561Sobrien You should have received a copy of the GNU General Public License 18130561Sobrien along with this program; if not, write to the Free Software 19218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2059024Sobrien 21218822Sdim#include "sysdep.h" 2259024Sobrien#include "bfd.h" 2359024Sobrien#include "bfdlink.h" 2459024Sobrien#include "libbfd.h" 2559024Sobrien#include "elf-bfd.h" 2659024Sobrien#include "elf/sparc.h" 2777298Sobrien#include "opcode/sparc.h" 28218822Sdim#include "elfxx-sparc.h" 29218822Sdim#include "elf-vxworks.h" 3059024Sobrien 31130561Sobrien/* Support for core dump NOTE sections. */ 32130561Sobrien 33130561Sobrienstatic bfd_boolean 34130561Sobrienelf32_sparc_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 35130561Sobrien{ 36130561Sobrien switch (note->descsz) 37130561Sobrien { 38130561Sobrien default: 39130561Sobrien return FALSE; 40130561Sobrien 41130561Sobrien case 260: /* Solaris prpsinfo_t. */ 42130561Sobrien elf_tdata (abfd)->core_program 43130561Sobrien = _bfd_elfcore_strndup (abfd, note->descdata + 84, 16); 44130561Sobrien elf_tdata (abfd)->core_command 45130561Sobrien = _bfd_elfcore_strndup (abfd, note->descdata + 100, 80); 46130561Sobrien break; 47130561Sobrien 48130561Sobrien case 336: /* Solaris psinfo_t. */ 49130561Sobrien elf_tdata (abfd)->core_program 50130561Sobrien = _bfd_elfcore_strndup (abfd, note->descdata + 88, 16); 51130561Sobrien elf_tdata (abfd)->core_command 52130561Sobrien = _bfd_elfcore_strndup (abfd, note->descdata + 104, 80); 53130561Sobrien break; 54130561Sobrien } 55130561Sobrien 56130561Sobrien return TRUE; 57130561Sobrien} 58130561Sobrien 5959024Sobrien/* Functions for dealing with the e_flags field. 6059024Sobrien 6159024Sobrien We don't define set_private_flags or copy_private_bfd_data because 6259024Sobrien the only currently defined values are based on the bfd mach number, 6359024Sobrien so we use the latter instead and defer setting e_flags until the 6459024Sobrien file is written out. */ 6559024Sobrien 6659024Sobrien/* Merge backend specific data from an object file to the output 6759024Sobrien object file when linking. */ 6859024Sobrien 69130561Sobrienstatic bfd_boolean 70218822Sdimelf32_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd) 7159024Sobrien{ 72130561Sobrien bfd_boolean error; 73218822Sdim unsigned long ibfd_mach; 7460484Sobrien /* FIXME: This should not be static. */ 7560484Sobrien static unsigned long previous_ibfd_e_flags = (unsigned long) -1; 7659024Sobrien 7759024Sobrien if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 7859024Sobrien || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 79130561Sobrien return TRUE; 8059024Sobrien 81130561Sobrien error = FALSE; 8259024Sobrien 83218822Sdim ibfd_mach = bfd_get_mach (ibfd); 84218822Sdim if (bfd_mach_sparc_64bit_p (ibfd_mach)) 8559024Sobrien { 86130561Sobrien error = TRUE; 8759024Sobrien (*_bfd_error_handler) 88218822Sdim (_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd); 8959024Sobrien } 9060484Sobrien else if ((ibfd->flags & DYNAMIC) == 0) 9160484Sobrien { 92218822Sdim if (bfd_get_mach (obfd) < ibfd_mach) 93218822Sdim bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach); 9460484Sobrien } 9559024Sobrien 9660484Sobrien if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA) 9760484Sobrien != previous_ibfd_e_flags) 9860484Sobrien && previous_ibfd_e_flags != (unsigned long) -1) 9960484Sobrien { 10060484Sobrien (*_bfd_error_handler) 101218822Sdim (_("%B: linking little endian files with big endian files"), ibfd); 102130561Sobrien error = TRUE; 10360484Sobrien } 10460484Sobrien previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA; 10560484Sobrien 10659024Sobrien if (error) 10759024Sobrien { 10859024Sobrien bfd_set_error (bfd_error_bad_value); 109130561Sobrien return FALSE; 11059024Sobrien } 11159024Sobrien 112130561Sobrien return TRUE; 11359024Sobrien} 11459024Sobrien 11559024Sobrien/* The final processing done just before writing out the object file. 11659024Sobrien We need to set the e_machine field appropriately. */ 11759024Sobrien 11859024Sobrienstatic void 119218822Sdimelf32_sparc_final_write_processing (bfd *abfd, 120218822Sdim bfd_boolean linker ATTRIBUTE_UNUSED) 12159024Sobrien{ 12259024Sobrien switch (bfd_get_mach (abfd)) 12359024Sobrien { 12459024Sobrien case bfd_mach_sparc : 125218822Sdim case bfd_mach_sparc_sparclet : 126218822Sdim case bfd_mach_sparc_sparclite : 12759024Sobrien break; /* nothing to do */ 12859024Sobrien case bfd_mach_sparc_v8plus : 12959024Sobrien elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 13059024Sobrien elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 13159024Sobrien elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS; 13259024Sobrien break; 13359024Sobrien case bfd_mach_sparc_v8plusa : 13459024Sobrien elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 13559024Sobrien elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 13659024Sobrien elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1; 13759024Sobrien break; 13877298Sobrien case bfd_mach_sparc_v8plusb : 13977298Sobrien elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 14077298Sobrien elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 14177298Sobrien elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1 14277298Sobrien | EF_SPARC_SUN_US3; 14377298Sobrien break; 14460484Sobrien case bfd_mach_sparc_sparclite_le : 14560484Sobrien elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA; 14660484Sobrien break; 14759024Sobrien default : 14859024Sobrien abort (); 14960484Sobrien break; 15059024Sobrien } 15159024Sobrien} 15289857Sobrien 15389857Sobrienstatic enum elf_reloc_type_class 154218822Sdimelf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela) 15589857Sobrien{ 15689857Sobrien switch ((int) ELF32_R_TYPE (rela->r_info)) 15789857Sobrien { 15889857Sobrien case R_SPARC_RELATIVE: 15989857Sobrien return reloc_class_relative; 16089857Sobrien case R_SPARC_JMP_SLOT: 16189857Sobrien return reloc_class_plt; 16289857Sobrien case R_SPARC_COPY: 16389857Sobrien return reloc_class_copy; 16489857Sobrien default: 16589857Sobrien return reloc_class_normal; 16689857Sobrien } 16789857Sobrien} 168218822Sdim 16959024Sobrien#define TARGET_BIG_SYM bfd_elf32_sparc_vec 17059024Sobrien#define TARGET_BIG_NAME "elf32-sparc" 17159024Sobrien#define ELF_ARCH bfd_arch_sparc 17259024Sobrien#define ELF_MACHINE_CODE EM_SPARC 17359024Sobrien#define ELF_MACHINE_ALT1 EM_SPARC32PLUS 17459024Sobrien#define ELF_MAXPAGESIZE 0x10000 175218822Sdim#define ELF_COMMONPAGESIZE 0x2000 17659024Sobrien 177218822Sdim#define bfd_elf32_bfd_merge_private_bfd_data \ 178218822Sdim elf32_sparc_merge_private_bfd_data 179218822Sdim#define elf_backend_final_write_processing \ 180218822Sdim elf32_sparc_final_write_processing 181218822Sdim#define elf_backend_grok_psinfo elf32_sparc_grok_psinfo 182218822Sdim#define elf_backend_reloc_type_class elf32_sparc_reloc_type_class 183218822Sdim 184218822Sdim#define elf_info_to_howto _bfd_sparc_elf_info_to_howto 185218822Sdim#define bfd_elf32_bfd_reloc_type_lookup _bfd_sparc_elf_reloc_type_lookup 186218822Sdim#define bfd_elf32_bfd_reloc_name_lookup \ 187218822Sdim _bfd_sparc_elf_reloc_name_lookup 188130561Sobrien#define bfd_elf32_bfd_link_hash_table_create \ 189218822Sdim _bfd_sparc_elf_link_hash_table_create 190218822Sdim#define bfd_elf32_bfd_relax_section _bfd_sparc_elf_relax_section 191218822Sdim#define bfd_elf32_new_section_hook _bfd_sparc_elf_new_section_hook 192130561Sobrien#define elf_backend_copy_indirect_symbol \ 193218822Sdim _bfd_sparc_elf_copy_indirect_symbol 19459024Sobrien#define elf_backend_create_dynamic_sections \ 195218822Sdim _bfd_sparc_elf_create_dynamic_sections 196218822Sdim#define elf_backend_check_relocs _bfd_sparc_elf_check_relocs 19759024Sobrien#define elf_backend_adjust_dynamic_symbol \ 198218822Sdim _bfd_sparc_elf_adjust_dynamic_symbol 199218822Sdim#define elf_backend_omit_section_dynsym _bfd_sparc_elf_omit_section_dynsym 20059024Sobrien#define elf_backend_size_dynamic_sections \ 201218822Sdim _bfd_sparc_elf_size_dynamic_sections 202218822Sdim#define elf_backend_relocate_section _bfd_sparc_elf_relocate_section 20359024Sobrien#define elf_backend_finish_dynamic_symbol \ 204218822Sdim _bfd_sparc_elf_finish_dynamic_symbol 20559024Sobrien#define elf_backend_finish_dynamic_sections \ 206218822Sdim _bfd_sparc_elf_finish_dynamic_sections 207218822Sdim#define bfd_elf32_mkobject _bfd_sparc_elf_mkobject 208218822Sdim#define elf_backend_object_p _bfd_sparc_elf_object_p 209218822Sdim#define elf_backend_gc_mark_hook _bfd_sparc_elf_gc_mark_hook 210218822Sdim#define elf_backend_gc_sweep_hook _bfd_sparc_elf_gc_sweep_hook 211218822Sdim#define elf_backend_plt_sym_val _bfd_sparc_elf_plt_sym_val 212218822Sdim#define elf_backend_init_index_section _bfd_elf_init_1_index_section 21360484Sobrien 21460484Sobrien#define elf_backend_can_gc_sections 1 215130561Sobrien#define elf_backend_can_refcount 1 21659024Sobrien#define elf_backend_want_got_plt 0 21759024Sobrien#define elf_backend_plt_readonly 0 21859024Sobrien#define elf_backend_want_plt_sym 1 21960484Sobrien#define elf_backend_got_header_size 4 220130561Sobrien#define elf_backend_rela_normal 1 22159024Sobrien 22259024Sobrien#include "elf32-target.h" 223218822Sdim 224218822Sdim/* A wrapper around _bfd_sparc_elf_link_hash_table_create that identifies 225218822Sdim the target system as VxWorks. */ 226218822Sdim 227218822Sdimstatic struct bfd_link_hash_table * 228218822Sdimelf32_sparc_vxworks_link_hash_table_create (bfd *abfd) 229218822Sdim{ 230218822Sdim struct bfd_link_hash_table *ret; 231218822Sdim 232218822Sdim ret = _bfd_sparc_elf_link_hash_table_create (abfd); 233218822Sdim if (ret) 234218822Sdim { 235218822Sdim struct _bfd_sparc_elf_link_hash_table *htab; 236218822Sdim 237218822Sdim htab = (struct _bfd_sparc_elf_link_hash_table *) ret; 238218822Sdim htab->is_vxworks = 1; 239218822Sdim } 240218822Sdim return ret; 241218822Sdim} 242218822Sdim 243218822Sdim/* A final_write_processing hook that does both the SPARC- and VxWorks- 244218822Sdim specific handling. */ 245218822Sdim 246218822Sdimstatic void 247218822Sdimelf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker) 248218822Sdim{ 249218822Sdim elf32_sparc_final_write_processing (abfd, linker); 250218822Sdim elf_vxworks_final_write_processing (abfd, linker); 251218822Sdim} 252218822Sdim 253218822Sdim#undef TARGET_BIG_SYM 254218822Sdim#define TARGET_BIG_SYM bfd_elf32_sparc_vxworks_vec 255218822Sdim#undef TARGET_BIG_NAME 256218822Sdim#define TARGET_BIG_NAME "elf32-sparc-vxworks" 257218822Sdim 258218822Sdim#undef ELF_MINPAGESIZE 259218822Sdim#define ELF_MINPAGESIZE 0x1000 260218822Sdim 261218822Sdim#undef bfd_elf32_bfd_link_hash_table_create 262218822Sdim#define bfd_elf32_bfd_link_hash_table_create \ 263218822Sdim elf32_sparc_vxworks_link_hash_table_create 264218822Sdim 265218822Sdim#undef elf_backend_want_got_plt 266218822Sdim#define elf_backend_want_got_plt 1 267218822Sdim#undef elf_backend_plt_readonly 268218822Sdim#define elf_backend_plt_readonly 1 269218822Sdim#undef elf_backend_got_header_size 270218822Sdim#define elf_backend_got_header_size 12 271218822Sdim#undef elf_backend_add_symbol_hook 272218822Sdim#define elf_backend_add_symbol_hook \ 273218822Sdim elf_vxworks_add_symbol_hook 274218822Sdim#undef elf_backend_link_output_symbol_hook 275218822Sdim#define elf_backend_link_output_symbol_hook \ 276218822Sdim elf_vxworks_link_output_symbol_hook 277218822Sdim#undef elf_backend_emit_relocs 278218822Sdim#define elf_backend_emit_relocs \ 279218822Sdim elf_vxworks_emit_relocs 280218822Sdim#undef elf_backend_final_write_processing 281218822Sdim#define elf_backend_final_write_processing \ 282218822Sdim elf32_sparc_vxworks_final_write_processing 283218822Sdim 284218822Sdim#undef elf32_bed 285218822Sdim#define elf32_bed sparc_elf_vxworks_bed 286218822Sdim 287218822Sdim#include "elf32-target.h" 288