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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 205 julius
/* BFD back-end for Intel 960 b.out binaries.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
   Written by Cygnus Support.
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,
22
   MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "bfd.h"
26
#include "libbfd.h"
27
#include "bfdlink.h"
28
#include "genlink.h"
29
#include "bout.h"
30
#include "libiberty.h"
31
 
32
#include "aout/stab_gnu.h"
33
#include "libaout.h"            /* BFD a.out internal data structures.  */
34
 
35
#define ABS32CODE 0
36
#define ABS32CODE_SHRUNK 1
37
#define PCREL24 2
38
#define CALLJ 3
39
#define ABS32 4
40
#define PCREL13 5
41
#define ABS32_MAYBE_RELAXABLE 1
42
#define ABS32_WAS_RELAXABLE 2
43
 
44
#define ALIGNER 10
45
#define ALIGNDONE 11
46
 
47
static reloc_howto_type howto_reloc_callj =
48
  HOWTO (CALLJ, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE);
49
static  reloc_howto_type howto_reloc_abs32 =
50
  HOWTO (ABS32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"abs32", TRUE, 0xffffffff,0xffffffff,FALSE);
51
static reloc_howto_type howto_reloc_pcrel24 =
52
  HOWTO (PCREL24, 0, 2, 24, TRUE, 0, complain_overflow_signed,0,"pcrel24", TRUE, 0x00ffffff,0x00ffffff,FALSE);
53
static reloc_howto_type howto_reloc_pcrel13 =
54
  HOWTO (PCREL13, 0, 2, 13, TRUE, 0, complain_overflow_signed,0,"pcrel13", TRUE, 0x00001fff,0x00001fff,FALSE);
55
static reloc_howto_type howto_reloc_abs32codeshrunk =
56
  HOWTO (ABS32CODE_SHRUNK, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callx->callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE);
57
static  reloc_howto_type howto_reloc_abs32code =
58
  HOWTO (ABS32CODE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"callx", TRUE, 0xffffffff,0xffffffff,FALSE);
59
 
60
static reloc_howto_type howto_align_table[] =
61
{
62
  HOWTO (ALIGNER, 0, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "align16", FALSE, 0, 0, FALSE),
63
  HOWTO (ALIGNER, 0, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "align32", FALSE, 0, 0, FALSE),
64
  HOWTO (ALIGNER, 0, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "align64", FALSE, 0, 0, FALSE),
65
  HOWTO (ALIGNER, 0, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "align128", FALSE, 0, 0, FALSE),
66
};
67
 
68
static reloc_howto_type howto_done_align_table[] =
69
{
70
  HOWTO (ALIGNDONE, 0x1, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "donealign16", FALSE, 0, 0, FALSE),
71
  HOWTO (ALIGNDONE, 0x3, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "donealign32", FALSE, 0, 0, FALSE),
72
  HOWTO (ALIGNDONE, 0x7, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "donealign64", FALSE, 0, 0, FALSE),
73
  HOWTO (ALIGNDONE, 0xf, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "donealign128", FALSE, 0, 0, FALSE),
74
};
75
 
76
/* Swaps the information in an executable header taken from a raw byte
77
   stream memory image, into the internal exec_header structure.  */
78
 
79
static void
80
bout_swap_exec_header_in (bfd *abfd,
81
                          struct external_exec *bytes,
82
                          struct internal_exec *execp)
83
{
84
  /* Now fill in fields in the execp, from the bytes in the raw data.  */
85
  execp->a_info      = H_GET_32 (abfd, bytes->e_info);
86
  execp->a_text      = GET_WORD (abfd, bytes->e_text);
87
  execp->a_data      = GET_WORD (abfd, bytes->e_data);
88
  execp->a_bss       = GET_WORD (abfd, bytes->e_bss);
89
  execp->a_syms      = GET_WORD (abfd, bytes->e_syms);
90
  execp->a_entry     = GET_WORD (abfd, bytes->e_entry);
91
  execp->a_trsize    = GET_WORD (abfd, bytes->e_trsize);
92
  execp->a_drsize    = GET_WORD (abfd, bytes->e_drsize);
93
  execp->a_tload     = GET_WORD (abfd, bytes->e_tload);
94
  execp->a_dload     = GET_WORD (abfd, bytes->e_dload);
95
  execp->a_talign    = bytes->e_talign[0];
96
  execp->a_dalign    = bytes->e_dalign[0];
97
  execp->a_balign    = bytes->e_balign[0];
98
  execp->a_relaxable = bytes->e_relaxable[0];
99
}
100
 
101
/* Swaps the information in an internal exec header structure into the
102
   supplied buffer ready for writing to disk.  */
103
 
104
static void
105
bout_swap_exec_header_out (bfd *abfd,
106
                           struct internal_exec *execp,
107
                           struct external_exec *bytes)
108
{
109
  /* Now fill in fields in the raw data, from the fields in the exec struct.  */
110
  H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
111
  PUT_WORD (abfd, execp->a_text  , bytes->e_text);
112
  PUT_WORD (abfd, execp->a_data  , bytes->e_data);
113
  PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
114
  PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
115
  PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
116
  PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
117
  PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
118
  PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
119
  PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
120
  bytes->e_talign[0]    = execp->a_talign;
121
  bytes->e_dalign[0]    = execp->a_dalign;
122
  bytes->e_balign[0]    = execp->a_balign;
123
  bytes->e_relaxable[0] = execp->a_relaxable;
124
}
125
 
126
/* Finish up the opening of a b.out file for reading.  Fill in all the
127
   fields that are not handled by common code.  */
128
 
129
static const bfd_target *
130
b_out_callback (bfd *abfd)
131
{
132
  struct internal_exec *execp = exec_hdr (abfd);
133
  unsigned long bss_start;
134
 
135
  /* Architecture and machine type.  */
136
  bfd_set_arch_mach (abfd,
137
                     bfd_arch_i960,     /* B.out only used on i960.  */
138
                     bfd_mach_i960_core /* Default.  */
139
                     );
140
 
141
  /* The positions of the string table and symbol table.  */
142
  obj_str_filepos (abfd) = N_STROFF (*execp);
143
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);
144
 
145
  /* The alignments of the sections.  */
146
  obj_textsec (abfd)->alignment_power = execp->a_talign;
147
  obj_datasec (abfd)->alignment_power = execp->a_dalign;
148
  obj_bsssec  (abfd)->alignment_power = execp->a_balign;
149
 
150
  /* The starting addresses of the sections.  */
151
  obj_textsec (abfd)->vma = execp->a_tload;
152
  obj_datasec (abfd)->vma = execp->a_dload;
153
 
154
  obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
155
  obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
156
 
