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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [aout-tic30.c] - Blame information for rev 161

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* BFD back-end for TMS320C30 a.out binaries.
2
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009,
3 148 khays
   2010, 2011
4 14 khays
   Free Software Foundation, Inc.
5
   Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
6
 
7
   This file is part of BFD, the Binary File Descriptor library.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22
   02110-1301, USA.  */
23
 
24
#define TARGET_IS_BIG_ENDIAN_P
25
#define N_HEADER_IN_TEXT(x)     1
26
#define TEXT_START_ADDR         1024
27
#define TARGET_PAGE_SIZE        128
28
#define SEGMENT_SIZE            TARGET_PAGE_SIZE
29
#define DEFAULT_ARCH            bfd_arch_tic30
30
#define ARCH_SIZE 32
31
 
32
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
33
   remove whitespace added here, and thus will fail to concatenate
34
   the tokens.  */
35
#define MY(OP) CONCAT2 (tic30_aout_,OP)
36
#define TARGETNAME "a.out-tic30"
37
#define NAME(x,y) CONCAT3 (tic30_aout,_32_,y)
38
 
39
#include "sysdep.h"
40
#include "bfd.h"
41
#include "libaout.h"
42
#include "aout/aout64.h"
43
#include "aout/stab_gnu.h"
44
#include "aout/ar.h"
45
 
46
#define MY_reloc_howto(BFD, REL, IN, EX, PC)   tic30_aout_reloc_howto (BFD, REL, & IN, & EX, & PC)
47
 
48
#define MY_final_link_relocate    tic30_aout_final_link_relocate
49
#define MY_object_p               tic30_aout_object_p
50
#define MY_mkobject               NAME (aout,mkobject)
51
#define MY_write_object_contents  tic30_aout_write_object_contents
52
#define MY_set_sizes              tic30_aout_set_sizes
53
 
54
#ifndef MY_exec_hdr_flags
55
#define MY_exec_hdr_flags 1
56
#endif
57
 
58
#ifndef MY_backend_data
59
 
60
#ifndef MY_zmagic_contiguous
61
#define MY_zmagic_contiguous 0
62
#endif
63
#ifndef MY_text_includes_header
64
#define MY_text_includes_header 0
65
#endif
66
#ifndef MY_entry_is_text_address
67
#define MY_entry_is_text_address 0
68
#endif
69
#ifndef MY_exec_header_not_counted
70
#define MY_exec_header_not_counted 1
71
#endif
72
#ifndef MY_add_dynamic_symbols
73
#define MY_add_dynamic_symbols 0
74
#endif
75
#ifndef MY_add_one_symbol
76
#define MY_add_one_symbol 0
77
#endif
78
#ifndef MY_link_dynamic_object
79
#define MY_link_dynamic_object 0
80
#endif
81
#ifndef MY_write_dynamic_symbol
82
#define MY_write_dynamic_symbol 0
83
#endif
84
#ifndef MY_check_dynamic_reloc
85
#define MY_check_dynamic_reloc 0
86
#endif
87
#ifndef MY_finish_dynamic_link
88
#define MY_finish_dynamic_link 0
89
#endif
90
 
91
static bfd_boolean
92
tic30_aout_set_sizes (bfd *abfd)
93
{
94
  adata (abfd).page_size = TARGET_PAGE_SIZE;
95
 
96
#ifdef SEGMENT_SIZE
97
  adata (abfd).segment_size = SEGMENT_SIZE;
98
#else
99
  adata (abfd).segment_size = TARGET_PAGE_SIZE;
100
#endif
101
 
102
#ifdef ZMAGIC_DISK_BLOCK_SIZE
103
  adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
104
#else
105
  adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
106
#endif
107
 
108
  adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
109
 
110
  return TRUE;
111
}
112
 
113
static const struct aout_backend_data tic30_aout_backend_data =
114
{
115
  MY_zmagic_contiguous,
116
  MY_text_includes_header,
117
  MY_entry_is_text_address,
118
  MY_exec_hdr_flags,
119
  0,                             /* Text vma?  */
120
  MY_set_sizes,
121
  MY_exec_header_not_counted,
122
  MY_add_dynamic_symbols,
123
  MY_add_one_symbol,
124
  MY_link_dynamic_object,
125
  MY_write_dynamic_symbol,
126
  MY_check_dynamic_reloc,
127
  MY_finish_dynamic_link
128
};
129
#define MY_backend_data &tic30_aout_backend_data
130
#endif
131
 
132
static reloc_howto_type *
133
  tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *);
134
static bfd_reloc_status_type
135
  tic30_aout_final_link_relocate
