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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [mipsbsd.c] - Blame information for rev 1782

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

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

powered by: WebSVN 2.1.0

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