157
  /* And reload the sizes, since the aout module zaps them.  */
158
  obj_textsec (abfd)->size = execp->a_text;
159
 
160
  bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section.  */
161
  obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
162
 
163
  obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
164
 
165
  /* The file positions of the sections.  */
166
  obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
167
  obj_datasec (abfd)->filepos = N_DATOFF (*execp);
168
 
169
  /* The file positions of the relocation info.  */
170
  obj_textsec (abfd)->rel_filepos = N_TROFF (*execp);
171
  obj_datasec (abfd)->rel_filepos =  N_DROFF (*execp);
172
 
173
  adata (abfd).page_size = 1;   /* Not applicable.  */
174
  adata (abfd).segment_size = 1; /* Not applicable.  */
175
  adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
176
 
177
  if (execp->a_relaxable)
178
   abfd->flags |= BFD_IS_RELAXABLE;
179
  return abfd->xvec;
180
}
181
 
182
static const bfd_target *
183
b_out_object_p (bfd *abfd)
184
{
185
  struct internal_exec anexec;
186
  struct external_exec exec_bytes;
187
  bfd_size_type amt = EXEC_BYTES_SIZE;
188
 
189
  if (bfd_bread ((void *) &exec_bytes, amt, abfd) != amt)
190
    {
191
      if (bfd_get_error () != bfd_error_system_call)
192
        bfd_set_error (bfd_error_wrong_format);
193
      return 0;
194
    }
195
 
196
  anexec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
197
 
198
  if (N_BADMAG (anexec))
199
    {
200
      bfd_set_error (bfd_error_wrong_format);
201
      return 0;
202
    }
203
 
204
  bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
205
  return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
206
}
207
 
208
struct bout_data_struct
209
  {
210
    struct aoutdata a;
211
    struct internal_exec e;
212
  };
213
 
214
static bfd_boolean
215
b_out_mkobject (bfd *abfd)
216
{
217
  struct bout_data_struct *rawptr;
218
  bfd_size_type amt = sizeof (struct bout_data_struct);
219
 
220
  rawptr = bfd_zalloc (abfd, amt);
221
  if (rawptr == NULL)
222
    return FALSE;
223
 
224
  abfd->tdata.bout_data = rawptr;
225
  exec_hdr (abfd) = &rawptr->e;
226
 
227
  obj_textsec (abfd) = NULL;
228
  obj_datasec (abfd) = NULL;
229
  obj_bsssec (abfd)  = NULL;
230
 
231
  return TRUE;
232
}
233
 
234
static int
235
b_out_symbol_cmp (const void * a_ptr, const void * b_ptr)
236
{
237
  struct aout_symbol ** a = (struct aout_symbol **) a_ptr;
238
  struct aout_symbol ** b = (struct aout_symbol **) b_ptr;
239
  asection *sec;
240
  bfd_vma av, bv;
241
 
242
  /* Primary key is address.  */
243
  sec = bfd_get_section (&(*a)->symbol);
244
  av = sec->output_section->vma + sec->output_offset + (*a)->symbol.value;
245
  sec = bfd_get_section (&(*b)->symbol);
246
  bv = sec->output_section->vma + sec->output_offset + (*b)->symbol.value;
247
 
248
  if (av < bv)
249
    return -1;
250
  if (av > bv)
251
    return 1;
252
 
253
  /* Secondary key puts CALLNAME syms last and BALNAME syms first,
254
     so that they have the best chance of being contiguous.  */
255
  if (IS_BALNAME ((*a)->other) || IS_CALLNAME ((*b)->other))
256
    return -1;
257
  if (IS_CALLNAME ((*a)->other) || IS_BALNAME ((*b)->other))
258
    return 1;
259
 
260
  return 0;
261
}
262
 
263
static bfd_boolean
264
b_out_squirt_out_relocs (bfd *abfd, asection *section)
265
{
266
  arelent **generic;
267
  int r_extern = 0;
268
  int r_idx;
269
  int incode_mask;
270
  int len_1;
271
  unsigned int count = section->reloc_count;
272
  struct relocation_info *native, *natptr;
273
  bfd_size_type natsize;
274
  int extern_mask, pcrel_mask, len_2, callj_mask;
275
 
276
  if (count == 0)
277
    return TRUE;
278
 
279
  generic = section->orelocation;
280
  natsize = (bfd_size_type) count * sizeof (struct relocation_info);
281
  native = bfd_malloc (natsize);
282
  if (!native && natsize != 0)
283
    return FALSE;
284
 
285
  if (bfd_header_big_endian (abfd))
286
    {
287
      /* Big-endian bit field allocation order.  */
288
      pcrel_mask  = 0x80;
289
      extern_mask = 0x10;
290
      len_2       = 0x40;
291
      len_1       = 0x20;
292
      callj_mask  = 0x02;
293
      incode_mask = 0x08;
294
    }
295
  else
296
    {
297
      /* Little-endian bit field allocation order.  */
298
      pcrel_mask  = 0x01;
299
      extern_mask = 0x08;
300
      len_2       = 0x04;
301
      len_1       = 0x02;
302
      callj_mask  = 0x40;
303
      incode_mask = 0x10;
304
    }
305
 
306
  for (natptr = native; count > 0; --count, ++natptr, ++generic)
307
    {
308
      arelent *g = *generic;
309
      unsigned char *raw = (unsigned char *) natptr;
310
      asymbol *sym = *(g->sym_ptr_ptr);
311
      asection *output_section = sym->section->output_section;
312
 
313
      H_PUT_32 (abfd, g->address, raw);
314
      /* Find a type in the output format which matches the input howto -
315
         at the moment we assume input format == output format FIXME!!  */
316
      r_idx = 0;
317
      /* FIXME:  Need callj stuff here, and to check the howto entries to
318
         be sure they are real for this architecture.  */
319
      if (g->howto== &howto_reloc_callj)
320
        raw[7] = callj_mask + pcrel_mask + len_2;
321
      else if (g->howto == &howto_reloc_pcrel24)
322
        raw[7] = pcrel_mask + len_2;
323
      else if (g->howto == &howto_reloc_pcrel13)
324
        raw[7] = pcrel_mask + len_1;
325
      else if (g->howto == &howto_reloc_abs32code)
326
        raw[7] = len_2 + incode_mask;
327
      else if (g->howto >= howto_align_table
328
               && g->howto <= (howto_align_table + ARRAY_SIZE (howto_align_table) - 1))
329
        {
330
          /* symnum == -2; extern_mask not set, pcrel_mask set.  */
331
          r_idx = -2;
332
          r_extern = 0;
333
          raw[7] = (pcrel_mask
334
                    | ((g->howto - howto_align_table) << 1));
335
        }
336
      else
337
        raw[7] = len_2;
338
 
339
      if (r_idx != 0)
340
        /* Already mucked with r_extern, r_idx.  */;
341
      else if (bfd_is_com_section (output_section)
342
               || bfd_is_abs_section (output_section)
343
               || bfd_is_und_section (output_section))
344
        {
345
          if (bfd_abs_section_ptr->symbol == sym)
346
            {
347
              /* Whoops, looked like an abs symbol, but is really an offset
348
                 from the abs section.  */
349
              r_idx = 0;
350
              r_extern = 0;
351
            }
352
          else
353
            {
354
              /* Fill in symbol.  */
355
              r_extern = 1;
356
              r_idx = (*g->sym_ptr_ptr)->udata.i;
357
            }
358
        }
359
      else
360
        {
361
          /* Just an ordinary section.  */
362
          r_extern = 0;
363
          r_idx  = output_section->target_index;
364
        }
365
 
366
      if (bfd_header_big_endian (abfd))
367
        {
368
          raw[4] = (unsigned char) (r_idx >> 16);
369
          raw[5] = (unsigned char) (r_idx >>  8);
370
          raw[6] = (unsigned char) (r_idx      );
371
        }
372
      else
373
        {
374
          raw[6] = (unsigned char) (r_idx >> 16);
375
          raw[5] = (unsigned char) (r_idx>>   8);
376
          raw[4] = (unsigned char) (r_idx      );
377
        }
378
 
379
      if (r_extern)
380
        raw[7] |= extern_mask;
381
    }
382
 
383
  if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
384
    {
385
      free (native);
386
      return FALSE;
387
    }
388
 
389
  free (native);
390
 
391
  return TRUE;
392
}
393
 