136
    (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
137
 
138
/* FIXME: This is wrong.  aoutx.h should really only be included by
139
   aout32.c.  */
140
 
141
#include "aoutx.h"
142
 
143
/* This function is used to work out pc-relative offsets for the
144
   TMS320C30.  The data already placed by md_pcrel_from within gas is
145
   useless for a relocation, so we just get the offset value and place
146
   a version of this within the object code.
147
   tic30_aout_final_link_relocate will then calculate the required
148
   relocation to add on to the value in the object code.  */
149
 
150
static bfd_reloc_status_type
151
tic30_aout_fix_pcrel_16 (bfd *abfd,
152
                         arelent *reloc_entry,
153
                         asymbol *symbol ATTRIBUTE_UNUSED,
154
                         void * data,
155
                         asection *input_section ATTRIBUTE_UNUSED,
156
                         bfd *output_bfd ATTRIBUTE_UNUSED,
157
                         char **error_message ATTRIBUTE_UNUSED)
158
{
159
  bfd_vma relocation = 1;
160
  bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);
161
 
162
  /* The byte before the location of the fix contains bits 23-16 of
163
     the pcrel instruction.  Bit 21 is set for a delayed instruction
164
     which requires on offset of 3 instead of 1.  */
165
  if (offset_data & 0x20)
166
    relocation -= 3;
167
  else
168
    relocation -= 1;
169
  bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
170
  return bfd_reloc_ok;
171
}
172
 
173
/* This function is used as a callback for 16-bit relocs.  This is
174
   required for relocations between segments.  A line in aoutx.h
175
   requires that any relocations for the data section should point to
176
   the end of the aligned text section, plus an offset.  By default,
177
   this does not happen, therefore this function takes care of
178
   that.  */
179
 
180
static bfd_reloc_status_type
181
tic30_aout_fix_16 (bfd *abfd,
182
                   arelent *reloc_entry,
183
                   asymbol *symbol,
184
                   void * data,
185
                   asection *input_section ATTRIBUTE_UNUSED,
186
                   bfd *output_bfd,
187
                   char **error_message ATTRIBUTE_UNUSED)
188
{
189
  bfd_vma relocation;
190
 
191
  /* Make sure that the symbol's section is defined.  */
192
  if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
193
    return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
194
  /* Get the size of the input section and turn it into the TMS320C30
195
     32-bit address format.  */
196
  relocation = (symbol->section->vma >> 2);
197
  relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
198
  bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
199
  return bfd_reloc_ok;
200
}
201
 
202
/* This function does the same thing as tic30_aout_fix_16 except for 32
203
   bit relocations.  */
204
 
205
static bfd_reloc_status_type
206
tic30_aout_fix_32 (bfd *abfd,
207
                   arelent *reloc_entry,
208
                   asymbol *symbol,
209
                   void * data,
210
                   asection *input_section ATTRIBUTE_UNUSED,
211
                   bfd *output_bfd,
212
                   char **error_message ATTRIBUTE_UNUSED)
213
{
214
  bfd_vma relocation;
215
 
216
  /* Make sure that the symbol's section is defined.  */
217
  if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
218
    return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
219
  /* Get the size of the input section and turn it into the TMS320C30
220
     32-bit address format.  */
221
  relocation = (symbol->section->vma >> 2);
222
  relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
223
  bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
224
  return bfd_reloc_ok;
225
}
226
 
227
/* This table lists the relocation types for the TMS320C30.  There are
228
   only a few relocations required, and all must be divided by 4 (>>
229
   2) to get the 32-bit addresses in the format the TMS320C30 likes
230
   it.  */
231
reloc_howto_type tic30_aout_howto_table[] =
232
{
233
  EMPTY_HOWTO (-1),
234
  HOWTO (1, 2, 1, 16, FALSE, 0, 0, tic30_aout_fix_16,
235
         "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE),
236
  HOWTO (2, 2, 2, 24, FALSE, 0, complain_overflow_bitfield, NULL,
237
         "24", FALSE, 0x00FFFFFF, 0x00FFFFFF, FALSE),
238
  HOWTO (3, 18, 3, 24, FALSE, 0, complain_overflow_bitfield, NULL,
239
         "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE),
240
  HOWTO (4, 2, 4, 32, FALSE, 0, complain_overflow_bitfield, tic30_aout_fix_32,
241
         "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE),
242
  HOWTO (5, 2, 1, 16, TRUE, 0, complain_overflow_signed,
243
         tic30_aout_fix_pcrel_16, "PCREL", TRUE, 0x0000FFFF, 0x0000FFFF, TRUE),
244
  EMPTY_HOWTO (-1),
245
  EMPTY_HOWTO (-1),
246
  EMPTY_HOWTO (-1),
247
  EMPTY_HOWTO (-1),
248
  EMPTY_HOWTO (-1)
249
};
250
 
251
 
252
static reloc_howto_type *
253
tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
254
                              bfd_reloc_code_real_type code)
255
{
256
  switch (code)
257
    {
258
    case BFD_RELOC_8:
259
    case BFD_RELOC_TIC30_LDP:
260
      return &tic30_aout_howto_table[3];
261
    case BFD_RELOC_16:
262
      return &tic30_aout_howto_table[1];
263
    case BFD_RELOC_24:
264
      return &tic30_aout_howto_table[2];
265
    case BFD_RELOC_16_PCREL:
266
      return &tic30_aout_howto_table[5];
267
    case BFD_RELOC_32:
268
      return &tic30_aout_howto_table[4];
269
    default:
270
      return NULL;
271
    }
272
}
273
 
274
static reloc_howto_type *
275
tic30_aout_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
276
                              const char *r_name)
277
{
278
  unsigned int i;
279
 
280
  for (i = 0;
281
       i < (sizeof (tic30_aout_howto_table)
282
            / sizeof (tic30_aout_howto_table[0]));
283
       i++)
284
    if (tic30_aout_howto_table[i].name != NULL
285
        && strcasecmp (tic30_aout_howto_table[i].name, r_name) == 0)
286
      return &tic30_aout_howto_table[i];
287
 
288
  return NULL;
289
}
290
 
291
static reloc_howto_type *
292
tic30_aout_reloc_howto (bfd *abfd,
293
                        struct reloc_std_external *relocs,
294
                        int *r_index,
295
                        int *r_extern,
296
                        int *r_pcrel)
297
{
298
  unsigned int r_length;
299
  unsigned int r_pcrel_done;
300
  int howto_index;
301
 
302
  *r_pcrel = 0;
303
  if (bfd_header_big_endian (abfd))
304
    {
305
      *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
306
      *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
307
      r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
308
      r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
309
    }
310
  else
311
    {
312
      *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
313
      *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
314
      r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
315
      r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
316
    }
317
  howto_index = r_length + 4 * r_pcrel_done;
318
  return tic30_aout_howto_table + howto_index;
319
}
320
 
321
/* These macros will get 24-bit values from the bfd definition.
322
   Big-endian only.  */
323
#define bfd_getb_24(BFD,ADDR)                   \
324
 (bfd_get_8 (BFD, ADDR    ) << 16) |            \
325
 (bfd_get_8 (BFD, ADDR + 1) <<  8) |            \
326
 (bfd_get_8 (BFD, ADDR + 2)      )
327
 
328
#define bfd_putb_24(BFD,DATA,ADDR)                              \
329
 bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR    );   \
