OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [elf32-pj.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* picoJava specific support for 32-bit ELF
2
   Copyright 1999, 2000 Free Software Foundation, Inc.
3
   Contributed by Steve Chamberlan of Transmeta (sac@pobox.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 "bfdlink.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/pj.h"
27
 
28
static bfd_reloc_status_type pj_elf_reloc
29
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
30
static reloc_howto_type *pj_elf_reloc_type_lookup
31
  PARAMS ((bfd *, bfd_reloc_code_real_type));
32
static void pj_elf_info_to_howto
33
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
34
 
35
static reloc_howto_type pj_elf_howto_table[] =
36
{
37
  /* No relocation.  */
38
  HOWTO (R_PJ_NONE,             /* type */
39
         0,                      /* rightshift */
40
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
41
         0,                      /* bitsize */
42
         false,                 /* pc_relative */
43
         0,                      /* bitpos */
44
         complain_overflow_dont, /* complain_on_overflow */
45
         pj_elf_reloc,          /* special_function */
46
         "R_PJ_NONE",           /* name */
47
         false,                 /* partial_inplace */
48
         0,                      /* src_mask */
49
         0,                      /* dst_mask */
50
         false),                /* pcrel_offset */
51
 
52
  /* 32 bit absolute relocation.  Setting partial_inplace to true and
53
     src_mask to a non-zero value is similar to the COFF toolchain.  */
54
  HOWTO (R_PJ_DATA_DIR32,               /* type */
55
         0,                      /* rightshift */
56
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
57
         32,                    /* bitsize */
58
         false,                 /* pc_relative */
59
         0,                      /* bitpos */
60
         complain_overflow_bitfield, /* complain_on_overflow */
61
         pj_elf_reloc,          /* special_function */
62
         "R_PJ_DIR32",          /* name */
63
         true,                  /* partial_inplace */
64
         0xffffffff,            /* src_mask */
65
         0xffffffff,            /* dst_mask */
66
         false),                /* pcrel_offset */
67
 
68
  /* 32 bit PC relative relocation.  */
69
  HOWTO (R_PJ_CODE_REL32,               /* type */
70
         0,                      /* rightshift */
71
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
72
         32,                    /* bitsize */
73
         true,                  /* pc_relative */
74
         0,                      /* bitpos */
75
         complain_overflow_signed, /* complain_on_overflow */
76
         pj_elf_reloc,          /* special_function */
77
         "R_PJ_REL32",          /* name */
78
         false,                 /* partial_inplace */
79
         0,                      /* src_mask */
80
         0xffffffff,            /* dst_mask */
81
         true),                 /* pcrel_offset */
82
 
83
/* 16 bit PC relative relocation.  */
84
  HOWTO (R_PJ_CODE_REL16,               /* type */
85
         0,                      /* rightshift */
86
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
87
         16,                    /* bitsize */
88
         true,                  /* pc_relative */
89
         0,                      /* bitpos */
90
         complain_overflow_signed, /* complain_on_overf6w */
91
         pj_elf_reloc,          /* special_function */
92
         "R_PJ_REL16",          /* name */
93
         false,                 /* partial_inplace */
94
         0xffff,                /* src_mask */
95
         0xffff,                /* dst_mask */
96
         true),                 /* pcrel_offset */
97
  EMPTY_HOWTO (4),
98
  EMPTY_HOWTO (5),
99
  HOWTO (R_PJ_CODE_DIR32,       /* type */
100
         0,                      /* rightshift */
101
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
102
         32,                    /* bitsize */
103
         false,                 /* pc_relative */
104
         0,                      /* bitpos */
105
         complain_overflow_bitfield, /* complain_on_overflow */
106
         pj_elf_reloc,          /* special_function */
107
         "R_PJ_CODE_DIR32",     /* name */
108
         true,                  /* partial_inplace */
109
         0xffffffff,            /* src_mask */
110
         0xffffffff,            /* dst_mask */
111
         false),                /* pcrel_offset */
112
 
113
  EMPTY_HOWTO (7),
114
  EMPTY_HOWTO (8),
115
  EMPTY_HOWTO (9),
116
  EMPTY_HOWTO (10),
117
  EMPTY_HOWTO (11),
118
  EMPTY_HOWTO (12),
119
 
120
  HOWTO (R_PJ_CODE_LO16,        /* type */
121
         0,                      /* rightshift */
122
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
123
         16,                    /* bitsize */
124
         false,                 /* pc_relative */
125
         0,                      /* bitpos */
126
         complain_overflow_unsigned, /* complain_on_overflow */
127
         pj_elf_reloc,          /* special_function */
128
         "R_PJ_LO16",           /* name */
129
         false,                 /* partial_inplace */
130
         0xffff,                /* src_mask */
131
         0xffff,                /* dst_mask */
132
         true),                 /* pcrel_offset */
133
 
134
    HOWTO (R_PJ_CODE_HI16,      /* type */
135
         16,                    /* rightshift */
136
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
137
         16,                    /* bitsize */
138
         false,                 /* pc_relative */
139
         0,                      /* bitpos */
140
         complain_overflow_unsigned, /* complain_on_overflow */
141
         pj_elf_reloc,          /* special_function */
142
         "R_PJ_HI16",           /* name */
143
         false,                 /* partial_inplace */
144
         0xffff,                /* src_mask */
145
         0xffff,                /* dst_mask */
146
         true),                 /* pcrel_offset */
147
 
148
  /* GNU extension to record C++ vtable hierarchy */
149
  HOWTO (R_PJ_GNU_VTINHERIT,    /* type */
150
         0,                     /* rightshift */
151
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
152
         0,                     /* bitsize */
153
         false,                 /* pc_relative */
154
         0,                     /* bitpos */
155
         complain_overflow_dont, /* complain_on_overflow */
156
         NULL,                  /* special_function */
157
         "R_PJ_GNU_VTINHERIT",  /* name */
158
         false,                 /* partial_inplace */
159
         0,                     /* src_mask */
160
         0,                     /* dst_mask */
161
         false),                /* pcrel_offset */
162
 
163
  /* GNU extension to record C++ vtable member usage */
164
  HOWTO (R_PJ_GNU_VTENTRY,     /* type */
165
         0,                     /* rightshift */
166
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
167
         0,                     /* bitsize */
168
         false,                 /* pc_relative */
169
         0,                     /* bitpos */
170
         complain_overflow_dont, /* complain_on_overflow */
171
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
172
         "R_PJ_GNU_VTENTRY",   /* name */
173
         false,                 /* partial_inplace */
174
         0,                     /* src_mask */
175
         0,                     /* dst_mask */
176
         false),                /* pcrel_offset */
177
 
178
};
179
 
180
/* This function is used for normal relocs.  This is like the COFF
181
   function, and is almost certainly incorrect for other ELF targets.  */
182
 
183
static bfd_reloc_status_type
184
pj_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
185
          error_message)
186
     bfd *abfd;
187
     arelent *reloc_entry;
188
     asymbol *symbol_in;
189
     PTR data;
190
     asection *input_section;
191
     bfd *output_bfd;
192
     char **error_message ATTRIBUTE_UNUSED;
193
{
194
  unsigned long insn;
195
  bfd_vma sym_value;
196
  enum elf_pj_reloc_type r_type;
197
  bfd_vma addr = reloc_entry->address;
198
  bfd_byte *hit_data = addr + (bfd_byte *) data;
199
 
200
  r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type;
201
 
202
  if (output_bfd != NULL)
203
    {
204
      /* Partial linking--do nothing.  */
205
      reloc_entry->address += input_section->output_offset;
206
      return bfd_reloc_ok;
207
    }
208
 
209
  if (symbol_in != NULL
210
      && bfd_is_und_section (symbol_in->section))
211
    return bfd_reloc_undefined;
212
 
213
  if (bfd_is_com_section (symbol_in->section))
214
    sym_value = 0;
215
  else
216
    sym_value = (symbol_in->value +
217
                 symbol_in->section->output_section->vma +
218
                 symbol_in->section->output_offset);
219
 
220
  switch (r_type)
221
    {
222
    case R_PJ_DATA_DIR32:
223
      insn = bfd_get_32 (abfd, hit_data);
224
      insn += sym_value + reloc_entry->addend;
225
      bfd_put_32 (abfd, insn, hit_data);
226
      break;
227
 
228
      /* Relocations in code are always bigendian, no matter what the
229
         data endianness is.  */
230
 
231
    case R_PJ_CODE_DIR32:
232
      insn = bfd_getb32 (hit_data);
233
      insn += sym_value + reloc_entry->addend;
234
      bfd_putb32 (insn, hit_data);
235
      break;
236
 
237
    case R_PJ_CODE_REL16:
238
      insn = bfd_getb16 (hit_data);
239
      insn += sym_value + reloc_entry->addend
240
        -  (input_section->output_section->vma
241
            + input_section->output_offset);
242
      bfd_putb16 (insn, hit_data);
243
      break;
244
    case R_PJ_CODE_LO16:
245
      insn = bfd_getb16 (hit_data);
246
      insn += sym_value + reloc_entry->addend;
247
      bfd_putb16 (insn, hit_data);
248
      break;
249
 
250
    case R_PJ_CODE_HI16:
251
      insn = bfd_getb16 (hit_data);
252
      insn += (sym_value + reloc_entry->addend) >> 16;
253
      bfd_putb16 (insn, hit_data);
254
      break;
255
 
256
    default:
257
      abort ();
258
      break;
259
    }
260
 
261
  return bfd_reloc_ok;
262
}
263
 
264
/* This structure is used to map BFD reloc codes to PJ ELF relocs.  */
265
 
266
struct elf_reloc_map
267
{
268
  bfd_reloc_code_real_type bfd_reloc_val;
269
  unsigned char elf_reloc_val;
270
};
271
 
272
/* An array mapping BFD reloc codes to PJ ELF relocs.  */
273
 
274
static const struct elf_reloc_map pj_reloc_map[] =
275
{
276
    { BFD_RELOC_NONE,           R_PJ_NONE          },
277
    { BFD_RELOC_32,             R_PJ_DATA_DIR32    },
278
    { BFD_RELOC_PJ_CODE_DIR16,  R_PJ_CODE_DIR16    },
279
    { BFD_RELOC_PJ_CODE_DIR32,  R_PJ_CODE_DIR32    },
280
    { BFD_RELOC_PJ_CODE_LO16,   R_PJ_CODE_LO16     },
281
    { BFD_RELOC_PJ_CODE_HI16,   R_PJ_CODE_HI16     },
282
    { BFD_RELOC_PJ_CODE_REL32,  R_PJ_CODE_REL32    },
283
    { BFD_RELOC_PJ_CODE_REL16,  R_PJ_CODE_REL16    },
284
    { BFD_RELOC_VTABLE_INHERIT, R_PJ_GNU_VTINHERIT },
285
    { BFD_RELOC_VTABLE_ENTRY,   R_PJ_GNU_VTENTRY   },
286
};
287
 
288
/* Given a BFD reloc code, return the howto structure for the
289
   corresponding PJ ELf reloc.  */
290
 
291
static reloc_howto_type *
292
pj_elf_reloc_type_lookup (abfd, code)
293
     bfd *abfd ATTRIBUTE_UNUSED;
294
     bfd_reloc_code_real_type code;
295
{
296
  unsigned int i;
297
 
298
  for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++)
299
    {
300
      if (pj_reloc_map[i].bfd_reloc_val == code)
301
        return &pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val];
302
    }