394
static bfd_boolean
395
b_out_write_object_contents (bfd *abfd)
396
{
397
  struct external_exec swapped_hdr;
398
  bfd_size_type amt;
399
 
400
  if (! aout_32_make_sections (abfd))
401
    return FALSE;
402
 
403
  exec_hdr (abfd)->a_info = BMAGIC;
404
 
405
  exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
406
  exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
407
  exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
408
  exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * 12;
409
  exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
410
  exec_hdr (abfd)->a_trsize = (obj_textsec (abfd)->reloc_count) * 8;
411
  exec_hdr (abfd)->a_drsize = (obj_datasec (abfd)->reloc_count) * 8;
412
 
413
  exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
414
  exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
415
  exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
416
 
417
  exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
418
  exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
419
 
420
  bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
421
 
422
  amt = EXEC_BYTES_SIZE;
423
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
424
      || bfd_bwrite ((void *) &swapped_hdr, amt, abfd) != amt)
425
    return FALSE;
426
 
427
  /* Now write out reloc info, followed by syms and strings */
428
  if (bfd_get_symcount (abfd) != 0)
429
    {
430
      /* Make sure {CALL,BAL}NAME symbols remain adjacent on output
431
         by sorting.  This is complicated by the fact that stabs are
432
         also ordered.  Solve this by shifting all stabs to the end
433
         in order, then sorting the rest.  */
434
 
435
      asymbol **outsyms, **p, **q;
436
 
437
      outsyms = bfd_get_outsymbols (abfd);
438
      p = outsyms + bfd_get_symcount (abfd);
439
 
440
      for (q = p--; p >= outsyms; p--)
441
        {
442
          if ((*p)->flags & BSF_DEBUGGING)
443
            {
444
              asymbol *t = *--q;
445
              *q = *p;
446
              *p = t;
447
            }
448
        }
449
 
450
      if (q > outsyms)
451
        qsort (outsyms, (size_t) (q - outsyms), sizeof (asymbol*),
452
               b_out_symbol_cmp);
453
 
454
      /* Back to your regularly scheduled program.  */
455
      if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
456
          != 0)
457
        return FALSE;
458
 
459
      if (! aout_32_write_syms (abfd))
460
        return FALSE;
461
 
462
      if (bfd_seek (abfd, (file_ptr) (N_TROFF (*exec_hdr (abfd))), SEEK_SET)
463
          != 0)
464
        return FALSE;
465
 
466
      if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd)))
467
        return FALSE;
468
      if (bfd_seek (abfd, (file_ptr) (N_DROFF (*exec_hdr (abfd))), SEEK_SET)
469
          != 0)
470
        return FALSE;
471
 
472
      if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd)))
473
        return FALSE;
474
    }
475
  return TRUE;
476
}
477
 
478
/* Some reloc hackery.  */
479
 
480
#define CALLS     0x66003800    /* Template for 'calls' instruction     */
481
#define BAL       0x0b000000    /* Template for 'bal' instruction       */
482
#define BAL_MASK  0x00ffffff
483
#define BALX      0x85f00000    /* Template for 'balx' instruction      */
484
#define BALX_MASK 0x0007ffff
485
#define CALL      0x09000000
486
#define PCREL13_MASK 0x1fff
487
 
488
#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma)
489
 
490
static bfd_vma
491
get_value (arelent *reloc,
492
           struct bfd_link_info *link_info,
493
           asection *input_section)
494
{
495
  bfd_vma value;
496
  asymbol *symbol = *(reloc->sym_ptr_ptr);
497
 
498
  /* A symbol holds a pointer to a section, and an offset from the
499
     base of the section.  To relocate, we find where the section will
500
     live in the output and add that in.  */
501
  if (bfd_is_und_section (symbol->section))
502
    {
503
      struct bfd_link_hash_entry *h;
504
 
505
      /* The symbol is undefined in this BFD.  Look it up in the
506
         global linker hash table.  FIXME: This should be changed when
507
         we convert b.out to use a specific final_link function and
508
         change the interface to bfd_relax_section to not require the
509
         generic symbols.  */
510
      h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
511
                                        bfd_asymbol_name (symbol),
512
                                        FALSE, FALSE, TRUE);
513
      if (h != (struct bfd_link_hash_entry *) NULL
514
          && (h->type == bfd_link_hash_defined
515
              || h->type == bfd_link_hash_defweak))
516
        value = h->u.def.value + output_addr (h->u.def.section);
517
      else if (h != (struct bfd_link_hash_entry *) NULL
518
               && h->type == bfd_link_hash_common)
519
        value = h->u.c.size;
520
      else
521
        {
522
          if (! ((*link_info->callbacks->undefined_symbol)
523
                 (link_info, bfd_asymbol_name (symbol),
524
                  input_section->owner, input_section, reloc->address,
525
                  TRUE)))
526
            abort ();
527
          value = 0;
528
        }
529
    }
530
  else
531
    value = symbol->value + output_addr (symbol->section);
532
 
533
  /* Add the value contained in the relocation.  */