330
 bfd_put_8 (BFD, (bfd_byte) ((DATA >>  8) & 0xFF), ADDR + 1);   \
331
 bfd_put_8 (BFD, (bfd_byte) ( DATA        & 0xFF), ADDR + 2)
332
 
333
/* Set parameters about this a.out file that are machine-dependent.
334
   This routine is called from some_aout_object_p just before it returns.  */
335
 
336
static const bfd_target *
337
tic30_aout_callback (bfd *abfd)
338
{
339
  struct internal_exec *execp = exec_hdr (abfd);
340
  unsigned int arch_align_power;
341
  unsigned long arch_align;
342
 
343
  /* Calculate the file positions of the parts of a newly read aout header.  */
344
  obj_textsec (abfd)->size = N_TXTSIZE (*execp);
345
 
346
  /* The virtual memory addresses of the sections.  */
347
  obj_textsec (abfd)->vma = N_TXTADDR (*execp);
348
  obj_datasec (abfd)->vma = N_DATADDR (*execp);
349
  obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
350
 
351
  obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
352
  obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
353
  obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
354
 
355
  /* The file offsets of the sections.  */
356
  obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
357
  obj_datasec (abfd)->filepos = N_DATOFF (*execp);
358
 
359
  /* The file offsets of the relocation info.  */
360
  obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
361
  obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
362
 
363
  /* The file offsets of the string table and symbol table.  */
364
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);
365
  obj_str_filepos (abfd) = N_STROFF (*execp);
366
 
367
  /* Determine the architecture and machine type of the object file.  */
368
#ifdef SET_ARCH_MACH
369
  SET_ARCH_MACH (abfd, *execp);
370
#else
371
  bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L);
372
#endif
373
 
374
  /* Now that we know the architecture, set the alignments of the
375
     sections.  This is normally done by NAME (aout,new_section_hook),
376
     but when the initial sections were created the architecture had
377
     not yet been set.  However, for backward compatibility, we don't
378
     set the alignment power any higher than as required by the size
379
     of the section.  */
380
  arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
381
  arch_align = 1 << arch_align_power;
382
  if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align)
383
       == obj_textsec (abfd)->size)
384
      && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
385
          == obj_datasec (abfd)->size)
386
      && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
387
          == obj_bsssec (abfd)->size))
388
    {
389
      obj_textsec (abfd)->alignment_power = arch_align_power;
390
      obj_datasec (abfd)->alignment_power = arch_align_power;
391
      obj_bsssec (abfd)->alignment_power = arch_align_power;
392
    }
393
  return abfd->xvec;
394
}
395
 
396
static bfd_reloc_status_type
397
tic30_aout_relocate_contents (reloc_howto_type *howto,
398
                              bfd *input_bfd,
399
                              bfd_vma relocation,
400
                              bfd_byte *location)
