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