534
  value += reloc->addend;
535
 
536
  return value;
537
}
538
 
539
/* Magic to turn callx into calljx.  */
540
 
541
static bfd_reloc_status_type
542
calljx_callback (bfd *abfd,
543
                 struct bfd_link_info *link_info,
544
                 arelent *reloc_entry,
545
                 void * src,
546
                 void * dst,
547
                 asection *input_section)
548
{
549
  int word = bfd_get_32 (abfd, src);
550
  asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
551
  aout_symbol_type *symbol = aout_symbol (symbol_in);
552
  bfd_vma value;
553
 
554
  value = get_value (reloc_entry, link_info, input_section);
555
 
556
  if (IS_CALLNAME (symbol->other))
557
    {
558
      aout_symbol_type *balsym = symbol+1;
559
      int inst = bfd_get_32 (abfd, (bfd_byte *) src-4);
560
 
561
      /* The next symbol should be an N_BALNAME.  */
562
      BFD_ASSERT (IS_BALNAME (balsym->other));
563
      inst &= BALX_MASK;
564
      inst |= BALX;
565
      bfd_put_32 (abfd, (bfd_vma) inst, (bfd_byte *) dst-4);
566
      symbol = balsym;
567
      value = (symbol->symbol.value
568
               + output_addr (symbol->symbol.section));
569
    }
570
 
571
  word += value + reloc_entry->addend;
572
 
573
  bfd_put_32 (abfd, (bfd_vma) word, dst);
574
  return bfd_reloc_ok;
575
}
576
 
577
/* Magic to turn call into callj.  */
578
 
579
static bfd_reloc_status_type
580
callj_callback (bfd *abfd,
581
                struct bfd_link_info *link_info,
582
                arelent *reloc_entry,
583
                void * data,
584
                unsigned int srcidx,
585
                unsigned int dstidx,
586
                asection *input_section,
587
                bfd_boolean shrinking)
588
{
589
  int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx);
590
  asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
591
  aout_symbol_type *symbol = aout_symbol (symbol_in);
592
  bfd_vma value;
593
 
594
  value = get_value (reloc_entry, link_info, input_section);
595
 
596
  if (IS_OTHER (symbol->other))
597
    /* Call to a system procedure - replace code with system
598
       procedure number.  */
599
    word = CALLS | (symbol->other - 1);
600
 
601
  else if (IS_CALLNAME (symbol->other))
602
    {
603
      aout_symbol_type *balsym = symbol+1;
604
 
605
      /* The next symbol should be an N_BALNAME.  */
606
      BFD_ASSERT (IS_BALNAME (balsym->other));
607
 
608
      /* We are calling a leaf, so replace the call instruction with a
609
         bal.  */
610
      word = BAL | ((word
611
                     + output_addr (balsym->symbol.section)
612
                     + balsym->symbol.value + reloc_entry->addend
613
                     - dstidx
614
                     - output_addr (input_section))
615
                    & BAL_MASK);
616
    }
617
  else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0)
618
    {
619
      /* A callj against a symbol in the same section is a fully
620
         resolved relative call.  We don't need to do anything here.
621
         If the symbol is not in the same section, I'm not sure what
622
         to do; fortunately, this case will probably never arise.  */
623
      BFD_ASSERT (! shrinking);
624
      BFD_ASSERT (symbol->symbol.section == input_section);
625
    }
626
  else
627
    word = CALL | (((word & BAL_MASK)
628
                    + value
629
                    + reloc_entry->addend
630
                    - (shrinking ? dstidx : 0)
631
                    - output_addr (input_section))
632
                   & BAL_MASK);
633
 
634
  bfd_put_32 (abfd, (bfd_vma) word, (bfd_byte *) data + dstidx);
635
  return bfd_reloc_ok;
636
}
637
 
638
static reloc_howto_type *
639
b_out_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
640
                             bfd_reloc_code_real_type code)
641
{
642
  switch (code)
643
    {
644
    default:
645
      return 0;
646
    case BFD_RELOC_I960_CALLJ:
647
      return &howto_reloc_callj;
648
    case BFD_RELOC_32:
649
    case BFD_RELOC_CTOR:
650
      return &howto_reloc_abs32;
651
    case BFD_RELOC_24_PCREL:
652
      return &howto_reloc_pcrel24;
653
    }
654
}
655
 
656
static reloc_howto_type *
657
b_out_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
658
                             const char *r_name)
659
{
660
  if (strcasecmp (howto_reloc_callj.name, r_name) == 0)
661
    return &howto_reloc_callj;
662
  if (strcasecmp (howto_reloc_abs32.name, r_name) == 0)
663
    return &howto_reloc_abs32;
664
  if (strcasecmp (howto_reloc_pcrel24.name, r_name) == 0)
665
    return &howto_reloc_pcrel24;
666
 
667
  return NULL;
668
}
669
 
670
/* Allocate enough room for all the reloc entries, plus pointers to them all.  */
671
 
672
static bfd_boolean
673
b_out_slurp_reloc_table (bfd *abfd, sec_ptr asect, asymbol **symbols)
674
{
675
  struct relocation_info *rptr;
676
  unsigned int counter;
677
  arelent *cache_ptr;
678
  int extern_mask, pcrel_mask, callj_mask, length_shift;
679
  int incode_mask;
680
  int size_mask;
681
  bfd_vma prev_addr = 0;
682
  unsigned int count;
683
  bfd_size_type reloc_size, amt;
684
  struct relocation_info *relocs;
685
  arelent *reloc_cache;
686
 
687
  if (asect->relocation)
688
    return TRUE;
689
 
690
  if (!aout_32_slurp_symbol_table (abfd))
691
    return FALSE;
692
 
693
  if (asect == obj_datasec (abfd))
694
    reloc_size = exec_hdr (abfd)->a_drsize;
695
  else if (asect == obj_textsec (abfd))
696
    reloc_size = exec_hdr (abfd)->a_trsize;
697
  else if (asect == obj_bsssec (abfd))
698
    reloc_size = 0;
699
  else
700
    {
701
      bfd_set_error (bfd_error_invalid_operation);
702
      return FALSE;
703
    }
704
 
705
  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
706
    return FALSE;
707
  count = reloc_size / sizeof (struct relocation_info);
708
 
709
  relocs = bfd_malloc (reloc_size);
710
  if (!relocs && reloc_size != 0)
711
    return FALSE;
712
 
713
  amt = ((bfd_size_type) count + 1) * sizeof (arelent);
714
  reloc_cache = bfd_malloc (amt);
715
  if (!reloc_cache)
716
    {
717
      if (relocs != NULL)
718
        free (relocs);
719
      return FALSE;
720
    }
721
 
722
  if (bfd_bread ((void *) relocs, reloc_size, abfd) != reloc_size)
723
    {
724
      free (reloc_cache);
725
      if (relocs != NULL)
726
        free (relocs);
727
      return FALSE;
728
    }
729
 
730
  if (bfd_header_big_endian (abfd))
731
    {
732
      /* Big-endian bit field allocation order.  */
733
      pcrel_mask  = 0x80;
734
      extern_mask = 0x10;
735
      incode_mask = 0x08;
736
      callj_mask  = 0x02;
737
      size_mask =   0x20;
738
      length_shift = 5;
739
    }
740
  else
741
    {
742
      /* Little-endian bit field allocation order.  */
743
      pcrel_mask  = 0x01;
744
      extern_mask = 0x08;
745
      incode_mask = 0x10;
746
      callj_mask  = 0x40;
747
      size_mask   = 0x02;
748
      length_shift = 1;
749
    }
750
 
751
  for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
752
       counter < count;
753
       counter++, rptr++, cache_ptr++)