401
{
402
  bfd_vma x;
403
  bfd_boolean overflow;
404
 
405
  if (howto->size < 0)
406
    relocation = -relocation;
407
 
408
  switch (howto->size)
409
    {
410
    default:
411
    case 0:
412
      abort ();
413
      break;
414
    case 1:
415
      x = bfd_get_16 (input_bfd, location);
416
      break;
417
    case 2:
418
      x = bfd_getb_24 (input_bfd, location);
419
      break;
420
    case 3:
421
      x = bfd_get_8 (input_bfd, location);
422
      break;
423
    case 4:
424
      x = bfd_get_32 (input_bfd, location);
425
      break;
426
    }
427
 
428
  overflow = FALSE;
429
 
430
  if (howto->complain_on_overflow != complain_overflow_dont)
431
    {
432
      bfd_vma check;
433
      bfd_signed_vma signed_check;
434
      bfd_vma add;
435
      bfd_signed_vma signed_add;
436
 
437
      if (howto->rightshift == 0)
438
        {
439
          check = relocation;
440
          signed_check = (bfd_signed_vma) relocation;
441
        }
442
      else
443
        {
444
          check = relocation >> howto->rightshift;
445
          if ((bfd_signed_vma) relocation >= 0)
446
            signed_check = check;
447
          else
448
            signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
449
        }
450
      add = x & howto->src_mask;
451
      signed_add = add;
452
      if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
453
        signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
454
      if (howto->bitpos == 0)
455
        {
456
          check += add;
457
          signed_check += signed_add;
458
        }
459
      else
460
        {
461
          check += add >> howto->bitpos;
462
          if (signed_add >= 0)
463
            signed_check += add >> howto->bitpos;
464
          else
465
            signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
466
        }
467
      switch (howto->complain_on_overflow)
468
        {
469
        case complain_overflow_signed:
470
          {
471
            bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
472
            bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
473
 
474
            if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
475
              overflow = TRUE;
476
          }
477
          break;
478
        case complain_overflow_unsigned:
479
          {
480
            bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
481
 
482
            if (check > reloc_unsigned_max)
483
              overflow = TRUE;
484
          }
485
          break;
486
        case complain_overflow_bitfield:
487
          {
488
            bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
489
 
490
            if ((check & ~reloc_bits) != 0
491
                && (((bfd_vma) signed_check & ~reloc_bits)
492
                    != ((bfd_vma) -1 & ~reloc_bits)))
493
              overflow = TRUE;
494
          }
495
          break;
496
        default:
497
          abort ();
498
        }
499
    }
500
  relocation >>= (bfd_vma) howto->rightshift;
501
  relocation <<= (bfd_vma) howto->bitpos;
502
  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
503
  switch (howto->size)
504
    {
505
    default:
506
    case 0:
507
      abort ();
508
      break;
509
    case 1:
510
      bfd_put_16 (input_bfd, x, location);
511
      break;
512
    case 2:
513
      bfd_putb_24 (input_bfd, x, location);
514
      break;
515
    case 3:
516
      bfd_put_8 (input_bfd, x, location);
517
      break;
518
    case 4:
519
      bfd_put_32 (input_bfd, x, location);
520
      break;
521
    }
522
  return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
523
}
524
 
525
static bfd_reloc_status_type
526
tic30_aout_final_link_relocate (reloc_howto_type *howto,
527
                                bfd *input_bfd,
528
                                asection *input_section,
529
                                bfd_byte *contents,
530
                                bfd_vma address,
531
                                bfd_vma value,
532
                                bfd_vma addend)
533
{
534
  bfd_vma relocation;
535
 
536
  if (address > bfd_get_section_limit (input_bfd, input_section))
537
    return bfd_reloc_outofrange;
538
 
539
  relocation = value + addend;
540
  if (howto->pc_relative)
541
    {
542
      relocation -= (input_section->output_section->vma + input_section->output_offset);
543
      if (howto->pcrel_offset)
544
        relocation -= address;
545
    }
546
  return tic30_aout_relocate_contents (howto, input_bfd, relocation,
547
                                       contents + address);
548
}
549
 
550
/* Finish up the reading of an a.out file header.  */
551
 
552
static const bfd_target *
553
tic30_aout_object_p (bfd *abfd)
554
{
555
  struct external_exec exec_bytes;      /* Raw exec header from file.  */
556
  struct internal_exec exec;            /* Cleaned-up exec header.  */
557
  const bfd_target *target;
558
  bfd_size_type amt = EXEC_BYTES_SIZE;
559
 
560
  if (bfd_bread (& exec_bytes, amt, abfd) != amt)
561
    {
562
      if (bfd_get_error () != bfd_error_system_call)
563
        bfd_set_error (bfd_error_wrong_format);
564
      return 0;
565
    }
566
 
567
#ifdef SWAP_MAGIC
568
  exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
569
#else
570
  exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
571
#endif /* SWAP_MAGIC */
572
 
573
  if (N_BADMAG (exec))
574
    return 0;
575
#ifdef MACHTYPE_OK
576
  if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
577
    return 0;
578
#endif
579
 
580
  NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec);
581
 
582
#ifdef SWAP_MAGIC
583
  /* Swap_exec_header_in read in a_info with the wrong byte order.  */
584
  exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
585
#endif
586
 
587
  target = NAME (aout, some_aout_object_p) (abfd, &exec, tic30_aout_callback);
588
 
589
#ifdef ENTRY_CAN_BE_ZERO
590
  /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
591
     means that it isn't obvious if EXEC_P should be set.
592
     All of the following must be true for an executable:
593
     There must be no relocations, the bfd can be neither an
594
     archive nor an archive element, and the file must be executable.  */
595
 
596
  if (exec.a_trsize + exec.a_drsize == 0
597
      && bfd_get_format (abfd) == bfd_object && abfd->my_archive == NULL)
