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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [bout.c] - Blame information for rev 104

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

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

powered by: WebSVN 2.1.0

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