754
  {
755
    unsigned char *raw = (unsigned char *)rptr;
756
    unsigned int symnum;
757
 
758
    cache_ptr->address = H_GET_32 (abfd, raw + 0);
759
    cache_ptr->howto = 0;
760
 
761
    if (bfd_header_big_endian (abfd))
762
      symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
763
    else
764
      symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
765
 
766
    if (raw[7] & extern_mask)
767
      {
768
        /* If this is set then the r_index is an index into the symbol table;
769
           if the bit is not set then r_index contains a section map.
770
           We either fill in the sym entry with a pointer to the symbol,
771
           or point to the correct section.  */
772
      cache_ptr->sym_ptr_ptr = symbols + symnum;
773
      cache_ptr->addend = 0;
774
      }
775
    else
776
      {
777
        /* In a.out symbols are relative to the beginning of the
778
           file rather than sections ?
779
           (look in translate_from_native_sym_flags)
780
           The reloc entry addend has added to it the offset into the
781
           file of the data, so subtract the base to make the reloc
782
           section relative.  */
783
        int s;
784
 
785
        /* Sign-extend symnum from 24 bits to whatever host uses.  */
786
        s = symnum;
787
        if (s & (1 << 23))
788
          s |= (~0) << 24;
789
 
790
        cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
791
        switch (s)
792
          {
793
          case N_TEXT:
794
          case N_TEXT | N_EXT:
795
            cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr;
796
            cache_ptr->addend = - obj_textsec (abfd)->vma;
797
            break;
798
          case N_DATA:
799
          case N_DATA | N_EXT:
800
            cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr;
801
            cache_ptr->addend = - obj_datasec (abfd)->vma;
802
            break;
803
          case N_BSS:
804
          case N_BSS | N_EXT:
805
            cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;
806
            cache_ptr->addend =  - obj_bsssec (abfd)->vma;
807
            break;
808
          case N_ABS:
809
          case N_ABS | N_EXT:
810
            cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;
811
            cache_ptr->addend = 0;
812
            break;
813
          case -2: /* .align */
814
            if (raw[7] & pcrel_mask)
815
              {
816
                cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
817
                cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
818
              }
819
            else
820
              {
821
                /* .org? */
822
                abort ();
823
              }
824
            cache_ptr->addend = 0;
825
            break;
826
          default:
827
            BFD_ASSERT (FALSE);
828
            break;
829
          }
830
      }
831
 
832
    /* The i960 only has a few relocation types:
833
       abs 32-bit and pcrel 24bit.   except for callj's!  */
834
    if (cache_ptr->howto != 0)
835
      ;
836
    else if (raw[7] & callj_mask)
837
      {
838
        cache_ptr->howto = &howto_reloc_callj;
839
      }
840
    else if ( raw[7] & pcrel_mask)
841
      {
842
        if (raw[7] & size_mask)
843
          cache_ptr->howto = &howto_reloc_pcrel13;
844
        else
845
          cache_ptr->howto = &howto_reloc_pcrel24;
846
      }
847
    else
848
      {
849
        if (raw[7] & incode_mask)
850
          cache_ptr->howto = &howto_reloc_abs32code;
851
        else
852
          cache_ptr->howto = &howto_reloc_abs32;
853
      }
854
 
855
    if (cache_ptr->address < prev_addr)
856
      {
857
        /* Ouch! this reloc is out of order, insert into the right place.  */
858
        arelent tmp;
859
        arelent *cursor = cache_ptr-1;
860
        bfd_vma stop = cache_ptr->address;
861
 
862
        tmp  = *cache_ptr;
863
        while (cursor->address > stop && cursor >= reloc_cache)
864
          {
865
            cursor[1] = cursor[0];
866
            cursor--;
867
          }
868
 
869
        cursor[1] = tmp;
870
      }
871
    else
872
      prev_addr = cache_ptr->address;
873
  }
874
 
875
  if (relocs != NULL)
876
    free (relocs);
877
  asect->relocation = reloc_cache;
878
  asect->reloc_count = count;
879
 
880
  return TRUE;
881
}
882
 
883
/* This is stupid.  This function should be a boolean predicate.  */
884
 
885
static long
886
b_out_canonicalize_reloc (bfd *abfd,
887
                          sec_ptr section,
888
                          arelent **relptr,
889
                          asymbol **symbols)
890
{
891
  arelent *tblptr;
892
  unsigned int count;
893
 
894
  if ((section->flags & SEC_CONSTRUCTOR) != 0)
895
    {
896
      arelent_chain *chain = section->constructor_chain;
897
 
898
      for (count = 0; count < section->reloc_count; count++)
899
        {
900
          *relptr++ = &chain->relent;
901
          chain = chain->next;
902
        }
903
    }
904
  else
905
    {
906
      if (section->relocation == NULL
907
          && ! b_out_slurp_reloc_table (abfd, section, symbols))
908
        return -1;
909
 
910
      tblptr = section->relocation;
911
      for (count = 0; count++ < section->reloc_count;)
912
        *relptr++ = tblptr++;
913
    }
914
 
915
  *relptr = NULL;
916
 
917
  return section->reloc_count;
918
}
919
 
920
static long
921
b_out_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
922
{
923
  if (bfd_get_format (abfd) != bfd_object)
924
    {
925
      bfd_set_error (bfd_error_invalid_operation);
926
      return -1;
927
    }
928
 
929
  if (asect->flags & SEC_CONSTRUCTOR)
930
    return sizeof (arelent *) * (asect->reloc_count + 1);
931
 
932
  if (asect == obj_datasec (abfd))
933
    return (sizeof (arelent *) *
934
            ((exec_hdr (abfd)->a_drsize / sizeof (struct relocation_info))
935
             + 1));
936
 
937
  if (asect == obj_textsec (abfd))
938
    return (sizeof (arelent *) *
939
            ((exec_hdr (abfd)->a_trsize / sizeof (struct relocation_info))
940
             + 1));
941
 
942
  if (asect == obj_bsssec (abfd))
943
    return 0;
944
 
945
  bfd_set_error (bfd_error_invalid_operation);
946
  return -1;
947
}
948
 