598
    {
599
      struct stat buf;
600
#ifndef S_IXUSR
601
#define S_IXUSR 0100            /* Execute by owner.  */
602
#endif
603
      if (stat (abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
604
        abfd->flags |= EXEC_P;
605
    }
606
#endif
607
 
608
  return target;
609
}
610
 
611
/* Copy private section data.  This actually does nothing with the
612
   sections.  It copies the subformat field.  We copy it here, because
613
   we need to know whether this is a QMAGIC file before we set the
614
   section contents, and copy_private_bfd_data is not called until
615
   after the section contents have been set.  */
616
 
617
static bfd_boolean
618
MY_bfd_copy_private_section_data (bfd *ibfd,
619
                                  asection *isec ATTRIBUTE_UNUSED,
620
                                  bfd *obfd,
621
                                  asection *osec ATTRIBUTE_UNUSED)
622
{
623
  if (bfd_get_flavour (obfd) == bfd_target_aout_flavour)
624
    obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
625
  return TRUE;
626
}
627
 
628
/* Write an object file.
629
   Section contents have already been written.  We write the
630
   file header, symbols, and relocation.  */
631
 
632
static bfd_boolean
633
tic30_aout_write_object_contents (bfd *abfd)
634
{
635
  struct external_exec exec_bytes;
636
  struct internal_exec *execp = exec_hdr (abfd);
637
 
638
  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
639
 
640
  {
641
    bfd_size_type text_size;    /* Dummy vars.  */
642
    file_ptr text_end;
643
 
644
    if (adata (abfd).magic == undecided_magic)
645
      NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
646
 
647
    execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
648
    execp->a_entry = bfd_get_start_address (abfd);
649
 
650
    execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
651
    execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * obj_reloc_entry_size (abfd));
652
    NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes);
653
 
654
    if (adata (abfd).exec_bytes_size > 0)
655
      {
656
        bfd_size_type amt;
657
 
658
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
659
          return FALSE;
660
        amt = adata (abfd).exec_bytes_size;
661
        if (bfd_bwrite (& exec_bytes, amt, abfd) != amt)
662
          return FALSE;
663
      }
664
 
665
    /* Now write out reloc info, followed by syms and strings.  */
666
    if (bfd_get_outsymbols (abfd) != (asymbol **) NULL
667
        && bfd_get_symcount (abfd) != 0)
668
      {
669
        if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*execp)), SEEK_SET) != 0)
670
          return FALSE;
671
 
672
        if (!NAME (aout, write_syms) (abfd))
673
          return FALSE;
674
      }
675
 
676
    if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0)
677
      return FALSE;
678
    if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd)))
679
      return FALSE;
680
 
681
    if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0)
682
      return FALSE;
683
    if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
684
      return FALSE;
685
  }
686
 
687
  return TRUE;
688
}
689
 
690
#ifndef MY_final_link_callback
691
 
692
/* Callback for the final_link routine to set the section offsets.  */
693
 
694
static void
695
MY_final_link_callback (bfd *abfd,
696
                        file_ptr *ptreloff,
697
                        file_ptr *pdreloff,
698
                        file_ptr *psymoff)
699
{
700
  struct internal_exec *execp = exec_hdr (abfd);
701
 
702
  *ptreloff = obj_datasec (abfd)->filepos + execp->a_data;
703
  *pdreloff = *ptreloff + execp->a_trsize;
704
  *psymoff = *pdreloff + execp->a_drsize;;
705
}
706
 
707
#endif
708
 
709
#ifndef MY_bfd_final_link
710
 
711
/* Final link routine.  We need to use a call back to get the correct
712
   offsets in the output file.  */
713
 
714
static bfd_boolean
715
MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
716
{
717
  struct internal_exec *execp = exec_hdr (abfd);
718
  file_ptr pos;
719
  bfd_vma vma = 0;
720
  int pad;
721
 
722
  /* Set the executable header size to 0, as we don't want one for an
723
     output.  */
724
  adata (abfd).exec_bytes_size = 0;
725
  pos = adata (abfd).exec_bytes_size;
726
  /* Text.  */
727
  vma = info->create_object_symbols_section->vma;
728
  pos += vma;
729
  obj_textsec (abfd)->filepos = pos;
730
  obj_textsec (abfd)->vma = vma;
731
  obj_textsec (abfd)->user_set_vma = 1;
732
  pos += obj_textsec (abfd)->size;
733
  vma += obj_textsec (abfd)->size;
734
 
735
  /* Data.  */
736
  if (abfd->flags & D_PAGED)
737
    {
738
      if (info->create_object_symbols_section->next->vma > 0)
739
        obj_datasec (abfd)->vma = info->create_object_symbols_section->next->vma;
740
      else
741
        obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
742
    }
743
  else
744
    obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
745
 
746
  if (obj_datasec (abfd)->vma < vma)
747
    obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
748
 
749
  obj_datasec (abfd)->user_set_vma = 1;
750
  vma = obj_datasec (abfd)->vma;
751
  obj_datasec (abfd)->filepos = vma + adata (abfd).exec_bytes_size;
752
  execp->a_text = vma - obj_textsec (abfd)->vma;
753
  obj_textsec (abfd)->size = execp->a_text;
754
 
755
  /* Since BSS follows data immediately, see if it needs alignment.  */
756
  vma += obj_datasec (abfd)->size;
757
  pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
758
  obj_datasec (abfd)->size += pad;
759
  pos += obj_datasec (abfd)->size;
760
  execp->a_data = obj_datasec (abfd)->size;
761
 
762
  /* BSS.  */
763
  obj_bsssec (abfd)->vma = vma;
764
  obj_bsssec (abfd)->user_set_vma = 1;
765
 
766
  /* We are fully resized, so don't readjust in final_link.  */
767
  adata (abfd).magic = z_magic;
768
 
769
  return NAME (aout, final_link) (abfd, info, MY_final_link_callback);
770
}
771
 
