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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [mipsbsd.c] - Blame information for rev 861

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

Line No. Rev Author Line
1 205 julius
/* BFD backend for MIPS BSD (a.out) binaries.
2
   Copyright 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3
   2005, 2007 Free Software Foundation, Inc.
4
   Written by Ralph Campbell.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
 
24
/* #define ENTRY_CAN_BE_ZERO */
25
#define N_HEADER_IN_TEXT(x) 1
26
#define N_SHARED_LIB(x) 0
27
#define N_TXTADDR(x) \
28
    (N_MAGIC(x) != ZMAGIC ? (x).a_entry :       /* object file or NMAGIC */\
29
            TEXT_START_ADDR + EXEC_BYTES_SIZE   /* no padding */\
30
    )
31
#define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
32
#define TEXT_START_ADDR 4096
33
#define TARGET_PAGE_SIZE 4096
34
#define SEGMENT_SIZE TARGET_PAGE_SIZE
35
#define DEFAULT_ARCH bfd_arch_mips
36
#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
37
                            || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
38
#define MY_symbol_leading_char '\0'
39
 
40
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
41
   remove whitespace added here, and thus will fail to concatenate
42
   the tokens.  */
43
#define MY(OP) CONCAT2 (mipsbsd_,OP)
44
 
45
#include "sysdep.h"
46
#include "bfd.h"
47
#include "libbfd.h"
48
#include "libaout.h"
49
 
