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

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

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

revision 1.1.1.1 by camm, Fri Aug 9 05:35:21 2002 UTC revision 1.1.1.1.20.1 by camm, Fri Sep 30 02:08:59 2005 UTC
# Line 1  Line 1 
1  /* V850-specific support for 32-bit ELF  /* V850-specific support for 32-bit ELF
2     Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002     Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3     Free Software Foundation, Inc.     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    
7  This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.     (at your option) any later version.
11    
12  This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.     GNU General Public License for more details.
16    
17  You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20    
21  /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char  /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
22     dependencies.  As is the gas & simulator code or the v850.  */     dependencies.  As is the gas & simulator code for the v850.  */
23    
24  #include "bfd.h"  #include "bfd.h"
25  #include "sysdep.h"  #include "sysdep.h"
# Line 35  Foundation, Inc., 59 Temple Place - Suit Line 35  Foundation, Inc., 59 Temple Place - Suit
35  static reloc_howto_type *v850_elf_reloc_type_lookup  static reloc_howto_type *v850_elf_reloc_type_lookup
36    PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));    PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
37  static void v850_elf_info_to_howto_rel  static void v850_elf_info_to_howto_rel
38    PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));    PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
39  static void v850_elf_info_to_howto_rela  static void v850_elf_info_to_howto_rela
40    PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));    PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
41  static bfd_reloc_status_type v850_elf_reloc  static bfd_reloc_status_type v850_elf_reloc
42    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
43  static boolean v850_elf_is_local_label_name  static bfd_boolean v850_elf_is_local_label_name
44    PARAMS ((bfd *, const char *));    PARAMS ((bfd *, const char *));
45  static boolean v850_elf_relocate_section  static bfd_boolean v850_elf_relocate_section
46    PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,    PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
47            Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));            Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
48  static bfd_reloc_status_type v850_elf_perform_relocation  static bfd_reloc_status_type v850_elf_perform_relocation
49    PARAMS ((bfd *, unsigned int, bfd_vma, bfd_byte *));    PARAMS ((bfd *, unsigned int, bfd_vma, bfd_byte *));
50  static boolean v850_elf_check_relocs  static bfd_boolean v850_elf_check_relocs
51    PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));    PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
52  static void remember_hi16s_reloc  static void remember_hi16s_reloc
53    PARAMS ((bfd *, bfd_vma, bfd_byte *));    PARAMS ((bfd *, bfd_vma, bfd_byte *));
54  static bfd_byte * find_remembered_hi16s_reloc  static bfd_byte * find_remembered_hi16s_reloc
55    PARAMS ((bfd_vma, boolean *));    PARAMS ((bfd_vma, bfd_boolean *));
56  static bfd_reloc_status_type v850_elf_final_link_relocate  static bfd_reloc_status_type v850_elf_final_link_relocate
57    PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma,    PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma,
58             bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int));             bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int));
59  static boolean v850_elf_object_p  static bfd_boolean v850_elf_object_p
60    PARAMS ((bfd *));    PARAMS ((bfd *));
61  static boolean v850_elf_fake_sections  static bfd_boolean v850_elf_fake_sections
62    PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));    PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
63  static void v850_elf_final_write_processing  static void v850_elf_final_write_processing
64    PARAMS ((bfd *, boolean));    PARAMS ((bfd *, bfd_boolean));
65  static boolean v850_elf_set_private_flags  static bfd_boolean v850_elf_set_private_flags
66    PARAMS ((bfd *, flagword));    PARAMS ((bfd *, flagword));
67  static boolean v850_elf_merge_private_bfd_data  static bfd_boolean v850_elf_merge_private_bfd_data
68    PARAMS ((bfd *, bfd *));    PARAMS ((bfd *, bfd *));
69  static boolean v850_elf_print_private_bfd_data  static bfd_boolean v850_elf_print_private_bfd_data
70    PARAMS ((bfd *, PTR));    PARAMS ((bfd *, PTR));
71  static boolean v850_elf_section_from_bfd_section  static bfd_boolean v850_elf_section_from_bfd_section
72    PARAMS ((bfd *, asection *, int *));    PARAMS ((bfd *, asection *, int *));
73  static void v850_elf_symbol_processing  static void v850_elf_symbol_processing
74    PARAMS ((bfd *, asymbol *));    PARAMS ((bfd *, asymbol *));
75  static boolean v850_elf_add_symbol_hook  static bfd_boolean v850_elf_add_symbol_hook
76    PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,    PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
77             const char **, flagword *, asection **, bfd_vma *));             const char **, flagword *, asection **, bfd_vma *));
78  static boolean v850_elf_link_output_symbol_hook  static bfd_boolean v850_elf_link_output_symbol_hook
79    PARAMS ((bfd *, struct bfd_link_info *, const char *,    PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *,
80             Elf_Internal_Sym *, asection *));             asection *, struct elf_link_hash_entry *));
81  static boolean v850_elf_section_from_shdr  static bfd_boolean v850_elf_section_from_shdr
82    PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));    PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
83  static boolean v850_elf_gc_sweep_hook  static bfd_boolean v850_elf_gc_sweep_hook
84    PARAMS ((bfd *, struct bfd_link_info *, asection *,    PARAMS ((bfd *, struct bfd_link_info *, asection *,
85             const Elf_Internal_Rela *));             const Elf_Internal_Rela *));
86  static asection * v850_elf_gc_mark_hook  static asection * v850_elf_gc_mark_hook
87    PARAMS ((asection *, struct bfd_link_info *,    PARAMS ((asection *, struct bfd_link_info *,
88             Elf_Internal_Rela *, struct elf_link_hash_entry *,             Elf_Internal_Rela *, struct elf_link_hash_entry *,
89             Elf_Internal_Sym *));             Elf_Internal_Sym *));
90    static bfd_reloc_status_type v850_elf_ignore_reloc
91      PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
92    static bfd_boolean v850_elf_relax_delete_bytes
93      PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int));
94    static bfd_boolean v850_elf_relax_section
95      PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
96    
97  /* Note: It is REQUIRED that the 'type' value of each entry  /* Note: It is REQUIRED that the 'type' value of each entry
98     in this array match the index of the entry in the array.  */     in this array match the index of the entry in the array.  */
# Line 97  static reloc_howto_type v850_elf_howto_t Line 103  static reloc_howto_type v850_elf_howto_t
103           0,                             /* rightshift */           0,                             /* rightshift */
104           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
105           32,                            /* bitsize */           32,                            /* bitsize */
106           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
107           0,                             /* bitpos */           0,                             /* bitpos */
108           complain_overflow_bitfield,    /* complain_on_overflow */           complain_overflow_bitfield,    /* complain_on_overflow */
109           bfd_elf_generic_reloc,         /* special_function */           bfd_elf_generic_reloc,         /* special_function */
110           "R_V850_NONE",                 /* name */           "R_V850_NONE",                 /* name */
111           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
112           0,                             /* src_mask */           0,                             /* src_mask */
113           0,                             /* dst_mask */           0,                             /* dst_mask */
114           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
115    
116    /* A PC relative 9 bit branch.  */    /* A PC relative 9 bit branch.  */
117    HOWTO (R_V850_9_PCREL,                /* type */    HOWTO (R_V850_9_PCREL,                /* type */
118           2,                             /* rightshift */           2,                             /* rightshift */
119           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
120           26,                            /* bitsize */           26,                            /* bitsize */
121           true,                          /* pc_relative */           TRUE,                          /* pc_relative */
122           0,                             /* bitpos */           0,                             /* bitpos */
123           complain_overflow_bitfield,    /* complain_on_overflow */           complain_overflow_bitfield,    /* complain_on_overflow */
124           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
125           "R_V850_9_PCREL",              /* name */           "R_V850_9_PCREL",              /* name */
126           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
127           0x00ffffff,                    /* src_mask */           0x00ffffff,                    /* src_mask */
128           0x00ffffff,                    /* dst_mask */           0x00ffffff,                    /* dst_mask */
129           true),                         /* pcrel_offset */           TRUE),                         /* pcrel_offset */
130    
131    /* A PC relative 22 bit branch.  */    /* A PC relative 22 bit branch.  */
132    HOWTO (R_V850_22_PCREL,               /* type */    HOWTO (R_V850_22_PCREL,               /* type */
133           2,                             /* rightshift */           2,                             /* rightshift */
134           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
135           22,                            /* bitsize */           22,                            /* bitsize */
136           true,                          /* pc_relative */           TRUE,                          /* pc_relative */
137           7,                             /* bitpos */           7,                             /* bitpos */
138           complain_overflow_signed,      /* complain_on_overflow */           complain_overflow_signed,      /* complain_on_overflow */
139           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
140           "R_V850_22_PCREL",             /* name */           "R_V850_22_PCREL",             /* name */
141           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
142           0x07ffff80,                    /* src_mask */           0x07ffff80,                    /* src_mask */
143           0x07ffff80,                    /* dst_mask */           0x07ffff80,                    /* dst_mask */
144           true),                         /* pcrel_offset */           TRUE),                         /* pcrel_offset */
145    
146    /* High 16 bits of symbol value.  */    /* High 16 bits of symbol value.  */
147    HOWTO (R_V850_HI16_S,                 /* type */    HOWTO (R_V850_HI16_S,                 /* type */
148           0,                             /* rightshift */           0,                             /* rightshift */
149           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
150           16,                            /* bitsize */           16,                            /* bitsize */
151           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
152           0,                             /* bitpos */           0,                             /* bitpos */
153           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
154           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
155           "R_V850_HI16_S",               /* name */           "R_V850_HI16_S",               /* name */
156           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
157           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
158           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
159           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
160    
161    /* High 16 bits of symbol value.  */    /* High 16 bits of symbol value.  */
162    HOWTO (R_V850_HI16,                   /* type */    HOWTO (R_V850_HI16,                   /* type */
163           0,                             /* rightshift */           0,                             /* rightshift */
164           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
165           16,                            /* bitsize */           16,                            /* bitsize */
166           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
167           0,                             /* bitpos */           0,                             /* bitpos */
168           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
169           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
170           "R_V850_HI16",                 /* name */           "R_V850_HI16",                 /* name */
171           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
172           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
173           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
174           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
175    
176    /* Low 16 bits of symbol value.  */    /* Low 16 bits of symbol value.  */
177    HOWTO (R_V850_LO16,                   /* type */    HOWTO (R_V850_LO16,                   /* type */
178           0,                             /* rightshift */           0,                             /* rightshift */
179           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
180           16,                            /* bitsize */           16,                            /* bitsize */
181           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
182           0,                             /* bitpos */           0,                             /* bitpos */
183           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
184           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
185           "R_V850_LO16",                 /* name */           "R_V850_LO16",                 /* name */
186           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
187           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
188           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
189           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
190    
191    /* Simple 32bit reloc.  */    /* Simple 32bit reloc.  */
192    HOWTO (R_V850_32,                     /* type */    HOWTO (R_V850_ABS32,                  /* type */
193           0,                             /* rightshift */           0,                             /* rightshift */
194           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
195           32,                            /* bitsize */           32,                            /* bitsize */
196           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
197           0,                             /* bitpos */           0,                             /* bitpos */
198           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
199           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
200           "R_V850_32",                   /* name */           "R_V850_ABS32",                /* name */
201           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
202           0xffffffff,                    /* src_mask */           0xffffffff,                    /* src_mask */
203           0xffffffff,                    /* dst_mask */           0xffffffff,                    /* dst_mask */
204           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
205    
206    /* Simple 16bit reloc.  */    /* Simple 16bit reloc.  */
207    HOWTO (R_V850_16,                     /* type */    HOWTO (R_V850_16,                     /* type */
208           0,                             /* rightshift */           0,                             /* rightshift */
209           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
210           16,                            /* bitsize */           16,                            /* bitsize */
211           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
212           0,                             /* bitpos */           0,                             /* bitpos */
213           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
214           bfd_elf_generic_reloc,         /* special_function */           bfd_elf_generic_reloc,         /* special_function */
215           "R_V850_16",                   /* name */           "R_V850_16",                   /* name */
216           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
217           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
218           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
219           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
220    
221    /* Simple 8bit reloc.  */    /* Simple 8bit reloc.  */
222    HOWTO (R_V850_8,                      /* type */    HOWTO (R_V850_8,                      /* type */
223           0,                             /* rightshift */           0,                             /* rightshift */
224           0,                             /* size (0 = byte, 1 = short, 2 = long) */           0,                             /* size (0 = byte, 1 = short, 2 = long) */
225           8,                             /* bitsize */           8,                             /* bitsize */
226           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
227           0,                             /* bitpos */           0,                             /* bitpos */
228           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
229           bfd_elf_generic_reloc,         /* special_function */           bfd_elf_generic_reloc,         /* special_function */
230           "R_V850_8",                    /* name */           "R_V850_8",                    /* name */
231           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
232           0xff,                          /* src_mask */           0xff,                          /* src_mask */
233           0xff,                          /* dst_mask */           0xff,                          /* dst_mask */
234           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
235    
236    /* 16 bit offset from the short data area pointer.  */    /* 16 bit offset from the short data area pointer.  */
237    HOWTO (R_V850_SDA_16_16_OFFSET,       /* type */    HOWTO (R_V850_SDA_16_16_OFFSET,       /* type */
238           0,                             /* rightshift */           0,                             /* rightshift */
239           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
240           16,                            /* bitsize */           16,                            /* bitsize */
241           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
242           0,                             /* bitpos */           0,                             /* bitpos */
243           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
244           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
245           "R_V850_SDA_16_16_OFFSET",     /* name */           "R_V850_SDA_16_16_OFFSET",     /* name */
246           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
247           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
248           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
249           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
250    
251    /* 15 bit offset from the short data area pointer.  */    /* 15 bit offset from the short data area pointer.  */
252    HOWTO (R_V850_SDA_15_16_OFFSET,       /* type */    HOWTO (R_V850_SDA_15_16_OFFSET,       /* type */
253           1,                             /* rightshift */           1,                             /* rightshift */
254           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
255           16,                            /* bitsize */           16,                            /* bitsize */
256           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
257           1,                             /* bitpos */           1,                             /* bitpos */
258           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
259           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
260           "R_V850_SDA_15_16_OFFSET",     /* name */           "R_V850_SDA_15_16_OFFSET",     /* name */
261           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
262           0xfffe,                        /* src_mask */           0xfffe,                        /* src_mask */
263           0xfffe,                        /* dst_mask */           0xfffe,                        /* dst_mask */
264           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
265    
266    /* 16 bit offset from the zero data area pointer.  */    /* 16 bit offset from the zero data area pointer.  */
267    HOWTO (R_V850_ZDA_16_16_OFFSET,       /* type */    HOWTO (R_V850_ZDA_16_16_OFFSET,       /* type */
268           0,                             /* rightshift */           0,                             /* rightshift */
269           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
270           16,                            /* bitsize */           16,                            /* bitsize */
271           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
272           0,                             /* bitpos */           0,                             /* bitpos */
273           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
274           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
275           "R_V850_ZDA_16_16_OFFSET",     /* name */           "R_V850_ZDA_16_16_OFFSET",     /* name */
276           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
277           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
278           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
279           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
280    
281    /* 15 bit offset from the zero data area pointer.  */    /* 15 bit offset from the zero data area pointer.  */
282    HOWTO (R_V850_ZDA_15_16_OFFSET,       /* type */    HOWTO (R_V850_ZDA_15_16_OFFSET,       /* type */
283           1,                             /* rightshift */           1,                             /* rightshift */
284           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
285           16,                            /* bitsize */           16,                            /* bitsize */
286           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
287           1,                             /* bitpos */           1,                             /* bitpos */
288           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
289           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
290           "R_V850_ZDA_15_16_OFFSET",     /* name */           "R_V850_ZDA_15_16_OFFSET",     /* name */
291           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
292           0xfffe,                        /* src_mask */           0xfffe,                        /* src_mask */
293           0xfffe,                        /* dst_mask */           0xfffe,                        /* dst_mask */
294           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
295    
296    /* 6 bit offset from the tiny data area pointer.  */    /* 6 bit offset from the tiny data area pointer.  */
297    HOWTO (R_V850_TDA_6_8_OFFSET,         /* type */    HOWTO (R_V850_TDA_6_8_OFFSET,         /* type */
298           2,                             /* rightshift */           2,                             /* rightshift */
299           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
300           8,                             /* bitsize */           8,                             /* bitsize */
301           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
302           1,                             /* bitpos */           1,                             /* bitpos */
303           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
304           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
305           "R_V850_TDA_6_8_OFFSET",       /* name */           "R_V850_TDA_6_8_OFFSET",       /* name */
306           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
307           0x7e,                          /* src_mask */           0x7e,                          /* src_mask */
308           0x7e,                          /* dst_mask */           0x7e,                          /* dst_mask */
309           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
310    
311    /* 8 bit offset from the tiny data area pointer.  */    /* 8 bit offset from the tiny data area pointer.  */
312    HOWTO (R_V850_TDA_7_8_OFFSET,         /* type */    HOWTO (R_V850_TDA_7_8_OFFSET,         /* type */
313           1,                             /* rightshift */           1,                             /* rightshift */
314           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
315           8,                             /* bitsize */           8,                             /* bitsize */
316           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
317           0,                             /* bitpos */           0,                             /* bitpos */
318           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
319           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
320           "R_V850_TDA_7_8_OFFSET",       /* name */           "R_V850_TDA_7_8_OFFSET",       /* name */
321           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
322           0x7f,                          /* src_mask */           0x7f,                          /* src_mask */
323           0x7f,                          /* dst_mask */           0x7f,                          /* dst_mask */
324           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
325    
326    /* 7 bit offset from the tiny data area pointer.  */    /* 7 bit offset from the tiny data area pointer.  */
327    HOWTO (R_V850_TDA_7_7_OFFSET,         /* type */    HOWTO (R_V850_TDA_7_7_OFFSET,         /* type */
328           0,                             /* rightshift */           0,                             /* rightshift */
329           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
330           7,                             /* bitsize */           7,                             /* bitsize */
331           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
332           0,                             /* bitpos */           0,                             /* bitpos */
333           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
334           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
335           "R_V850_TDA_7_7_OFFSET",       /* name */           "R_V850_TDA_7_7_OFFSET",       /* name */
336           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
337           0x7f,                          /* src_mask */           0x7f,                          /* src_mask */
338           0x7f,                          /* dst_mask */           0x7f,                          /* dst_mask */
339           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
340    
341    /* 16 bit offset from the tiny data area pointer!  */    /* 16 bit offset from the tiny data area pointer!  */
342    HOWTO (R_V850_TDA_16_16_OFFSET,       /* type */    HOWTO (R_V850_TDA_16_16_OFFSET,       /* type */
343           0,                             /* rightshift */           0,                             /* rightshift */
344           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
345           16,                            /* bitsize */           16,                            /* bitsize */
346           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
347           0,                             /* bitpos */           0,                             /* bitpos */
348           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
349           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
350           "R_V850_TDA_16_16_OFFSET",     /* name */           "R_V850_TDA_16_16_OFFSET",     /* name */
351           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
352           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
353           0xfff,                         /* dst_mask */           0xfff,                         /* dst_mask */
354           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
355    
356    /* 5 bit offset from the tiny data area pointer.  */    /* 5 bit offset from the tiny data area pointer.  */
357    HOWTO (R_V850_TDA_4_5_OFFSET,         /* type */    HOWTO (R_V850_TDA_4_5_OFFSET,         /* type */
358           1,                             /* rightshift */           1,                             /* rightshift */
359           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
360           5,                             /* bitsize */           5,                             /* bitsize */
361           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
362           0,                             /* bitpos */           0,                             /* bitpos */
363           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
364           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
365           "R_V850_TDA_4_5_OFFSET",       /* name */           "R_V850_TDA_4_5_OFFSET",       /* name */
366           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
367           0x0f,                          /* src_mask */           0x0f,                          /* src_mask */
368           0x0f,                          /* dst_mask */           0x0f,                          /* dst_mask */
369           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
370    
371    /* 4 bit offset from the tiny data area pointer.  */    /* 4 bit offset from the tiny data area pointer.  */
372    HOWTO (R_V850_TDA_4_4_OFFSET,         /* type */    HOWTO (R_V850_TDA_4_4_OFFSET,         /* type */
373           0,                             /* rightshift */           0,                             /* rightshift */
374           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
375           4,                             /* bitsize */           4,                             /* bitsize */
376           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
377           0,                             /* bitpos */           0,                             /* bitpos */
378           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
379           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
380           "R_V850_TDA_4_4_OFFSET",       /* name */           "R_V850_TDA_4_4_OFFSET",       /* name */
381           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
382           0x0f,                          /* src_mask */           0x0f,                          /* src_mask */
383           0x0f,                          /* dst_mask */           0x0f,                          /* dst_mask */
384           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
385    
386    /* 16 bit offset from the short data area pointer.  */    /* 16 bit offset from the short data area pointer.  */
387    HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */    HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
388           0,                             /* rightshift */           0,                             /* rightshift */
389           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
390           16,                            /* bitsize */           16,                            /* bitsize */
391           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
392           0,                             /* bitpos */           0,                             /* bitpos */
393           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
394           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
395           "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */           "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
396           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
397           0xfffe0020,                    /* src_mask */           0xfffe0020,                    /* src_mask */
398           0xfffe0020,                    /* dst_mask */           0xfffe0020,                    /* dst_mask */
399           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
400    
401    /* 16 bit offset from the zero data area pointer.  */    /* 16 bit offset from the zero data area pointer.  */
402    HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */    HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
403           0,                             /* rightshift */           0,                             /* rightshift */
404           2,                             /* size (0 = byte, 1 = short, 2 = long) */           2,                             /* size (0 = byte, 1 = short, 2 = long) */
405           16,                            /* bitsize */           16,                            /* bitsize */
406           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
407           0,                             /* bitpos */           0,                             /* bitpos */
408           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
409           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
410           "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */           "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
411           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
412           0xfffe0020,                    /* src_mask */           0xfffe0020,                    /* src_mask */
413           0xfffe0020,                    /* dst_mask */           0xfffe0020,                    /* dst_mask */
414           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
415    
416    /* 6 bit offset from the call table base pointer.  */    /* 6 bit offset from the call table base pointer.  */
417    HOWTO (R_V850_CALLT_6_7_OFFSET,       /* type */    HOWTO (R_V850_CALLT_6_7_OFFSET,       /* type */
418           0,                             /* rightshift */           0,                             /* rightshift */
419           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
420           7,                             /* bitsize */           7,                             /* bitsize */
421           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
422           0,                             /* bitpos */           0,                             /* bitpos */
423           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
424           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
425           "R_V850_CALLT_6_7_OFFSET",     /* name */           "R_V850_CALLT_6_7_OFFSET",     /* name */
426           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
427           0x3f,                          /* src_mask */           0x3f,                          /* src_mask */
428           0x3f,                          /* dst_mask */           0x3f,                          /* dst_mask */
429           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
430    
431    /* 16 bit offset from the call table base pointer.  */    /* 16 bit offset from the call table base pointer.  */
432    HOWTO (R_V850_CALLT_16_16_OFFSET,     /* type */    HOWTO (R_V850_CALLT_16_16_OFFSET,     /* type */
433           0,                             /* rightshift */           0,                             /* rightshift */
434           1,                             /* size (0 = byte, 1 = short, 2 = long) */           1,                             /* size (0 = byte, 1 = short, 2 = long) */
435           16,                            /* bitsize */           16,                            /* bitsize */
436           false,                         /* pc_relative */           FALSE,                         /* pc_relative */
437           0,                             /* bitpos */           0,                             /* bitpos */
438           complain_overflow_dont,        /* complain_on_overflow */           complain_overflow_dont,        /* complain_on_overflow */
439           v850_elf_reloc,                /* special_function */           v850_elf_reloc,                /* special_function */
440           "R_V850_CALLT_16_16_OFFSET",   /* name */           "R_V850_CALLT_16_16_OFFSET",   /* name */
441           false,                         /* partial_inplace */           FALSE,                         /* partial_inplace */
442           0xffff,                        /* src_mask */           0xffff,                        /* src_mask */
443           0xffff,                        /* dst_mask */           0xffff,                        /* dst_mask */
444           false),                        /* pcrel_offset */           FALSE),                        /* pcrel_offset */
445    
446    /* GNU extension to record C++ vtable hierarchy */    /* GNU extension to record C++ vtable hierarchy */
447    HOWTO (R_V850_GNU_VTINHERIT, /* type */    HOWTO (R_V850_GNU_VTINHERIT, /* type */
448           0,                     /* rightshift */           0,                     /* rightshift */
449           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
450           0,                     /* bitsize */           0,                     /* bitsize */
451           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
452           0,                     /* bitpos */           0,                     /* bitpos */
453           complain_overflow_dont, /* complain_on_overflow */           complain_overflow_dont, /* complain_on_overflow */
454           NULL,                  /* special_function */           NULL,                  /* special_function */
455           "R_V850_GNU_VTINHERIT", /* name */           "R_V850_GNU_VTINHERIT", /* name */
456           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
457           0,                     /* src_mask */           0,                     /* src_mask */
458           0,                     /* dst_mask */           0,                     /* dst_mask */
459           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
460    
461    /* GNU extension to record C++ vtable member usage */    /* GNU extension to record C++ vtable member usage */
462    HOWTO (R_V850_GNU_VTENTRY,     /* type */    HOWTO (R_V850_GNU_VTENTRY,     /* type */
463           0,                     /* rightshift */           0,                     /* rightshift */
464           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
465           0,                     /* bitsize */           0,                     /* bitsize */
466           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
467           0,                     /* bitpos */           0,                     /* bitpos */
468           complain_overflow_dont, /* complain_on_overflow */           complain_overflow_dont, /* complain_on_overflow */
469           _bfd_elf_rel_vtable_reloc_fn,  /* special_function */           _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
470           "R_V850_GNU_VTENTRY",   /* name */           "R_V850_GNU_VTENTRY",   /* name */
471           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
472           0,                     /* src_mask */           0,                     /* src_mask */
473           0,                     /* dst_mask */           0,                     /* dst_mask */
474           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
475    
476      /* Indicates a .longcall pseudo-op.  The compiler will generate a .longcall
477         pseudo-op when it finds a function call which can be relaxed.  */
478      HOWTO (R_V850_LONGCALL,     /* type */
479           0,                     /* rightshift */
480           2,                     /* size (0 = byte, 1 = short, 2 = long) */
481           32,                    /* bitsize */
482           TRUE,                  /* pc_relative */
483           0,                     /* bitpos */
484           complain_overflow_signed, /* complain_on_overflow */
485           v850_elf_ignore_reloc, /* special_function */
486           "R_V850_LONGCALL",     /* name */
487           FALSE,                 /* partial_inplace */
488           0,                     /* src_mask */
489           0,                     /* dst_mask */
490           TRUE),                 /* pcrel_offset */
491    
492      /* Indicates a .longjump pseudo-op.  The compiler will generate a
493         .longjump pseudo-op when it finds a branch which can be relaxed.  */
494      HOWTO (R_V850_LONGJUMP,     /* type */
495           0,                     /* rightshift */
496           2,                     /* size (0 = byte, 1 = short, 2 = long) */
497           32,                    /* bitsize */
498           TRUE,                  /* pc_relative */
499           0,                     /* bitpos */
500           complain_overflow_signed, /* complain_on_overflow */
501           v850_elf_ignore_reloc, /* special_function */
502           "R_V850_LONGJUMP",     /* name */
503           FALSE,                 /* partial_inplace */
504           0,                     /* src_mask */
505           0,                     /* dst_mask */
506           TRUE),                 /* pcrel_offset */
507    
508      HOWTO (R_V850_ALIGN,        /* type */
509           0,                     /* rightshift */
510           1,                     /* size (0 = byte, 1 = short, 2 = long) */
511           0,                     /* bitsize */
512           FALSE,                 /* pc_relative */
513           0,                     /* bitpos */
514           complain_overflow_unsigned, /* complain_on_overflow */
515           v850_elf_ignore_reloc, /* special_function */
516           "R_V850_ALIGN",        /* name */
517           FALSE,                 /* partial_inplace */
518           0,                     /* src_mask */
519           0,                     /* dst_mask */
520           TRUE),                 /* pcrel_offset */
521      
522      /* Simple pc-relative 32bit reloc.  */
523      HOWTO (R_V850_REL32,                  /* type */
524             0,                             /* rightshift */
525             2,                             /* size (0 = byte, 1 = short, 2 = long) */
526             32,                            /* bitsize */
527             TRUE,                          /* pc_relative */
528             0,                             /* bitpos */
529             complain_overflow_dont,        /* complain_on_overflow */
530             v850_elf_reloc,                /* special_function */
531             "R_V850_REL32",                /* name */
532             FALSE,                         /* partial_inplace */
533             0xffffffff,                    /* src_mask */
534             0xffffffff,                    /* dst_mask */
535             FALSE),                        /* pcrel_offset */
536    
537      /* An ld.bu version of R_V850_LO16.  */
538      HOWTO (R_V850_LO16_SPLIT_OFFSET,      /* type */
539             0,                             /* rightshift */
540             2,                             /* size (0 = byte, 1 = short, 2 = long) */
541             16,                            /* bitsize */
542             FALSE,                         /* pc_relative */
543             0,                             /* bitpos */
544             complain_overflow_dont,        /* complain_on_overflow */
545             v850_elf_reloc,                /* special_function */
546             "R_V850_LO16_SPLIT_OFFSET",    /* name */
547             FALSE,                         /* partial_inplace */
548             0xfffe0020,                    /* src_mask */
549             0xfffe0020,                    /* dst_mask */
550             FALSE),                        /* pcrel_offset */
551  };  };
552    
553  /* Map BFD reloc types to V850 ELF reloc types.  */  /* Map BFD reloc types to V850 ELF reloc types.  */
# Line 481  struct v850_elf_reloc_map Line 562  struct v850_elf_reloc_map
562    
563  static const struct v850_elf_reloc_map v850_elf_reloc_map[] =  static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
564  {  {
565    { BFD_RELOC_NONE,             R_V850_NONE },    { BFD_RELOC_NONE,                        R_V850_NONE                   },
566    { BFD_RELOC_V850_9_PCREL,     R_V850_9_PCREL },    { BFD_RELOC_V850_9_PCREL,                R_V850_9_PCREL                },
567    { BFD_RELOC_V850_22_PCREL,    R_V850_22_PCREL },    { BFD_RELOC_V850_22_PCREL,               R_V850_22_PCREL               },
568    { BFD_RELOC_HI16_S,           R_V850_HI16_S },    { BFD_RELOC_HI16_S,                      R_V850_HI16_S                 },
569    { BFD_RELOC_HI16,             R_V850_HI16 },    { BFD_RELOC_HI16,                        R_V850_HI16                   },
570    { BFD_RELOC_LO16,             R_V850_LO16 },    { BFD_RELOC_LO16,                        R_V850_LO16                   },
571    { BFD_RELOC_32,               R_V850_32 },    { BFD_RELOC_32,                          R_V850_ABS32                  },
572    { BFD_RELOC_16,               R_V850_16 },    { BFD_RELOC_32_PCREL,                    R_V850_REL32                  },
573    { BFD_RELOC_8,                R_V850_8 },    { BFD_RELOC_16,                          R_V850_16                     },
574    { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },    { BFD_RELOC_8,                           R_V850_8                      },
575    { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },    { BFD_RELOC_V850_SDA_16_16_OFFSET,       R_V850_SDA_16_16_OFFSET       },
576    { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },    { BFD_RELOC_V850_SDA_15_16_OFFSET,       R_V850_SDA_15_16_OFFSET       },
577    { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },    { BFD_RELOC_V850_ZDA_16_16_OFFSET,       R_V850_ZDA_16_16_OFFSET       },
578    { BFD_RELOC_V850_TDA_6_8_OFFSET,   R_V850_TDA_6_8_OFFSET   },    { BFD_RELOC_V850_ZDA_15_16_OFFSET,       R_V850_ZDA_15_16_OFFSET       },
579    { BFD_RELOC_V850_TDA_7_8_OFFSET,   R_V850_TDA_7_8_OFFSET   },    { BFD_RELOC_V850_TDA_6_8_OFFSET,         R_V850_TDA_6_8_OFFSET         },
580    { BFD_RELOC_V850_TDA_7_7_OFFSET,   R_V850_TDA_7_7_OFFSET   },    { BFD_RELOC_V850_TDA_7_8_OFFSET,         R_V850_TDA_7_8_OFFSET         },
581    { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },    { BFD_RELOC_V850_TDA_7_7_OFFSET,         R_V850_TDA_7_7_OFFSET         },
582      { BFD_RELOC_V850_TDA_16_16_OFFSET,       R_V850_TDA_16_16_OFFSET       },
583    { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },    { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },
584    { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },    { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },
585      { BFD_RELOC_V850_LO16_SPLIT_OFFSET,      R_V850_LO16_SPLIT_OFFSET      },
586    { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },    { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
587    { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },    { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
588    { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },    { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },
589    { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },    { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
590    { BFD_RELOC_VTABLE_INHERIT,               R_V850_GNU_VTINHERIT },    { BFD_RELOC_VTABLE_INHERIT,              R_V850_GNU_VTINHERIT          },
591    { BFD_RELOC_VTABLE_ENTRY,                 R_V850_GNU_VTENTRY },    { BFD_RELOC_VTABLE_ENTRY,                R_V850_GNU_VTENTRY            },
592      { BFD_RELOC_V850_LONGCALL,               R_V850_LONGCALL               },
593      { BFD_RELOC_V850_LONGJUMP,               R_V850_LONGJUMP               },
594      { BFD_RELOC_V850_ALIGN,                  R_V850_ALIGN                  },
595    
596  };  };
597    
# Line 513  static const struct v850_elf_reloc_map v Line 599  static const struct v850_elf_reloc_map v
599    
600  static reloc_howto_type *  static reloc_howto_type *
601  v850_elf_reloc_type_lookup (abfd, code)  v850_elf_reloc_type_lookup (abfd, code)
602       bfd *                     abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
603       bfd_reloc_code_real_type  code;       bfd_reloc_code_real_type code;
604  {  {
605    unsigned int i;    unsigned int i;
606    
# Line 535  v850_elf_reloc_type_lookup (abfd, code) Line 621  v850_elf_reloc_type_lookup (abfd, code)
621    
622  static void  static void
623  v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)  v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
624       bfd *                 abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
625       arelent *             cache_ptr;       arelent *cache_ptr;
626       Elf32_Internal_Rel *  dst;       Elf_Internal_Rela *dst;
627  {  {
628    unsigned int r_type;    unsigned int r_type;
629    
# Line 549  v850_elf_info_to_howto_rel (abfd, cache_ Line 635  v850_elf_info_to_howto_rel (abfd, cache_
635  /* Set the howto pointer for a V850 ELF reloc (type RELA).  */  /* Set the howto pointer for a V850 ELF reloc (type RELA).  */
636  static void  static void
637  v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)  v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
638       bfd *                 abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
639       arelent *             cache_ptr;       arelent * cache_ptr;
640       Elf32_Internal_Rela   *dst;       Elf_Internal_Rela *dst;
641  {  {
642    unsigned int r_type;    unsigned int r_type;
643    
# Line 564  v850_elf_info_to_howto_rela (abfd, cache Line 650  v850_elf_info_to_howto_rela (abfd, cache
650     allocate space in the global offset table or procedure linkage     allocate space in the global offset table or procedure linkage
651     table.  */     table.  */
652    
653  static boolean  static bfd_boolean
654  v850_elf_check_relocs (abfd, info, sec, relocs)  v850_elf_check_relocs (abfd, info, sec, relocs)
655       bfd *                      abfd;       bfd *abfd;
656       struct bfd_link_info *     info;       struct bfd_link_info *info;
657       asection *                 sec;       asection *sec;
658       const Elf_Internal_Rela *  relocs;       const Elf_Internal_Rela *relocs;
659  {  {
660    boolean ret = true;    bfd_boolean ret = TRUE;
661    bfd *dynobj;    bfd *dynobj;
662    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
663    struct elf_link_hash_entry **sym_hashes;    struct elf_link_hash_entry **sym_hashes;
# Line 582  v850_elf_check_relocs (abfd, info, sec, Line 668  v850_elf_check_relocs (abfd, info, sec,
668    int other = 0;    int other = 0;
669    const char *common = (const char *)0;    const char *common = (const char *)0;
670    
671    if (info->relocateable)    if (info->relocatable)
672      return true;      return TRUE;
673    
674  #ifdef DEBUG  #ifdef DEBUG
675    fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",    _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
676             bfd_get_section_name (abfd, sec),                        sec, abfd);
            bfd_archive_filename (abfd));  
677  #endif  #endif
678    
679    dynobj = elf_hash_table (info)->dynobj;    dynobj = elf_hash_table (info)->dynobj;
# Line 618  v850_elf_check_relocs (abfd, info, sec, Line 703  v850_elf_check_relocs (abfd, info, sec,
703          case R_V850_HI16_S:          case R_V850_HI16_S:
704          case R_V850_HI16:          case R_V850_HI16:
705          case R_V850_LO16:          case R_V850_LO16:
706          case R_V850_32:          case R_V850_LO16_SPLIT_OFFSET:
707            case R_V850_ABS32:
708            case R_V850_REL32:
709          case R_V850_16:          case R_V850_16:
710          case R_V850_8:          case R_V850_8:
711          case R_V850_CALLT_6_7_OFFSET:          case R_V850_CALLT_6_7_OFFSET:
# Line 628  v850_elf_check_relocs (abfd, info, sec, Line 715  v850_elf_check_relocs (abfd, info, sec,
715          /* This relocation describes the C++ object vtable hierarchy.          /* This relocation describes the C++ object vtable hierarchy.
716             Reconstruct it for later use during GC.  */             Reconstruct it for later use during GC.  */
717          case R_V850_GNU_VTINHERIT:          case R_V850_GNU_VTINHERIT:
718            if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))            if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
719              return false;              return FALSE;
720            break;            break;
721    
722          /* This relocation describes which C++ vtable entries          /* This relocation describes which C++ vtable entries
723             are actually used.  Record for later use during GC.  */             are actually used.  Record for later use during GC.  */
724          case R_V850_GNU_VTENTRY:          case R_V850_GNU_VTENTRY:
725            if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))            if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
726              return false;              return FALSE;
727            break;            break;
728    
729          case R_V850_SDA_16_16_SPLIT_OFFSET:          case R_V850_SDA_16_16_SPLIT_OFFSET:
# Line 702  v850_elf_check_relocs (abfd, info, sec, Line 789  v850_elf_check_relocs (abfd, info, sec,
789    
790                    bfd_set_error (bfd_error_bad_value);                    bfd_set_error (bfd_error_bad_value);
791                    h->other |= V850_OTHER_ERROR;                    h->other |= V850_OTHER_ERROR;
792                    ret = false;                    ret = FALSE;
793                  }                  }
794              }              }
795    
# Line 734  v850_elf_check_relocs (abfd, info, sec, Line 821  v850_elf_check_relocs (abfd, info, sec,
821     more than once, as the second attempted retry failed.     more than once, as the second attempted retry failed.
822    
823     In the current version, the entry is not deleted, instead we set     In the current version, the entry is not deleted, instead we set
824     the field 'found' to true.  If a second lookup matches the same     the field 'found' to TRUE.  If a second lookup matches the same
825     entry, then we know that the hi16s reloc has already been updated     entry, then we know that the hi16s reloc has already been updated
826     and does not need to be updated a second time.     and does not need to be updated a second time.
827    
# Line 744  v850_elf_check_relocs (abfd, info, sec, Line 831  v850_elf_check_relocs (abfd, info, sec,
831    
832  typedef struct hi16s_location  typedef struct hi16s_location
833  {  {
834    bfd_vma       addend;    bfd_vma addend;
835    bfd_byte *    address;    bfd_byte *address;
836    unsigned long counter;    unsigned long counter;
837    boolean       found;    bfd_boolean found;
838    struct hi16s_location * next;    struct hi16s_location *next;
839  }  }
840  hi16s_location;  hi16s_location;
841    
842  static hi16s_location *  previous_hi16s;  static hi16s_location *previous_hi16s;
843  static hi16s_location *  free_hi16s;  static hi16s_location *free_hi16s;
844  static unsigned long     hi16s_counter;  static unsigned long hi16s_counter;
845    
846  static void  static void
847  remember_hi16s_reloc (abfd, addend, address)  remember_hi16s_reloc (abfd, addend, address)
848       bfd *      abfd;       bfd *abfd;
849       bfd_vma    addend;       bfd_vma addend;
850       bfd_byte * address;       bfd_byte *address;
851  {  {
852    hi16s_location * entry = NULL;    hi16s_location * entry = NULL;
853    bfd_size_type amt = sizeof (* free_hi16s);    bfd_size_type amt = sizeof (* free_hi16s);
# Line 775  remember_hi16s_reloc (abfd, addend, addr Line 862  remember_hi16s_reloc (abfd, addend, addr
862    entry->addend  = addend;    entry->addend  = addend;
863    entry->address = address;    entry->address = address;
864    entry->counter = hi16s_counter ++;    entry->counter = hi16s_counter ++;
865    entry->found   = false;    entry->found   = FALSE;
866    entry->next    = previous_hi16s;    entry->next    = previous_hi16s;
867    previous_hi16s = entry;    previous_hi16s = entry;
868    
# Line 794  remember_hi16s_reloc (abfd, addend, addr Line 881  remember_hi16s_reloc (abfd, addend, addr
881    
882  static bfd_byte *  static bfd_byte *
883  find_remembered_hi16s_reloc (addend, already_found)  find_remembered_hi16s_reloc (addend, already_found)
884       bfd_vma   addend;       bfd_vma addend;
885       boolean * already_found;       bfd_boolean *already_found;
886  {  {
887    hi16s_location * match = NULL;    hi16s_location *match = NULL;
888    hi16s_location * entry;    hi16s_location *entry;
889    hi16s_location * previous = NULL;    hi16s_location *previous = NULL;
890    hi16s_location * prev;    hi16s_location *prev;
891    bfd_byte *       addr;    bfd_byte *addr;
892    
893    /* Search the table.  Record the most recent entry that matches.  */    /* Search the table.  Record the most recent entry that matches.  */
894    for (entry = previous_hi16s; entry; entry = entry->next)    for (entry = previous_hi16s; entry; entry = entry->next)
# Line 822  find_remembered_hi16s_reloc (addend, alr Line 909  find_remembered_hi16s_reloc (addend, alr
909    /* Extract the address.  */    /* Extract the address.  */
910    addr = match->address;    addr = match->address;
911    
912    /* Remeber if this entry has already been used before.  */    /* Remember if this entry has already been used before.  */
913    if (already_found)    if (already_found)
914      * already_found = match->found;      * already_found = match->found;
915    
916    /* Note that this entry has now been used.  */    /* Note that this entry has now been used.  */
917    match->found = true;    match->found = TRUE;
918    
919    return addr;    return addr;
920  }  }
921    
922    /* Calculate the final operand value for a R_V850_LO16 or
923       R_V850_LO16_SPLIT_OFFSET.  *INSN is the current operand value and
924       ADDEND is the sum of the relocation symbol and offset.  Store the
925       operand value in *INSN and return true on success.
926    
927       The assembler has already done some of this: If the value stored in
928       the instruction has its 15th bit set, (counting from zero) then the
929       assembler will have added 1 to the value stored in the associated
930       HI16S reloc.  So for example, these relocations:
931    
932           movhi hi( fred ), r0, r1
933           movea lo( fred ), r1, r1
934    
935       will store 0 in the value fields for the MOVHI and MOVEA instructions
936       and addend will be the address of fred, but for these instructions:
937    
938           movhi hi( fred + 0x123456), r0, r1
939           movea lo( fred + 0x123456), r1, r1
940    
941       the value stored in the MOVHI instruction will be 0x12 and the value
942       stored in the MOVEA instruction will be 0x3456.  If however the
943       instructions were:
944    
945           movhi hi( fred + 0x10ffff), r0, r1
946           movea lo( fred + 0x10ffff), r1, r1
947    
948       then the value stored in the MOVHI instruction would be 0x11 (not
949       0x10) and the value stored in the MOVEA instruction would be 0xffff.
950       Thus (assuming for the moment that the addend is 0), at run time the
951       MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
952       adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
953       the instructions were:
954    
955           movhi hi( fred - 1), r0, r1
956           movea lo( fred - 1), r1, r1
957    
958       then 0 is stored in the MOVHI instruction and -1 is stored in the
959       MOVEA instruction.
960    
961       Overflow can occur if the addition of the value stored in the
962       instruction plus the addend sets the 15th bit when before it was clear.
963       This is because the 15th bit will be sign extended into the high part,
964       thus reducing its value by one, but since the 15th bit was originally
965       clear, the assembler will not have added 1 to the previous HI16S reloc
966       to compensate for this effect.  For example:
967    
968          movhi hi( fred + 0x123456), r0, r1
969          movea lo( fred + 0x123456), r1, r1
970    
971       The value stored in HI16S reloc is 0x12, the value stored in the LO16
972       reloc is 0x3456.  If we assume that the address of fred is 0x00007000
973       then the relocations become:
974    
975         HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
976         LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
977    
978       but when the instructions are executed, the MOVEA instruction's value
979       is signed extended, so the sum becomes:
980    
981            0x00120000
982          + 0xffffa456
983          ------------
984            0x0011a456    but 'fred + 0x123456' = 0x0012a456
985    
986       Note that if the 15th bit was set in the value stored in the LO16
987       reloc, then we do not have to do anything:
988    
989          movhi hi( fred + 0x10ffff), r0, r1
990          movea lo( fred + 0x10ffff), r1, r1
991    
992          HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
993          LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
994    
995            0x00110000
996          + 0x00006fff
997          ------------
998            0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
999    
1000       Overflow can also occur if the computation carries into the 16th bit
1001       and it also results in the 15th bit having the same value as the 15th
1002       bit of the original value.   What happens is that the HI16S reloc
1003       will have already examined the 15th bit of the original value and
1004       added 1 to the high part if the bit is set.  This compensates for the
1005       sign extension of 15th bit of the result of the computation.  But now
1006       there is a carry into the 16th bit, and this has not been allowed for.
1007    
1008       So, for example if fred is at address 0xf000:
1009    
1010         movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
1011         movea lo( fred + 0xffff), r1, r1
1012    
1013         HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
1014         LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
1015    
1016           0x00010000
1017         + 0xffffefff
1018         ------------
1019           0x0000efff   but 'fred + 0xffff' = 0x0001efff
1020    
1021       Similarly, if the 15th bit remains clear, but overflow occurs into
1022       the 16th bit then (assuming the address of fred is 0xf000):
1023    
1024         movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
1025         movea lo( fred + 0x7000), r1, r1
1026    
1027         HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
1028         LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
1029    
1030           0x00000000
1031         + 0x00006fff
1032         ------------
1033           0x00006fff   but 'fred + 0x7000' = 0x00016fff
1034    
1035       Note - there is no need to change anything if a carry occurs, and the
1036       15th bit changes its value from being set to being clear, as the HI16S
1037       reloc will have already added in 1 to the high part for us:
1038    
1039         movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
1040         movea lo( fred + 0xffff), r1, r1
1041    
1042         HI16S: 0x0001 + (0x00007000 >> 16)
1043         LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
1044    
1045           0x00010000
1046         + 0x00006fff   (bit 15 not set, so the top half is zero)
1047         ------------
1048           0x00016fff   which is right (assuming that fred is at 0x7000)
1049    
1050       but if the 15th bit goes from being clear to being set, then we must
1051       once again handle overflow:
1052    
1053         movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
1054         movea lo( fred + 0x7000), r1, r1
1055    
1056         HI16S: 0x0000 + (0x0000ffff >> 16)
1057         LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
1058    
1059           0x00000000
1060         + 0x00006fff   (bit 15 not set, so the top half is zero)
1061         ------------
1062           0x00006fff   which is wrong (assuming that fred is at 0xffff).  */
1063    
1064    static bfd_boolean
1065    v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
1066                                      unsigned long addend)
1067    {
1068    #define BIT15_SET(x) ((x) & 0x8000)
1069    #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
1070      if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
1071          || (OVERFLOWS (addend, *insn)
1072              && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
1073        {
1074          bfd_boolean already_updated;
1075          bfd_byte *hi16s_address = find_remembered_hi16s_reloc
1076            (addend, & already_updated);
1077    
1078          /* Amend the matching HI16_S relocation.  */
1079          if (hi16s_address != NULL)
1080            {
1081              if (! already_updated)
1082                {
1083                  unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
1084                  hi_insn += 1;
1085                  bfd_put_16 (abfd, hi_insn, hi16s_address);
1086                }
1087            }
1088          else
1089            {
1090              fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
1091              return FALSE;
1092            }
1093        }
1094    #undef OVERFLOWS
1095    #undef BIT15_SET
1096    
1097      /* Do not complain if value has top bit set, as this has been
1098         anticipated.  */
1099      *insn = (*insn + addend) & 0xffff;
1100      return TRUE;
1101    }
1102    
1103  /* FIXME:  The code here probably ought to be removed and the code in reloc.c  /* FIXME:  The code here probably ought to be removed and the code in reloc.c
1104     allowed to do its  stuff instead.  At least for most of the relocs, anwyay.  */     allowed to do its stuff instead.  At least for most of the relocs, anyway.  */
1105    
1106  static bfd_reloc_status_type  static bfd_reloc_status_type
1107  v850_elf_perform_relocation (abfd, r_type, addend, address)  v850_elf_perform_relocation (abfd, r_type, addend, address)
# Line 843  v850_elf_perform_relocation (abfd, r_typ Line 1111  v850_elf_perform_relocation (abfd, r_typ
1111       bfd_byte *address;       bfd_byte *address;
1112  {  {
1113    unsigned long insn;    unsigned long insn;
1114      unsigned long result;
1115    bfd_signed_vma saddend = (bfd_signed_vma) addend;    bfd_signed_vma saddend = (bfd_signed_vma) addend;
1116    
1117    switch (r_type)    switch (r_type)
# Line 851  v850_elf_perform_relocation (abfd, r_typ Line 1120  v850_elf_perform_relocation (abfd, r_typ
1120        /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */        /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
1121        return bfd_reloc_notsupported;        return bfd_reloc_notsupported;
1122    
1123      case R_V850_32:      case R_V850_REL32:
1124        case R_V850_ABS32:
1125        bfd_put_32 (abfd, addend, address);        bfd_put_32 (abfd, addend, address);
1126        return bfd_reloc_ok;        return bfd_reloc_ok;
1127    
# Line 901  v850_elf_perform_relocation (abfd, r_typ Line 1171  v850_elf_perform_relocation (abfd, r_typ
1171        break;        break;
1172    
1173      case R_V850_LO16:      case R_V850_LO16:
1174        /* Calculate the sum of the value stored in the instruction and the        insn = bfd_get_16 (abfd, address);
1175           addend and check for overflow from the low 16 bits into the high        if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
1176           16 bits.  The assembler has already done some of this:  If the          return bfd_reloc_overflow;
1177           value stored in the instruction has its 15th bit set, (counting        break;
          from zero) then the assembler will have added 1 to the value  
          stored in the associated HI16S reloc.  So for example, these  
          relocations:  
   
              movhi hi( fred ), r0, r1  
              movea lo( fred ), r1, r1  
   
          will store 0 in the value fields for the MOVHI and MOVEA instructions  
          and addend will be the address of fred, but for these instructions:  
   
              movhi hi( fred + 0x123456), r0, r1  
              movea lo( fred + 0x123456), r1, r1  
   
          the value stored in the MOVHI instruction will be 0x12 and the value  
          stored in the MOVEA instruction will be 0x3456.  If however the  
          instructions were:  
   
              movhi hi( fred + 0x10ffff), r0, r1  
              movea lo( fred + 0x10ffff), r1, r1  
   
          then the value stored in the MOVHI instruction would be 0x11 (not  
          0x10) and the value stored in the MOVEA instruction would be 0xffff.  
          Thus (assuming for the moment that the addend is 0), at run time the  
          MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction  
          adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if  
          the instructions were:  
   
              movhi hi( fred - 1), r0, r1  
              movea lo( fred - 1), r1, r1  
   
          then 0 is stored in the MOVHI instruction and -1 is stored in the  
          MOVEA instruction.  
   
          Overflow can occur if the addition of the value stored in the  
          instruction plus the addend sets the 15th bit when before it was clear.  
          This is because the 15th bit will be sign extended into the high part,  
          thus reducing its value by one, but since the 15th bit was originally  
          clear, the assembler will not have added 1 to the previous HI16S reloc  
          to compensate for this effect.  For example:  
   
             movhi hi( fred + 0x123456), r0, r1  
             movea lo( fred + 0x123456), r1, r1  
   
          The value stored in HI16S reloc is 0x12, the value stored in the LO16  
          reloc is 0x3456.  If we assume that the address of fred is 0x00007000  
          then the relocations become:  
   
            HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12  
            LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456  
   
          but when the instructions are executed, the MOVEA instruction's value  
          is signed extended, so the sum becomes:  
   
               0x00120000  
             + 0xffffa456  
             ------------  
               0x0011a456    but 'fred + 0x123456' = 0x0012a456  
   
          Note that if the 15th bit was set in the value stored in the LO16  
          reloc, then we do not have to do anything:  
   
             movhi hi( fred + 0x10ffff), r0, r1  
             movea lo( fred + 0x10ffff), r1, r1  
   
             HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11  
             LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff  
   
               0x00110000  
             + 0x00006fff  
             ------------  
               0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff  
   
          Overflow can also occur if the computation carries into the 16th bit  
          and it also results in the 15th bit having the same value as the 15th  
          bit of the original value.   What happens is that the HI16S reloc  
          will have already examined the 15th bit of the original value and  
          added 1 to the high part if the bit is set.  This compensates for the  
          sign extension of 15th bit of the result of the computation.  But now  
          there is a carry into the 16th bit, and this has not been allowed for.  
   
          So, for example if fred is at address 0xf000:  
   
            movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]  
            movea lo( fred + 0xffff), r1, r1  
   
            HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001  
            LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)  
   
              0x00010000  
            + 0xffffefff  
            ------------  
              0x0000efff   but 'fred + 0xffff' = 0x0001efff  
   
          Similarly, if the 15th bit remains clear, but overflow occurs into  
          the 16th bit then (assuming the address of fred is 0xf000):  
   
            movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]  
            movea lo( fred + 0x7000), r1, r1  
   
            HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000  
            LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)  
   
              0x00000000  
            + 0x00006fff  
            ------------  
              0x00006fff   but 'fred + 0x7000' = 0x00016fff  
   
          Note - there is no need to change anything if a carry occurs, and the  
          15th bit changes its value from being set to being clear, as the HI16S  
          reloc will have already added in 1 to the high part for us:  
   
            movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]  
            movea lo( fred + 0xffff), r1, r1  
   
            HI16S: 0x0001 + (0x00007000 >> 16)  
            LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)  
   
              0x00010000  
            + 0x00006fff   (bit 15 not set, so the top half is zero)  
            ------------  
              0x00016fff   which is right (assuming that fred is at 0x7000)  
   
          but if the 15th bit goes from being clear to being set, then we must  
          once again handle overflow:  
   
            movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]  
            movea lo( fred + 0x7000), r1, r1  
   
            HI16S: 0x0000 + (0x0000ffff >> 16)  
            LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)  
   
              0x00000000  
            + 0x00006fff   (bit 15 not set, so the top half is zero)  
            ------------  
              0x00006fff   which is wrong (assuming that fred is at 0xffff).  */  
       {  
         long result;  
   
         insn   = bfd_get_16 (abfd, address);  
         result = insn + addend;  
   
 #define BIT15_SET(x) ((x) & 0x8000)  
 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)  
   
         if ((BIT15_SET (result) && ! BIT15_SET (addend))  
             || (OVERFLOWS (addend, insn)  
                 && ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))  
           {  
             boolean already_updated;  
             bfd_byte * hi16s_address = find_remembered_hi16s_reloc  
               (addend, & already_updated);  
   
             /* Amend the matching HI16_S relocation.  */  
             if (hi16s_address != NULL)  
               {  
                 if (! already_updated)  
                   {  
                     insn = bfd_get_16 (abfd, hi16s_address);  
                     insn += 1;  
                     bfd_put_16 (abfd, (bfd_vma) insn, hi16s_address);  
                   }  
               }  
             else  
               {  
                 fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));  
                 return bfd_reloc_overflow;  
               }  
           }  
   
         /* Do not complain if value has top bit set, as this has been anticipated.  */  
         insn = result & 0xffff;  
         break;  
       }  
1178    
1179      case R_V850_8:      case R_V850_8:
1180        addend += (char) bfd_get_8 (abfd, address);        addend += (char) bfd_get_8 (abfd, address);
# Line 1207  v850_elf_perform_relocation (abfd, r_typ Line 1304  v850_elf_perform_relocation (abfd, r_typ
1304        insn |= addend;        insn |= addend;
1305        break;        break;
1306    
1307        case R_V850_LO16_SPLIT_OFFSET:
1308          insn = bfd_get_32 (abfd, address);
1309          result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
1310          if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
1311            return bfd_reloc_overflow;
1312          insn = (((result << 16) & 0xfffe0000)
1313                  | ((result << 5) & 0x20)
1314                  | (insn & ~0xfffe0020));
1315          bfd_put_32 (abfd, insn, address);
1316          return bfd_reloc_ok;
1317    
1318      case R_V850_ZDA_16_16_SPLIT_OFFSET:      case R_V850_ZDA_16_16_SPLIT_OFFSET:
1319      case R_V850_SDA_16_16_SPLIT_OFFSET:      case R_V850_SDA_16_16_SPLIT_OFFSET:
1320        insn = bfd_get_32 (abfd, address);        insn = bfd_get_32 (abfd, address);
# Line 1254  v850_elf_perform_relocation (abfd, r_typ Line 1362  v850_elf_perform_relocation (abfd, r_typ
1362    
1363  static bfd_reloc_status_type  static bfd_reloc_status_type
1364  v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)  v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
1365       bfd *       abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
1366       arelent *   reloc;       arelent *reloc;
1367       asymbol *   symbol;       asymbol *symbol;
1368       PTR         data ATTRIBUTE_UNUSED;       PTR data ATTRIBUTE_UNUSED;
1369       asection *  isection;       asection *isection;
1370       bfd *       obfd;       bfd *obfd;
1371       char **     err ATTRIBUTE_UNUSED;       char **err ATTRIBUTE_UNUSED;
1372  {  {
1373    long relocation;    long relocation;
1374    
# Line 1277  v850_elf_reloc (abfd, reloc, symbol, dat Line 1385  v850_elf_reloc (abfd, reloc, symbol, dat
1385        reloc->address += isection->output_offset;        reloc->address += isection->output_offset;
1386        return bfd_reloc_ok;        return bfd_reloc_ok;
1387      }      }
 #if 0  
   else if (obfd != NULL)  
     return bfd_reloc_continue;  
 #endif  
1388    
1389    /* Catch relocs involving undefined symbols.  */    /* Catch relocs involving undefined symbols.  */
1390    if (bfd_is_und_section (symbol->section)    if (bfd_is_und_section (symbol->section)
# Line 1291  v850_elf_reloc (abfd, reloc, symbol, dat Line 1395  v850_elf_reloc (abfd, reloc, symbol, dat
1395    /* We handle final linking of some relocs ourselves.  */    /* We handle final linking of some relocs ourselves.  */
1396    
1397    /* Is the address of the relocation really within the section?  */    /* Is the address of the relocation really within the section?  */
1398    if (reloc->address > isection->_cooked_size)    if (reloc->address > bfd_get_section_limit (abfd, isection))
1399      return bfd_reloc_outofrange;      return bfd_reloc_outofrange;
1400    
1401    /* Work out which section the relocation is targetted at and the    /* Work out which section the relocation is targeted at and the
1402       initial relocation command value.  */       initial relocation command value.  */
1403    
1404      if (reloc->howto->pc_relative)
1405        return bfd_reloc_ok;
1406    
1407    /* Get symbol value.  (Common symbols are special.)  */    /* Get symbol value.  (Common symbols are special.)  */
1408    if (bfd_is_com_section (symbol->section))    if (bfd_is_com_section (symbol->section))
1409      relocation = 0;      relocation = 0;
# Line 1308  v850_elf_reloc (abfd, reloc, symbol, dat Line 1415  v850_elf_reloc (abfd, reloc, symbol, dat
1415    relocation += symbol->section->output_offset;    relocation += symbol->section->output_offset;
1416    relocation += reloc->addend;    relocation += reloc->addend;
1417    
 #if 0 /* Since this reloc is going to be processed later on, we should  
          not make it pc-relative here.  To test this, try assembling and  
          linking this program:  
   
                 .text  
                 .globl _start  
                 nop  
         _start:  
                 jr foo  
   
                 .section ".foo","ax"  
                 nop  
         foo:  
                 nop      */  
   if (reloc->howto->pc_relative)  
     {  
       /* Here the variable relocation holds the final address of the  
          symbol we are relocating against, plus any addend.  */  
       relocation -= isection->output_section->vma + isection->output_offset;  
   
       /* Deal with pcrel_offset.  */  
       relocation -= reloc->address;  
     }  
 #endif  
1418    reloc->addend = relocation;    reloc->addend = relocation;
1419    return bfd_reloc_ok;    return bfd_reloc_ok;
1420  }  }
1421    
1422    /* This function is used for relocs which are only used
1423       for relaxing, which the linker should otherwise ignore.  */
1424    
1425    static bfd_reloc_status_type
1426    v850_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
1427                           output_bfd, error_message)
1428         bfd *abfd ATTRIBUTE_UNUSED;
1429         arelent *reloc_entry;
1430         asymbol *symbol ATTRIBUTE_UNUSED;
1431         PTR data ATTRIBUTE_UNUSED;
1432         asection *input_section;
1433         bfd *output_bfd;
1434         char **error_message ATTRIBUTE_UNUSED;
1435    {
1436      if (output_bfd != NULL)
1437        reloc_entry->address += input_section->output_offset;
1438    
1439      return bfd_reloc_ok;
1440    }
1441    
1442  static boolean  static bfd_boolean
1443  v850_elf_is_local_label_name (abfd, name)  v850_elf_is_local_label_name (abfd, name)
1444       bfd *         abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
1445       const char *  name;       const char *name;
1446  {  {
1447    return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))    return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1448            || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));            || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1449  }  }
1450    
1451    /* We overload some of the bfd_reloc error codes for own purposes.  */
1452    #define bfd_reloc_gp_not_found          bfd_reloc_other
1453    #define bfd_reloc_ep_not_found          bfd_reloc_continue
1454    #define bfd_reloc_ctbp_not_found        (bfd_reloc_dangerous + 1)
1455    
1456  /* Perform a relocation as part of a final link.  */  /* Perform a relocation as part of a final link.  */
1457    
1458  static bfd_reloc_status_type  static bfd_reloc_status_type
1459  v850_elf_final_link_relocate (howto, input_bfd, output_bfd,  v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1460                                      input_section, contents, offset, value,                                input_section, contents, offset, value,
1461                                      addend, info, sym_sec, is_local)                                addend, info, sym_sec, is_local)
1462       reloc_howto_type *      howto;       reloc_howto_type *howto;
1463       bfd *                   input_bfd;       bfd *input_bfd;
1464       bfd *                   output_bfd ATTRIBUTE_UNUSED;       bfd *output_bfd ATTRIBUTE_UNUSED;
1465       asection *              input_section;       asection *input_section;
1466       bfd_byte *              contents;       bfd_byte *contents;
1467       bfd_vma                 offset;       bfd_vma offset;
1468       bfd_vma                 value;       bfd_vma value;
1469       bfd_vma                 addend;       bfd_vma addend;
1470       struct bfd_link_info *  info;       struct bfd_link_info *info;
1471       asection *              sym_sec;       asection *sym_sec;
1472       int                     is_local ATTRIBUTE_UNUSED;       int is_local ATTRIBUTE_UNUSED;
1473  {  {
1474    unsigned int   r_type   = howto->type;    unsigned int r_type = howto->type;
1475    bfd_byte *     hit_data = contents + offset;    bfd_byte *hit_data = contents + offset;
1476    
1477    /* Adjust the value according to the relocation.  */    /* Adjust the value according to the relocation.  */
1478    switch (r_type)    switch (r_type)
# Line 1388  v850_elf_final_link_relocate (howto, inp Line 1496  v850_elf_final_link_relocate (howto, inp
1496        value = SEXT24 (value);        value = SEXT24 (value);
1497        break;        break;
1498    
1499        case R_V850_REL32:
1500          value -= (input_section->output_section->vma
1501                    + input_section->output_offset
1502                    + offset);
1503          break;
1504    
1505      case R_V850_HI16_S:      case R_V850_HI16_S:
1506      case R_V850_HI16:      case R_V850_HI16:
1507      case R_V850_LO16:      case R_V850_LO16:
1508        case R_V850_LO16_SPLIT_OFFSET:
1509      case R_V850_16:      case R_V850_16:
1510      case R_V850_32:      case R_V850_ABS32:
1511      case R_V850_8:      case R_V850_8:
1512        break;        break;
1513    
# Line 1416  v850_elf_final_link_relocate (howto, inp Line 1531  v850_elf_final_link_relocate (howto, inp
1531            return bfd_reloc_undefined;            return bfd_reloc_undefined;
1532    
1533          /* Get the value of __gp.  */          /* Get the value of __gp.  */
1534          h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);          h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE);
1535          if (h == (struct bfd_link_hash_entry *) NULL          if (h == (struct bfd_link_hash_entry *) NULL
1536              || h->type != bfd_link_hash_defined)              || h->type != bfd_link_hash_defined)
1537            return bfd_reloc_other;            return bfd_reloc_gp_not_found;
1538    
1539          gp = (h->u.def.value          gp = (h->u.def.value
1540                + h->u.def.section->output_section->vma                + h->u.def.section->output_section->vma
# Line 1441  v850_elf_final_link_relocate (howto, inp Line 1556  v850_elf_final_link_relocate (howto, inp
1556          struct bfd_link_hash_entry * h;          struct bfd_link_hash_entry * h;
1557    
1558          /* Get the value of __ep.  */          /* Get the value of __ep.  */
1559          h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);          h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE);
1560          if (h == (struct bfd_link_hash_entry *) NULL          if (h == (struct bfd_link_hash_entry *) NULL
1561              || h->type != bfd_link_hash_defined)              || h->type != bfd_link_hash_defined)
1562            /* Actually this indicates that __ep could not be found.  */            return bfd_reloc_ep_not_found;
           return bfd_reloc_continue;  
1563    
1564          ep = (h->u.def.value          ep = (h->u.def.value
1565                + h->u.def.section->output_section->vma                + h->u.def.section->output_section->vma
# Line 1461  v850_elf_final_link_relocate (howto, inp Line 1575  v850_elf_final_link_relocate (howto, inp
1575          struct bfd_link_hash_entry * h;          struct bfd_link_hash_entry * h;
1576    
1577          /* Get the value of __ctbp.  */          /* Get the value of __ctbp.  */
1578          h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);          h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
1579          if (h == (struct bfd_link_hash_entry *) NULL          if (h == (struct bfd_link_hash_entry *) NULL
1580              || h->type != bfd_link_hash_defined)              || h->type != bfd_link_hash_defined)
1581            /* Actually this indicates that __ctbp could not be found.  */            return bfd_reloc_ctbp_not_found;
           return bfd_reloc_dangerous + 1;  
1582    
1583          ctbp = (h->u.def.value          ctbp = (h->u.def.value
1584                + h->u.def.section->output_section->vma                + h->u.def.section->output_section->vma
# Line 1483  v850_elf_final_link_relocate (howto, inp Line 1596  v850_elf_final_link_relocate (howto, inp
1596            return bfd_reloc_undefined;            return bfd_reloc_undefined;
1597    
1598          /* Get the value of __ctbp.  */          /* Get the value of __ctbp.  */
1599          h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);          h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
1600          if (h == (struct bfd_link_hash_entry *) NULL          if (h == (struct bfd_link_hash_entry *) NULL
1601              || h->type != bfd_link_hash_defined)              || h->type != bfd_link_hash_defined)
1602            return (bfd_reloc_dangerous + 1);            return bfd_reloc_ctbp_not_found;
1603    
1604          ctbp = (h->u.def.value          ctbp = (h->u.def.value
1605                + h->u.def.section->output_section->vma                + h->u.def.section->output_section->vma
# Line 1500  v850_elf_final_link_relocate (howto, inp Line 1613  v850_elf_final_link_relocate (howto, inp
1613      case R_V850_NONE:      case R_V850_NONE:
1614      case R_V850_GNU_VTINHERIT:      case R_V850_GNU_VTINHERIT:
1615      case R_V850_GNU_VTENTRY:      case R_V850_GNU_VTENTRY:
1616        case R_V850_LONGCALL:
1617        case R_V850_LONGJUMP:
1618        case R_V850_ALIGN:
1619        return bfd_reloc_ok;        return bfd_reloc_ok;
1620    
1621      default:      default:
# Line 1512  v850_elf_final_link_relocate (howto, inp Line 1628  v850_elf_final_link_relocate (howto, inp
1628    
1629  /* Relocate an V850 ELF section.  */  /* Relocate an V850 ELF section.  */
1630    
1631  static boolean  static bfd_boolean
1632  v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,  v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1633                             contents, relocs, local_syms, local_sections)                             contents, relocs, local_syms, local_sections)
1634       bfd *                  output_bfd;       bfd *output_bfd;
1635       struct bfd_link_info * info;       struct bfd_link_info *info;
1636       bfd *                  input_bfd;       bfd *input_bfd;
1637       asection *             input_section;       asection *input_section;
1638       bfd_byte *             contents;       bfd_byte *contents;
1639       Elf_Internal_Rela *    relocs;       Elf_Internal_Rela *relocs;
1640       Elf_Internal_Sym *     local_syms;       Elf_Internal_Sym *local_syms;
1641       asection **            local_sections;       asection **local_sections;
1642  {  {
1643    Elf_Internal_Shdr *           symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
1644    struct elf_link_hash_entry ** sym_hashes;    struct elf_link_hash_entry **sym_hashes;
1645    Elf_Internal_Rela *           rel;    Elf_Internal_Rela *rel;
1646    Elf_Internal_Rela *           relend;    Elf_Internal_Rela *relend;
1647    
1648      if (info->relocatable)
1649        return TRUE;
1650    
1651    symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;    symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1652    sym_hashes = elf_sym_hashes (input_bfd);    sym_hashes = elf_sym_hashes (input_bfd);
# Line 1538  v850_elf_relocate_section (output_bfd, i Line 1657  v850_elf_relocate_section (output_bfd, i
1657          (info, "no hash table available",          (info, "no hash table available",
1658           NULL, input_bfd, input_section, (bfd_vma) 0);           NULL, input_bfd, input_section, (bfd_vma) 0);
1659    
1660        return false;        return FALSE;
1661      }      }
1662    
1663    /* Reset the list of remembered HI16S relocs to empty.  */    /* Reset the list of remembered HI16S relocs to empty.  */
# Line 1550  v850_elf_relocate_section (output_bfd, i Line 1669  v850_elf_relocate_section (output_bfd, i
1669    relend = relocs + input_section->reloc_count;    relend = relocs + input_section->reloc_count;
1670    for (; rel < relend; rel++)    for (; rel < relend; rel++)
1671      {      {
1672        int                          r_type;        int r_type;
1673        reloc_howto_type *           howto;        reloc_howto_type *howto;
1674        unsigned long                r_symndx;        unsigned long r_symndx;
1675        Elf_Internal_Sym *           sym;        Elf_Internal_Sym *sym;
1676        asection *                   sec;        asection *sec;
1677        struct elf_link_hash_entry * h;        struct elf_link_hash_entry *h;
1678        bfd_vma                      relocation;        bfd_vma relocation;
1679        bfd_reloc_status_type        r;        bfd_reloc_status_type r;
1680    
1681        r_symndx = ELF32_R_SYM (rel->r_info);        r_symndx = ELF32_R_SYM (rel->r_info);
1682        r_type   = ELF32_R_TYPE (rel->r_info);        r_type   = ELF32_R_TYPE (rel->r_info);
# Line 1566  v850_elf_relocate_section (output_bfd, i Line 1685  v850_elf_relocate_section (output_bfd, i
1685            || r_type == R_V850_GNU_VTINHERIT)            || r_type == R_V850_GNU_VTINHERIT)
1686          continue;          continue;
1687    
       howto = v850_elf_howto_table + r_type;  
   
       if (info->relocateable)  
         {  
           /* This is a relocateable link.  We don't have to change  
              anything, unless the reloc is against a section symbol,  
              in which case we have to adjust according to where the  
              section symbol winds up in the output section.  */  
           if (r_symndx < symtab_hdr->sh_info)  
             {  
               sym = local_syms + r_symndx;  
               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)  
                 {  
                   sec = local_sections[r_symndx];  
                   rel->r_addend += sec->output_offset + sym->st_value;  
                 }  
             }  
   
           continue;  
         }  
   
1688        /* This is a final link.  */        /* This is a final link.  */
1689          howto = v850_elf_howto_table + r_type;
1690        h = NULL;        h = NULL;
1691        sym = NULL;        sym = NULL;
1692        sec = NULL;        sec = NULL;
# Line 1595  v850_elf_relocate_section (output_bfd, i Line 1694  v850_elf_relocate_section (output_bfd, i
1694          {          {
1695            sym = local_syms + r_symndx;            sym = local_syms + r_symndx;
1696            sec = local_sections[r_symndx];            sec = local_sections[r_symndx];
1697            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
 #if 0  
           {  
             char * name;  
   
             name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);  
             name = (name == NULL) ? "<none>" : name;  
             fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",  
                      sec->name, name, sym->st_name,  
                      sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);  
           }  
 #endif  
1698          }          }
1699        else        else
1700          {          {
1701            h = sym_hashes[r_symndx - symtab_hdr->sh_info];            bfd_boolean unresolved_reloc, warned;
   
           while (h->root.type == bfd_link_hash_indirect  
                  || h->root.type == bfd_link_hash_warning)  
             h = (struct elf_link_hash_entry *) h->root.u.i.link;  
1702    
1703            if (h->root.type == bfd_link_hash_defined            RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1704                || h->root.type == bfd_link_hash_defweak)                                     r_symndx, symtab_hdr, sym_hashes,
1705              {                                     h, sec, relocation,
1706                sec = h->root.u.def.section;                                     unresolved_reloc, warned);
               relocation = (h->root.u.def.value  
                             + sec->output_section->vma  
                             + sec->output_offset);  
 #if 0  
               fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",  
                        sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);  
 #endif  
             }  
           else if (h->root.type == bfd_link_hash_undefweak)  
             {  
 #if 0  
               fprintf (stderr, "undefined: sec: %s, name: %s\n",  
                        sec->name, h->root.root.string);  
 #endif  
               relocation = 0;  
             }  
           else  
             {  
               if (! ((*info->callbacks->undefined_symbol)  
                      (info, h->root.root.string, input_bfd,  
                       input_section, rel->r_offset, true)))  
                 return false;  
 #if 0  
               fprintf (stderr, "unknown: name: %s\n", h->root.root.string);  
 #endif  
               relocation = 0;  
             }  
1707          }          }
1708    
1709        /* FIXME: We should use the addend, but the COFF relocations don't.  */        /* FIXME: We should use the addend, but the COFF relocations don't.  */
# Line 1675  v850_elf_relocate_section (output_bfd, i Line 1732  v850_elf_relocate_section (output_bfd, i
1732              {              {
1733              case bfd_reloc_overflow:              case bfd_reloc_overflow:
1734                if (! ((*info->callbacks->reloc_overflow)                if (! ((*info->callbacks->reloc_overflow)
1735                       (info, name, howto->name, (bfd_vma) 0,                       (info, (h ? &h->root : NULL), name, howto->name,
1736                        input_bfd, input_section, rel->r_offset)))                        (bfd_vma) 0, input_bfd, input_section,
1737                  return false;                        rel->r_offset)))
1738                    return FALSE;
1739                break;                break;
1740    
1741              case bfd_reloc_undefined:              case bfd_reloc_undefined:
1742                if (! ((*info->callbacks->undefined_symbol)                if (! ((*info->callbacks->undefined_symbol)
1743                       (info, name, input_bfd, input_section,                       (info, name, input_bfd, input_section,
1744                        rel->r_offset, true)))                        rel->r_offset, TRUE)))
1745                  return false;                  return FALSE;
1746                break;                break;
1747    
1748              case bfd_reloc_outofrange:              case bfd_reloc_outofrange:
# Line 1699  v850_elf_relocate_section (output_bfd, i Line 1757  v850_elf_relocate_section (output_bfd, i
1757                msg = _("internal error: dangerous relocation");                msg = _("internal error: dangerous relocation");
1758                goto common_error;                goto common_error;
1759    
1760              case bfd_reloc_other:              case bfd_reloc_gp_not_found:
1761                msg = _("could not locate special linker symbol __gp");                msg = _("could not locate special linker symbol __gp");
1762                goto common_error;                goto common_error;
1763    
1764              case bfd_reloc_continue:              case bfd_reloc_ep_not_found:
1765                msg = _("could not locate special linker symbol __ep");                msg = _("could not locate special linker symbol __ep");
1766                goto common_error;                goto common_error;
1767    
1768              case (bfd_reloc_dangerous + 1):              case bfd_reloc_ctbp_not_found:
1769                msg = _("could not locate special linker symbol __ctbp");                msg = _("could not locate special linker symbol __ctbp");
1770                goto common_error;                goto common_error;
1771    
# Line 1719  v850_elf_relocate_section (output_bfd, i Line 1777  v850_elf_relocate_section (output_bfd, i
1777                if (!((*info->callbacks->warning)                if (!((*info->callbacks->warning)
1778                      (info, msg, name, input_bfd, input_section,                      (info, msg, name, input_bfd, input_section,
1779                       rel->r_offset)))                       rel->r_offset)))
1780                  return false;                  return FALSE;
1781                break;                break;
1782              }              }
1783          }          }
1784      }      }
1785    
1786    return true;    return TRUE;
1787  }  }
1788    
1789  static boolean  static bfd_boolean
1790  v850_elf_gc_sweep_hook (abfd, info, sec, relocs)  v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
1791       bfd *abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
1792       struct bfd_link_info *info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
# Line 1736  v850_elf_gc_sweep_hook (abfd, info, sec, Line 1794  v850_elf_gc_sweep_hook (abfd, info, sec,
1794       const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;       const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
1795  {  {
1796    /* No got and plt entries for v850-elf.  */    /* No got and plt entries for v850-elf.  */
1797    return true;    return TRUE;
1798  }  }
1799    
1800  static asection *  static asection *
# Line 1778  v850_elf_gc_mark_hook (sec, info, rel, h Line 1836  v850_elf_gc_mark_hook (sec, info, rel, h
1836    
1837  /* Set the right machine number.  */  /* Set the right machine number.  */
1838    
1839  static boolean  static bfd_boolean
1840  v850_elf_object_p (abfd)  v850_elf_object_p (abfd)
1841       bfd *abfd;       bfd *abfd;
1842  {  {
1843    switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)    switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1844      {      {
1845      default:      default:
1846      case E_V850_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;      case E_V850_ARCH:
1847      case E_V850E_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;        bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850);
1848      case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;        break;
1849        case E_V850E_ARCH:
1850          bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e);
1851          break;
1852        case E_V850E1_ARCH:
1853          bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e1);
1854          break;
1855      }      }
1856    return true;    return TRUE;
1857  }  }
1858    
1859  /* Store the machine number in the flags field.  */  /* Store the machine number in the flags field.  */
1860    
1861  static void  static void
1862  v850_elf_final_write_processing (abfd, linker)  v850_elf_final_write_processing (abfd, linker)
1863       bfd *   abfd;       bfd *abfd;
1864       boolean linker ATTRIBUTE_UNUSED;       bfd_boolean linker ATTRIBUTE_UNUSED;
1865  {  {
1866    unsigned long val;    unsigned long val;
1867    
1868    switch (bfd_get_mach (abfd))    switch (bfd_get_mach (abfd))
1869      {      {
1870      default:      default:
1871      case 0: val = E_V850_ARCH; break;      case bfd_mach_v850:  val = E_V850_ARCH; break;
1872      case bfd_mach_v850e:  val = E_V850E_ARCH; break;      case bfd_mach_v850e: val = E_V850E_ARCH; break;
1873      case bfd_mach_v850ea: val = E_V850EA_ARCH;  break;      case bfd_mach_v850e1: val = E_V850E1_ARCH;  break;
1874      }      }
1875    
1876    elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;    elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
# Line 1815  v850_elf_final_write_processing (abfd, l Line 1879  v850_elf_final_write_processing (abfd, l
1879    
1880  /* Function to keep V850 specific file flags.  */  /* Function to keep V850 specific file flags.  */
1881    
1882  static boolean  static bfd_boolean
1883  v850_elf_set_private_flags (abfd, flags)  v850_elf_set_private_flags (abfd, flags)
1884       bfd *    abfd;       bfd *abfd;
1885       flagword flags;       flagword flags;
1886  {  {
1887    BFD_ASSERT (!elf_flags_init (abfd)    BFD_ASSERT (!elf_flags_init (abfd)
1888                || elf_elfheader (abfd)->e_flags == flags);                || elf_elfheader (abfd)->e_flags == flags);
1889    
1890    elf_elfheader (abfd)->e_flags = flags;    elf_elfheader (abfd)->e_flags = flags;
1891    elf_flags_init (abfd) = true;    elf_flags_init (abfd) = TRUE;
1892    return true;    return TRUE;
1893  }  }
1894    
1895  /* Merge backend specific data from an object file  /* Merge backend specific data from an object file
1896     to the output object file when linking.  */     to the output object file when linking.  */
1897  static boolean  static bfd_boolean
1898  v850_elf_merge_private_bfd_data (ibfd, obfd)  v850_elf_merge_private_bfd_data (ibfd, obfd)
1899       bfd * ibfd;       bfd *ibfd;
1900       bfd * obfd;       bfd *obfd;
1901  {  {
1902    flagword out_flags;    flagword out_flags;
1903    flagword in_flags;    flagword in_flags;
1904    
1905    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour    if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1906        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1907      return true;      return TRUE;
1908    
1909    in_flags = elf_elfheader (ibfd)->e_flags;    in_flags = elf_elfheader (ibfd)->e_flags;
1910    out_flags = elf_elfheader (obfd)->e_flags;    out_flags = elf_elfheader (obfd)->e_flags;
# Line 1854  v850_elf_merge_private_bfd_data (ibfd, o Line 1918  v850_elf_merge_private_bfd_data (ibfd, o
1918           unitialised values, which surprise surprise, correspond           unitialised values, which surprise surprise, correspond
1919           to the default values.  */           to the default values.  */
1920        if (bfd_get_arch_info (ibfd)->the_default)        if (bfd_get_arch_info (ibfd)->the_default)
1921          return true;          return TRUE;
1922    
1923        elf_flags_init (obfd) = true;        elf_flags_init (obfd) = TRUE;
1924        elf_elfheader (obfd)->e_flags = in_flags;        elf_elfheader (obfd)->e_flags = in_flags;
1925    
1926        if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)        if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1927            && bfd_get_arch_info (obfd)->the_default)            && bfd_get_arch_info (obfd)->the_default)
1928          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1929    
1930        return true;        return TRUE;
1931      }      }
1932    
1933    /* Check flag compatibility.  */    /* Check flag compatibility.  */
1934    if (in_flags == out_flags)    if (in_flags == out_flags)
1935      return true;      return TRUE;
1936    
1937    if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)    if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
1938        && (in_flags & EF_V850_ARCH) != E_V850_ARCH)        && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
1939      _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),      {
1940                          bfd_archive_filename (ibfd));        /* Allow v850e1 binaries to be linked with v850e binaries.
1941             Set the output binary to v850e.  */
1942          if ((in_flags & EF_V850_ARCH) == E_V850E1_ARCH
1943              && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
1944            return TRUE;
1945    
1946          if ((in_flags & EF_V850_ARCH) == E_V850E_ARCH
1947              && (out_flags & EF_V850_ARCH) == E_V850E1_ARCH)
1948            {
1949              elf_elfheader (obfd)->e_flags =
1950                ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
1951              return TRUE;
1952            }
1953    
1954          _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
1955                              ibfd);
1956        }
1957    
1958    return true;    return TRUE;
1959  }  }
1960    
1961  /* Display the flags field.  */  /* Display the flags field.  */
1962    
1963  static boolean  static bfd_boolean
1964  v850_elf_print_private_bfd_data (abfd, ptr)  v850_elf_print_private_bfd_data (abfd, ptr)
1965       bfd *   abfd;       bfd *abfd;
1966       PTR     ptr;       PTR ptr;
1967  {  {
1968    FILE * file = (FILE *) ptr;    FILE * file = (FILE *) ptr;
1969    
# Line 1899  v850_elf_print_private_bfd_data (abfd, p Line 1979  v850_elf_print_private_bfd_data (abfd, p
1979      default:      default:
1980      case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;      case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
1981      case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;      case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;
1982      case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;      case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
1983      }      }
1984    
1985    fputc ('\n', file);    fputc ('\n', file);
1986    
1987    return true;    return TRUE;
1988  }  }
1989    
1990  /* V850 ELF uses four common sections.  One is the usual one, and the  /* V850 ELF uses four common sections.  One is the usual one, and the
# Line 1927  static asymbol * v850_elf_zcom_symbol_pt Line 2007  static asymbol * v850_elf_zcom_symbol_pt
2007  /* Given a BFD section, try to locate the  /* Given a BFD section, try to locate the
2008     corresponding ELF section index.  */     corresponding ELF section index.  */
2009    
2010  static boolean  static bfd_boolean
2011  v850_elf_section_from_bfd_section (abfd, sec, retval)  v850_elf_section_from_bfd_section (abfd, sec, retval)
2012       bfd *                 abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
2013       asection *            sec;       asection *sec;
2014       int *                 retval;       int *retval;
2015  {  {
2016    if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)    if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2017      *retval = SHN_V850_SCOMMON;      *retval = SHN_V850_SCOMMON;
# Line 1940  v850_elf_section_from_bfd_section (abfd, Line 2020  v850_elf_section_from_bfd_section (abfd,
2020    else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)    else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
2021      *retval = SHN_V850_ZCOMMON;      *retval = SHN_V850_ZCOMMON;
2022    else    else
2023      return false;      return FALSE;
2024    
2025    return true;    return TRUE;
2026  }  }
2027    
2028  /* Handle the special V850 section numbers that a symbol may use.  */  /* Handle the special V850 section numbers that a symbol may use.  */
2029    
2030  static void  static void
2031  v850_elf_symbol_processing (abfd, asym)  v850_elf_symbol_processing (abfd, asym)
2032       bfd *     abfd;       bfd *abfd;
2033       asymbol * asym;       asymbol *asym;
2034  {  {
2035    elf_symbol_type * elfsym = (elf_symbol_type *) asym;    elf_symbol_type * elfsym = (elf_symbol_type *) asym;
2036    unsigned int indx;    unsigned int indx;
# Line 2043  v850_elf_symbol_processing (abfd, asym) Line 2123  v850_elf_symbol_processing (abfd, asym)
2123  /* Hook called by the linker routine which adds symbols from an object  /* Hook called by the linker routine which adds symbols from an object
2124     file.  We must handle the special v850 section numbers here.  */     file.  We must handle the special v850 section numbers here.  */
2125    
2126  static boolean  static bfd_boolean
2127  v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)  v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
2128       bfd *                    abfd;       bfd *abfd;
2129       struct bfd_link_info *   info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
2130       const Elf_Internal_Sym * sym;       Elf_Internal_Sym *sym;
2131       const char **            namep ATTRIBUTE_UNUSED;       const char **namep ATTRIBUTE_UNUSED;
2132       flagword *               flagsp ATTRIBUTE_UNUSED;       flagword *flagsp ATTRIBUTE_UNUSED;
2133       asection **              secp;       asection **secp;
2134       bfd_vma *                valp;       bfd_vma *valp;
2135  {  {
2136    unsigned int indx = sym->st_shndx;    unsigned int indx = sym->st_shndx;
2137    
# Line 2101  v850_elf_add_symbol_hook (abfd, info, sy Line 2181  v850_elf_add_symbol_hook (abfd, info, sy
2181        break;        break;
2182      }      }
2183    
2184    return true;    return TRUE;
2185  }  }
2186    
2187  static boolean  static bfd_boolean
2188  v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)  v850_elf_link_output_symbol_hook (info, name, sym, input_sec, h)
2189       bfd *                  abfd ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
2190       struct bfd_link_info * info ATTRIBUTE_UNUSED;       const char *name ATTRIBUTE_UNUSED;
2191       const char *           name ATTRIBUTE_UNUSED;       Elf_Internal_Sym *sym;
2192       Elf_Internal_Sym *     sym;       asection *input_sec;
2193       asection *             input_sec;       struct elf_link_hash_entry *h ATTRIBUTE_UNUSED;
2194  {  {
2195    /* If we see a common symbol, which implies a relocatable link, then    /* If we see a common symbol, which implies a relocatable link, then
2196       if a symbol was in a special common section in an input file, mark       if a symbol was in a special common section in an input file, mark
# Line 2126  v850_elf_link_output_symbol_hook (abfd, Line 2206  v850_elf_link_output_symbol_hook (abfd,
2206          sym->st_shndx = SHN_V850_ZCOMMON;          sym->st_shndx = SHN_V850_ZCOMMON;
2207      }      }
2208    
2209    return true;    return TRUE;
2210  }  }
2211    
2212  static boolean  static bfd_boolean
2213  v850_elf_section_from_shdr (abfd, hdr, name)  v850_elf_section_from_shdr (abfd, hdr, name)
2214       bfd *               abfd;       bfd *abfd;
2215       Elf_Internal_Shdr * hdr;       Elf_Internal_Shdr *hdr;
2216       const char *        name;       const char *name;
2217  {  {
2218    /* There ought to be a place to keep ELF backend specific flags, but    /* There ought to be a place to keep ELF backend specific flags, but
2219       at the moment there isn't one.  We just keep track of the       at the moment there isn't one.  We just keep track of the
2220       sections by their name, instead.  */       sections by their name, instead.  */
2221    
2222    if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))    if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2223      return false;      return FALSE;
2224    
2225    switch (hdr->sh_type)    switch (hdr->sh_type)
2226      {      {
# Line 2151  v850_elf_section_from_shdr (abfd, hdr, n Line 2231  v850_elf_section_from_shdr (abfd, hdr, n
2231                                     (bfd_get_section_flags (abfd,                                     (bfd_get_section_flags (abfd,
2232                                                             hdr->bfd_section)                                                             hdr->bfd_section)
2233                                      | SEC_IS_COMMON)))                                      | SEC_IS_COMMON)))
2234          return false;          return FALSE;
2235      }      }
2236    
2237    return true;    return TRUE;
2238  }  }
2239    
2240  /* Set the correct type for a V850 ELF section.  We do this  /* Set the correct type for a V850 ELF section.  We do this
2241     by the section name, which is a hack, but ought to work.  */     by the section name, which is a hack, but ought to work.  */
2242    
2243  static boolean  static bfd_boolean
2244  v850_elf_fake_sections (abfd, hdr, sec)  v850_elf_fake_sections (abfd, hdr, sec)
2245       bfd *                 abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
2246       Elf32_Internal_Shdr * hdr;       Elf_Internal_Shdr *hdr;
2247       asection *            sec;       asection *sec;
2248  {  {
2249    register const char * name;    register const char * name;
2250    
# Line 2181  v850_elf_fake_sections (abfd, hdr, sec) Line 2261  v850_elf_fake_sections (abfd, hdr, sec)
2261    else if (strcmp (name, ".zcommon") == 0)    else if (strcmp (name, ".zcommon") == 0)
2262      hdr->sh_type = SHT_V850_ZCOMMON;      hdr->sh_type = SHT_V850_ZCOMMON;
2263    
2264    return true;    return TRUE;
2265    }
2266    
2267    /* Delete some bytes from a section while relaxing.  */
2268    
2269    static bfd_boolean
2270    v850_elf_relax_delete_bytes (abfd, sec, addr, toaddr, count)
2271         bfd *abfd;
2272         asection *sec;
2273         bfd_vma addr;
2274         bfd_vma toaddr;
2275         int count;
2276    {
2277      Elf_Internal_Shdr *symtab_hdr;
2278      Elf32_External_Sym *extsyms;
2279      Elf32_External_Sym *esym;
2280      Elf32_External_Sym *esymend;
2281      int index;
2282      unsigned int sec_shndx;
2283      bfd_byte *contents;
2284      Elf_Internal_Rela *irel;
2285      Elf_Internal_Rela *irelend;
2286      struct elf_link_hash_entry *sym_hash;
2287      Elf_Internal_Shdr *shndx_hdr;
2288      Elf_External_Sym_Shndx *shndx;
2289    
2290      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2291      extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
2292    
2293      sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2294    
2295      contents = elf_section_data (sec)->this_hdr.contents;
2296    
2297      /* The deletion must stop at the next ALIGN reloc for an alignment
2298         power larger than the number of bytes we are deleting.  */
2299    
2300      /* Actually delete the bytes.  */
2301    #if (DEBUG_RELAX & 2)
2302      fprintf (stderr, "relax_delete: contents: sec: %s  %p .. %p %x\n",
2303               sec->name, addr, toaddr, count );
2304    #endif
2305      memmove (contents + addr, contents + addr + count,
2306               toaddr - addr - count);
2307      memset (contents + toaddr-count, 0, count);
2308    
2309      /* Adjust all the relocs.  */
2310      irel = elf_section_data (sec)->relocs;
2311      irelend = irel + sec->reloc_count;
2312      shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
2313      shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
2314    
2315      for (; irel < irelend; irel++)
2316        {
2317          bfd_vma raddr, paddr, symval;
2318          Elf_Internal_Sym isym;
2319    
2320          /* Get the new reloc address.  */
2321          raddr = irel->r_offset;
2322          if ((raddr >= (addr + count) && raddr < toaddr))
2323            irel->r_offset -= count;
2324    
2325          if (raddr >= addr && raddr < addr + count)
2326            {
2327              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2328                                           (int) R_V850_NONE);
2329              continue;
2330            }
2331    
2332          if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
2333            continue;
2334    
2335          bfd_elf32_swap_symbol_in (abfd,
2336                                    extsyms + ELF32_R_SYM (irel->r_info),
2337                                    shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
2338                                    & isym);
2339    
2340          if (isym.st_shndx != sec_shndx)
2341            continue;
2342    
2343          /* Get the value of the symbol referred to by the reloc.  */
2344          if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2345            {
2346              symval = isym.st_value;
2347    #if (DEBUG_RELAX & 2)
2348              {
2349                char * name = bfd_elf_string_from_elf_section
2350                               (abfd, symtab_hdr->sh_link, isym.st_name);
2351                fprintf (stderr,
2352                   "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
2353                   sec->name, name, isym.st_name,
2354                   sec->output_section->vma, sec->output_offset,
2355                   isym.st_value, irel->r_addend);
2356              }
2357    #endif
2358            }
2359          else
2360            {
2361              unsigned long indx;
2362              struct elf_link_hash_entry * h;
2363    
2364              /* An external symbol.  */
2365              indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2366    
2367              h = elf_sym_hashes (abfd) [indx];
2368              BFD_ASSERT (h != NULL);
2369    
2370              symval = h->root.u.def.value;
2371    #if (DEBUG_RELAX & 2)
2372              fprintf (stderr,
2373                       "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
2374                       sec->name, h->root.root.string, h->root.u.def.value,
2375                       sec->output_section->vma, sec->output_offset, irel->r_addend);
2376    #endif
2377            }
2378    
2379          paddr = symval + irel->r_addend;
2380    
2381          if ( (symval >= addr + count && symval < toaddr)
2382              && (paddr < addr + count || paddr >= toaddr))
2383            irel->r_addend += count;
2384          else if (    (symval < addr + count || symval >= toaddr)
2385                    && (paddr >= addr + count && paddr < toaddr))
2386            irel->r_addend -= count;
2387        }
2388    
2389      /* Adjust the local symbols defined in this section.  */
2390      esym = extsyms;
2391      esymend = esym + symtab_hdr->sh_info;
2392    
2393      for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
2394        {
2395          Elf_Internal_Sym isym;
2396    
2397          bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
2398    
2399          if (isym.st_shndx == sec_shndx
2400              && isym.st_value >= addr + count
2401              && isym.st_value < toaddr)
2402            {
2403              isym.st_value -= count;
2404    
2405              if (isym.st_value + isym.st_size >= toaddr)
2406                isym.st_size += count;
2407    
2408              bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2409            }
2410          else if (isym.st_shndx == sec_shndx
2411                   && isym.st_value < addr + count)
2412            {
2413              if (isym.st_value+isym.st_size >= addr + count
2414                  && isym.st_value+isym.st_size < toaddr)
2415                isym.st_size -= count;
2416    
2417              if (isym.st_value >= addr
2418                  && isym.st_value <  addr + count)
2419                isym.st_value = addr;
2420    
2421              bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2422            }
2423        }
2424    
2425      /* Now adjust the global symbols defined in this section.  */
2426      esym = extsyms + symtab_hdr->sh_info;
2427      esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
2428    
2429      for (index = 0; esym < esymend; esym ++, index ++)
2430        {
2431          Elf_Internal_Sym isym;
2432    
2433          bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
2434          sym_hash = elf_sym_hashes (abfd) [index];
2435    
2436          if (isym.st_shndx == sec_shndx
2437              && ((sym_hash)->root.type == bfd_link_hash_defined
2438                  || (sym_hash)->root.type == bfd_link_hash_defweak)
2439              && (sym_hash)->root.u.def.section == sec
2440              && (sym_hash)->root.u.def.value >= addr + count
2441              && (sym_hash)->root.u.def.value < toaddr)
2442            {
2443              if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
2444                {
2445                  isym.st_size += count;
2446                  bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2447                }
2448    
2449              (sym_hash)->root.u.def.value -= count;
2450            }
2451          else if (isym.st_shndx == sec_shndx
2452                   && ((sym_hash)->root.type == bfd_link_hash_defined
2453                       || (sym_hash)->root.type == bfd_link_hash_defweak)
2454                   && (sym_hash)->root.u.def.section == sec
2455                   && (sym_hash)->root.u.def.value < addr + count)
2456            {
2457              if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
2458                  && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
2459                isym.st_size -= count;
2460    
2461              if ((sym_hash)->root.u.def.value >= addr
2462                  && (sym_hash)->root.u.def.value < addr + count)
2463                (sym_hash)->root.u.def.value = addr;
2464    
2465              bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2466            }
2467    
2468          if (shndx)
2469            ++ shndx;
2470        }
2471    
2472      return TRUE;
2473  }  }
2474    
2475    #define NOP_OPCODE      (0x0000)
2476    #define MOVHI           0x0640                          /* 4byte */
2477    #define MOVHI_MASK      0x07e0
2478    #define MOVHI_R1(insn)  ((insn) & 0x1f)                 /* 4byte */
2479    #define MOVHI_R2(insn)  ((insn) >> 11)
2480    #define MOVEA           0x0620                          /* 2byte */
2481    #define MOVEA_MASK      0x07e0
2482    #define MOVEA_R1(insn)  ((insn) & 0x1f)
2483    #define MOVEA_R2(insn)  ((insn) >> 11)
2484    #define JARL_4          0x00040780                              /* 4byte */
2485    #define JARL_4_MASK     0xFFFF07FF
2486    #define JARL_R2(insn)   (int)(((insn) & (~JARL_4_MASK)) >> 11)
2487    #define ADD_I           0x0240                                  /* 2byte */
2488    #define ADD_I_MASK      0x07e0
2489    #define ADD_I5(insn)    ((((insn) & 0x001f) << 11) >> 11)       /* 2byte */
2490    #define ADD_R2(insn)    ((insn) >> 11)
2491    #define JMP_R           0x0060                                  /* 2byte */
2492    #define JMP_R_MASK      0xFFE0
2493    #define JMP_R1(insn)    ((insn) & 0x1f)
2494    
2495    static bfd_boolean
2496    v850_elf_relax_section (abfd, sec, link_info, again)
2497         bfd *abfd;
2498         asection *sec;
2499         struct bfd_link_info *link_info;
2500         bfd_boolean *again;
2501    {
2502      Elf_Internal_Shdr *symtab_hdr;
2503      Elf_Internal_Rela *internal_relocs;
2504      Elf_Internal_Rela *irel;
2505      Elf_Internal_Rela *irelend;
2506      Elf_Internal_Rela *irelalign = NULL;
2507      Elf_Internal_Sym *isymbuf = NULL;
2508      bfd_byte *contents = NULL;
2509      bfd_vma addr = 0;
2510      bfd_vma toaddr;
2511      int align_pad_size = 0;
2512      bfd_boolean result = TRUE;
2513    
2514      *again = FALSE;
2515    
2516      if (link_info->relocatable
2517          || (sec->flags & SEC_RELOC) == 0
2518          || sec->reloc_count == 0)
2519        return TRUE;
2520    
2521      symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2522    
2523      internal_relocs = (_bfd_elf_link_read_relocs
2524                         (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2525                          link_info->keep_memory));
2526      if (internal_relocs == NULL)
2527        goto error_return;
2528    
2529      irelend = internal_relocs + sec->reloc_count;
2530    
2531      while (addr < sec->size)
2532        {
2533          toaddr = sec->size;
2534    
2535          for (irel = internal_relocs; irel < irelend; irel ++)
2536            if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
2537                && irel->r_offset > addr
2538                && irel->r_offset < toaddr)
2539              toaddr = irel->r_offset;
2540    
2541    #ifdef DEBUG_RELAX
2542          fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
2543                   addr, toaddr, align_pad_size);
2544    #endif
2545          if (irelalign)
2546            {
2547              bfd_vma alignto;
2548              bfd_vma alignmoveto;
2549    
2550              alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
2551              alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
2552    
2553              if (alignmoveto < alignto)
2554                {
2555                  unsigned int i;
2556    
2557                  align_pad_size = alignto - alignmoveto;
2558    #ifdef DEBUG_RELAX
2559                  fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
2560                           alignmoveto, toaddr, align_pad_size);
2561    #endif
2562                  if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
2563                                                    toaddr, align_pad_size))
2564                    goto error_return;
2565    
2566                  for (i  = BFD_ALIGN (toaddr - align_pad_size, 1);
2567                       (i + 1) < toaddr; i += 2)
2568                    bfd_put_16 (abfd, NOP_OPCODE, contents + i);
2569    
2570                  addr = alignmoveto;
2571                }
2572              else
2573                align_pad_size = 0;
2574            }
2575    
2576          for (irel = internal_relocs; irel < irelend; irel++)
2577            {
2578              bfd_vma laddr;
2579              bfd_vma addend;
2580              bfd_vma symval;
2581              int insn[5];
2582              int no_match = -1;
2583              Elf_Internal_Rela *hi_irelfn;
2584              Elf_Internal_Rela *lo_irelfn;
2585              Elf_Internal_Rela *irelcall;
2586              bfd_signed_vma foff;
2587    
2588              if (! (irel->r_offset >= addr && irel->r_offset < toaddr
2589                     && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
2590                         || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
2591                continue;
2592    
2593    #ifdef DEBUG_RELAX
2594              fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
2595                       irel->r_info,
2596                       irel->r_offset,
2597                       irel->r_addend );
2598    #endif
2599    
2600              /* Get the section contents.  */
2601              if (contents == NULL)
2602                {
2603                  if (elf_section_data (sec)->this_hdr.contents != NULL)
2604                    contents = elf_section_data (sec)->this_hdr.contents;
2605                  else
2606                    {
2607                      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
2608                        goto error_return;
2609                    }
2610                }
2611    
2612              /* Read this BFD's local symbols if we haven't done so already.  */
2613              if (isymbuf == NULL && symtab_hdr->sh_info != 0)
2614                {
2615                  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2616                  if (isymbuf == NULL)
2617                    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2618                                                    symtab_hdr->sh_info, 0,
2619                                                    NULL, NULL, NULL);
2620                  if (isymbuf == NULL)
2621                    goto error_return;
2622                }
2623    
2624              laddr = irel->r_offset;
2625    
2626              if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
2627                {
2628                  /* Check code for -mlong-calls output. */
2629                  if (laddr + 16 <= (bfd_vma) sec->size)
2630                    {
2631                      insn[0] = bfd_get_16 (abfd, contents + laddr);
2632                      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
2633                      insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
2634                      insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
2635                      insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
2636    
2637                      if ((insn[0] & MOVHI_MASK) != MOVHI
2638                           || MOVHI_R1 (insn[0]) != 0)
2639                        no_match = 0;
2640    
2641                      if (no_match < 0
2642                          && ((insn[1] & MOVEA_MASK) != MOVEA
2643                               || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
2644                        no_match = 1;
2645    
2646                      if (no_match < 0
2647                          && (insn[2] & JARL_4_MASK) != JARL_4)
2648                        no_match = 2;
2649    
2650                      if (no_match < 0
2651                          && ((insn[3] & ADD_I_MASK) != ADD_I
2652                               || ADD_I5 (insn[3]) != 4
2653                               || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
2654                        no_match = 3;
2655    
2656                      if (no_match < 0
2657                          && ((insn[4] & JMP_R_MASK) != JMP_R
2658                               || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
2659                        no_match = 4;
2660                    }
2661                  else
2662                    {
2663                      ((*_bfd_error_handler)
2664                       ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
2665                        bfd_get_filename (abfd), (unsigned long) irel->r_offset));
2666    
2667                      continue;
2668                    }
2669    
2670                  if (no_match >= 0)
2671                    {
2672                      ((*_bfd_error_handler)
2673                       ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
2674                        bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
2675    
2676                      continue;
2677                    }
2678    
2679                  /* Get the reloc for the address from which the register is
2680                     being loaded.  This reloc will tell us which function is
2681                     actually being called.  */
2682                  for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
2683                    if (hi_irelfn->r_offset == laddr + 2
2684                        && ELF32_R_TYPE (hi_irelfn->r_info)
2685                            == (int) R_V850_HI16_S)
2686                      break;
2687    
2688                  for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
2689                    if (lo_irelfn->r_offset == laddr + 6
2690                        && ELF32_R_TYPE (lo_irelfn->r_info)
2691                            == (int) R_V850_LO16)
2692                      break;
2693    
2694                  for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
2695                    if (irelcall->r_offset == laddr + 8
2696                        && ELF32_R_TYPE (irelcall->r_info)
2697                            == (int) R_V850_22_PCREL)
2698                      break;
2699    
2700                  if (   hi_irelfn == irelend
2701                      || lo_irelfn == irelend
2702                      || irelcall  == irelend)
2703                    {
2704                      ((*_bfd_error_handler)
2705                       ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
2706                        bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
2707    
2708                      continue;
2709                    }
2710    
2711                  if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
2712                    {
2713                      Elf_Internal_Sym *  isym;
2714    
2715                      /* A local symbol.  */
2716                      isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
2717    
2718                      symval = isym->st_value;
2719                    }
2720                  else
2721                    {
2722                      unsigned long indx;
2723                      struct elf_link_hash_entry * h;
2724    
2725                      /* An external symbol.  */
2726                      indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
2727                      h = elf_sym_hashes (abfd)[indx];
2728                      BFD_ASSERT (h != NULL);
2729    
2730                      if (   h->root.type != bfd_link_hash_defined
2731                          && h->root.type != bfd_link_hash_defweak)
2732                        /* This appears to be a reference to an undefined
2733                           symbol.  Just ignore it--it will be caught by the
2734                           regular reloc processing.  */
2735                        continue;
2736    
2737                      symval = h->root.u.def.value;
2738                    }
2739    
2740                  if (symval + irelcall->r_addend != irelcall->r_offset + 4)
2741                    {
2742                      ((*_bfd_error_handler)
2743                       ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
2744                        bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
2745    
2746                      continue;
2747                    }
2748    
2749                  /* Get the value of the symbol referred to by the reloc.  */
2750                  if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
2751                    {
2752                      Elf_Internal_Sym *isym;
2753                      asection *sym_sec;
2754    
2755                      /* A local symbol.  */
2756                      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
2757    
2758                      if (isym->st_shndx == SHN_UNDEF)
2759                        sym_sec = bfd_und_section_ptr;
2760                      else if (isym->st_shndx == SHN_ABS)
2761                        sym_sec = bfd_abs_section_ptr;
2762                      else if (isym->st_shndx == SHN_COMMON)
2763                        sym_sec = bfd_com_section_ptr;
2764                      else
2765                        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2766                      symval = (isym->st_value
2767                                + sym_sec->output_section->vma
2768                                + sym_sec->output_offset);
2769                    }
2770                  else
2771                    {
2772                      unsigned long indx;
2773                      struct elf_link_hash_entry *h;
2774    
2775                      /* An external symbol.  */
2776                      indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
2777                      h = elf_sym_hashes (abfd)[indx];
2778                      BFD_ASSERT (h != NULL);
2779    
2780                      if (   h->root.type != bfd_link_hash_defined
2781                          && h->root.type != bfd_link_hash_defweak)
2782                        /* This appears to be a reference to an undefined
2783                           symbol.  Just ignore it--it will be caught by the
2784                           regular reloc processing.  */
2785                        continue;
2786    
2787                      symval = (h->root.u.def.value
2788                                + h->root.u.def.section->output_section->vma
2789                                + h->root.u.def.section->output_offset);
2790                    }
2791    
2792                  addend = irel->r_addend;
2793    
2794                  foff = (symval + addend
2795                          - (irel->r_offset
2796                             + sec->output_section->vma
2797                             + sec->output_offset
2798                             + 4));
2799    #ifdef DEBUG_RELAX
2800                  fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
2801                           irel->r_offset,
2802                           (irel->r_offset
2803                            + sec->output_section->vma
2804                            + sec->output_offset),
2805                           symval, addend, foff);
2806    #endif
2807    
2808                  if (foff < -0x100000 || foff >= 0x100000)
2809                    /* After all that work, we can't shorten this function call.  */
2810                    continue;
2811    
2812                  /* For simplicity of coding, we are going to modify the section
2813                     contents, the section relocs, and the BFD symbol table.  We
2814                     must tell the rest of the code not to free up this
2815                     information.  It would be possible to instead create a table
2816                     of changes which have to be made, as is done in coff-mips.c;
2817                     that would be more work, but would require less memory when
2818                     the linker is run.  */
2819                  elf_section_data (sec)->relocs = internal_relocs;
2820                  elf_section_data (sec)->this_hdr.contents = contents;
2821                  symtab_hdr->contents = (bfd_byte *) isymbuf;
2822    
2823                  /* Replace the long call with a jarl.  */
2824                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
2825    
2826                  addend = 0;
2827    
2828                  if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
2829                    /* If this needs to be changed because of future relaxing,
2830                       it will be handled here like other internal IND12W
2831                       relocs.  */
2832                    bfd_put_32 (abfd,
2833                                0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
2834                                contents + irel->r_offset);
2835                  else
2836                    /* We can't fully resolve this yet, because the external
2837                       symbol value may be changed by future relaxing.
2838                       We let the final link phase handle it.  */
2839                    bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
2840                                contents + irel->r_offset);
2841    
2842                  hi_irelfn->r_info =
2843                    ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
2844                  lo_irelfn->r_info =
2845                    ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
2846                  irelcall->r_info =
2847                    ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
2848    
2849                  if (! v850_elf_relax_delete_bytes (abfd, sec,
2850                                                     irel->r_offset + 4, toaddr, 12))
2851                    goto error_return;
2852    
2853                  align_pad_size += 12;
2854                }
2855              else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
2856                {
2857                  /* Check code for -mlong-jumps output.  */
2858                  if (laddr + 10 <= (bfd_vma) sec->size)
2859                    {
2860                      insn[0] = bfd_get_16 (abfd, contents + laddr);
2861                      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
2862                      insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
2863    
2864                      if ((insn[0] & MOVHI_MASK) != MOVHI
2865                           || MOVHI_R1 (insn[0]) != 0)
2866                        no_match = 0;
2867    
2868                      if (no_match < 0
2869                          && ((insn[1] & MOVEA_MASK) != MOVEA
2870                               || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
2871                        no_match = 1;
2872    
2873                      if (no_match < 0
2874                          && ((insn[2] & JMP_R_MASK) != JMP_R
2875                               || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
2876                        no_match = 4;
2877                    }
2878                  else
2879                    {
2880                      ((*_bfd_error_handler)
2881                       ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
2882                        bfd_get_filename (abfd), (unsigned long) irel->r_offset));
2883    
2884                      continue;
2885                    }
2886    
2887                  if (no_match >= 0)
2888                    {
2889                      ((*_bfd_error_handler)
2890                       ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
2891                        bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
2892    
2893                      continue;
2894                    }
2895    
2896                  /* Get the reloc for the address from which the register is
2897                     being loaded.  This reloc will tell us which function is
2898                     actually being called.  */
2899                  for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
2900                    if (hi_irelfn->r_offset == laddr + 2
2901                        && ELF32_R_TYPE (hi_irelfn->r_info) == (int) R_V850_HI16_S)
2902                      break;
2903    
2904                  for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
2905                    if (lo_irelfn->r_offset == laddr + 6
2906                        && ELF32_R_TYPE (lo_irelfn->r_info) == (int) R_V850_LO16)
2907                      break;
2908    
2909                  if (   hi_irelfn == irelend
2910                      || lo_irelfn == irelend)
2911                    {
2912                      ((*_bfd_error_handler)
2913                       ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
2914                        bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
2915    
2916                      continue;
2917                    }
2918    
2919                  /* Get the value of the symbol referred to by the reloc.  */
2920                  if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
2921                    {
2922                      Elf_Internal_Sym *  isym;
2923                      asection *          sym_sec;
2924    
2925                      /* A local symbol.  */
2926                      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
2927    
2928                      if (isym->st_shndx == SHN_UNDEF)
2929                        sym_sec = bfd_und_section_ptr;
2930                      else if (isym->st_shndx == SHN_ABS)
2931                        sym_sec = bfd_abs_section_ptr;
2932                      else if (isym->st_shndx == SHN_COMMON)
2933                        sym_sec = bfd_com_section_ptr;
2934                      else
2935                        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2936                      symval = (isym->st_value
2937                                + sym_sec->output_section->vma
2938                                + sym_sec->output_offset);
2939    #ifdef DEBUG_RELAX
2940                      {
2941                        char * name = bfd_elf_string_from_elf_section
2942                          (abfd, symtab_hdr->sh_link, isym->st_name);
2943    
2944                        fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
2945                                 sym_sec->name, name, isym->st_name,
2946                                 sym_sec->output_section->vma,
2947                                 sym_sec->output_offset,
2948                                 isym->st_value, irel->r_addend);
2949                      }
2950    #endif
2951                    }
2952                  else
2953                    {
2954                      unsigned long indx;
2955                      struct elf_link_hash_entry * h;
2956    
2957                      /* An external symbol.  */
2958                      indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2959                      h = elf_sym_hashes (abfd)[indx];
2960                      BFD_ASSERT (h != NULL);
2961    
2962                      if (   h->root.type != bfd_link_hash_defined
2963                          && h->root.type != bfd_link_hash_defweak)
2964                        /* This appears to be a reference to an undefined
2965                           symbol.  Just ignore it--it will be caught by the
2966                           regular reloc processing.  */
2967                        continue;
2968    
2969                      symval = (h->root.u.def.value
2970                                + h->root.u.def.section->output_section->vma
2971                                + h->root.u.def.section->output_offset);
2972    #ifdef DEBUG_RELAX
2973                      fprintf (stderr,
2974                               "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
2975                               sec->name, h->root.root.string, h->root.u.def.value,
2976                               sec->output_section->vma, sec->output_offset, irel->r_addend);
2977    #endif
2978                    }
2979    
2980                  addend = irel->r_addend;
2981    
2982                  foff = (symval + addend
2983                          - (irel->r_offset
2984                             + sec->output_section->vma
2985                             + sec->output_offset
2986                             + 4));
2987    #ifdef DEBUG_RELAX
2988                  fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
2989                           irel->r_offset,
2990                           (irel->r_offset
2991                            + sec->output_section->vma
2992                            + sec->output_offset),
2993                           symval, addend, foff);
2994    #endif
2995                  if (foff < -0x100000 || foff >= 0x100000)
2996                    /* After all that work, we can't shorten this function call.  */
2997                    continue;
2998    
2999                  /* For simplicity of coding, we are going to modify the section
3000                     contents, the section relocs, and the BFD symbol table.  We
3001                     must tell the rest of the code not to free up this
3002                     information.  It would be possible to instead create a table
3003                     of changes which have to be made, as is done in coff-mips.c;
3004                     that would be more work, but would require less memory when
3005                     the linker is run.  */
3006                  elf_section_data (sec)->relocs = internal_relocs;
3007                  elf_section_data (sec)->this_hdr.contents = contents;
3008                  symtab_hdr->contents = (bfd_byte *) isymbuf;
3009    
3010                  if (foff < -0x100 || foff >= 0x100)
3011                    {
3012                      /* Replace the long jump with a jr.  */
3013    
3014                      irel->r_info =
3015                        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
3016    
3017                      irel->r_addend = addend;
3018                      addend = 0;
3019    
3020                      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3021                        /* If this needs to be changed because of future relaxing,
3022                           it will be handled here like other internal IND12W
3023                           relocs.  */
3024                        bfd_put_32 (abfd,
3025                                    0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
3026                                    contents + irel->r_offset);
3027                      else
3028                        /* We can't fully resolve this yet, because the external
3029                           symbol value may be changed by future relaxing.
3030                           We let the final link phase handle it.  */
3031                        bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
3032    
3033                      hi_irelfn->r_info =
3034                            ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3035                      lo_irelfn->r_info =
3036                            ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3037                      if (!v850_elf_relax_delete_bytes (abfd, sec,
3038                                                        irel->r_offset + 4, toaddr, 6))
3039                        goto error_return;
3040    
3041                      align_pad_size += 6;
3042                    }
3043                  else
3044                    {
3045                      /* Replace the long jump with a br.  */
3046    
3047                      irel->r_info =
3048                            ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
3049    
3050                      irel->r_addend = addend;
3051                      addend = 0;
3052    
3053                      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3054                        /* If this needs to be changed because of future relaxing,
3055                           it will be handled here like other internal IND12W
3056                           relocs.  */
3057                        bfd_put_16 (abfd,
3058                                    0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
3059                                    contents + irel->r_offset);
3060                      else
3061                        /* We can't fully resolve this yet, because the external
3062                           symbol value may be changed by future relaxing.
3063                           We let the final link phase handle it.  */
3064                        bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
3065    
3066                      hi_irelfn->r_info =
3067                            ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3068                      lo_irelfn->r_info =
3069                            ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3070                      if (!v850_elf_relax_delete_bytes (abfd, sec,
3071                                                        irel->r_offset + 2, toaddr, 8))
3072                        goto error_return;
3073    
3074                      align_pad_size += 8;
3075                    }
3076                }
3077            }
3078    
3079          irelalign = NULL;
3080          for (irel = internal_relocs; irel < irelend; irel++)
3081            {
3082              if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3083                  && irel->r_offset == toaddr)
3084                {
3085                  irel->r_offset -= align_pad_size;
3086    
3087                  if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
3088                    irelalign = irel;
3089                }
3090            }
3091    
3092          addr = toaddr;
3093        }
3094    
3095      if (!irelalign)
3096        {
3097    #ifdef DEBUG_RELAX
3098          fprintf (stderr, "relax pad %d shorten %d -> %d\n",
3099                   align_pad_size,
3100                   sec->size,
3101                   sec->size - align_pad_size);
3102    #endif
3103          sec->size -= align_pad_size;
3104        }
3105    
3106     finish:
3107      if (internal_relocs != NULL
3108          && elf_section_data (sec)->relocs != internal_relocs)
3109        free (internal_relocs);
3110    
3111      if (contents != NULL
3112          && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
3113        free (contents);
3114    
3115      if (isymbuf != NULL
3116          && symtab_hdr->contents != (bfd_byte *) isymbuf)
3117        free (isymbuf);
3118    
3119      return result;
3120    
3121     error_return:
3122      result = FALSE;
3123      goto finish;
3124    }
3125    
3126    static struct bfd_elf_special_section const v850_elf_special_sections[]=
3127    {
3128      { ".sdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
3129                                                       + SHF_V850_GPREL) },
3130      { ".rosdata",          8, -2, SHT_PROGBITS,     (SHF_ALLOC
3131                                                       + SHF_V850_GPREL) },
3132      { ".sbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
3133                                                       + SHF_V850_GPREL) },
3134      { ".scommon",          8, -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
3135                                                       + SHF_V850_GPREL) },
3136      { ".tdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
3137                                                       + SHF_V850_EPREL) },
3138      { ".tbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
3139                                                       + SHF_V850_EPREL) },
3140      { ".tcommon",          8, -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
3141                                                       + SHF_V850_R0REL) },
3142      { ".zdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
3143                                                       + SHF_V850_R0REL) },
3144      { ".rozdata",          8, -2, SHT_PROGBITS,     (SHF_ALLOC
3145                                                       + SHF_V850_R0REL) },
3146      { ".zbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
3147                                                       + SHF_V850_R0REL) },
3148      { ".zcommon",          8, -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
3149                                                       + SHF_V850_R0REL) },
3150      { ".call_table_data", 16,  0, SHT_PROGBITS,     (SHF_ALLOC
3151                                                       + SHF_WRITE) },
3152      { ".call_table_text", 16,  0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
3153                                                       + SHF_EXECINSTR) },
3154      { NULL,               0,   0, 0,                0 }
3155    };
3156    
3157  #define TARGET_LITTLE_SYM                       bfd_elf32_v850_vec  #define TARGET_LITTLE_SYM                       bfd_elf32_v850_vec
3158  #define TARGET_LITTLE_NAME                      "elf32-v850"  #define TARGET_LITTLE_NAME                      "elf32-v850"
# Line 2206  v850_elf_fake_sections (abfd, hdr, sec) Line 3176  v850_elf_fake_sections (abfd, hdr, sec)
3176  #define elf_backend_fake_sections               v850_elf_fake_sections  #define elf_backend_fake_sections               v850_elf_fake_sections
3177  #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook  #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
3178  #define elf_backend_gc_sweep_hook               v850_elf_gc_sweep_hook  #define elf_backend_gc_sweep_hook               v850_elf_gc_sweep_hook
3179    #define elf_backend_special_sections            v850_elf_special_sections
3180    
3181  #define elf_backend_can_gc_sections 1  #define elf_backend_can_gc_sections 1
3182    #define elf_backend_rela_normal 1
3183    
3184  #define bfd_elf32_bfd_is_local_label_name       v850_elf_is_local_label_name  #define bfd_elf32_bfd_is_local_label_name       v850_elf_is_local_label_name
3185  #define bfd_elf32_bfd_reloc_type_lookup         v850_elf_reloc_type_lookup  #define bfd_elf32_bfd_reloc_type_lookup         v850_elf_reloc_type_lookup
3186  #define bfd_elf32_bfd_merge_private_bfd_data    v850_elf_merge_private_bfd_data  #define bfd_elf32_bfd_merge_private_bfd_data    v850_elf_merge_private_bfd_data
3187  #define bfd_elf32_bfd_set_private_flags         v850_elf_set_private_flags  #define bfd_elf32_bfd_set_private_flags         v850_elf_set_private_flags
3188  #define bfd_elf32_bfd_print_private_bfd_data    v850_elf_print_private_bfd_data  #define bfd_elf32_bfd_print_private_bfd_data    v850_elf_print_private_bfd_data
3189    #define bfd_elf32_bfd_relax_section             v850_elf_relax_section
3190    
3191  #define elf_symbol_leading_char                 '_'  #define elf_symbol_leading_char                 '_'
3192    

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

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