/[gcl]/gcl/binutils/bfd/elf32-sh64.c
ViewVC logotype

Diff of /gcl/binutils/bfd/elf32-sh64.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:36:02 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:12 2005 UTC
# Line 1  Line 1 
1  /* Hitachi SH64-specific support for 32-bit ELF  /* SuperH SH64-specific support for 32-bit ELF
2     Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.     Copyright 2000, 2001, 2002, 2003, 2004, 2005
3       Free Software Foundation, Inc.
4    
5     This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
6    
# Line 23  Line 24 
24  #include "sysdep.h"  #include "sysdep.h"
25  #include "elf-bfd.h"  #include "elf-bfd.h"
26  #include "../opcodes/sh64-opc.h"  #include "../opcodes/sh64-opc.h"
27    #include "elf32-sh64.h"
28    
29  /* Add a suffix for datalabel indirection symbols.  It must not match any  /* Add a suffix for datalabel indirection symbols.  It must not match any
30     other symbols; user symbols with or without version or other     other symbols; user symbols with or without version or other
# Line 37  struct sh64_find_section_vma_data Line 39  struct sh64_find_section_vma_data
39     bfd_vma addr;     bfd_vma addr;
40   };   };
41    
42  static boolean sh64_elf_copy_private_data PARAMS ((bfd *, bfd *));  static bfd_boolean sh64_elf_new_section_hook
43  static boolean sh64_elf_merge_private_data PARAMS ((bfd *, bfd *));    (bfd *, asection *);
44  static boolean sh64_elf_fake_sections PARAMS ((bfd *, Elf_Internal_Shdr *,  static bfd_boolean sh64_elf_copy_private_data
45                                                asection *));    (bfd *, bfd *);
46  static boolean sh64_elf_set_private_flags PARAMS ((bfd *, flagword));  static bfd_boolean sh64_elf_merge_private_data
47  static boolean sh64_elf_set_mach_from_flags PARAMS ((bfd *));    (bfd *, bfd *);
48  static boolean shmedia_prepare_reloc  static bfd_boolean sh64_elf_fake_sections
49    PARAMS ((struct bfd_link_info *, bfd *, asection *,    (bfd *, Elf_Internal_Shdr *, asection *);
50             bfd_byte *, const Elf_Internal_Rela *, bfd_vma *));  static bfd_boolean sh64_elf_set_private_flags
51  static int sh64_elf_get_symbol_type PARAMS ((Elf_Internal_Sym *, int));    (bfd *, flagword);
52  static boolean sh64_elf_add_symbol_hook  static bfd_boolean sh64_elf_set_mach_from_flags
53    PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,    (bfd *);
54             const char **, flagword *, asection **, bfd_vma *));  static bfd_boolean shmedia_prepare_reloc
55  static boolean sh64_elf_link_output_symbol_hook    (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
56    PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,     const Elf_Internal_Rela *, bfd_vma *);
57             asection *));  static int sh64_elf_get_symbol_type
58  static boolean sh64_backend_section_from_shdr    (Elf_Internal_Sym *, int);
59    PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));  static bfd_boolean sh64_elf_add_symbol_hook
60  static void sh64_elf_final_write_processing PARAMS ((bfd *, boolean));    (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
61  static boolean sh64_bfd_elf_copy_private_section_data     flagword *, asection **, bfd_vma *);
62    PARAMS ((bfd *, asection *, bfd *, asection *));  static bfd_boolean sh64_elf_link_output_symbol_hook
63  static void sh64_find_section_for_address PARAMS ((bfd *, asection *, PTR));    (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
64       struct elf_link_hash_entry *);
65    static bfd_boolean sh64_backend_section_from_shdr
66      (bfd *, Elf_Internal_Shdr *, const char *);
67    static void sh64_elf_final_write_processing
68      (bfd *, bfd_boolean);
69    static bfd_boolean sh64_bfd_elf_copy_private_section_data
70      (bfd *, asection *, bfd *, asection *);
71    static void sh64_find_section_for_address
72      (bfd *, asection *, void *);
73    
74  /* Let elf32-sh.c handle the "bfd_" definitions, so we only have to  /* Let elf32-sh.c handle the "bfd_" definitions, so we only have to
75     intrude with an #ifndef around the function definition.  */     intrude with an #ifndef around the function definition.  */
# Line 75  static void sh64_find_section_for_addres Line 86  static void sh64_find_section_for_addres
86  #define elf_backend_add_symbol_hook             sh64_elf_add_symbol_hook  #define elf_backend_add_symbol_hook             sh64_elf_add_symbol_hook
87  #define elf_backend_link_output_symbol_hook \  #define elf_backend_link_output_symbol_hook \
88          sh64_elf_link_output_symbol_hook          sh64_elf_link_output_symbol_hook
89    #define elf_backend_merge_symbol_attribute      sh64_elf_merge_symbol_attribute
90  #define elf_backend_final_write_processing      sh64_elf_final_write_processing  #define elf_backend_final_write_processing      sh64_elf_final_write_processing
91  #define elf_backend_section_from_shdr           sh64_backend_section_from_shdr  #define elf_backend_section_from_shdr           sh64_backend_section_from_shdr
92    #define elf_backend_special_sections            sh64_elf_special_sections
93    #define elf_backend_section_flags               sh64_elf_section_flags
94    
95    #define bfd_elf32_new_section_hook              sh64_elf_new_section_hook
96    
97  /* For objcopy, we need to set up sh64_elf_section_data (asection *) from  /* For objcopy, we need to set up sh64_elf_section_data (asection *) from
98     incoming section flags.  This is otherwise done in sh64elf.em when     incoming section flags.  This is otherwise done in sh64elf.em when
# Line 85  static void sh64_find_section_for_addres Line 101  static void sh64_find_section_for_addres
101          sh64_bfd_elf_copy_private_section_data          sh64_bfd_elf_copy_private_section_data
102    
103  /* This COFF-only function (only compiled with COFF support, making  /* This COFF-only function (only compiled with COFF support, making
104     ELF-only chains problematic) returns true early for SH4, so let's just     ELF-only chains problematic) returns TRUE early for SH4, so let's just
105     define it true here.  */     define it TRUE here.  */
106  #define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) true  #define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) TRUE
   
 #ifndef ELF_ARCH  
 #define TARGET_BIG_SYM          bfd_elf32_sh64_vec  
 #define TARGET_BIG_NAME         "elf32-sh64"  
 #define TARGET_LITTLE_SYM       bfd_elf32_sh64l_vec  
 #define TARGET_LITTLE_NAME      "elf32-sh64l"  
 #define ELF_ARCH                bfd_arch_sh  
 #define ELF_MACHINE_CODE        EM_SH  
 #define ELF_MAXPAGESIZE         128  
   
 #define elf_symbol_leading_char '_'  
 #endif /* ELF_ARCH */  