50
#define SET_ARCH_MACH(ABFD, EXEC) \
51
  MY(set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \
52
  MY(choose_reloc_size) (ABFD);
53
static void MY(set_arch_mach) PARAMS ((bfd *abfd, unsigned long machtype));
54
static void MY(choose_reloc_size) PARAMS ((bfd *abfd));
55
 
56
#define MY_write_object_contents MY(write_object_contents)
57
static bfd_boolean MY(write_object_contents) PARAMS ((bfd *abfd));
58
 
59
/* We can't use MY(x) here because it leads to a recursive call to CONCAT2
60
   when expanded inside JUMP_TABLE.  */
61
#define MY_bfd_reloc_type_lookup mipsbsd_reloc_type_lookup
62
#define MY_bfd_reloc_name_lookup mipsbsd_reloc_name_lookup
63
#define MY_canonicalize_reloc mipsbsd_canonicalize_reloc
64
 
65
#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
66
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
67
#define MY_final_link_callback unused
68
#define MY_bfd_final_link _bfd_generic_final_link
69
 
70
#define MY_backend_data &MY(backend_data)
71
#define MY_BFD_TARGET
72
 
73
#include "aout-target.h"
74
 
75
static bfd_reloc_status_type mips_fix_jmp_addr
76
  PARAMS ((bfd *, arelent *, struct bfd_symbol *, PTR, asection *,
77
           bfd *, char **));
78
 
79
long MY(canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
80
 
81
static void
82
MY(set_arch_mach) (abfd, machtype)
83
     bfd *abfd;
84
     unsigned long machtype;
85
{
86
  enum bfd_architecture arch;
87
  unsigned int machine;
88
 
89
  /* Determine the architecture and machine type of the object file.  */
90
  switch (machtype)
91
    {
92
    case M_MIPS1:
93
      arch = bfd_arch_mips;
94
      machine = bfd_mach_mips3000;
95
      break;
96
 
97
    case M_MIPS2:
98
      arch = bfd_arch_mips;
99
      machine = bfd_mach_mips4000;
100
      break;
101
 
102
    default:
103
      arch = bfd_arch_obscure;
104
      machine = 0;
105
      break;
106
    }
107
 
108
  bfd_set_arch_mach (abfd, arch, machine);
109
}
110
 
111
/* Determine the size of a relocation entry, based on the architecture */
112
static void
113
MY (choose_reloc_size) (abfd)
114
     bfd *abfd;
115
{
116
  switch (bfd_get_arch (abfd))
117
    {
118
    case bfd_arch_sparc:
119
    case bfd_arch_mips:
120
      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
121
      break;
122
    default:
123
      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
124
      break;
125
    }
126
}
127
 
128
/* Write an object file in BSD a.out format.
129
  Section contents have already been written.  We write the
130
  file header, symbols, and relocation.  */
131
 
132
static bfd_boolean
133
MY (write_object_contents) (abfd)
134
     bfd *abfd;
135
{
136
  struct external_exec exec_bytes;
137
  struct internal_exec *execp = exec_hdr (abfd);
138
 
139
  /* Magic number, maestro, please!  */
140
  switch (bfd_get_arch (abfd))
141
    {
142
    case bfd_arch_m68k:
143
      switch (bfd_get_mach (abfd))
144
        {
145
        case bfd_mach_m68010:
146
          N_SET_MACHTYPE (*execp, M_68010);
147
          break;
148
        default:
149
        case bfd_mach_m68020:
150
          N_SET_MACHTYPE (*execp, M_68020);
151
          break;
152
        }
153
      break;
154
    case bfd_arch_sparc:
155
      N_SET_MACHTYPE (*execp, M_SPARC);
156
      break;
157
    case bfd_arch_i386:
158
      N_SET_MACHTYPE (*execp, M_386);
159
      break;
160
    case bfd_arch_mips:
161
      switch (bfd_get_mach (abfd))
162
        {
163
        case bfd_mach_mips4000:
164
        case bfd_mach_mips6000:
165
          N_SET_MACHTYPE (*execp, M_MIPS2);
166
          break;
167
        default:
168
          N_SET_MACHTYPE (*execp, M_MIPS1);
169
          break;
170
        }
171
      break;
172
    default:
173
      N_SET_MACHTYPE (*execp, M_UNKNOWN);
174
    }
175
 
176
  MY (choose_reloc_size) (abfd);
177
 
178
  WRITE_HEADERS (abfd, execp);
179
 
180
  return TRUE;
181
}
182
 
183
/* MIPS relocation types.  */
184
#define MIPS_RELOC_32           0
185
#define MIPS_RELOC_JMP          1
186
#define MIPS_RELOC_WDISP16      2
187
#define MIPS_RELOC_HI16         3
188
#define MIPS_RELOC_HI16_S       4
189
#define MIPS_RELOC_LO16         5
190
 
191
/* This is only called when performing a BFD_RELOC_MIPS_JMP relocation.
192
   The jump destination address is formed from the upper 4 bits of the
193
   "current" program counter concatenated with the jump instruction's
194
   26 bit field and two trailing zeros.
195
   If the destination address is not in the same segment as the "current"
196
   program counter, then we need to signal an error.  */
197
 
198
static bfd_reloc_status_type
199
mips_fix_jmp_addr (abfd, reloc_entry, symbol, data, input_section, output_bfd,
200
                   error_message)
201
     bfd *abfd ATTRIBUTE_UNUSED;
202
     arelent *reloc_entry;
203
     struct bfd_symbol *symbol;
204
     PTR data ATTRIBUTE_UNUSED;
205
     asection *input_section;
206
     bfd *output_bfd;
207
     char **error_message ATTRIBUTE_UNUSED;
208
{
209
  bfd_vma relocation, pc;
210
 
211
  /* If this is a partial relocation, just continue.  */
212
  if (output_bfd != (bfd *)NULL)
213
    return bfd_reloc_continue;
214
 
215
  /* If this is an undefined symbol, return error */
216
  if (bfd_is_und_section (symbol->section)
217
      && (symbol->flags & BSF_WEAK) == 0)
218
    return bfd_reloc_undefined;
219
 
220
  /* Work out which section the relocation is targeted at and the
221
     initial relocation command value.  */
222
  if (bfd_is_com_section (symbol->section))
223
    relocation = 0;
224
  else
225
    relocation = symbol->value;
226
 
227
  relocation += symbol->section->output_section->vma;
228
  relocation += symbol->section->output_offset;
229
  relocation += reloc_entry->addend;
230
 
231
  pc = input_section->output_section->vma + input_section->output_offset +
232
    reloc_entry->address + 4;
233
 
234
  if ((relocation & 0xF0000000) != (pc & 0xF0000000))
235
    return bfd_reloc_overflow;
236
 
237
  return bfd_reloc_continue;
238
}
239
 
240
/* This is only called when performing a BFD_RELOC_HI16_S relocation.
241
   We need to see if bit 15 is set in the result. If it is, we add
242
   0x10000 and continue normally. This will compensate for the sign extension
243
   when the low bits are added at run time.  */
244
 
245
static bfd_reloc_status_type
246
mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR,
247
                         asection *, bfd *, char **));
248
 
249
static bfd_reloc_status_type
250
mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
251
                 output_bfd, error_message)
252
     bfd *abfd ATTRIBUTE_UNUSED;
253
     arelent *reloc_entry;
254
     asymbol *symbol;
255
     PTR data ATTRIBUTE_UNUSED;
256
     asection *input_section ATTRIBUTE_UNUSED;
257
     bfd *output_bfd;
258
     char **error_message ATTRIBUTE_UNUSED;