772
#endif
773
 
774
static enum machine_type
775
tic30_aout_machine_type (enum bfd_architecture arch,
776
                         unsigned long machine ATTRIBUTE_UNUSED,
777
                         bfd_boolean *unknown)
778
{
779
  enum machine_type arch_flags;
780
 
781
  arch_flags = M_UNKNOWN;
782
  *unknown = TRUE;
783
 
784
  switch (arch)
785
    {
786
    case bfd_arch_tic30:
787
      *unknown = FALSE;
788
      break;
789
    default:
790
      arch_flags = M_UNKNOWN;
791
    }
792
  if (arch_flags != M_UNKNOWN)
793
    *unknown = FALSE;
794
  return arch_flags;
795
}
796
 
797
static bfd_boolean
798
tic30_aout_set_arch_mach (bfd *abfd,
799
                          enum bfd_architecture arch,
800
                          unsigned long machine)
801
{
802
  if (!bfd_default_set_arch_mach (abfd, arch, machine))
803
    return FALSE;
804
  if (arch != bfd_arch_unknown)
805
    {
806
      bfd_boolean unknown;
807
      tic30_aout_machine_type (arch, machine, &unknown);
808
      if (unknown)
809
        return FALSE;
810
    }
811
  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
812
  return (*aout_backend_info (abfd)->set_sizes) (abfd);
813
}
814
 
815
/* We assume BFD generic archive files.  */
816
#ifndef MY_openr_next_archived_file
817
#define MY_openr_next_archived_file     bfd_generic_openr_next_archived_file
818
#endif
819
#ifndef MY_get_elt_at_index
820
#define MY_get_elt_at_index             _bfd_generic_get_elt_at_index
821
#endif
822
#ifndef MY_generic_stat_arch_elt
823
#define MY_generic_stat_arch_elt        bfd_generic_stat_arch_elt
824
#endif
825
#ifndef MY_slurp_armap
826
#define MY_slurp_armap                  bfd_slurp_bsd_armap
827
#endif
828
#ifndef MY_slurp_extended_name_table
829
#define MY_slurp_extended_name_table    _bfd_slurp_extended_name_table
830
#endif
831
#ifndef MY_construct_extended_name_table
832
#define MY_construct_extended_name_table \
833
  _bfd_archive_bsd_construct_extended_name_table
834
#endif
835
#ifndef MY_write_armap
836
#define MY_write_armap                  bsd_write_armap
837
#endif
838
#ifndef MY_read_ar_hdr
839
#define MY_read_ar_hdr                  _bfd_generic_read_ar_hdr
840
#endif
841
#ifndef MY_write_ar_hdr
842
#define MY_write_ar_hdr                 _bfd_generic_write_ar_hdr
843
#endif
844
#ifndef MY_truncate_arname
845
#define MY_truncate_arname              bfd_bsd_truncate_arname
846
#endif
847
#ifndef MY_update_armap_timestamp
848
#define MY_update_armap_timestamp       _bfd_archive_bsd_update_armap_timestamp
849
#endif
850
 
851
/* No core file defined here -- configure in trad-core.c separately.  */
852
#ifndef MY_core_file_failing_command
853
#define MY_core_file_failing_command    _bfd_nocore_core_file_failing_command
854
#endif
855
#ifndef MY_core_file_failing_signal
856
#define MY_core_file_failing_signal     _bfd_nocore_core_file_failing_signal
857
#endif
858
#ifndef MY_core_file_matches_executable_p
859
#define MY_core_file_matches_executable_p       \
860
                                _bfd_nocore_core_file_matches_executable_p
861
#endif
862
#ifndef MY_core_file_pid
863
#define MY_core_file_pid                _bfd_nocore_core_file_pid
864
#endif
865
#ifndef MY_core_file_p
866
#define MY_core_file_p                  _bfd_dummy_target
867
#endif
868
 
869
#ifndef MY_bfd_debug_info_start
870
#define MY_bfd_debug_info_start         bfd_void
871
#endif
872
#ifndef MY_bfd_debug_info_end
873
#define MY_bfd_debug_info_end           bfd_void
874
#endif
875
#ifndef MY_bfd_debug_info_accumulate
876
#define MY_bfd_debug_info_accumulate    \
877
                (void (*) (bfd*, struct bfd_section *)) bfd_void
878
#endif
879
 
