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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [mipsbsd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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