107    
108  #define GOT_BIAS (-((long)-32768))  #define GOT_BIAS (-((long)-32768))
109  #define INCLUDE_SHMEDIA  #define INCLUDE_SHMEDIA
110    #define SH_TARGET_ALREADY_DEFINED
111  #include "elf32-sh.c"  #include "elf32-sh.c"
112    
113    /* Tack some extra info on struct bfd_elf_section_data.  */
114    
115    static bfd_boolean
116    sh64_elf_new_section_hook (bfd *abfd, asection *sec)
117    {
118      struct _sh64_elf_section_data *sdata;
119      bfd_size_type amt = sizeof (*sdata);
120    
121      sdata = (struct _sh64_elf_section_data *) bfd_zalloc (abfd, amt);
122      if (sdata == NULL)
123        return FALSE;
124      sec->used_by_bfd = sdata;
125    
126      return _bfd_elf_new_section_hook (abfd, sec);
127    }
128    
129  /* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass  /* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
130     through SHT_SH5_CR_SORTED on a sorted .cranges section.  */     through SHT_SH5_CR_SORTED on a sorted .cranges section.  */
131    
132  boolean  bfd_boolean
133  sh64_elf_fake_sections (output_bfd, elf_section_hdr, asect)  sh64_elf_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
134       bfd *output_bfd ATTRIBUTE_UNUSED;                          Elf_Internal_Shdr *elf_section_hdr,
135       Elf_Internal_Shdr *elf_section_hdr;                          asection *asect)
      asection *asect;  
136  {  {
137    if (sh64_elf_section_data (asect) != NULL)    if (sh64_elf_section_data (asect)->sh64_info != NULL)
138      elf_section_hdr->sh_flags      elf_section_hdr->sh_flags
139        |= sh64_elf_section_data (asect)->contents_flags;        |= sh64_elf_section_data (asect)->sh64_info->contents_flags;
140    
141    /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted    /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted
142       .cranges section passing through objcopy.  */       .cranges section passing through objcopy.  */
# Line 125  sh64_elf_fake_sections (output_bfd, elf_ Line 145  sh64_elf_fake_sections (output_bfd, elf_
145                   SH64_CRANGES_SECTION_NAME) == 0)                   SH64_CRANGES_SECTION_NAME) == 0)
146      elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;      elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;
147    
148    return true;    return TRUE;
149  }  }
150    
151  static boolean  static bfd_boolean
152  sh64_elf_set_mach_from_flags (abfd)  sh64_elf_set_mach_from_flags (bfd *abfd)
      bfd *abfd;  