880
#ifndef MY_core_file_failing_command
881
#define MY_core_file_failing_command NAME (aout, core_file_failing_command)
882
#endif
883
#ifndef MY_core_file_failing_signal
884
#define MY_core_file_failing_signal NAME (aout, core_file_failing_signal)
885
#endif
886
#ifndef MY_core_file_matches_executable_p
887
#define MY_core_file_matches_executable_p NAME (aout, core_file_matches_executable_p)
888
#endif
889
#ifndef MY_set_section_contents
890
#define MY_set_section_contents NAME (aout, set_section_contents)
891
#endif
892
#ifndef MY_get_section_contents
893
#define MY_get_section_contents aout_32_get_section_contents
894
#endif
895
#ifndef MY_get_section_contents_in_window
896
#define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
897
#endif
898
#ifndef MY_new_section_hook
899
#define MY_new_section_hook NAME (aout, new_section_hook)
900
#endif
901
#ifndef MY_get_symtab_upper_bound
902
#define MY_get_symtab_upper_bound NAME (aout, get_symtab_upper_bound)
903
#endif
904
#ifndef MY_canonicalize_symtab
905
#define MY_canonicalize_symtab NAME (aout, canonicalize_symtab)
906
#endif
907
#ifndef MY_get_reloc_upper_bound
908
#define MY_get_reloc_upper_bound NAME (aout, get_reloc_upper_bound)
909
#endif
910
#ifndef MY_canonicalize_reloc
911
#define MY_canonicalize_reloc NAME (aout, canonicalize_reloc)
912
#endif
913
#ifndef MY_make_empty_symbol
914
#define MY_make_empty_symbol NAME (aout, make_empty_symbol)
915
#endif
916
#ifndef MY_print_symbol
917
#define MY_print_symbol NAME (aout, print_symbol)
918
#endif
919
#ifndef MY_get_symbol_info
920
#define MY_get_symbol_info NAME (aout, get_symbol_info)
921
#endif
922
#ifndef MY_get_lineno
923
#define MY_get_lineno NAME (aout, get_lineno)
924
#endif
925
#ifndef MY_set_arch_mach
926
#define MY_set_arch_mach tic30_aout_set_arch_mach
927
#endif
928
#ifndef MY_find_nearest_line
929
#define MY_find_nearest_line NAME (aout, find_nearest_line)
930
#endif
931
#ifndef MY_find_inliner_info
932
#define MY_find_inliner_info _bfd_nosymbols_find_inliner_info
933
#endif
934
#ifndef MY_sizeof_headers
935
#define MY_sizeof_headers NAME (aout, sizeof_headers)
936
#endif
937
#ifndef MY_bfd_get_relocated_section_contents
938
#define MY_bfd_get_relocated_section_contents \
939
                        bfd_generic_get_relocated_section_contents
940
#endif
941
#ifndef MY_bfd_relax_section
942
#define MY_bfd_relax_section bfd_generic_relax_section
943
#endif
944
#ifndef MY_bfd_gc_sections
945
#define MY_bfd_gc_sections bfd_generic_gc_sections
946
#endif
947 161 khays
#ifndef MY_bfd_lookup_section_flags
948
#define MY_bfd_lookup_section_flags bfd_generic_lookup_section_flags
949
#endif
950 14 khays
#ifndef MY_bfd_merge_sections
951
#define MY_bfd_merge_sections bfd_generic_merge_sections
952
#endif
953
#ifndef MY_bfd_is_group_section
954
#define MY_bfd_is_group_section bfd_generic_is_group_section
955
#endif
956
#ifndef MY_bfd_discard_group
957
#define MY_bfd_discard_group bfd_generic_discard_group
958
#endif
959
#ifndef MY_section_already_linked
960
#define MY_section_already_linked \
961
  _bfd_generic_section_already_linked
962
#endif
963
#ifndef MY_bfd_define_common_symbol
964
#define MY_bfd_define_common_symbol bfd_generic_define_common_symbol
965
#endif
966
#ifndef MY_bfd_reloc_type_lookup
967
#define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
968
#endif
969
#ifndef MY_bfd_reloc_name_lookup
970
#define MY_bfd_reloc_name_lookup tic30_aout_reloc_name_lookup
971
#endif
972
#ifndef MY_bfd_make_debug_symbol
973
#define MY_bfd_make_debug_symbol 0
974
#endif
975
#ifndef MY_read_minisymbols
976
#define MY_read_minisymbols NAME (aout, read_minisymbols)
977
#endif
978
#ifndef MY_minisymbol_to_symbol
979
#define MY_minisymbol_to_symbol NAME (aout, minisymbol_to_symbol)
980
#endif
981
#ifndef MY_bfd_link_hash_table_create
982
#define MY_bfd_link_hash_table_create NAME (aout, link_hash_table_create)
983
#endif
984
#ifndef MY_bfd_link_hash_table_free
985
#define MY_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
986
#endif
987
#ifndef MY_bfd_link_add_symbols
988
#define MY_bfd_link_add_symbols NAME (aout, link_add_symbols)
989
#endif
990
#ifndef MY_bfd_link_just_syms
991
#define MY_bfd_link_just_syms _bfd_generic_link_just_syms
992
#endif
993
#ifndef MY_bfd_copy_link_hash_symbol_type
994
#define MY_bfd_copy_link_hash_symbol_type \
995
  _bfd_generic_copy_link_hash_symbol_type