259
{
260
  bfd_vma relocation;
261
 
262
  /* If this is a partial relocation, just continue.  */
263
  if (output_bfd != (bfd *)NULL)
264
    return bfd_reloc_continue;
265
 
266
  /* If this is an undefined symbol, return error.  */
267
  if (bfd_is_und_section (symbol->section)
268
      && (symbol->flags & BSF_WEAK) == 0)
269
    return bfd_reloc_undefined;
270
 
271
  /* Work out which section the relocation is targeted at and the
272
     initial relocation command value.  */
273
  if (bfd_is_com_section (symbol->section))
274
    relocation = 0;
275
  else
276
    relocation = symbol->value;
277
 
278
  relocation += symbol->section->output_section->vma;
279
  relocation += symbol->section->output_offset;
280
  relocation += reloc_entry->addend;
281
 
282
  if (relocation & 0x8000)
283
    reloc_entry->addend += 0x10000;
284
 
285
  return bfd_reloc_continue;
286
}
287
 
288
static reloc_howto_type mips_howto_table_ext[] = {
289
  {MIPS_RELOC_32,      0, 2, 32, FALSE, 0,  complain_overflow_bitfield, 0,
290
        "32",       FALSE, 0, 0xffffffff, FALSE},
291
  {MIPS_RELOC_JMP,     2, 2, 26, FALSE, 0, complain_overflow_dont,
292
        mips_fix_jmp_addr,
293
        "MIPS_JMP", FALSE, 0, 0x03ffffff, FALSE},
294
  {MIPS_RELOC_WDISP16, 2, 2, 16, TRUE,  0, complain_overflow_signed, 0,
295
        "WDISP16",  FALSE, 0, 0x0000ffff, FALSE},
296
  {MIPS_RELOC_HI16,   16, 2, 16, FALSE, 0, complain_overflow_bitfield, 0,
297
        "HI16",     FALSE, 0, 0x0000ffff, FALSE},
298
  {MIPS_RELOC_HI16_S, 16, 2, 16, FALSE, 0, complain_overflow_bitfield,
299
        mips_fix_hi16_s,
300
        "HI16_S",   FALSE, 0, 0x0000ffff, FALSE},
301
  {MIPS_RELOC_LO16,    0, 2, 16, FALSE, 0, complain_overflow_dont, 0,
302
        "LO16",     FALSE, 0, 0x0000ffff, FALSE},
303
};
304
 
305
static reloc_howto_type *
306
MY(reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
307
{
308
 
309
  if (bfd_get_arch (abfd) != bfd_arch_mips)
310
    return 0;
311
 
312
  switch (code)
313
    {
314
    case BFD_RELOC_CTOR:
315
    case BFD_RELOC_32:
316
      return (&mips_howto_table_ext[MIPS_RELOC_32]);
317
    case BFD_RELOC_MIPS_JMP:
318
      return (&mips_howto_table_ext[MIPS_RELOC_JMP]);
319
    case BFD_RELOC_16_PCREL_S2:
320
      return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]);
321
    case BFD_RELOC_HI16:
322
      return (&mips_howto_table_ext[MIPS_RELOC_HI16]);
323
    case BFD_RELOC_HI16_S:
324
      return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]);
325
    case BFD_RELOC_LO16:
326
      return (&mips_howto_table_ext[MIPS_RELOC_LO16]);
327
    default:
328
      return 0;
329
    }
330
}
331
 
332
static reloc_howto_type *
333
MY(reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
334
                             const char *r_name)
335
{
336
  unsigned int i;
337
 
338
  for (i = 0;
339
       i < sizeof (mips_howto_table_ext) / sizeof (mips_howto_table_ext[0]);
340
       i++)
341
    if (mips_howto_table_ext[i].name != NULL
342
        && strcasecmp (mips_howto_table_ext[i].name, r_name) == 0)
343
      return &mips_howto_table_ext[i];
344
 
345
  return NULL;
346
}
347
 
348
/* This is just like the standard aoutx.h version but we need to do our
349
   own mapping of external reloc type values to howto entries.  */
350
long
351
MY(canonicalize_reloc) (abfd, section, relptr, symbols)
352
      bfd *abfd;
353
      sec_ptr section;
354
      arelent **relptr;
355
      asymbol **symbols;
356
{
357
  arelent *tblptr = section->relocation;
358
  unsigned int count, c;
359
  extern reloc_howto_type NAME(aout,ext_howto_table)[];
360
 
361
  /* If we have already read in the relocation table, return the values.  */
362
  if (section->flags & SEC_CONSTRUCTOR)
363
    {
364
      arelent_chain *chain = section->constructor_chain;
365
 
366
      for (count = 0; count < section->reloc_count; count++)
367
        {
368
          *relptr++ = &chain->relent;
369
          chain = chain->next;
370
        }
371
      *relptr = 0;
372
      return section->reloc_count;
373
    }
374
 
375
  if (tblptr && section->reloc_count)
376
    {
377
      for (count = 0; count++ < section->reloc_count;)
378
        *relptr++ = tblptr++;
379
      *relptr = 0;
380
      return section->reloc_count;
381
    }
382
 
383
  if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
384
    return -1;
385
  tblptr = section->relocation;
386
 
387
  /* fix up howto entries.  */
388
  for (count = 0; count++ < section->reloc_count;)
389
    {
390
      c = tblptr->howto - NAME(aout,ext_howto_table);
391
      tblptr->howto = &mips_howto_table_ext[c];
392
 
393
      *relptr++ = tblptr++;
394
    }
395
  *relptr = 0;
396
  return section->reloc_count;
397
}
398
 
