* elf.c (prep_headers): Get the machine code from the elf
[external/binutils.git] / bfd / elf32-arc.c
1 /* ARC-specific support for 32-bit ELF
2    Copyright 1994, 1995, 1997, 1999, 2001 Free Software Foundation, Inc.
3    Contributed by Doug Evans (dje@cygnus.com).
4
5    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
8    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
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/arc.h"
26
27 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
28   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29 static void arc_info_to_howto_rel
30   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
31 static boolean arc_elf_object_p
32   PARAMS ((bfd *));
33 static void arc_elf_final_write_processing
34   PARAMS ((bfd *, boolean));
35
36 /* Try to minimize the amount of space occupied by relocation tables
37    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
38
39 #define USE_REL
40
41 static reloc_howto_type elf_arc_howto_table[] =
42 {
43   /* This reloc does nothing.  */
44   HOWTO (R_ARC_NONE,            /* type  */
45          0,                     /* rightshift  */
46          2,                     /* size (0 = byte, 1 = short, 2 = long)  */
47          32,                    /* bitsize  */
48          false,                 /* pc_relative  */
49          0,                     /* bitpos  */
50          complain_overflow_bitfield, /* complain_on_overflow  */
51          bfd_elf_generic_reloc, /* special_function  */
52          "R_ARC_NONE",          /* name  */
53          false,                 /* partial_inplace  */
54          0,                     /* src_mask  */
55          0,                     /* dst_mask  */
56          false),                /* pcrel_offset  */
57
58   /* A standard 32 bit relocation.  */
59   HOWTO (R_ARC_32,              /* type  */
60          0,                     /* rightshift  */
61          2,                     /* size (0 = byte, 1 = short, 2 = long)  */
62          32,                    /* bitsize  */
63          false,                 /* pc_relative  */
64          0,                     /* bitpos  */
65          complain_overflow_bitfield, /* complain_on_overflow  */
66          bfd_elf_generic_reloc, /* special_function  */
67          "R_ARC_32",            /* name  */
68          false,                 /* partial_inplace  */
69          0xffffffff,            /* src_mask  */
70          0xffffffff,            /* dst_mask  */
71          false),                /* pcrel_offset  */
72
73   /* A 26 bit absolute branch, right shifted by 2.  */
74   HOWTO (R_ARC_B26,             /* type  */
75          2,                     /* rightshift  */
76          2,                     /* size (0 = byte, 1 = short, 2 = long)  */
77          26,                    /* bitsize  */
78          false,                 /* pc_relative  */
79          0,                     /* bitpos  */
80          complain_overflow_bitfield, /* complain_on_overflow  */
81          bfd_elf_generic_reloc, /* special_function  */
82          "R_ARC_B26",           /* name  */
83          false,                 /* partial_inplace  */
84          0x00ffffff,            /* src_mask  */
85          0x00ffffff,            /* dst_mask  */
86          false),                /* pcrel_offset  */
87
88   /* A relative 22 bit branch; bits 21-2 are stored in bits 26-7.  */
89   HOWTO (R_ARC_B22_PCREL,       /* type  */
90          2,                     /* rightshift  */
91          2,                     /* size (0 = byte, 1 = short, 2 = long)  */
92          22,                    /* bitsize  */
93          true,                  /* pc_relative  */
94          7,                     /* bitpos  */
95          complain_overflow_signed, /* complain_on_overflow  */
96          bfd_elf_generic_reloc, /* special_function  */
97          "R_ARC_B22_PCREL",     /* name  */
98          true,                  /* partial_inplace  */
99          0x07ffff80,            /* src_mask  */
100          0x07ffff80,            /* dst_mask  */
101          false),                /* pcrel_offset  */
102
103 };
104
105 /* Map BFD reloc types to ARC ELF reloc types.  */
106
107 struct arc_reloc_map
108 {
109   bfd_reloc_code_real_type bfd_reloc_val;
110   unsigned char elf_reloc_val;
111 };
112
113 static const struct arc_reloc_map arc_reloc_map[] =
114 {
115   { BFD_RELOC_NONE, R_ARC_NONE, },
116   { BFD_RELOC_32, R_ARC_32 },
117   { BFD_RELOC_CTOR, R_ARC_32 },
118   { BFD_RELOC_ARC_B26, R_ARC_B26 },
119   { BFD_RELOC_ARC_B22_PCREL, R_ARC_B22_PCREL },
120 };
121
122 static reloc_howto_type *
123 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
124      bfd *abfd ATTRIBUTE_UNUSED;
125      bfd_reloc_code_real_type code;
126 {
127   unsigned int i;
128
129   for (i = 0; i < sizeof (arc_reloc_map) / sizeof (struct arc_reloc_map); i++)
130     {
131       if (arc_reloc_map[i].bfd_reloc_val == code)
132         return &elf_arc_howto_table[arc_reloc_map[i].elf_reloc_val];
133     }
134   return NULL;
135 }
136
137 /* Set the howto pointer for an ARC ELF reloc.  */
138
139 static void
140 arc_info_to_howto_rel (abfd, cache_ptr, dst)
141      bfd *abfd ATTRIBUTE_UNUSED;
142      arelent *cache_ptr;
143      Elf32_Internal_Rel *dst;
144 {
145   unsigned int r_type;
146
147   r_type = ELF32_R_TYPE (dst->r_info);
148   BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
149   cache_ptr->howto = &elf_arc_howto_table[r_type];
150 }
151
152 /* Set the right machine number for an ARC ELF file.  */
153
154 static boolean
155 arc_elf_object_p (abfd)
156      bfd *abfd;
157 {
158   int mach = bfd_mach_arc_6;
159
160   if (elf_elfheader(abfd)->e_machine == EM_ARC)
161     {
162       unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH;
163
164       switch (arch)
165         {
166         case E_ARC_MACH_ARC5:
167           mach = bfd_mach_arc_5;
168           break;
169         default:
170         case E_ARC_MACH_ARC6:
171           mach = bfd_mach_arc_6;
172           break;
173         case E_ARC_MACH_ARC7:
174           mach = bfd_mach_arc_7;
175           break;
176         case E_ARC_MACH_ARC8:
177           mach = bfd_mach_arc_8;
178           break;
179         }
180     }
181   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
182 }
183
184 /* The final processing done just before writing out an ARC ELF object file.
185    This gets the ARC architecture right based on the machine number.  */
186
187 static void
188 arc_elf_final_write_processing (abfd, linker)
189      bfd *abfd;
190      boolean linker ATTRIBUTE_UNUSED;
191 {
192   unsigned long val;
193
194   switch (bfd_get_mach (abfd))
195     {
196     case bfd_mach_arc_5:
197       val = E_ARC_MACH_ARC5;
198       break;
199     default:
200     case bfd_mach_arc_6:
201       val = E_ARC_MACH_ARC6;
202       break;
203     case bfd_mach_arc_7:
204       val = E_ARC_MACH_ARC7;
205       break;
206     case bfd_mach_arc_8:
207       val = E_ARC_MACH_ARC8;
208       break;
209     }
210   elf_elfheader (abfd)->e_flags &=~ EF_ARC_MACH;
211   elf_elfheader (abfd)->e_flags |= val;
212 }
213
214 #define TARGET_LITTLE_SYM bfd_elf32_littlearc_vec
215 #define TARGET_LITTLE_NAME "elf32-littlearc"
216 #define TARGET_BIG_SYM bfd_elf32_bigarc_vec
217 #define TARGET_BIG_NAME "elf32-bigarc"
218 #define ELF_ARCH bfd_arch_arc
219 #define ELF_MACHINE_CODE EM_ARC
220 #define ELF_MAXPAGESIZE 0x1000
221
222 #define elf_info_to_howto 0
223 #define elf_info_to_howto_rel arc_info_to_howto_rel
224 #define elf_backend_object_p arc_elf_object_p
225 #define elf_backend_final_write_processing arc_elf_final_write_processing
226
227 #include "elf32-target.h"