153  {  {
154    flagword flags = elf_elfheader (abfd)->e_flags;    flagword flags = elf_elfheader (abfd)->e_flags;
   asection *cranges;  
155    
156    switch (flags & EF_SH_MACH_MASK)    switch (flags & EF_SH_MACH_MASK)
157      {      {
# Line 145  sh64_elf_set_mach_from_flags (abfd) Line 163  sh64_elf_set_mach_from_flags (abfd)
163    
164      default:      default:
165        bfd_set_error (bfd_error_wrong_format);        bfd_set_error (bfd_error_wrong_format);
166        return false;        return FALSE;
167      }      }
168    
169    /* We also need to set SEC_DEBUGGING on an incoming .cranges section.    return TRUE;
170       We could have used elf_backend_section_flags if it had given us the  }
171       section name; the bfd_section member in the header argument is not  
172       set at the point of the call.  FIXME: Find out whether that is by  static bfd_boolean
173       undocumented design or a bug.  */  sh64_elf_section_flags (flagword *flags,
174    cranges = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);                          const Elf_Internal_Shdr *hdr)
175    if (cranges != NULL  {
176        && ! bfd_set_section_flags (abfd, cranges,    if (hdr->bfd_section == NULL)
177                                    bfd_get_section_flags (abfd, cranges)      return FALSE;
178                                    | SEC_DEBUGGING))  
179      return false;    if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
180        *flags |= SEC_DEBUGGING;
181    return true;  
182  }    return TRUE;
183    }
184  static boolean  
185  sh64_elf_copy_private_data (ibfd, obfd)  static bfd_boolean
186       bfd * ibfd;  sh64_elf_copy_private_data (bfd * ibfd, bfd * obfd)
      bfd * obfd;  
187  {  {
188    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
189        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
190      return true;      return TRUE;
191    
192    BFD_ASSERT (!elf_flags_init (obfd)    BFD_ASSERT (!elf_flags_init (obfd)
193                || (elf_elfheader (obfd)->e_flags                || (elf_elfheader (obfd)->e_flags
194                    == elf_elfheader (ibfd)->e_flags));                    == elf_elfheader (ibfd)->e_flags));
195    
196    elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;    elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
197    return true;    return TRUE;
198  }  }
199    
200  static boolean  static bfd_boolean
201  sh64_elf_merge_private_data (ibfd, obfd)  sh64_elf_merge_private_data (bfd *ibfd, bfd *obfd)
      bfd *ibfd;  
      bfd *obfd;  
202  {  {
203    flagword old_flags, new_flags;    flagword old_flags, new_flags;
204    
205    if (! _bfd_generic_verify_endian_match (ibfd, obfd))    if (! _bfd_generic_verify_endian_match (ibfd, obfd))
206      return false;      return FALSE;
207    
208    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
209        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
210      return true;      return TRUE;
211    
212    if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))    if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
213      {      {
# Line 210  sh64_elf_merge_private_data (ibfd, obfd) Line 225  sh64_elf_merge_private_data (ibfd, obfd)
225        (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),        (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
226                               bfd_get_filename (obfd));                               bfd_get_filename (obfd));
227        bfd_set_error (bfd_error_wrong_format);        bfd_set_error (bfd_error_wrong_format);
228        return false;        return FALSE;
229      }      }
230    
231    old_flags = elf_elfheader (obfd)->e_flags;    old_flags = elf_elfheader (obfd)->e_flags;
# Line 218  sh64_elf_merge_private_data (ibfd, obfd) Line 233  sh64_elf_merge_private_data (ibfd, obfd)
233    if (! elf_flags_init (obfd))    if (! elf_flags_init (obfd))
234      {      {
235        /* This happens when ld starts out with a 'blank' output file.  */        /* This happens when ld starts out with a 'blank' output file.  */
236        elf_flags_init (obfd) = true;        elf_flags_init (obfd) = TRUE;
237        elf_elfheader (obfd)->e_flags = old_flags = new_flags;        elf_elfheader (obfd)->e_flags = old_flags = new_flags;
238      }      }
239    /* We don't allow linking in non-SH64 code.  */    /* We don't allow linking in non-SH64 code.  */
# Line 228  sh64_elf_merge_private_data (ibfd, obfd) Line 243  sh64_elf_merge_private_data (ibfd, obfd)
243          ("%s: uses non-SH64 instructions while previous modules use SH64 instructions",          ("%s: uses non-SH64 instructions while previous modules use SH64 instructions",
244           bfd_get_filename (ibfd));           bfd_get_filename (ibfd));
245        bfd_set_error (bfd_error_bad_value);        bfd_set_error (bfd_error_bad_value);
246        return false;        return FALSE;
247      }      }
248    
249    /* I can't think of anything sane other than old_flags being EF_SH5 and    /* I can't think of anything sane other than old_flags being EF_SH5 and
# Line 242  sh64_elf_merge_private_data (ibfd, obfd) Line 257  sh64_elf_merge_private_data (ibfd, obfd)
257    
258     We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */     We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */
259    
260  boolean  bfd_boolean
261  sh64_backend_section_from_shdr (abfd, hdr, name)  sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
262       bfd *abfd;                                  const char *name)
      Elf_Internal_Shdr *hdr;  
      const char *name;  
