elf32-arc.c revision 1.3 1 1.1 christos /* ARC-specific support for 32-bit ELF
2 1.3 christos Copyright (C) 1994-2015 Free Software Foundation, Inc.
3 1.1 christos Contributed by Doug Evans (dje (at) cygnus.com).
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 christos MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos #include "sysdep.h"
23 1.1 christos #include "bfd.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "elf-bfd.h"
26 1.1 christos #include "elf/arc.h"
27 1.1 christos #include "libiberty.h"
28 1.1 christos
29 1.1 christos /* Try to minimize the amount of space occupied by relocation tables
30 1.1 christos on the ROM (not that the ROM won't be swamped by other ELF overhead). */
31 1.1 christos
32 1.1 christos #define USE_REL 1
33 1.1 christos
34 1.1 christos static bfd_reloc_status_type
35 1.1 christos arc_elf_b22_pcrel (bfd * abfd,
36 1.1 christos arelent * reloc_entry,
37 1.1 christos asymbol * symbol,
38 1.1 christos void * data,
39 1.1 christos asection * input_section,
40 1.1 christos bfd * output_bfd,
41 1.1 christos char ** error_message)
42 1.1 christos {
43 1.1 christos /* If linking, back up the final symbol address by the address of the
44 1.1 christos reloc. This cannot be accomplished by setting the pcrel_offset
45 1.1 christos field to TRUE, as bfd_install_relocation will detect this and refuse
46 1.1 christos to install the offset in the first place, but bfd_perform_relocation
47 1.1 christos will still insist on removing it. */
48 1.1 christos if (output_bfd == NULL)
49 1.1 christos reloc_entry->addend -= reloc_entry->address;
50 1.1 christos
51 1.1 christos /* Fall through to the default elf reloc handler. */
52 1.1 christos return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
53 1.1 christos input_section, output_bfd, error_message);
54 1.1 christos }
55 1.1 christos
56 1.1 christos static reloc_howto_type elf_arc_howto_table[] =
57 1.1 christos {
58 1.1 christos /* This reloc does nothing. */
59 1.1 christos HOWTO (R_ARC_NONE, /* Type. */
60 1.1 christos 0, /* Rightshift. */
61 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
62 1.1 christos 32, /* Bitsize. */
63 1.1 christos FALSE, /* PC_relative. */
64 1.1 christos 0, /* Bitpos. */
65 1.1 christos complain_overflow_bitfield, /* Complain_on_overflow. */
66 1.1 christos bfd_elf_generic_reloc, /* Special_function. */
67 1.1 christos "R_ARC_NONE", /* Name. */
68 1.1 christos TRUE, /* Partial_inplace. */
69 1.1 christos 0, /* Src_mask. */
70 1.1 christos 0, /* Dst_mask. */
71 1.1 christos FALSE), /* PCrel_offset. */
72 1.1 christos
73 1.1 christos /* A standard 32 bit relocation. */
74 1.1 christos HOWTO (R_ARC_32, /* Type. */
75 1.1 christos 0, /* Rightshift. */
76 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
77 1.1 christos 32, /* Bitsize. */
78 1.1 christos FALSE, /* PC_relative. */
79 1.1 christos 0, /* Bitpos. */
80 1.1 christos complain_overflow_bitfield, /* Complain_on_overflow. */
81 1.1 christos bfd_elf_generic_reloc, /* Special_function. */
82 1.1 christos "R_ARC_32", /* Name. */
83 1.1 christos TRUE, /* Partial_inplace. */
84 1.1 christos 0xffffffff, /* Src_mask. */
85 1.1 christos 0xffffffff, /* Dst_mask. */
86 1.1 christos FALSE), /* PCrel_offset. */
87 1.1 christos
88 1.1 christos /* A 26 bit absolute branch, right shifted by 2. */
89 1.1 christos HOWTO (R_ARC_B26, /* Type. */
90 1.1 christos 2, /* Rightshift. */
91 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
92 1.1 christos 26, /* Bitsize. */
93 1.1 christos FALSE, /* PC_relative. */
94 1.1 christos 0, /* Bitpos. */
95 1.1 christos complain_overflow_bitfield, /* Complain_on_overflow. */
96 1.1 christos bfd_elf_generic_reloc, /* Special_function. */
97 1.1 christos "R_ARC_B26", /* Name. */
98 1.1 christos TRUE, /* Partial_inplace. */
99 1.1 christos 0x00ffffff, /* Src_mask. */
100 1.1 christos 0x00ffffff, /* Dst_mask. */
101 1.1 christos FALSE), /* PCrel_offset. */
102 1.1 christos
103 1.1 christos /* A relative 22 bit branch; bits 21-2 are stored in bits 26-7. */
104 1.1 christos HOWTO (R_ARC_B22_PCREL, /* Type. */
105 1.1 christos 2, /* Rightshift. */
106 1.1 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
107 1.1 christos 22, /* Bitsize. */
108 1.1 christos TRUE, /* PC_relative. */
109 1.1 christos 7, /* Bitpos. */
110 1.1 christos complain_overflow_signed, /* Complain_on_overflow. */
111 1.1 christos arc_elf_b22_pcrel, /* Special_function. */
112 1.1 christos "R_ARC_B22_PCREL", /* Name. */
113 1.1 christos TRUE, /* Partial_inplace. */
114 1.1 christos 0x07ffff80, /* Src_mask. */
115 1.1 christos 0x07ffff80, /* Dst_mask. */
116 1.1 christos FALSE), /* PCrel_offset. */
117 1.1 christos };
118 1.1 christos
119 1.1 christos /* Map BFD reloc types to ARC ELF reloc types. */
120 1.1 christos
121 1.1 christos struct arc_reloc_map
122 1.1 christos {
123 1.1 christos bfd_reloc_code_real_type bfd_reloc_val;
124 1.1 christos unsigned char elf_reloc_val;
125 1.1 christos };
126 1.1 christos
127 1.1 christos static const struct arc_reloc_map arc_reloc_map[] =
128 1.1 christos {
129 1.1 christos { BFD_RELOC_NONE, R_ARC_NONE, },
130 1.1 christos { BFD_RELOC_32, R_ARC_32 },
131 1.1 christos { BFD_RELOC_CTOR, R_ARC_32 },
132 1.1 christos { BFD_RELOC_ARC_B26, R_ARC_B26 },
133 1.1 christos { BFD_RELOC_ARC_B22_PCREL, R_ARC_B22_PCREL },
134 1.1 christos };
135 1.1 christos
136 1.1 christos static reloc_howto_type *
137 1.1 christos bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
138 1.1 christos bfd_reloc_code_real_type code)
139 1.1 christos {
140 1.1 christos unsigned int i;
141 1.1 christos
142 1.1 christos for (i = ARRAY_SIZE (arc_reloc_map); i--;)
143 1.1 christos if (arc_reloc_map[i].bfd_reloc_val == code)
144 1.1 christos return elf_arc_howto_table + arc_reloc_map[i].elf_reloc_val;
145 1.1 christos
146 1.1 christos return NULL;
147 1.1 christos }
148 1.1 christos
149 1.1 christos static reloc_howto_type *
150 1.1 christos bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
151 1.1 christos const char *r_name)
152 1.1 christos {
153 1.1 christos unsigned int i;
154 1.1 christos
155 1.1 christos for (i = 0;
156 1.1 christos i < sizeof (elf_arc_howto_table) / sizeof (elf_arc_howto_table[0]);
157 1.1 christos i++)
158 1.1 christos if (elf_arc_howto_table[i].name != NULL
159 1.1 christos && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
160 1.1 christos return &elf_arc_howto_table[i];
161 1.1 christos
162 1.1 christos return NULL;
163 1.1 christos }
164 1.1 christos
165 1.1 christos /* Set the howto pointer for an ARC ELF reloc. */
166 1.1 christos
167 1.1 christos static void
168 1.1 christos arc_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
169 1.1 christos arelent *cache_ptr,
170 1.1 christos Elf_Internal_Rela *dst)
171 1.1 christos {
172 1.1 christos unsigned int r_type;
173 1.1 christos
174 1.1 christos r_type = ELF32_R_TYPE (dst->r_info);
175 1.3 christos if (r_type >= (unsigned int) R_ARC_max)
176 1.3 christos {
177 1.3 christos _bfd_error_handler (_("%A: invalid ARC reloc number: %d"), abfd, r_type);
178 1.3 christos r_type = 0;
179 1.3 christos }
180 1.1 christos cache_ptr->howto = &elf_arc_howto_table[r_type];
181 1.1 christos }
182 1.1 christos
183 1.1 christos /* Set the right machine number for an ARC ELF file. */
184 1.1 christos
185 1.1 christos static bfd_boolean
186 1.1 christos arc_elf_object_p (bfd *abfd)
187 1.1 christos {
188 1.1 christos unsigned int mach = bfd_mach_arc_6;
189 1.1 christos
190 1.1 christos if (elf_elfheader(abfd)->e_machine == EM_ARC)
191 1.1 christos {
192 1.1 christos unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH;
193 1.1 christos
194 1.1 christos switch (arch)
195 1.1 christos {
196 1.1 christos case E_ARC_MACH_ARC5:
197 1.1 christos mach = bfd_mach_arc_5;
198 1.1 christos break;
199 1.1 christos default:
200 1.1 christos case E_ARC_MACH_ARC6:
201 1.1 christos mach = bfd_mach_arc_6;
202 1.1 christos break;
203 1.1 christos case E_ARC_MACH_ARC7:
204 1.1 christos mach = bfd_mach_arc_7;
205 1.1 christos break;
206 1.1 christos case E_ARC_MACH_ARC8:
207 1.1 christos mach = bfd_mach_arc_8;
208 1.1 christos break;
209 1.1 christos }
210 1.1 christos }
211 1.1 christos return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
212 1.1 christos }
213 1.1 christos
214 1.1 christos /* The final processing done just before writing out an ARC ELF object file.
215 1.1 christos This gets the ARC architecture right based on the machine number. */
216 1.1 christos
217 1.1 christos static void
218 1.1 christos arc_elf_final_write_processing (bfd *abfd,
219 1.1 christos bfd_boolean linker ATTRIBUTE_UNUSED)
220 1.1 christos {
221 1.1 christos unsigned long val;
222 1.1 christos
223 1.1 christos switch (bfd_get_mach (abfd))
224 1.1 christos {
225 1.1 christos case bfd_mach_arc_5:
226 1.1 christos val = E_ARC_MACH_ARC5;
227 1.1 christos break;
228 1.1 christos default:
229 1.1 christos case bfd_mach_arc_6:
230 1.1 christos val = E_ARC_MACH_ARC6;
231 1.1 christos break;
232 1.1 christos case bfd_mach_arc_7:
233 1.1 christos val = E_ARC_MACH_ARC7;
234 1.1 christos break;
235 1.1 christos case bfd_mach_arc_8:
236 1.1 christos val = E_ARC_MACH_ARC8;
237 1.1 christos break;
238 1.1 christos }
239 1.1 christos elf_elfheader (abfd)->e_flags &=~ EF_ARC_MACH;
240 1.1 christos elf_elfheader (abfd)->e_flags |= val;
241 1.1 christos }
242 1.1 christos
243 1.3 christos #define TARGET_LITTLE_SYM arc_elf32_le_vec
244 1.1 christos #define TARGET_LITTLE_NAME "elf32-littlearc"
245 1.3 christos #define TARGET_BIG_SYM arc_elf32_be_vec
246 1.1 christos #define TARGET_BIG_NAME "elf32-bigarc"
247 1.1 christos #define ELF_ARCH bfd_arch_arc
248 1.1 christos #define ELF_MACHINE_CODE EM_ARC
249 1.1 christos #define ELF_MAXPAGESIZE 0x1000
250 1.1 christos
251 1.1 christos #define elf_info_to_howto 0
252 1.1 christos #define elf_info_to_howto_rel arc_info_to_howto_rel
253 1.1 christos #define elf_backend_object_p arc_elf_object_p
254 1.1 christos #define elf_backend_final_write_processing arc_elf_final_write_processing
255 1.1 christos
256 1.1 christos #include "elf32-target.h"
257