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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [bout.c] - Blame information for rev 856

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

Line No. Rev Author Line
1 38 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
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 (reloc_size < 0)
1149
    return FALSE;
1150
 
1151
  /* We only run this relaxation once.  It might work to run it
1152
     multiple times, but it hasn't been tested.  */
1153
  *again = FALSE;
1154
 
1155
  if (reloc_size)
1156
    {
1157
      long reloc_count;
1158
 
1159
      reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
1160
      if (reloc_vector == NULL && reloc_size != 0)
1161
        goto error_return;
1162
 
1163
      /* Get the relocs and think about them.  */
1164
      reloc_count =
1165
        bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
1166
                                _bfd_generic_link_get_symbols (input_bfd));
1167
      if (reloc_count < 0)
1168
        goto error_return;
1169
      if (reloc_count > 0)
1170
        {
1171
          arelent **parent;
1172
 
1173
          for (parent = reloc_vector; *parent; parent++)
1174
            {
1175
              arelent *r = *parent;
1176
 
1177
              switch (r->howto->type)
1178
                {
1179
                case ALIGNER:
1180
                  /* An alignment reloc.  */
1181
                  shrink = aligncode (abfd, input_section, r, shrink);
1182
                  break;
1183
                case ABS32CODE:
1184
                  /* A 32bit reloc in an addressing mode.  */
1185
                  shrink = abs32code (input_bfd, input_section, r, shrink,
1186
                                      link_info);
1187
                  break;
1188
                case ABS32CODE_SHRUNK:
1189
                  shrink += 4;
1190
                  break;
1191
                }
1192
            }
1193
        }
1194
    }
1195
  input_section->size -= shrink;
1196
 
1197
  if (reloc_vector != NULL)
1198
    free (reloc_vector);
1199
  return TRUE;
1200
 error_return:
1201
  if (reloc_vector != NULL)
1202
    free (reloc_vector);
1203
  return FALSE;
1204
}
1205
 
1206
static bfd_byte *
1207
b_out_bfd_get_relocated_section_contents (bfd *output_bfd,
1208
                                          struct bfd_link_info *link_info,
1209
                                          struct bfd_link_order *link_order,
1210
                                          bfd_byte *data,
1211
                                          bfd_boolean relocatable,
1212
                                          asymbol **symbols)
1213
{
1214
  /* Get enough memory to hold the stuff.  */
1215
  bfd *input_bfd = link_order->u.indirect.section->owner;
1216
  asection *input_section = link_order->u.indirect.section;
1217
  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
1218
  arelent **reloc_vector = NULL;
1219
  long reloc_count;
1220
 
1221
  if (reloc_size < 0)
1222
    goto error_return;
1223
 
1224
  /* If producing relocatable output, don't bother to relax.  */
1225
  if (relocatable)
1226
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1227
                                                       link_order,
1228
                                                       data, relocatable,
1229
                                                       symbols);
1230
 
1231
  reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
1232
  if (reloc_vector == NULL && reloc_size != 0)
1233
    goto error_return;
1234
 
1235
  /* Read in the section.  */
1236
  BFD_ASSERT (bfd_get_section_contents (input_bfd,
1237
                                        input_section,
1238
                                        data,
1239
                                        (bfd_vma) 0,
1240
                                        input_section->size));
1241
 
1242
  reloc_count = bfd_canonicalize_reloc (input_bfd,
1243
                                        input_section,
1244
                                        reloc_vector,
1245
                                        symbols);
1246
  if (reloc_count < 0)
1247
    goto error_return;
1248
  if (reloc_count > 0)