303
 
304
  return NULL;
305
}
306
 
307
/* Given an ELF reloc, fill in the howto field of a relent.  */
308
 
309
static void
310
pj_elf_info_to_howto (abfd, cache_ptr, dst)
311
     bfd *abfd ATTRIBUTE_UNUSED;
312
     arelent *cache_ptr;
313
     Elf_Internal_Rela *dst;
314
{
315
  unsigned int r;
316
 
317
  r = ELF32_R_TYPE (dst->r_info);
318
 
319
  BFD_ASSERT (r < (unsigned int) R_PJ_max);
320
 
321
  cache_ptr->howto = &pj_elf_howto_table[r];
322
}
323
 
324
/* Take this moment to fill in the special picoJava bits in the
325
   e_flags field.  */
326
 
327
static void
328
pj_elf_final_write_processing (abfd, linker)
329
     bfd *abfd;
330
     boolean linker ATTRIBUTE_UNUSED;
331
{
332
    elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH;
333
    elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS;
334
}
335
 
336
#define TARGET_BIG_SYM          bfd_elf32_pj_vec
337
#define TARGET_BIG_NAME         "elf32-pj"
338
#define TARGET_LITTLE_SYM       bfd_elf32_pjl_vec
339
#define TARGET_LITTLE_NAME      "elf32-pjl"
340
#define ELF_ARCH                bfd_arch_pj
341
#define ELF_MACHINE_CODE        EM_PJ
342
#define ELF_MAXPAGESIZE         0x1000
343
#define bfd_elf32_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
344
#define bfd_elf32_bfd_reloc_type_lookup              pj_elf_reloc_type_lookup
345
#define elf_backend_final_write_processing           pj_elf_final_write_processing
346
#define elf_info_to_howto                            pj_elf_info_to_howto
347
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.