399
static const struct aout_backend_data MY(backend_data) = {
400
  0,                             /* zmagic contiguous */
401
  1,                            /* text incl header */
402
  0,                             /* entry is text address */
403
  0,                             /* exec_hdr_flags */
404
  TARGET_PAGE_SIZE,                     /* text vma */
405
  MY_set_sizes,
406
  0,                             /* text size includes exec header */
407
  0,                             /* add_dynamic_symbols */
408
  0,                             /* add_one_symbol */
409
  0,                             /* link_dynamic_object */
410
  0,                             /* write_dynamic_symbol */
411
  0,                             /* check_dynamic_reloc */
412
 
413
};
414
 
415
extern const bfd_target aout_mips_big_vec;
416
 
417
const bfd_target aout_mips_little_vec =
418
  {
419
    "a.out-mips-little",                /* name */
420
    bfd_target_aout_flavour,
421
    BFD_ENDIAN_LITTLE,          /* target byte order (little) */
422
    BFD_ENDIAN_LITTLE,          /* target headers byte order (little) */
423
    (HAS_RELOC | EXEC_P |               /* object flags */
424
     HAS_LINENO | HAS_DEBUG |
425
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
426
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
427
    MY_symbol_leading_char,
428
    ' ',                                /* ar_pad_char */
429
    15,                         /* ar_max_namelen */
430
    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
431
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
432
    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
433
    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
434
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
435
    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
436
    {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
437
     bfd_generic_archive_p, MY_core_file_p},
438
    {bfd_false, MY_mkobject,    /* bfd_set_format */
439
     _bfd_generic_mkarchive, bfd_false},
440
    {bfd_false, MY_write_object_contents, /* bfd_write_contents */
441
     _bfd_write_archive_contents, bfd_false},
442
 
443
    BFD_JUMP_TABLE_GENERIC (MY),
444
    BFD_JUMP_TABLE_COPY (MY),
445
    BFD_JUMP_TABLE_CORE (MY),
446
    BFD_JUMP_TABLE_ARCHIVE (MY),
447
    BFD_JUMP_TABLE_SYMBOLS (MY),
448
    BFD_JUMP_TABLE_RELOCS (MY),
449
    BFD_JUMP_TABLE_WRITE (MY),
450
    BFD_JUMP_TABLE_LINK (MY),
451
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
452
 
453
    & aout_mips_big_vec,
454
 
455
    (PTR) MY_backend_data
456
  };
457
 
458
const bfd_target aout_mips_big_vec =
459
  {
460
    "a.out-mips-big",           /* name */
461
    bfd_target_aout_flavour,
462
    BFD_ENDIAN_BIG,             /* target byte order (big) */
463
    BFD_ENDIAN_BIG,             /* target headers byte order (big) */
464
    (HAS_RELOC | EXEC_P |               /* object flags */
465
     HAS_LINENO | HAS_DEBUG |
466
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
467
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
468
    MY_symbol_leading_char,
469
    ' ',                                /* ar_pad_char */
470
    15,                         /* ar_max_namelen */
471
    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
472
    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
473
    bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
474
    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
475
    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
476
    bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
477
    {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
478
     bfd_generic_archive_p, MY_core_file_p},
479
    {bfd_false, MY_mkobject,    /* bfd_set_format */
480
     _bfd_generic_mkarchive, bfd_false},
481
    {bfd_false, MY_write_object_contents, /* bfd_write_contents */
482
     _bfd_write_archive_contents, bfd_false},
483
 
484
    BFD_JUMP_TABLE_GENERIC (MY),
485
    BFD_JUMP_TABLE_COPY (MY),
486
    BFD_JUMP_TABLE_CORE (MY),
487
    BFD_JUMP_TABLE_ARCHIVE (MY),
488
    BFD_JUMP_TABLE_SYMBOLS (MY),
489
    BFD_JUMP_TABLE_RELOCS (MY),
490
    BFD_JUMP_TABLE_WRITE (MY),
491
    BFD_JUMP_TABLE_LINK (MY),
492
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
493
 
494
    & aout_mips_little_vec,
495
 
496
    (PTR) MY_backend_data
497
  };

powered by: WebSVN 2.1.0

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