1 /* SPARC-specific support for 32-bit ELF 2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 3 2003, 2004, 2005, 2006, 2007, 2010, 2011 4 Free Software Foundation, Inc. 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "bfdlink.h" 26 #include "libbfd.h" 27 #include "elf-bfd.h" 28 #include "elf/sparc.h" 29 #include "opcode/sparc.h" 30 #include "elfxx-sparc.h" 31 #include "elf-vxworks.h" 32 33 /* Support for core dump NOTE sections. */ 34 35 static bfd_boolean 36 elf32_sparc_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 37 { 38 switch (note->descsz) 39 { 40 default: 41 return FALSE; 42 43 case 260: /* Solaris prpsinfo_t. */ 44 elf_tdata (abfd)->core->program 45 = _bfd_elfcore_strndup (abfd, note->descdata + 84, 16); 46 elf_tdata (abfd)->core->command 47 = _bfd_elfcore_strndup (abfd, note->descdata + 100, 80); 48 break; 49 50 case 336: /* Solaris psinfo_t. */ 51 elf_tdata (abfd)->core->program 52 = _bfd_elfcore_strndup (abfd, note->descdata + 88, 16); 53 elf_tdata (abfd)->core->command 54 = _bfd_elfcore_strndup (abfd, note->descdata + 104, 80); 55 break; 56 } 57 58 return TRUE; 59 } 60 61 /* Functions for dealing with the e_flags field. 62 63 We don't define set_private_flags or copy_private_bfd_data because 64 the only currently defined values are based on the bfd mach number, 65 so we use the latter instead and defer setting e_flags until the 66 file is written out. */ 67 68 /* Merge backend specific data from an object file to the output 69 object file when linking. */ 70 71 static bfd_boolean 72 elf32_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd) 73 { 74 bfd_boolean error; 75 unsigned long ibfd_mach; 76 /* FIXME: This should not be static. */ 77 static unsigned long previous_ibfd_e_flags = (unsigned long) -1; 78 79 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 80 || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 81 return TRUE; 82 83 error = FALSE; 84 85 ibfd_mach = bfd_get_mach (ibfd); 86 if (bfd_mach_sparc_64bit_p (ibfd_mach)) 87 { 88 error = TRUE; 89 (*_bfd_error_handler) 90 (_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd); 91 } 92 else if ((ibfd->flags & DYNAMIC) == 0) 93 { 94 if (bfd_get_mach (obfd) < ibfd_mach) 95 bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach); 96 } 97 98 if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA) 99 != previous_ibfd_e_flags) 100 && previous_ibfd_e_flags != (unsigned long) -1) 101 { 102 (*_bfd_error_handler) 103 (_("%B: linking little endian files with big endian files"), ibfd); 104 error = TRUE; 105 } 106 previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA; 107 108 if (error) 109 { 110 bfd_set_error (bfd_error_bad_value); 111 return FALSE; 112 } 113 114 return _bfd_sparc_elf_merge_private_bfd_data (ibfd, obfd); 115 } 116 117 /* The final processing done just before writing out the object file. 118 We need to set the e_machine field appropriately. */ 119 120 static void 121 elf32_sparc_final_write_processing (bfd *abfd, 122 bfd_boolean linker ATTRIBUTE_UNUSED) 123 { 124 switch (bfd_get_mach (abfd)) 125 { 126 case bfd_mach_sparc : 127 case bfd_mach_sparc_sparclet : 128 case bfd_mach_sparc_sparclite : 129 break; /* nothing to do */ 130 case bfd_mach_sparc_v8plus : 131 elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 132 elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 133 elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS; 134 break; 135 case bfd_mach_sparc_v8plusa : 136 elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 137 elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 138 elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1; 139 break; 140 case bfd_mach_sparc_v8plusb : 141 elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; 142 elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; 143 elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1 144 | EF_SPARC_SUN_US3; 145 break; 146 case bfd_mach_sparc_sparclite_le : 147 elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA; 148 break; 149 default : 150 abort (); 151 break; 152 } 153 } 154 155 static enum elf_reloc_type_class 156 elf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela) 157 { 158 switch ((int) ELF32_R_TYPE (rela->r_info)) 159 { 160 case R_SPARC_RELATIVE: 161 return reloc_class_relative; 162 case R_SPARC_JMP_SLOT: 163 return reloc_class_plt; 164 case R_SPARC_COPY: 165 return reloc_class_copy; 166 default: 167 return reloc_class_normal; 168 } 169 } 170 171 /* Hook called by the linker routine which adds symbols from an object 172 file. */ 173 174 static bfd_boolean 175 elf32_sparc_add_symbol_hook (bfd * abfd, 176 struct bfd_link_info * info ATTRIBUTE_UNUSED, 177 Elf_Internal_Sym * sym, 178 const char ** namep ATTRIBUTE_UNUSED, 179 flagword * flagsp ATTRIBUTE_UNUSED, 180 asection ** secp ATTRIBUTE_UNUSED, 181 bfd_vma * valp ATTRIBUTE_UNUSED) 182 { 183 if ((abfd->flags & DYNAMIC) == 0 184 && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC 185 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)) 186 elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE; 187 return TRUE; 188 } 189 190 #define TARGET_BIG_SYM bfd_elf32_sparc_vec 191 #define TARGET_BIG_NAME "elf32-sparc" 192 #define ELF_ARCH bfd_arch_sparc 193 #define ELF_TARGET_ID SPARC_ELF_DATA 194 #define ELF_MACHINE_CODE EM_SPARC 195 #define ELF_MACHINE_ALT1 EM_SPARC32PLUS 196 #define ELF_MAXPAGESIZE 0x10000 197 #define ELF_COMMONPAGESIZE 0x2000 198 199 #define bfd_elf32_bfd_merge_private_bfd_data \ 200 elf32_sparc_merge_private_bfd_data 201 #define elf_backend_final_write_processing \ 202 elf32_sparc_final_write_processing 203 #define elf_backend_grok_psinfo elf32_sparc_grok_psinfo 204 #define elf_backend_reloc_type_class elf32_sparc_reloc_type_class 205 206 #define elf_info_to_howto _bfd_sparc_elf_info_to_howto 207 #define bfd_elf32_bfd_reloc_type_lookup _bfd_sparc_elf_reloc_type_lookup 208 #define bfd_elf32_bfd_reloc_name_lookup \ 209 _bfd_sparc_elf_reloc_name_lookup 210 #define bfd_elf32_bfd_link_hash_table_create \ 211 _bfd_sparc_elf_link_hash_table_create 212 #define bfd_elf32_bfd_link_hash_table_free \ 213 _bfd_sparc_elf_link_hash_table_free 214 #define bfd_elf32_bfd_relax_section _bfd_sparc_elf_relax_section 215 #define bfd_elf32_new_section_hook _bfd_sparc_elf_new_section_hook 216 #define elf_backend_copy_indirect_symbol \ 217 _bfd_sparc_elf_copy_indirect_symbol 218 #define elf_backend_create_dynamic_sections \ 219 _bfd_sparc_elf_create_dynamic_sections 220 #define elf_backend_check_relocs _bfd_sparc_elf_check_relocs 221 #define elf_backend_adjust_dynamic_symbol \ 222 _bfd_sparc_elf_adjust_dynamic_symbol 223 #define elf_backend_omit_section_dynsym _bfd_sparc_elf_omit_section_dynsym 224 #define elf_backend_size_dynamic_sections \ 225 _bfd_sparc_elf_size_dynamic_sections 226 #define elf_backend_relocate_section _bfd_sparc_elf_relocate_section 227 #define elf_backend_finish_dynamic_symbol \ 228 _bfd_sparc_elf_finish_dynamic_symbol 229 #define elf_backend_finish_dynamic_sections \ 230 _bfd_sparc_elf_finish_dynamic_sections 231 #define bfd_elf32_mkobject _bfd_sparc_elf_mkobject 232 #define elf_backend_object_p _bfd_sparc_elf_object_p 233 #define elf_backend_gc_mark_hook _bfd_sparc_elf_gc_mark_hook 234 #define elf_backend_gc_sweep_hook _bfd_sparc_elf_gc_sweep_hook 235 #define elf_backend_plt_sym_val _bfd_sparc_elf_plt_sym_val 236 #define elf_backend_init_index_section _bfd_elf_init_1_index_section 237 238 #define elf_backend_can_gc_sections 1 239 #define elf_backend_can_refcount 1 240 #define elf_backend_want_got_plt 0 241 #define elf_backend_plt_readonly 0 242 #define elf_backend_want_plt_sym 1 243 #define elf_backend_got_header_size 4 244 #define elf_backend_rela_normal 1 245 246 #define elf_backend_post_process_headers _bfd_elf_set_osabi 247 #define elf_backend_add_symbol_hook elf32_sparc_add_symbol_hook 248 249 #include "elf32-target.h" 250 251 /* Solaris 2. */ 252 253 #undef TARGET_BIG_SYM 254 #define TARGET_BIG_SYM bfd_elf32_sparc_sol2_vec 255 #undef TARGET_BIG_NAME 256 #define TARGET_BIG_NAME "elf32-sparc-sol2" 257 258 #undef elf32_bed 259 #define elf32_bed elf32_sparc_sol2_bed 260 261 /* The 32-bit static TLS arena size is rounded to the nearest 8-byte 262 boundary. */ 263 #undef elf_backend_static_tls_alignment 264 #define elf_backend_static_tls_alignment 8 265 266 #include "elf32-target.h" 267 268 /* A wrapper around _bfd_sparc_elf_link_hash_table_create that identifies 269 the target system as VxWorks. */ 270 271 static struct bfd_link_hash_table * 272 elf32_sparc_vxworks_link_hash_table_create (bfd *abfd) 273 { 274 struct bfd_link_hash_table *ret; 275 276 ret = _bfd_sparc_elf_link_hash_table_create (abfd); 277 if (ret) 278 { 279 struct _bfd_sparc_elf_link_hash_table *htab; 280 281 htab = (struct _bfd_sparc_elf_link_hash_table *) ret; 282 htab->is_vxworks = 1; 283 } 284 return ret; 285 } 286 287 /* A final_write_processing hook that does both the SPARC- and VxWorks- 288 specific handling. */ 289 290 static void 291 elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker) 292 { 293 elf32_sparc_final_write_processing (abfd, linker); 294 elf_vxworks_final_write_processing (abfd, linker); 295 } 296 297 #undef TARGET_BIG_SYM 298 #define TARGET_BIG_SYM bfd_elf32_sparc_vxworks_vec 299 #undef TARGET_BIG_NAME 300 #define TARGET_BIG_NAME "elf32-sparc-vxworks" 301 302 #undef ELF_MINPAGESIZE 303 #define ELF_MINPAGESIZE 0x1000 304 305 #undef bfd_elf32_bfd_link_hash_table_create 306 #define bfd_elf32_bfd_link_hash_table_create \ 307 elf32_sparc_vxworks_link_hash_table_create 308 309 #undef elf_backend_want_got_plt 310 #define elf_backend_want_got_plt 1 311 #undef elf_backend_plt_readonly 312 #define elf_backend_plt_readonly 1 313 #undef elf_backend_got_header_size 314 #define elf_backend_got_header_size 12 315 #undef elf_backend_add_symbol_hook 316 #define elf_backend_add_symbol_hook \ 317 elf_vxworks_add_symbol_hook 318 #undef elf_backend_link_output_symbol_hook 319 #define elf_backend_link_output_symbol_hook \ 320 elf_vxworks_link_output_symbol_hook 321 #undef elf_backend_emit_relocs 322 #define elf_backend_emit_relocs \ 323 elf_vxworks_emit_relocs 324 #undef elf_backend_final_write_processing 325 #define elf_backend_final_write_processing \ 326 elf32_sparc_vxworks_final_write_processing 327 #undef elf_backend_static_tls_alignment 328 329 #undef elf32_bed 330 #define elf32_bed sparc_elf_vxworks_bed 331 332 #include "elf32-target.h" 333