263  {  {
264    flagword flags = 0;    flagword flags = 0;
265    
266    /* We do like MIPS with a bit switch for recognized types, and returning    /* We do like MIPS with a bit switch for recognized types, and returning
267       false for a recognized section type with an unexpected name.  Right       FALSE for a recognized section type with an unexpected name.  Right
268       now we only have one recognized type, but that might change.  */       now we only have one recognized type, but that might change.  */
269    switch (hdr->sh_type)    switch (hdr->sh_type)
270      {      {
271      case SHT_SH5_CR_SORTED:      case SHT_SH5_CR_SORTED:
272        if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)        if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)
273          return false;          return FALSE;
274    
275        /* We set the SEC_SORT_ENTRIES flag so it can be passed on to        /* We set the SEC_SORT_ENTRIES flag so it can be passed on to
276           sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object           sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object
# Line 268  sh64_backend_section_from_shdr (abfd, hd Line 281  sh64_backend_section_from_shdr (abfd, hd
281        break;        break;
282    
283      default:      default:
284        return false;        return FALSE;
285      }      }
286    
287    if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))    if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
288      return false;      return FALSE;
289    
290    if (flags    if (flags
291        && ! bfd_set_section_flags (abfd, hdr->bfd_section,        && ! bfd_set_section_flags (abfd, hdr->bfd_section,
292                                    bfd_get_section_flags (abfd,                                    bfd_get_section_flags (abfd,
293                                                           hdr->bfd_section)                                                           hdr->bfd_section)
294                                    | flags))                                    | flags))
295      return false;      return FALSE;
296    
297    return true;    return TRUE;
298  }  }
299    
300  /* In contrast to sh64_backend_section_from_shdr, this is called for all  /* In contrast to sh64_backend_section_from_shdr, this is called for all
# Line 289  sh64_backend_section_from_shdr (abfd, hd Line 302  sh64_backend_section_from_shdr (abfd, hd
302     assembling.  We need to set up the sh64_elf_section_data (asection *)     assembling.  We need to set up the sh64_elf_section_data (asection *)
303     structure for the SH64 ELF section flags to be copied correctly.  */     structure for the SH64 ELF section flags to be copied correctly.  */
304    
305  boolean  bfd_boolean
306  sh64_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)  sh64_bfd_elf_copy_private_section_data (bfd *ibfd, asection *isec,
307       bfd *ibfd;                                          bfd *obfd, asection *osec)
      asection *isec;  
      bfd *obfd;  
      asection *osec;  
308  {  {
309    struct sh64_section_data *sh64_sec_data;    struct sh64_section_data *sh64_sec_data;
310    
311    if (ibfd->xvec->flavour != bfd_target_elf_flavour    if (ibfd->xvec->flavour != bfd_target_elf_flavour
312        || obfd->xvec->flavour != bfd_target_elf_flavour)        || obfd->xvec->flavour != bfd_target_elf_flavour)
313      return true;      return TRUE;
314    
315    if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))    if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
316      return false;      return FALSE;
317    
318    sh64_sec_data = sh64_elf_section_data (isec);    sh64_sec_data = sh64_elf_section_data (isec)->sh64_info;
319    if (sh64_sec_data == NULL)    if (sh64_sec_data == NULL)
320      {      {
321        sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));        sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));
322    
323        if (sh64_sec_data == NULL)        if (sh64_sec_data == NULL)
324          return false;          return FALSE;
325    
326        sh64_sec_data->contents_flags        sh64_sec_data->contents_flags
327          = (elf_section_data (isec)->this_hdr.sh_flags          = (elf_section_data (isec)->this_hdr.sh_flags
328             & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));             & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));
329    
330        sh64_elf_section_data (osec) = sh64_sec_data;        sh64_elf_section_data (osec)->sh64_info = sh64_sec_data;
331      }      }
332    
333    return true;    return TRUE;
334  }  }
335    
336  /* Function to keep SH64 specific file flags.  */  /* Function to keep SH64 specific file flags.  */
337    
338  static boolean  static bfd_boolean
339  sh64_elf_set_private_flags (abfd, flags)  sh64_elf_set_private_flags (bfd *abfd, flagword flags)
      bfd *    abfd;  
      flagword flags;  
