Back to index

cell-binutils  2.17cvs20070401
elf32-sparc.c
Go to the documentation of this file.
00001 /* SPARC-specific support for 32-bit ELF
00002    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
00003    2003, 2004, 2005, 2007 Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "bfdlink.h"
00024 #include "libbfd.h"
00025 #include "elf-bfd.h"
00026 #include "elf/sparc.h"
00027 #include "opcode/sparc.h"
00028 #include "elfxx-sparc.h"
00029 #include "elf-vxworks.h"
00030 
00031 /* Support for core dump NOTE sections.  */
00032 
00033 static bfd_boolean
00034 elf32_sparc_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
00035 {
00036   switch (note->descsz)
00037     {
00038     default:
00039       return FALSE;
00040 
00041     case 260:               /* Solaris prpsinfo_t.  */
00042       elf_tdata (abfd)->core_program
00043        = _bfd_elfcore_strndup (abfd, note->descdata + 84, 16);
00044       elf_tdata (abfd)->core_command
00045        = _bfd_elfcore_strndup (abfd, note->descdata + 100, 80);
00046       break;
00047 
00048     case 336:               /* Solaris psinfo_t.  */
00049       elf_tdata (abfd)->core_program
00050        = _bfd_elfcore_strndup (abfd, note->descdata + 88, 16);
00051       elf_tdata (abfd)->core_command
00052        = _bfd_elfcore_strndup (abfd, note->descdata + 104, 80);
00053       break;
00054     }
00055 
00056   return TRUE;
00057 }
00058 
00059 /* Functions for dealing with the e_flags field.
00060 
00061    We don't define set_private_flags or copy_private_bfd_data because
00062    the only currently defined values are based on the bfd mach number,
00063    so we use the latter instead and defer setting e_flags until the
00064    file is written out.  */
00065 
00066 /* Merge backend specific data from an object file to the output
00067    object file when linking.  */
00068 
00069 static bfd_boolean
00070 elf32_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
00071 {
00072   bfd_boolean error;
00073   unsigned long ibfd_mach;
00074   /* FIXME: This should not be static.  */
00075   static unsigned long previous_ibfd_e_flags = (unsigned long) -1;
00076 
00077   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00078       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00079     return TRUE;
00080 
00081   error = FALSE;
00082 
00083   ibfd_mach = bfd_get_mach (ibfd);
00084   if (bfd_mach_sparc_64bit_p (ibfd_mach))
00085     {
00086       error = TRUE;
00087       (*_bfd_error_handler)
00088        (_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd);
00089     }
00090   else if ((ibfd->flags & DYNAMIC) == 0)
00091     {
00092       if (bfd_get_mach (obfd) < ibfd_mach)
00093        bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach);
00094     }
00095 
00096   if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
00097        != previous_ibfd_e_flags)
00098       && previous_ibfd_e_flags != (unsigned long) -1)
00099     {
00100       (*_bfd_error_handler)
00101        (_("%B: linking little endian files with big endian files"), ibfd);
00102       error = TRUE;
00103     }
00104   previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA;
00105 
00106   if (error)
00107     {
00108       bfd_set_error (bfd_error_bad_value);
00109       return FALSE;
00110     }
00111 
00112   return TRUE;
00113 }
00114 
00115 /* The final processing done just before writing out the object file.
00116    We need to set the e_machine field appropriately.  */
00117 
00118 static void
00119 elf32_sparc_final_write_processing (bfd *abfd,
00120                                 bfd_boolean linker ATTRIBUTE_UNUSED)
00121 {
00122   switch (bfd_get_mach (abfd))
00123     {
00124     case bfd_mach_sparc :
00125     case bfd_mach_sparc_sparclet :
00126     case bfd_mach_sparc_sparclite :
00127       break; /* nothing to do */
00128     case bfd_mach_sparc_v8plus :
00129       elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
00130       elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
00131       elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS;
00132       break;
00133     case bfd_mach_sparc_v8plusa :
00134       elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
00135       elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
00136       elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
00137       break;
00138     case bfd_mach_sparc_v8plusb :
00139       elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
00140       elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
00141       elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1
00142                                    | EF_SPARC_SUN_US3;
00143       break;
00144     case bfd_mach_sparc_sparclite_le :
00145       elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA;
00146       break;
00147     default :
00148       abort ();
00149       break;
00150     }
00151 }
00152 
00153 static enum elf_reloc_type_class
00154 elf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
00155 {
00156   switch ((int) ELF32_R_TYPE (rela->r_info))
00157     {
00158     case R_SPARC_RELATIVE:
00159       return reloc_class_relative;
00160     case R_SPARC_JMP_SLOT:
00161       return reloc_class_plt;
00162     case R_SPARC_COPY:
00163       return reloc_class_copy;
00164     default:
00165       return reloc_class_normal;
00166     }
00167 }
00168 
00169 #define TARGET_BIG_SYM      bfd_elf32_sparc_vec
00170 #define TARGET_BIG_NAME     "elf32-sparc"
00171 #define ELF_ARCH     bfd_arch_sparc
00172 #define ELF_MACHINE_CODE EM_SPARC
00173 #define ELF_MACHINE_ALT1 EM_SPARC32PLUS
00174 #define ELF_MAXPAGESIZE 0x10000
00175 #define ELF_COMMONPAGESIZE 0x2000
00176 
00177 #define bfd_elf32_bfd_merge_private_bfd_data \
00178                                    elf32_sparc_merge_private_bfd_data
00179 #define elf_backend_final_write_processing \
00180                                    elf32_sparc_final_write_processing
00181 #define elf_backend_grok_psinfo           elf32_sparc_grok_psinfo
00182 #define elf_backend_reloc_type_class      elf32_sparc_reloc_type_class
00183 
00184 #define elf_info_to_howto          _bfd_sparc_elf_info_to_howto
00185 #define bfd_elf32_bfd_reloc_type_lookup   _bfd_sparc_elf_reloc_type_lookup
00186 #define bfd_elf32_bfd_reloc_name_lookup \
00187   _bfd_sparc_elf_reloc_name_lookup
00188 #define bfd_elf32_bfd_link_hash_table_create \
00189                                    _bfd_sparc_elf_link_hash_table_create
00190 #define bfd_elf32_bfd_relax_section       _bfd_sparc_elf_relax_section
00191 #define bfd_elf32_new_section_hook _bfd_sparc_elf_new_section_hook
00192 #define elf_backend_copy_indirect_symbol \
00193                                    _bfd_sparc_elf_copy_indirect_symbol
00194 #define elf_backend_create_dynamic_sections \
00195                                    _bfd_sparc_elf_create_dynamic_sections
00196 #define elf_backend_check_relocs   _bfd_sparc_elf_check_relocs
00197 #define elf_backend_adjust_dynamic_symbol \
00198                                    _bfd_sparc_elf_adjust_dynamic_symbol
00199 #define elf_backend_omit_section_dynsym   _bfd_sparc_elf_omit_section_dynsym
00200 #define elf_backend_size_dynamic_sections \
00201                                    _bfd_sparc_elf_size_dynamic_sections
00202 #define elf_backend_relocate_section      _bfd_sparc_elf_relocate_section
00203 #define elf_backend_finish_dynamic_symbol \
00204                                    _bfd_sparc_elf_finish_dynamic_symbol
00205 #define elf_backend_finish_dynamic_sections \
00206                                    _bfd_sparc_elf_finish_dynamic_sections
00207 #define bfd_elf32_mkobject         _bfd_sparc_elf_mkobject
00208 #define elf_backend_object_p              _bfd_sparc_elf_object_p
00209 #define elf_backend_gc_mark_hook   _bfd_sparc_elf_gc_mark_hook
00210 #define elf_backend_gc_sweep_hook       _bfd_sparc_elf_gc_sweep_hook
00211 #define elf_backend_plt_sym_val           _bfd_sparc_elf_plt_sym_val
00212 #define elf_backend_init_index_section    _bfd_elf_init_1_index_section
00213 
00214 #define elf_backend_can_gc_sections 1
00215 #define elf_backend_can_refcount 1
00216 #define elf_backend_want_got_plt 0
00217 #define elf_backend_plt_readonly 0
00218 #define elf_backend_want_plt_sym 1
00219 #define elf_backend_got_header_size 4
00220 #define elf_backend_rela_normal 1
00221 
00222 #include "elf32-target.h"
00223 
00224 /* A wrapper around _bfd_sparc_elf_link_hash_table_create that identifies
00225    the target system as VxWorks.  */
00226 
00227 static struct bfd_link_hash_table *
00228 elf32_sparc_vxworks_link_hash_table_create (bfd *abfd)
00229 {
00230   struct bfd_link_hash_table *ret;
00231 
00232   ret = _bfd_sparc_elf_link_hash_table_create (abfd);
00233   if (ret)
00234     {
00235       struct _bfd_sparc_elf_link_hash_table *htab;
00236 
00237       htab = (struct _bfd_sparc_elf_link_hash_table *) ret;
00238       htab->is_vxworks = 1;
00239     }
00240   return ret;
00241 }
00242 
00243 /* A final_write_processing hook that does both the SPARC- and VxWorks-
00244    specific handling.  */
00245 
00246 static void
00247 elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
00248 {
00249   elf32_sparc_final_write_processing (abfd, linker);
00250   elf_vxworks_final_write_processing (abfd, linker);
00251 }
00252 
00253 #undef TARGET_BIG_SYM
00254 #define TARGET_BIG_SYM      bfd_elf32_sparc_vxworks_vec
00255 #undef TARGET_BIG_NAME
00256 #define TARGET_BIG_NAME     "elf32-sparc-vxworks"
00257 
00258 #undef ELF_MINPAGESIZE
00259 #define ELF_MINPAGESIZE     0x1000
00260 
00261 #undef bfd_elf32_bfd_link_hash_table_create
00262 #define bfd_elf32_bfd_link_hash_table_create \
00263   elf32_sparc_vxworks_link_hash_table_create
00264 
00265 #undef elf_backend_want_got_plt
00266 #define elf_backend_want_got_plt          1
00267 #undef elf_backend_plt_readonly
00268 #define elf_backend_plt_readonly          1
00269 #undef elf_backend_got_header_size
00270 #define elf_backend_got_header_size              12
00271 #undef elf_backend_add_symbol_hook
00272 #define elf_backend_add_symbol_hook \
00273   elf_vxworks_add_symbol_hook
00274 #undef elf_backend_link_output_symbol_hook
00275 #define elf_backend_link_output_symbol_hook \
00276   elf_vxworks_link_output_symbol_hook
00277 #undef elf_backend_emit_relocs
00278 #define elf_backend_emit_relocs \
00279   elf_vxworks_emit_relocs
00280 #undef elf_backend_final_write_processing
00281 #define elf_backend_final_write_processing \
00282   elf32_sparc_vxworks_final_write_processing
00283 
00284 #undef elf32_bed
00285 #define elf32_bed                         sparc_elf_vxworks_bed
00286 
00287 #include "elf32-target.h"