949
 
950
static bfd_boolean
951
b_out_set_section_contents (bfd *abfd,
952
                            asection *section,
953
                            const void * location,
954
                            file_ptr offset,
955
                            bfd_size_type count)
956
{
957
  if (! abfd->output_has_begun)
958
    {
959
      /* Set by bfd.c handler.  */
960
      if (! aout_32_make_sections (abfd))
961
        return FALSE;
962
 
963
      obj_textsec (abfd)->filepos = sizeof (struct external_exec);
964
      obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos
965
        +  obj_textsec (abfd)->size;
966
    }
967
 
968
  /* Regardless, once we know what we're doing, we might as well get going.  */
969
  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
970
    return FALSE;
971
 
972
  if (count == 0)
973
    return TRUE;
974
 
975
  return bfd_bwrite ((void *) location, count, abfd) == count;
976
}
977
 
978
static bfd_boolean
979
b_out_set_arch_mach (bfd *abfd,
980
                     enum bfd_architecture arch,
981
                     unsigned long machine)
982
{
983
  bfd_default_set_arch_mach (abfd, arch, machine);
984
 
985
  if (arch == bfd_arch_unknown) /* Unknown machine arch is OK.  */
986
    return TRUE;
987
 
988
  if (arch == bfd_arch_i960)    /* i960 default is OK.  */
989
    switch (machine)
990
      {
991
      case bfd_mach_i960_core:
992
      case bfd_mach_i960_kb_sb:
993
      case bfd_mach_i960_mc:
994
      case bfd_mach_i960_xa:
995
      case bfd_mach_i960_ca:
996
      case bfd_mach_i960_ka_sa:
997
      case bfd_mach_i960_jx:
998
      case bfd_mach_i960_hx:
999
      case 0:
1000
        return TRUE;
1001
      default:
1002
        return FALSE;
1003
      }
1004
 
1005
  return FALSE;
1006
}
1007
 
1008
static int
1009
b_out_sizeof_headers (bfd *ignore_abfd ATTRIBUTE_UNUSED,
1010
                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
1011
{
1012
  return sizeof (struct external_exec);
1013
}
1014
 
1015
static void
1016
perform_slip (bfd *abfd,
1017
              unsigned int slip,
1018
              asection *input_section,
1019
              bfd_vma value)
1020
{
1021
  asymbol **s;
1022
 
1023
  s = _bfd_generic_link_get_symbols (abfd);
1024
  BFD_ASSERT (s != (asymbol **) NULL);
1025
 
1026
  /* Find all symbols past this point, and make them know
1027
     what's happened.  */
1028
  while (*s)
1029
    {
1030
      asymbol *p = *s;
1031
 
1032
      if (p->section == input_section)
1033
        {
1034
          /* This was pointing into this section, so mangle it.  */
1035
          if (p->value > value)
1036
            {
1037
              p->value -=slip;
1038
 
1039
              if (p->udata.p != NULL)
1040
                {
1041
                  struct generic_link_hash_entry *h;
1042
 
1043
                  h = (struct generic_link_hash_entry *) p->udata.p;
1044
                  BFD_ASSERT (h->root.type == bfd_link_hash_defined);
1045
                  h->root.u.def.value -= slip;
1046
                  BFD_ASSERT (h->root.u.def.value == p->value);
1047
                }
1048
            }
1049
        }
1050
      s++;
1051
    }
1052
}
1053
 
1054
/* This routine works out if the thing we want to get to can be
1055
   reached with a 24bit offset instead of a 32 bit one.
1056
   If it can, then it changes the amode.  */
1057
 
1058
static int
1059
abs32code (bfd *abfd,
1060
           asection *input_section,
1061
           arelent *r,
1062
           unsigned int shrink,
1063
           struct bfd_link_info *link_info)
1064
{
1065
  bfd_vma value = get_value (r, link_info, input_section);
1066
  bfd_vma dot = output_addr (input_section) + r->address;
1067
  bfd_vma gap;
1068
 
1069
  /* See if the address we're looking at within 2^23 bytes of where
1070
     we are, if so then we can use a small branch rather than the
1071
     jump we were going to.  */
1072
  gap = value - (dot - shrink);
1073
 
1074
  if (-1 << 23 < (long)gap && (long)gap < 1 << 23)
1075
    {
1076
      /* Change the reloc type from 32bitcode possible 24, to 24bit
1077
         possible 32.  */
1078
      r->howto = &howto_reloc_abs32codeshrunk;
1079
      /* The place to relc moves back by four bytes.  */
1080
      r->address -=4;
1081
 
1082
      /* This will be four bytes smaller in the long run.  */
1083
      shrink += 4 ;
1084
      perform_slip (abfd, 4, input_section, r->address-shrink + 4);
1085
    }
1086
 
1087
  return shrink;
1088
}
1089
 
1090
static int
1091
aligncode (bfd *abfd,
1092
           asection *input_section,
1093
           arelent *r,
1094
           unsigned int shrink)
1095
{
1096
  bfd_vma dot = output_addr (input_section) + r->address;
1097
  bfd_vma gap;
1098
  bfd_vma old_end;
1099
  bfd_vma new_end;
1100
  unsigned int shrink_delta;
1101
  int size = r->howto->size;
1102
 
1103
  /* Reduce the size of the alignment so that it's still aligned but
1104
     smaller  - the current size is already the same size as or bigger
1105
     than the alignment required.  */
1106
 
1107
  /* Calculate the first byte following the padding before we optimize.  */
1108
  old_end = ((dot + size ) & ~size) + size+1;
1109
  /* Work out where the new end will be - remember that we're smaller
1110
     than we used to be.  */
1111
  new_end = ((dot - shrink + size) & ~size);
1112
 
1113
  /* This is the new end.  */
1114
  gap = old_end - ((dot + size) & ~size);
1115
 
1116
  shrink_delta = (old_end - new_end) - shrink;
1117
 
1118
  if (shrink_delta)
1119
    {
1120
      /* Change the reloc so that it knows how far to align to.  */
1121
      r->howto = howto_done_align_table + (r->howto - howto_align_table);
1122
 
1123
      /* Encode the stuff into the addend - for future use we need to
1124
         know how big the reloc used to be.  */
1125
      r->addend = old_end - dot + r->address;
1126
 
1127
      /* This will be N bytes smaller in the long run, adjust all the symbols.  */
1128
      perform_slip (abfd, shrink_delta, input_section, r->address - shrink);
1129
      shrink += shrink_delta;
1130
    }
1131
 
1132
  return shrink;
1133
}
1134
 
1135
static bfd_boolean
1136
b_out_bfd_relax_section (bfd *abfd,
1137
                         asection *i,
1138
                         struct bfd_link_info *link_info,
1139
                         bfd_boolean *again)
1140
{
1141
  /* Get enough memory to hold the stuff.  */
1142
  bfd *input_bfd = i->owner;
1143
  asection *input_section = i;
1144
  unsigned int shrink = 0 ;
1145
  arelent **reloc_vector = NULL;
1146
  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
1147
 
1148
  if (link_info->relocatable)
1149
    (*link_info->callbacks->einfo)
1150
      (_("%P%F: --relax and -r may not be used together\n"));
1151
 
1152
  if (reloc_size < 0)
1153
    return FALSE;
1154
 
1155
  /* We only run this relaxation once.  It might work to run it
1156
     multiple times, but it hasn't been tested.  */
1157
  *again = FALSE;
1158
 
1159
  if (reloc_size)
1160
    {
1161
      long reloc_count;
1162
 
1163
      reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
1164
      if (reloc_vector == NULL && reloc_size != 0)
1165
        goto error_return;
1166
 
1167
      /* Get the relocs and think about them.  */
1168
      reloc_count =
1169
        bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
1170
                                _bfd_generic_link_get_symbols (input_bfd));
1171
      if (reloc_count < 0)
1172
        goto error_return;
1173
      if (reloc_count > 0)
1174
        {
1175
          arelent **parent;
1176
 
1177
          for (parent = reloc_vector; *parent; parent++)
1178
            {
1179
              arelent *r = *parent;
1180
 
1181
              switch (r->howto->type)
1182
                {
1183
                case ALIGNER:
1184
                  /* An alignment reloc.  */
1185
                  shrink = aligncode (abfd, input_section, r, shrink);
1186
                  break;
1187
                case ABS32CODE:
1188
                  /* A 32bit reloc in an addressing mode.  */
1189
                  shrink = abs32code (input_bfd, input_section, r, shrink,
1190
                                      link_info);
1191
                  break;
1192
                case ABS32CODE_SHRUNK:
1193
                  shrink += 4;
1194
                  break;
1195
                }
1196
            }
1197
        }
1198
    }
1199
  input_section->size -= shrink;
1200
 
1201
  if (reloc_vector != NULL)
1202
    free (reloc_vector);
1203
  return TRUE;
1204
 error_return:
1205
  if (reloc_vector != NULL)
1206
    free (reloc_vector);
1207
  return FALSE;
1208
}
1209
 