340  {  {
341    BFD_ASSERT (! elf_flags_init (abfd)    BFD_ASSERT (! elf_flags_init (abfd)
342                || elf_elfheader (abfd)->e_flags == flags);                || elf_elfheader (abfd)->e_flags == flags);
343    
344    elf_elfheader (abfd)->e_flags = flags;    elf_elfheader (abfd)->e_flags = flags;
345    elf_flags_init (abfd) = true;    elf_flags_init (abfd) = TRUE;
346    return sh64_elf_set_mach_from_flags (abfd);    return sh64_elf_set_mach_from_flags (abfd);
347  }  }
348    
349  /* Called when writing out an object file to decide the type of a symbol.  */  /* Called when writing out an object file to decide the type of a symbol.  */
350    
351  static int  static int
352  sh64_elf_get_symbol_type (elf_sym, type)  sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
      Elf_Internal_Sym * elf_sym;  
      int type;  
353  {  {
354    if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)    if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
355      return STT_DATALABEL;      return STT_DATALABEL;
# Line 369  sh64_elf_get_symbol_type (elf_sym, type) Line 375  sh64_elf_get_symbol_type (elf_sym, type)
375     or the hash entry, alternatively adding the index to Elf_Internal_Sym     or the hash entry, alternatively adding the index to Elf_Internal_Sym
376     (not so good).  */     (not so good).  */
377    
378  static boolean  static bfd_boolean
379  sh64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)  sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
380       bfd *abfd;                            Elf_Internal_Sym *sym, const char **namep,
381       struct bfd_link_info *info;                            flagword *flagsp ATTRIBUTE_UNUSED,
382       const Elf_Internal_Sym *sym;                            asection **secp, bfd_vma *valp)
      const char **namep;  
      flagword *flagsp ATTRIBUTE_UNUSED;  
      asection **secp;  
      bfd_vma *valp;  
383  {  {
384    /* We want to do this for relocatable as well as final linking.  */    /* We want to do this for relocatable as well as final linking.  */
385    if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL    if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
386        && info->hash->creator->flavour == bfd_target_elf_flavour)        && is_elf_hash_table (info->hash))
387      {      {
388        struct elf_link_hash_entry *h;        struct elf_link_hash_entry *h;
389    
390        /* For relocateable links, we register the DataLabel sym in its own        /* For relocatable links, we register the DataLabel sym in its own
391           right, and tweak the name when it's output.  Otherwise, we make           right, and tweak the name when it's output.  Otherwise, we make
392           an indirect symbol of it.  */           an indirect symbol of it.  */
393        flagword flags        flagword flags
394          = info->relocateable || info->emitrelocations          = info->relocatable || info->emitrelocations
395          ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;          ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
396    
397        char *dl_name        char *dl_name
# Line 400  sh64_elf_add_symbol_hook (abfd, info, sy Line 402  sh64_elf_add_symbol_hook (abfd, info, sy
402    
403        /* Allocation may fail.  */        /* Allocation may fail.  */
404        if (dl_name == NULL)        if (dl_name == NULL)
405          return false;          return FALSE;
406    
407        strcpy (dl_name, *namep);        strcpy (dl_name, *namep);
408        strcat (dl_name, DATALABEL_SUFFIX);        strcat (dl_name, DATALABEL_SUFFIX);
409    
410        h = (struct elf_link_hash_entry *)        h = (struct elf_link_hash_entry *)
411          bfd_link_hash_lookup (info->hash, dl_name, false, false, false);          bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
412    
413        if (h == NULL)        if (h == NULL)
414          {          {
415            /* No previous datalabel symbol.  Make one.  */            /* No previous datalabel symbol.  Make one.  */
416              struct bfd_link_hash_entry *bh = NULL;
417              const struct elf_backend_data *bed = get_elf_backend_data (abfd);
418    
419            if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,            if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
420                                                    flags, *secp, *valp,                                                    flags, *secp, *valp,
421                                                    *namep, false,                                                    *namep, FALSE,
422                                                    get_elf_backend_data (abfd)->collect,                                                    bed->collect, &bh))
                                                   (struct bfd_link_hash_entry **) &h))  
