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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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