1249
    {
1250
      arelent **parent = reloc_vector;
1251
      arelent *reloc ;
1252
      unsigned int dst_address = 0;
1253
      unsigned int src_address = 0;
1254
      unsigned int run;
1255
      unsigned int idx;
1256
 
1257
      /* Find how long a run we can do.  */
1258
      while (dst_address < link_order->size)
1259
        {
1260
          reloc = *parent;
1261
          if (reloc)
1262
            {
1263
              /* Note that the relaxing didn't tie up the addresses in the
1264
                 relocation, so we use the original address to work out the
1265
                 run of non-relocated data.  */
1266
              BFD_ASSERT (reloc->address >= src_address);
1267
              run = reloc->address - src_address;
1268
              parent++;
1269
            }
1270
          else
1271
            run = link_order->size - dst_address;
1272
 
1273
          /* Copy the bytes.  */
1274
          for (idx = 0; idx < run; idx++)
1275
            data[dst_address++] = data[src_address++];
1276
 
1277
          /* Now do the relocation.  */
1278
          if (reloc)
1279
            {
1280
              switch (reloc->howto->type)
1281
                {
1282
                case ABS32CODE:
1283
                  calljx_callback (input_bfd, link_info, reloc,
1284
                                   src_address + data, dst_address + data,
1285
                                   input_section);
1286
                  src_address += 4;
1287
                  dst_address += 4;
1288
                  break;
1289
                case ABS32:
1290
                  bfd_put_32 (input_bfd,
1291
                              (bfd_get_32 (input_bfd, data + src_address)
1292
                               + get_value (reloc, link_info, input_section)),
1293
                              data + dst_address);
1294
                  src_address += 4;
1295
                  dst_address += 4;
1296
                  break;
1297
                case CALLJ:
1298
                  callj_callback (input_bfd, link_info, reloc, data,
1299
                                  src_address, dst_address, input_section,
1300
                                  FALSE);
1301
                  src_address += 4;
1302
                  dst_address += 4;
1303
                  break;
1304
                case ALIGNDONE:
1305
                  BFD_ASSERT (reloc->addend >= src_address);
1306
                  BFD_ASSERT ((bfd_vma) reloc->addend
1307
                              <= input_section->size);
1308
                  src_address = reloc->addend;
1309
                  dst_address = ((dst_address + reloc->howto->size)
1310
                                 & ~reloc->howto->size);
1311
                  break;
1312
                case ABS32CODE_SHRUNK:
1313
                  /* This used to be a callx, but we've found out that a
1314
                     callj will reach, so do the right thing.  */
1315
                  callj_callback (input_bfd, link_info, reloc, data,
1316
                                  src_address + 4, dst_address, input_section,
1317
                                  TRUE);
1318
                  dst_address += 4;
1319
                  src_address += 8;
1320
                  break;
1321
                case PCREL24:
1322
                  {
1323
                    long int word = bfd_get_32 (input_bfd,
1324
                                                data + src_address);
1325
                    bfd_vma value;
1326
 
1327
                    value = get_value (reloc, link_info, input_section);
1328
                    word = ((word & ~BAL_MASK)
1329
                            | (((word & BAL_MASK)
1330
                                + value
1331
                                - output_addr (input_section)
1332
                                + reloc->addend)
1333
                               & BAL_MASK));
1334
 
1335
                    bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
1336
                    dst_address += 4;
1337
                    src_address += 4;
1338
 
1339
                  }
1340
                  break;
1341
                case PCREL13:
1342
                  {
1343
                    long int word = bfd_get_32 (input_bfd,
1344
                                                data + src_address);
1345
                    bfd_vma value;
1346
 
1347
                    value = get_value (reloc, link_info, input_section);
1348
                    word = ((word & ~PCREL13_MASK)
1349
                            | (((word & PCREL13_MASK)
1350
                                + value
1351
                                + reloc->addend
1352
                                - output_addr (input_section))
1353
                               & PCREL13_MASK));
1354
 
1355
                    bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
1356
                    dst_address += 4;
1357
                    src_address += 4;
1358
                  }
1359
                  break;
1360
 
1361
                default:
1362
                  abort ();
1363
                }
1364
            }
1365
        }
1366
    }
1367
  if (reloc_vector != NULL)
1368
    free (reloc_vector);
1369
  return data;
1370
 error_return:
1371
  if (reloc_vector != NULL)
1372
    free (reloc_vector);
1373
  return NULL;
1374
}
1375
 
1376
 