423              {              {
424                free (dl_name);                free (dl_name);
425                return false;                return FALSE;
426              }              }
427    
428            h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;            h = (struct elf_link_hash_entry *) bh;
429              h->non_elf = 0;
430            h->type = STT_DATALABEL;            h->type = STT_DATALABEL;
431          }          }
432        else        else
# Line 430  sh64_elf_add_symbol_hook (abfd, info, sy Line 435  sh64_elf_add_symbol_hook (abfd, info, sy
435          free (dl_name);          free (dl_name);
436    
437        if (h->type != STT_DATALABEL        if (h->type != STT_DATALABEL
438            || ((info->relocateable || info->emitrelocations)            || ((info->relocatable || info->emitrelocations)
439                && h->root.type != bfd_link_hash_undefined)                && h->root.type != bfd_link_hash_undefined)
440            || (! info->relocateable && !info->emitrelocations            || (! info->relocatable && !info->emitrelocations
441                && h->root.type != bfd_link_hash_indirect))                && h->root.type != bfd_link_hash_indirect))
442          {          {
443            /* Make sure we don't get confused on invalid input.  */            /* Make sure we don't get confused on invalid input.  */
# Line 440  sh64_elf_add_symbol_hook (abfd, info, sy Line 445  sh64_elf_add_symbol_hook (abfd, info, sy
445              (_("%s: encountered datalabel symbol in input"),              (_("%s: encountered datalabel symbol in input"),
446               bfd_get_filename (abfd));               bfd_get_filename (abfd));
447            bfd_set_error (bfd_error_bad_value);            bfd_set_error (bfd_error_bad_value);
448            return false;            return FALSE;
449          }          }
450    
451        /* Now find the hash-table slot for this entry and fill it in.  */        /* Now find the hash-table slot for this entry and fill it in.  */
# Line 452  sh64_elf_add_symbol_hook (abfd, info, sy Line 457  sh64_elf_add_symbol_hook (abfd, info, sy
457        *namep = NULL;        *namep = NULL;
458      }      }
459    
460    return true;    return TRUE;
461  }  }
462    
463  /* This hook function is called before the linker writes out a global  /* This hook function is called before the linker writes out a global
# Line 467  sh64_elf_add_symbol_hook (abfd, info, sy Line 472  sh64_elf_add_symbol_hook (abfd, info, sy
472     we don't need to look up and make sure to emit the main symbol for each     we don't need to look up and make sure to emit the main symbol for each
473     DataLabel symbol.  */     DataLabel symbol.  */
474    
475  boolean  bfd_boolean
476  sh64_elf_link_output_symbol_hook (abfd, info, cname, sym, input_sec)  sh64_elf_link_output_symbol_hook (struct bfd_link_info *info,
477       bfd *abfd ATTRIBUTE_UNUSED;                                    const char *cname,
478       struct bfd_link_info *info;                                    Elf_Internal_Sym *sym,
479       const char *cname;                                    asection *input_sec ATTRIBUTE_UNUSED,
480       Elf_Internal_Sym *sym;                                    struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
      asection *input_sec ATTRIBUTE_UNUSED;  
481  {  {
482    char *name = (char *) cname;    char *name = (char *) cname;
483    
484    if (info->relocateable || info->emitrelocations)    if (info->relocatable || info->emitrelocations)
485      {      {
486        if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)        if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
487          name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;          name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
488      }      }
489    
490    return true;    return TRUE;
491  }  }
492    
493  /* Check a SH64-specific reloc and put the value to relocate to into  /* Check a SH64-specific reloc and put the value to relocate to into
494     RELOCATION, ready to pass to _bfd_final_link_relocate.  Return FALSE if     RELOCATION, ready to pass to _bfd_final_link_relocate.  Return FALSE if
495     bad value, TRUE if ok.  */     bad value, TRUE if ok.  */
496    
497  static boolean  static bfd_boolean
498  shmedia_prepare_reloc (info, abfd, input_section,  shmedia_prepare_reloc (struct bfd_link_info *info, bfd *abfd,
499                         contents, rel, relocation)                         asection *input_section, bfd_byte *contents,
500       struct bfd_link_info *info;                         const Elf_Internal_Rela *rel, bfd_vma *relocation)
      bfd *abfd;  
      asection *input_section;  
      bfd_byte *contents;  
      const Elf_Internal_Rela *rel;  
      bfd_vma *relocation;  