1210
static bfd_byte *
1211
b_out_bfd_get_relocated_section_contents (bfd *output_bfd,
1212
                                          struct bfd_link_info *link_info,
1213
                                          struct bfd_link_order *link_order,
1214
                                          bfd_byte *data,
1215
                                          bfd_boolean relocatable,
1216
                                          asymbol **symbols)
1217
{
1218
  /* Get enough memory to hold the stuff.  */
1219
  bfd *input_bfd = link_order->u.indirect.section->owner;
1220
  asection *input_section = link_order->u.indirect.section;
1221
  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
1222
  arelent **reloc_vector = NULL;
1223
  long reloc_count;
1224
 
1225
  if (reloc_size < 0)
1226
    goto error_return;
1227
 
1228
  /* If producing relocatable output, don't bother to relax.  */
1229
  if (relocatable)
1230
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1231
                                                       link_order,
1232
                                                       data, relocatable,
1233
                                                       symbols);
1234
 
1235
  reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
1236
  if (reloc_vector == NULL && reloc_size != 0)
1237
    goto error_return;
1238
 
1239
  /* Read in the section.  */
1240
  BFD_ASSERT (bfd_get_section_contents (input_bfd,
1241
                                        input_section,
1242
                                        data,
1243
                                        (bfd_vma) 0,
1244
                                        input_section->size));
1245
 
1246
  reloc_count = bfd_canonicalize_reloc (input_bfd,
1247
                                        input_section,
1248
                                        reloc_vector,
1249
                                        symbols);
1250
  if (reloc_count < 0)
1251
    goto error_return;
1252
  if (reloc_count > 0)
1253
    {
1254
      arelent **parent = reloc_vector;
1255
      arelent *reloc ;
1256
      unsigned int dst_address = 0;
1257
      unsigned int src_address = 0;
1258
      unsigned int run;
1259
      unsigned int idx;
1260
 
1261
      /* Find how long a run we can do.  */
1262
      while (dst_address < link_order->size)
1263
        {
1264
          reloc = *parent;
1265
          if (reloc)
1266
            {
1267
              /* Note that the relaxing didn't tie up the addresses in the
1268
                 relocation, so we use the original address to work out the
1269
                 run of non-relocated data.  */
1270
              BFD_ASSERT (reloc->address >= src_address);
1271
              run = reloc->address - src_address;
1272
              parent++;
1273
            }
1274
          else
1275
            run = link_order->size - dst_address;
1276
 
1277
          /* Copy the bytes.  */
1278
          for (idx = 0; idx < run; idx++)
1279
            data[dst_address++] = data[src_address++];
1280
 
1281
          /* Now do the relocation.  */
1282
          if (reloc)
1283
            {
1284
              switch (reloc->howto->type)
1285
                {
1286
                case ABS32CODE:
1287
                  calljx_callback (input_bfd, link_info, reloc,
1288
                                   src_address + data, dst_address + data,
1289
                                   input_section);
1290
                  src_address += 4;
1291
                  dst_address += 4;
1292
                  break;
1293
                case ABS32:
1294
                  bfd_put_32 (input_bfd,
1295
                              (bfd_get_32 (input_bfd, data + src_address)
1296
                               + get_value (reloc, link_info, input_section)),
1297
                              data + dst_address);
1298
                  src_address += 4;
1299
                  dst_address += 4;
1300
                  break;
1301
                case CALLJ:
1302
                  callj_callback (input_bfd, link_info, reloc, data,
1303
                                  src_address, dst_address, input_section,
1304
                                  FALSE);
1305
                  src_address += 4;
1306
                  dst_address += 4;
1307
                  break;
1308
                case ALIGNDONE:
1309
                  BFD_ASSERT (reloc->addend >= src_address);
1310
                  BFD_ASSERT ((bfd_vma) reloc->addend
1311
                              <= input_section->size);
1312
                  src_address = reloc->addend;
1313
                  dst_address = ((dst_address + reloc->howto->size)
1314
                                 & ~reloc->howto->size);
1315
                  break;
1316
                case ABS32CODE_SHRUNK:
1317
                  /* This used to be a callx, but we've found out that a
1318
                     callj will reach, so do the right thing.  */
1319
                  callj_callback (input_bfd, link_info, reloc, data,
1320
                                  src_address + 4, dst_address, input_section,
1321
                                  TRUE);
1322
                  dst_address += 4;
1323
                  src_address += 8;
1324
                  break;
1325
                case PCREL24:
1326
                  {
1327
                    long int word = bfd_get_32 (input_bfd,
1328
                                                data + src_address);
1329
                    bfd_vma value;
1330
 
1331
                    value = get_value (reloc, link_info, input_section);
1332
                    word = ((word & ~BAL_MASK)
1333
                            | (((word & BAL_MASK)
1334
                                + value
1335
                                - output_addr (input_section)
1336
                                + reloc->addend)
1337
                               & BAL_MASK));
1338
 
1339
                    bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
1340
                    dst_address += 4;
1341
                    src_address += 4;
1342
 
1343
                  }
1344
                  break;
1345
                case PCREL13:
1346
                  {
1347
                    long int word = bfd_get_32 (input_bfd,
1348
                                                data + src_address);
1349
                    bfd_vma value;
1350
 
1351
                    value = get_value (reloc, link_info, input_section);
1352
                    word = ((word & ~PCREL13_MASK)
1353
                            | (((word & PCREL13_MASK)
1354
                                + value
1355
                                + reloc->addend
1356
                                - output_addr (input_section))
1357
                               & PCREL13_MASK));
1358
 
1359
                    bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
1360
                    dst_address += 4;
1361
                    src_address += 4;
1362
                  }
1363
                  break;
1364
 
1365
                default:
1366
                  abort ();
1367
                }
1368
            }
1369
        }
1370
    }