1377
/* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
1378
 
1379
#define aout_32_bfd_make_debug_symbol          _bfd_nosymbols_bfd_make_debug_symbol
1380
#define aout_32_close_and_cleanup              aout_32_bfd_free_cached_info
1381
#define b_out_bfd_link_hash_table_create       _bfd_generic_link_hash_table_create
1382
#define b_out_bfd_link_hash_table_free         _bfd_generic_link_hash_table_free
1383
#define b_out_bfd_link_add_symbols             _bfd_generic_link_add_symbols
1384
#define b_out_bfd_link_just_syms               _bfd_generic_link_just_syms
1385
#define b_out_bfd_final_link                   _bfd_generic_final_link
1386
#define b_out_bfd_link_split_section           _bfd_generic_link_split_section
1387
#define b_out_bfd_gc_sections                  bfd_generic_gc_sections
1388
#define b_out_bfd_merge_sections               bfd_generic_merge_sections
1389
#define b_out_bfd_is_group_section             bfd_generic_is_group_section
1390
#define b_out_bfd_discard_group                bfd_generic_discard_group
1391
#define b_out_section_already_linked           _bfd_generic_section_already_linked
1392
#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1393
 
1394
extern const bfd_target b_out_vec_little_host;
1395
 
1396
const bfd_target b_out_vec_big_host =
1397
{
1398
  "b.out.big",                  /* Name.  */
1399
  bfd_target_aout_flavour,
1400
  BFD_ENDIAN_LITTLE,            /* Data byte order.  */
1401
  BFD_ENDIAN_BIG,               /* Header byte order.  */
1402
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
1403
   HAS_LINENO | HAS_DEBUG |
1404
   HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1405
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1406
  '_',                          /* Symbol leading char.  */
1407
  ' ',                          /* AR_pad_char.  */
1408
  16,                           /* AR_max_namelen.  */
1409
 
1410
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1411
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1412
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
1413
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1414
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1415
     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1416
 {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
1417
   bfd_generic_archive_p, _bfd_dummy_target},
1418
 {bfd_false, b_out_mkobject,    /* bfd_set_format.  */
1419
   _bfd_generic_mkarchive, bfd_false},
1420
 {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
1421
   _bfd_write_archive_contents, bfd_false},
1422
 
1423
     BFD_JUMP_TABLE_GENERIC (aout_32),
1424
     BFD_JUMP_TABLE_COPY (_bfd_generic),
1425
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
1426
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1427
     BFD_JUMP_TABLE_SYMBOLS (aout_32),
1428
     BFD_JUMP_TABLE_RELOCS (b_out),
1429
     BFD_JUMP_TABLE_WRITE (b_out),
1430
     BFD_JUMP_TABLE_LINK (b_out),
1431
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1432
 
1433
  & b_out_vec_little_host,
1434
 
1435
  NULL
1436
};
1437
 
1438
const bfd_target b_out_vec_little_host =
1439
{
1440
  "b.out.little",               /* Name.  */
1441
  bfd_target_aout_flavour,
1442
  BFD_ENDIAN_LITTLE,            /* Data byte order.  */
1443
  BFD_ENDIAN_LITTLE,            /* Header byte order.  */
1444
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
1445
   HAS_LINENO | HAS_DEBUG |
1446
   HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
1447
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1448
  '_',                          /* Symbol leading char.  */
1449
  ' ',                          /* AR_pad_char.  */
1450
  16,                           /* AR_max_namelen.  */
1451
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1452
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1453
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
1454
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1455
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1456
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
1457
 
1458
  {_bfd_dummy_target, b_out_object_p, /* bfd_check_format.  */
1459
     bfd_generic_archive_p, _bfd_dummy_target},
1460
  {bfd_false, b_out_mkobject,   /* bfd_set_format.  */
1461
     _bfd_generic_mkarchive, bfd_false},
1462
  {bfd_false, b_out_write_object_contents, /* bfd_write_contents.  */
1463
     _bfd_write_archive_contents, bfd_false},
1464
 
1465
     BFD_JUMP_TABLE_GENERIC (aout_32),
1466
     BFD_JUMP_TABLE_COPY (_bfd_generic),
1467
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
1468
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
1469
     BFD_JUMP_TABLE_SYMBOLS (aout_32),
1470
     BFD_JUMP_TABLE_RELOCS (b_out),
1471
     BFD_JUMP_TABLE_WRITE (b_out),
1472
     BFD_JUMP_TABLE_LINK (b_out),
1473
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1474
 
1475
  & b_out_vec_big_host,
1476
 
1477
  NULL
1478
};

powered by: WebSVN 2.1.0

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