996
#endif
997
#ifndef MY_bfd_link_split_section
998
#define MY_bfd_link_split_section  _bfd_generic_link_split_section
999
#endif
1000
 
1001
#ifndef MY_bfd_copy_private_bfd_data
1002
#define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
1003
#endif
1004
 
1005
#ifndef MY_bfd_merge_private_bfd_data
1006
#define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
1007
#endif
1008
 
1009
#ifndef MY_bfd_copy_private_symbol_data
1010
#define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
1011
#endif
1012
 
1013
#ifndef MY_bfd_copy_private_header_data
1014
#define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
1015
#endif
1016
 
1017
#ifndef MY_bfd_print_private_bfd_data
1018
#define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
1019
#endif
1020
 
1021
#ifndef MY_bfd_set_private_flags
1022
#define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
1023
#endif
1024
 
1025
#ifndef MY_bfd_is_local_label_name
1026
#define MY_bfd_is_local_label_name bfd_generic_is_local_label_name
1027
#endif
1028
 
1029
#ifndef MY_bfd_is_target_special_symbol
1030
#define MY_bfd_is_target_special_symbol  \
1031
  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1032
#endif
1033
 
1034
#ifndef MY_bfd_free_cached_info
1035
#define MY_bfd_free_cached_info NAME (aout, bfd_free_cached_info)
1036
#endif
1037
 
1038
#ifndef MY_close_and_cleanup
1039
#define MY_close_and_cleanup MY_bfd_free_cached_info
1040
#endif
1041
 
1042
#ifndef MY_get_dynamic_symtab_upper_bound
1043
#define MY_get_dynamic_symtab_upper_bound \
1044
  _bfd_nodynamic_get_dynamic_symtab_upper_bound
1045
#endif
1046
#ifndef MY_canonicalize_dynamic_symtab
1047
#define MY_canonicalize_dynamic_symtab \
1048
  _bfd_nodynamic_canonicalize_dynamic_symtab
1049
#endif
1050
#ifndef MY_get_synthetic_symtab
1051
#define MY_get_synthetic_symtab \
1052
  _bfd_nodynamic_get_synthetic_symtab
1053
#endif
1054
#ifndef MY_get_dynamic_reloc_upper_bound
1055
#define MY_get_dynamic_reloc_upper_bound \
1056
  _bfd_nodynamic_get_dynamic_reloc_upper_bound
1057
#endif
1058
#ifndef MY_canonicalize_dynamic_reloc
1059
#define MY_canonicalize_dynamic_reloc \
1060
  _bfd_nodynamic_canonicalize_dynamic_reloc
1061
#endif
1062
 
1063
/* Aout symbols normally have leading underscores.  */
1064
#ifndef MY_symbol_leading_char
1065
#define MY_symbol_leading_char '_'
1066
#endif
1067
 
1068
/* Aout archives normally use spaces for padding.  */
1069
#ifndef AR_PAD_CHAR
1070
#define AR_PAD_CHAR ' '
1071
#endif
1072
 
1073
#ifndef MY_BFD_TARGET
1074
const bfd_target tic30_aout_vec =
1075
{
1076
  TARGETNAME,                   /* Name.  */
1077
  bfd_target_aout_flavour,
1078
  BFD_ENDIAN_BIG,               /* Target byte order (big).  */
1079
  BFD_ENDIAN_BIG,               /* Target headers byte order (big).  */
1080
  (HAS_RELOC |                  /* Object flags.  */
1081
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1082
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),        /* Section flags.  */
1083
  MY_symbol_leading_char,
1084
  AR_PAD_CHAR,                  /* AR_pad_char.  */
1085
  15,                           /* AR_max_namelen.  */
1086 148 khays
  0,                             /* match priority.  */
1087 14 khays
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1088
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1089
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Data.  */
1090
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1091
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1092
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Headers.  */
1093
  {_bfd_dummy_target, MY_object_p,              /* bfd_check_format.  */
1094
   bfd_generic_archive_p, MY_core_file_p},
1095
  {bfd_false, MY_mkobject,                      /* bfd_set_format.  */
1096
   _bfd_generic_mkarchive, bfd_false},
1097
  {bfd_false, MY_write_object_contents,         /* bfd_write_contents.  */
1098
   _bfd_write_archive_contents, bfd_false},
1099
 
1100
  BFD_JUMP_TABLE_GENERIC (MY),
1101
  BFD_JUMP_TABLE_COPY (MY),
1102
  BFD_JUMP_TABLE_CORE (MY),
1103
  BFD_JUMP_TABLE_ARCHIVE (MY),
1104
  BFD_JUMP_TABLE_SYMBOLS (MY),
1105
  BFD_JUMP_TABLE_RELOCS (MY),
1106
  BFD_JUMP_TABLE_WRITE (MY),
1107
  BFD_JUMP_TABLE_LINK (MY),
1108
  BFD_JUMP_TABLE_DYNAMIC (MY),
1109
 
1110
  NULL,
1111
 
1112
  MY_backend_data
1113
};
1114
#endif /* MY_BFD_TARGET */

powered by: WebSVN 2.1.0

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