501  {  {
502    bfd_vma disp, dropped;    bfd_vma disp, dropped;
503    
# Line 529  shmedia_prepare_reloc (info, abfd, input Line 528  shmedia_prepare_reloc (info, abfd, input
528                  && ! ((*info->callbacks->reloc_dangerous)                  && ! ((*info->callbacks->reloc_dangerous)
529                        (info, msg, abfd, input_section,                        (info, msg, abfd, input_section,
530                         rel->r_offset)))                         rel->r_offset)))
531                return false;                return FALSE;
532            }            }
533          else          else
534            {            {
# Line 543  shmedia_prepare_reloc (info, abfd, input Line 542  shmedia_prepare_reloc (info, abfd, input
542                  (*_bfd_error_handler)                  (*_bfd_error_handler)
543                    (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),                    (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),
544                     bfd_get_filename (input_section->owner));                     bfd_get_filename (input_section->owner));
545                  return false;                  return FALSE;
546                }                }
547    
548              /* Change the PTA to a PTB, if destination indicates so.  */              /* Change the PTA to a PTB, if destination indicates so.  */
# Line 576  shmedia_prepare_reloc (info, abfd, input Line 575  shmedia_prepare_reloc (info, abfd, input
575        break;        break;
576    
577      default:      default:
578        return false;        return FALSE;
579      }      }
580    
581    disp = (*relocation & 0xf);    disp = (*relocation & 0xf);
# Line 590  shmedia_prepare_reloc (info, abfd, input Line 589  shmedia_prepare_reloc (info, abfd, input
589    if (dropped != 0)    if (dropped != 0)
590      {      {
591        (*_bfd_error_handler)        (*_bfd_error_handler)
592          (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),          (_("%B: error: unaligned relocation type %d at %08x reloc %p\n"),
593           bfd_get_filename (input_section->owner), ELF32_R_TYPE (rel->r_info),           input_section->owner, ELF32_R_TYPE (rel->r_info),
594           (unsigned)rel->r_offset, (unsigned)relocation);           (unsigned) rel->r_offset, relocation);
595        return false;        return FALSE;
596      }      }
597    
598    return true;    return TRUE;
599  }  }
600    
601  /* Helper function to locate the section holding a certain address.  This  /* Helper function to locate the section holding a certain address.  This
602     is called via bfd_map_over_sections.  */     is called via bfd_map_over_sections.  */
603    
604  static void  static void
605  sh64_find_section_for_address (abfd, section, data)  sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
606       bfd *abfd ATTRIBUTE_UNUSED;                                 asection *section, void *data)
      asection *section;  
      PTR data;  