1371
  if (reloc_vector != NULL)
1372
    free (reloc_vector);
1373
  return data;
1374
 error_return:
1375
  if (reloc_vector != NULL)
1376
    free (reloc_vector);
1377
  return NULL;
1378
}
1379
 
1380
 
1381
/* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
1382
 
1383
#define aout_32_bfd_make_debug_symbol          _bfd_nosymbols_bfd_make_debug_symbol
1384
#define aout_32_close_and_cleanup              aout_32_bfd_free_cached_info
1385
#define b_out_bfd_link_hash_table_create       _bfd_generic_link_hash_table_create
1386
#define b_out_bfd_link_hash_table_free         _bfd_generic_link_hash_table_free
1387
#define b_out_bfd_link_add_symbols             _bfd_generic_link_add_symbols
1388
#define b_out_bfd_link_just_syms               _bfd_generic_link_just_syms
1389
#define b_out_bfd_final_link                   _bfd_generic_final_link
1390
#define b_out_bfd_link_split_section           _bfd_generic_link_split_section
1391
#define b_out_bfd_gc_sections                  bfd_generic_gc_sections
1392
#define b_out_bfd_merge_sections               bfd_generic_merge_sections
1393
#define b_out_bfd_is_group_section             bfd_generic_is_group_section
1394
#define b_out_bfd_discard_group                bfd_generic_discard_group
1395
#define b_out_section_already_linked           _bfd_generic_section_already_linked
1396
#define b_out_bfd_define_common_symbol         bfd_generic_define_common_symbol
1397
#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1398
 
1399
extern const bfd_target b_out_vec_little_host;
1400
 
1401
const bfd_target b_out_vec_big_host =
1402
{
1403
  "b.out.big",                  /* Name.  */
1404
  bfd_target_aout_flavour,
1405
  BFD_ENDIAN_LITTLE,            /* Data byte order.  */
1406
  BFD_ENDIAN_BIG,               /* Header byte order.  */
1407
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
1408
   HAS_LINENO | HAS_DEBUG |
1409
   HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1410
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1411
  '_',                          /* Symbol leading char.  */
1412
  ' ',                          /* AR_pad_char.  */
1413
  16,                           /* AR_max_namelen.  */
1414
 
1415
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1416
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1417
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
1418
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1419
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1420
     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1421
 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
1422
   bfd_generic_archive_p, _bfd_dummy_target},
1423
 {bfd_false, b_out_mkobject,    /* bfd_set_format.  */
1424
   _bfd_generic_mkarchive, bfd_false},
1425
 {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
1426
   _bfd_write_archive_contents, bfd_false},
1427
 
1428
     BFD_JUMP_TABLE_GENERIC (aout_32),
1429
     BFD_JUMP_TABLE_COPY (_bfd_generic),
1430
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
1431
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1432
     BFD_JUMP_TABLE_SYMBOLS (aout_32),
1433
     BFD_JUMP_TABLE_RELOCS (b_out),
1434
     BFD_JUMP_TABLE_WRITE (b_out),
1435
     BFD_JUMP_TABLE_LINK (b_out),
1436
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1437
 
1438
  & b_out_vec_little_host,
1439
 
1440
  NULL
1441
};
1442
 
1443
const bfd_target b_out_vec_little_host =
1444
{
1445
  "b.out.little",               /* Name.  */
1446
  bfd_target_aout_flavour,
1447
  BFD_ENDIAN_LITTLE,            /* Data byte order.  */
1448
  BFD_ENDIAN_LITTLE,            /* Header byte order.  */
1449
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
1450
   HAS_LINENO | HAS_DEBUG |
1451
   HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1452
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1453
  '_',                          /* Symbol leading char.  */
1454
  ' ',                          /* AR_pad_char.  */
1455
  16,                           /* AR_max_namelen.  */
1456
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1457
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1458
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
1459
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1460
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1461
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
1462
 
1463
  {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
1464
     bfd_generic_archive_p, _bfd_dummy_target},
1465
  {bfd_false, b_out_mkobject,   /* bfd_set_format.  */
1466
     _bfd_generic_mkarchive, bfd_false},
1467
  {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
1468
     _bfd_write_archive_contents, bfd_false},
1469
 
1470
     BFD_JUMP_TABLE_GENERIC (aout_32),
1471
     BFD_JUMP_TABLE_COPY (_bfd_generic),
1472
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
1473
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1474
     BFD_JUMP_TABLE_SYMBOLS (aout_32),
1475
     BFD_JUMP_TABLE_RELOCS (b_out),
1476
     BFD_JUMP_TABLE_WRITE (b_out),
1477
     BFD_JUMP_TABLE_LINK (b_out),
1478
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1479
 
1480
  & b_out_vec_big_host,
1481
 
1482
  NULL
1483
};

powered by: WebSVN 2.1.0

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