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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [bout.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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