607  {  {
608    bfd_vma vma;    bfd_vma vma;
609    bfd_size_type size;    bfd_size_type size;
610    
611    struct sh64_find_section_vma_data *fsec_datap    struct sh64_find_section_vma_data *fsec_datap
612      = (struct sh64_find_section_vma_data *) data;      = (struct sh64_find_section_vma_data *) data;
613    
# Line 625  sh64_find_section_for_address (abfd, sec Line 623  sh64_find_section_for_address (abfd, sec
623    if (fsec_datap->addr < vma)    if (fsec_datap->addr < vma)
624      return;      return;
625    
626    /* FIXME: section->reloc_done isn't set properly; a generic buglet    size = section->size;
      preventing us from using bfd_get_section_size_after_reloc.  */  
   size  
     = section->_cooked_size ? section->_cooked_size : section->_raw_size;  
   
627    if (fsec_datap->addr >= vma + size)    if (fsec_datap->addr >= vma + size)
628      return;      return;
629    
# Line 642  sh64_find_section_for_address (abfd, sec Line 636  sh64_find_section_for_address (abfd, sec
636     executables (final linking and objcopy).  */     executables (final linking and objcopy).  */
637    
638  static void  static void
639  sh64_elf_final_write_processing (abfd, linker)  sh64_elf_final_write_processing (bfd *abfd,
640       bfd *   abfd;                                   bfd_boolean linker ATTRIBUTE_UNUSED)
      boolean linker ATTRIBUTE_UNUSED;  
641  {  {
642    bfd_vma ld_generated_cranges_size;    bfd_vma ld_generated_cranges_size;
643    asection *cranges    asection *cranges
# Line 658  sh64_elf_final_write_processing (abfd, l Line 651  sh64_elf_final_write_processing (abfd, l
651        && cranges != NULL        && cranges != NULL
652        && elf_elfheader (abfd)->e_type != ET_EXEC        && elf_elfheader (abfd)->e_type != ET_EXEC
653        && (ld_generated_cranges_size        && (ld_generated_cranges_size
654            = sh64_elf_section_data (cranges)->cranges_growth) != 0)            = sh64_elf_section_data (cranges)->sh64_info->cranges_growth) != 0)
655      {      {
656        bfd_vma incoming_cranges_size        bfd_vma incoming_cranges_size
657          = ((cranges->_cooked_size != 0          = cranges->size - ld_generated_cranges_size;
             ? cranges->_cooked_size : cranges->_raw_size)  
            - ld_generated_cranges_size);  
658    
659        if (! bfd_set_section_contents (abfd, cranges,        if (! bfd_set_section_contents (abfd, cranges,
660                                        cranges->contents                                        cranges->contents
# Line 696  sh64_elf_final_write_processing (abfd, l Line 687  sh64_elf_final_write_processing (abfd, l
687        fsec_data.section = NULL;        fsec_data.section = NULL;
688    
689        bfd_map_over_sections (abfd, sh64_find_section_for_address,        bfd_map_over_sections (abfd, sh64_find_section_for_address,
690                               (PTR) &fsec_data);                               &fsec_data);
691        if (fsec_data.section        if (fsec_data.section
692            && (sh64_get_contents_type (fsec_data.section,            && (sh64_get_contents_type (fsec_data.section,
693                                        elf_elfheader (abfd)->e_entry,                                        elf_elfheader (abfd)->e_entry,
# Line 706  sh64_elf_final_write_processing (abfd, l Line 697  sh64_elf_final_write_processing (abfd, l
697        /* If we have a .cranges section, sort the entries.  */        /* If we have a .cranges section, sort the entries.  */
698        if (cranges != NULL)        if (cranges != NULL)
699          {          {
700            bfd_size_type cranges_size            bfd_size_type cranges_size = cranges->size;
             = (cranges->_cooked_size != 0  
                ? cranges->_cooked_size : cranges->_raw_size);  
701    
702            /* We know we always have these in memory at this time.  */            /* We know we always have these in memory at this time.  */
703            BFD_ASSERT (cranges->contents != NULL);            BFD_ASSERT (cranges->contents != NULL);
# Line 742  sh64_elf_final_write_processing (abfd, l Line 731  sh64_elf_final_write_processing (abfd, l
731          }          }
732      }      }
733  }  }
734    
735    /* Merge non visibility st_other attribute when the symbol comes from
736       a dynamic object.  */
737    static void
738    sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
739                                     const Elf_Internal_Sym *isym,
740                                     bfd_boolean definition,
741                                     bfd_boolean dynamic)
742    {
743      if (isym->st_other != 0 && dynamic)
744        {
745          unsigned char other;
746    
747          /* Take the balance of OTHER from the definition.  */
748          other = (definition ? isym->st_other : h->other);
749          other &= ~ ELF_ST_VISIBILITY (-1);
750          h->other = other | ELF_ST_VISIBILITY (h->other);
751        }
752    
753      return;
754    }
755    
756    static struct bfd_elf_special_section const sh64_elf_special_sections[]=
757    {
758      { ".cranges", 8, 0, SHT_PROGBITS, 0 },
759      { NULL,       0, 0, 0,            0 }
760    };
761    
762    #undef  TARGET_BIG_SYM
763    #define TARGET_BIG_SYM          bfd_elf32_sh64_vec
764    #undef  TARGET_BIG_NAME
765    #define TARGET_BIG_NAME         "elf32-sh64"
766    #undef  TARGET_LITTLE_SYM
767    #define TARGET_LITTLE_SYM       bfd_elf32_sh64l_vec
768    #undef  TARGET_LITTLE_NAME
769    #define TARGET_LITTLE_NAME      "elf32-sh64l"
770    
771    #include "elf32-target.h"
772    
773    /* NetBSD support.  */
774    #undef  TARGET_BIG_SYM
775    #define TARGET_BIG_SYM          bfd_elf32_sh64nbsd_vec
776    #undef  TARGET_BIG_NAME
777    #define TARGET_BIG_NAME         "elf32-sh64-nbsd"
778    #undef  TARGET_LITTLE_SYM
779    #define TARGET_LITTLE_SYM       bfd_elf32_sh64lnbsd_vec
780    #undef  TARGET_LITTLE_NAME
781    #define TARGET_LITTLE_NAME      "elf32-sh64l-nbsd"
782    #undef  ELF_MAXPAGESIZE
783    #define ELF_MAXPAGESIZE         0x10000
784    #undef  elf_symbol_leading_char
785    #define elf_symbol_leading_char 0
786    #undef  elf32_bed
787    #define elf32_bed               elf32_sh64_nbsd_bed
788    
789    #include "elf32-target.h"
790    
791    /* Linux support.  */
792    #undef  TARGET_BIG_SYM
793    #define TARGET_BIG_SYM          bfd_elf32_sh64blin_vec
794    #undef  TARGET_BIG_NAME
795    #define TARGET_BIG_NAME         "elf32-sh64big-linux"
796    #undef  TARGET_LITTLE_SYM
797    #define TARGET_LITTLE_SYM       bfd_elf32_sh64lin_vec
798    #undef  TARGET_LITTLE_NAME
799    #define TARGET_LITTLE_NAME      "elf32-sh64-linux"
800    #undef  elf32_bed
801    #define elf32_bed               elf32_sh64_lin_bed
802    
803    #include "elf32-target.h"
804    

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26