~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/riscix.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD back-end for RISC iX (Acorn, arm) binaries.
 
2
   Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001
 
3
   Free Software Foundation, Inc.
 
4
   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
 
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
/* RISC iX overloads the MAGIC field to indicate more than just the usual
 
23
   [ZNO]MAGIC values.  Also included are squeezing information and
 
24
   shared library usage.  */
 
25
 
 
26
/* The following come from the man page.  */
 
27
#define SHLIBLEN 60
 
28
 
 
29
#define MF_IMPURE       00200
 
30
#define MF_SQUEEZED     01000
 
31
#define MF_USES_SL      02000
 
32
#define MF_IS_SL        04000
 
33
 
 
34
/* Common combinations.  */
 
35
#define IMAGIC          (MF_IMPURE|ZMAGIC)      /* Demand load (impure text) */
 
36
#define SPOMAGIC        (MF_USES_SL|OMAGIC)     /* OMAGIC with large header */
 
37
                                        /* -- may contain a ref to a */
 
38
                                        /* shared lib required by the */
 
39
                                        /* object.  */
 
40
#define SLOMAGIC        (MF_IS_SL|OMAGIC) /* A reference to a shared library */
 
41
                                          /* The text portion of the object */
 
42
                                          /* contains "overflow text" from */
 
43
                                          /* the shared library to be linked */
 
44
                                          /* in with an object */
 
45
#define QMAGIC          (MF_SQUEEZED|ZMAGIC)    /* Sqeezed demand paged.  */
 
46
                                          /* NOTE: This interpretation of */
 
47
                                          /* QMAGIC seems to be at variance */
 
48
                                          /* With that used on other */
 
49
                                          /* architectures.  */
 
50
#define SPZMAGIC        (MF_USES_SL|ZMAGIC)     /* program which uses sl */
 
51
#define SPQMAGIC        (MF_USES_SL|QMAGIC)     /* sqeezed ditto */
 
52
#define SLZMAGIC        (MF_IS_SL|ZMAGIC)       /* shared lib part of prog */
 
53
#define SLPZMAGIC       (MF_USES_SL|SLZMAGIC)   /* sl which uses another */
 
54
 
 
55
#define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL)
 
56
 
 
57
/* Only a pure OMAGIC file has the minimal header */
 
58
#define N_TXTOFF(x)             \
 
59
 ((x).a_info == OMAGIC          \
 
60
  ? 32                          \
 
61
  : (N_MAGIC(x) == ZMAGIC       \
 
62
     ? TARGET_PAGE_SIZE         \
 
63
     : 999))
 
64
 
 
65
#define N_TXTADDR(x)                                                         \
 
66
  (N_MAGIC(x) != ZMAGIC                                                      \
 
67
   ? (bfd_vma) 0 /* object file or NMAGIC */                                 \
 
68
   /* Programs with shared libs are loaded at the first page after all the   \
 
69
      text segments of the shared library programs.  Without looking this    \
 
70
      up we can't know exactly what the address will be.  A reasonable guess \
 
71
      is that a_entry will be in the first page of the executable.  */       \
 
72
   : (N_SHARED_LIB(x)                                                        \
 
73
      ? ((x).a_entry & ~(bfd_vma) (TARGET_PAGE_SIZE - 1))                    \
 
74
      : (bfd_vma) TEXT_START_ADDR))
 
75
 
 
76
#define N_SYMOFF(x) \
 
77
  (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
 
78
 
 
79
#define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms)
 
80
 
 
81
#define TEXT_START_ADDR 32768
 
82
#define TARGET_PAGE_SIZE 32768
 
83
#define SEGMENT_SIZE TARGET_PAGE_SIZE
 
84
#define DEFAULT_ARCH bfd_arch_arm
 
85
 
 
86
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
 
87
   remove whitespace added here, and thus will fail to concatenate
 
88
   the tokens.  */
 
89
#define MY(OP) CONCAT2 (riscix_,OP)
 
90
#define TARGETNAME "a.out-riscix"
 
91
#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
 
92
                     (((x).a_info & ~006000) != OMAGIC) && \
 
93
                     ((x).a_info != NMAGIC))
 
94
#define N_MAGIC(x) ((x).a_info & ~07200)
 
95
 
 
96
#include "bfd.h"
 
97
#include "sysdep.h"
 
98
#include "libbfd.h"
 
99
 
 
100
#define WRITE_HEADERS(abfd, execp)                                          \
 
101
  {                                                                         \
 
102
    bfd_size_type text_size; /* dummy vars */                               \
 
103
    file_ptr text_end;                                                      \
 
104
    if (adata(abfd).magic == undecided_magic)                               \
 
105
      NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);       \
 
106
                                                                            \
 
107
    execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;          \
 
108
    execp->a_entry = bfd_get_start_address (abfd);                          \
 
109
                                                                            \
 
110
    execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                  \
 
111
                       obj_reloc_entry_size (abfd));                        \
 
112
    execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                  \
 
113
                       obj_reloc_entry_size (abfd));                        \
 
114
    NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);             \
 
115
                                                                            \
 
116
    if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0                        \
 
117
        || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE,   \
 
118
                      abfd) != EXEC_BYTES_SIZE)                             \
 
119
      return false;                                                         \
 
120
    /* Now write out reloc info, followed by syms and strings */            \
 
121
                                                                            \
 
122
    if (bfd_get_outsymbols (abfd) != (asymbol **) NULL                      \
 
123
        && bfd_get_symcount (abfd) != 0)                                    \
 
124
      {                                                                     \
 
125
        if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)  \
 
126
          return false;                                                     \
 
127
                                                                            \
 
128
        if (! NAME(aout,write_syms) (abfd)) return false;                   \
 
129
                                                                            \
 
130
        if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
 
131
          return false;                                                     \
 
132
                                                                            \
 
133
        if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd)))          \
 
134
          return false;                                                     \
 
135
        if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
 
136
          return false;                                                     \
 
137
                                                                            \
 
138
        if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))       \
 
139
          return false;                                                     \
 
140
      }                                                                     \
 
141
  }
 
142
 
 
143
#include "libaout.h"
 
144
#include "aout/aout64.h"
 
145
 
 
146
static bfd_reloc_status_type
 
147
riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
 
148
                                  asection *, bfd *, char **));
 
149
 
 
150
static bfd_reloc_status_type
 
151
riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
 
152
                             asection *, bfd *, char **));
 
153
static const bfd_target *
 
154
MY (object_p) PARAMS ((bfd *));
 
155
 
 
156
reloc_howto_type *
 
157
riscix_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
 
158
 
 
159
void
 
160
riscix_swap_std_reloc_out PARAMS ((bfd *, arelent *, struct reloc_std_external *));
 
161
 
 
162
boolean
 
163
riscix_squirt_out_relocs PARAMS ((bfd *, asection *));
 
164
 
 
165
long
 
166
MY (canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
 
167
 
 
168
const bfd_target *
 
169
riscix_some_aout_object_p PARAMS ((bfd *, struct internal_exec *, const bfd_target *(*) (bfd *)));
 
170
 
 
171
 
 
172
static reloc_howto_type riscix_std_reloc_howto[] = {
 
173
  /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
 
174
  HOWTO( 0,              0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",        true, 0x000000ff,0x000000ff, false),
 
175
  HOWTO( 1,              0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",        true, 0x0000ffff,0x0000ffff, false),
 
176
  HOWTO( 2,              0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",        true, 0xffffffff,0xffffffff, false),
 
177
  HOWTO( 3,              2,  3,   26, true, 0, complain_overflow_signed,  riscix_fix_pcrel_26 , "ARM26",      true, 0x00ffffff,0x00ffffff, false),
 
178
  HOWTO( 4,              0,  0,   8,  true,  0, complain_overflow_signed,  0,"DISP8",     true, 0x000000ff,0x000000ff, true),
 
179
  HOWTO( 5,              0,  1,   16, true,  0, complain_overflow_signed,  0,"DISP16",    true, 0x0000ffff,0x0000ffff, true),
 
180
  HOWTO( 6,              0,  2,   32, true,  0, complain_overflow_signed,  0,"DISP32",    true, 0xffffffff,0xffffffff, true),
 
181
  HOWTO( 7,              2,  3,   26, false, 0, complain_overflow_signed,  riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false),
 
182
  EMPTY_HOWTO (-1),
 
183
  HOWTO( 9,              0, -1,   16, false, 0, complain_overflow_bitfield,0,"NEG16",        true, 0x0000ffff,0x0000ffff, false),
 
184
  HOWTO( 10,              0, -2,   32, false, 0, complain_overflow_bitfield,0,"NEG32",        true, 0xffffffff,0xffffffff, false)
 
185
};
 
186
 
 
187
#define RISCIX_TABLE_SIZE \
 
188
  (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type))
 
189
 
 
190
static bfd_reloc_status_type
 
191
riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
 
192
                          output_bfd, error_message)
 
193
     bfd *abfd ATTRIBUTE_UNUSED;
 
194
     arelent *reloc_entry ATTRIBUTE_UNUSED;
 
195
     asymbol *symbol ATTRIBUTE_UNUSED;
 
196
     PTR data ATTRIBUTE_UNUSED;
 
197
     asection *input_section ATTRIBUTE_UNUSED;
 
198
     bfd *output_bfd ATTRIBUTE_UNUSED;
 
199
     char **error_message ATTRIBUTE_UNUSED;
 
200
{
 
201
  /* This is dead simple at present.  */
 
202
  return bfd_reloc_ok;
 
203
}
 
204
 
 
205
static bfd_reloc_status_type
 
206
riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
 
207
                     output_bfd, error_message)
 
208
     bfd *abfd;
 
209
     arelent *reloc_entry;
 
210
     asymbol *symbol;
 
211
     PTR data;
 
212
     asection *input_section;
 
213
     bfd *output_bfd;
 
214
     char **error_message ATTRIBUTE_UNUSED;
 
215
{
 
216
  bfd_vma relocation;
 
217
  bfd_size_type addr = reloc_entry->address;
 
218
  long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
 
219
  bfd_reloc_status_type flag = bfd_reloc_ok;
 
220
 
 
221
  /* If this is an undefined symbol, return error */
 
222
  if (symbol->section == &bfd_und_section
 
223
      && (symbol->flags & BSF_WEAK) == 0)
 
224
    return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
 
225
 
 
226
  /* If the sections are different, and we are doing a partial relocation,
 
227
     just ignore it for now.  */
 
228
  if (symbol->section->name != input_section->name
 
229
      && output_bfd != (bfd *)NULL)
 
230
    return bfd_reloc_continue;
 
231
 
 
232
  relocation = (target & 0x00ffffff) << 2;
 
233
  relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
 
234
  relocation += symbol->value;
 
235
  relocation += symbol->section->output_section->vma;
 
236
  relocation += symbol->section->output_offset;
 
237
  relocation += reloc_entry->addend;
 
238
  relocation -= input_section->output_section->vma;
 
239
  relocation -= input_section->output_offset;
 
240
  relocation -= addr;
 
241
  if (relocation & 3)
 
242
    return bfd_reloc_overflow;
 
243
 
 
244
  /* Check for overflow */
 
245
  if (relocation & 0x02000000)
 
246
    {
 
247
      if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
 
248
        flag = bfd_reloc_overflow;
 
249
    }
 
250
  else if (relocation & ~ (bfd_vma) 0x03ffffff)
 
251
    flag = bfd_reloc_overflow;
 
252
 
 
253
  target &= ~0x00ffffff;
 
254
  target |= (relocation >> 2) & 0x00ffffff;
 
255
  bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
 
256
 
 
257
  /* Now the ARM magic... Change the reloc type so that it is marked as done.
 
258
     Strictly this is only necessary if we are doing a partial relocation.  */
 
259
  reloc_entry->howto = &riscix_std_reloc_howto[7];
 
260
 
 
261
  return flag;
 
262
}
 
263
 
 
264
reloc_howto_type *
 
265
riscix_reloc_type_lookup (abfd, code)
 
266
     bfd *abfd;
 
267
     bfd_reloc_code_real_type code;
 
268
{
 
269
#define ASTD(i,j)       case i: return &riscix_std_reloc_howto[j]
 
270
  if (code == BFD_RELOC_CTOR)
 
271
    switch (bfd_get_arch_info (abfd)->bits_per_address)
 
272
      {
 
273
      case 32:
 
274
        code = BFD_RELOC_32;
 
275
        break;
 
276
      default: return (reloc_howto_type *) NULL;
 
277
      }
 
278
 
 
279
  switch (code)
 
280
    {
 
281
      ASTD (BFD_RELOC_16, 1);
 
282
      ASTD (BFD_RELOC_32, 2);
 
283
      ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
 
284
      ASTD (BFD_RELOC_8_PCREL, 4);
 
285
      ASTD (BFD_RELOC_16_PCREL, 5);
 
286
      ASTD (BFD_RELOC_32_PCREL, 6);
 
287
    default: return (reloc_howto_type *) NULL;
 
288
    }
 
289
}
 
290
 
 
291
#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 
292
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
 
293
#define MY_final_link_callback should_not_be_used
 
294
#define MY_bfd_final_link _bfd_generic_final_link
 
295
 
 
296
#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup
 
297
#define MY_canonicalize_reloc riscix_canonicalize_reloc
 
298
#define MY_object_p riscix_object_p
 
299
 
 
300
static const bfd_target *riscix_callback PARAMS ((bfd *));
 
301
 
 
302
void
 
303
riscix_swap_std_reloc_out (abfd, g, natptr)
 
304
     bfd *abfd;
 
305
     arelent *g;
 
306
     struct reloc_std_external *natptr;
 
307
{
 
308
  int r_index;
 
309
  asymbol *sym = *(g->sym_ptr_ptr);
 
310
  int r_extern;
 
311
  int r_length;
 
312
  int r_pcrel;
 
313
  int r_neg = 0;        /* Negative relocs use the BASEREL bit.  */
 
314
  asection *output_section = sym->section->output_section;
 
315
 
 
316
  PUT_WORD(abfd, g->address, natptr->r_address);
 
317
 
 
318
  r_length = g->howto->size ;   /* Size as a power of two */
 
319
  if (r_length < 0)
 
320
    {
 
321
      r_length = -r_length;
 
322
      r_neg = 1;
 
323
    }
 
324
 
 
325
  r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
 
326
 
 
327
  /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
 
328
     relocation has been done already (Only for the 26-bit one I think)???!!!
 
329
     */
 
330
 
 
331
  if (r_length == 3)
 
332
    r_pcrel = r_pcrel ? 0 : 1;
 
333
 
 
334
#if 0
 
335
  /* For a standard reloc, the addend is in the object file.  */
 
336
  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
 
337
#endif
 
338
 
 
339
  /* name was clobbered by aout_write_syms to be symbol index */
 
340
 
 
341
  /* If this relocation is relative to a symbol then set the
 
342
     r_index to the symbols index, and the r_extern bit.
 
343
 
 
344
     Absolute symbols can come in in two ways, either as an offset
 
345
     from the abs section, or as a symbol which has an abs value.
 
346
     check for that here
 
347
     */
 
348
 
 
349
  if (bfd_is_com_section (output_section)
 
350
      || output_section == &bfd_abs_section
 
351
      || output_section == &bfd_und_section)
 
352
    {
 
353
      if (bfd_abs_section.symbol == sym)
 
354
        {
 
355
          /* Whoops, looked like an abs symbol, but is really an offset
 
356
             from the abs section */
 
357
          r_index = 0;
 
358
          r_extern = 0;
 
359
        }
 
360
      else
 
361
        {
 
362
          /* Fill in symbol */
 
363
          r_extern = 1;
 
364
          r_index = (*g->sym_ptr_ptr)->udata.i;
 
365
        }
 
366
    }
 
367
  else
 
368
    {
 
369
      /* Just an ordinary section */
 
370
      r_extern = 0;
 
371
      r_index  = output_section->target_index;
 
372
    }
 
373
 
 
374
  /* now the fun stuff */
 
375
  if (bfd_header_big_endian (abfd))
 
376
    {
 
377
      natptr->r_index[0] = r_index >> 16;
 
378
      natptr->r_index[1] = r_index >> 8;
 
379
      natptr->r_index[2] = r_index;
 
380
      natptr->r_type[0] =
 
381
        (  (r_extern ?   RELOC_STD_BITS_EXTERN_BIG: 0)
 
382
         | (r_pcrel  ?   RELOC_STD_BITS_PCREL_BIG: 0)
 
383
         | (r_neg    ?   RELOC_STD_BITS_BASEREL_BIG: 0)
 
384
         | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
 
385
    }
 
386
  else
 
387
    {
 
388
      natptr->r_index[2] = r_index >> 16;
 
389
      natptr->r_index[1] = r_index >> 8;
 
390
      natptr->r_index[0] = r_index;
 
391
      natptr->r_type[0] =
 
392
        (  (r_extern ?   RELOC_STD_BITS_EXTERN_LITTLE: 0)
 
393
         | (r_pcrel  ?   RELOC_STD_BITS_PCREL_LITTLE: 0)
 
394
         | (r_neg    ?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
 
395
         | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
 
396
    }
 
397
}
 
398
 
 
399
boolean
 
400
riscix_squirt_out_relocs (abfd, section)
 
401
     bfd *abfd;
 
402
     asection *section;
 
403
{
 
404
  arelent **generic;
 
405
  unsigned char *native, *natptr;
 
406
  size_t each_size;
 
407
 
 
408
  unsigned int count = section->reloc_count;
 
409
  bfd_size_type natsize;
 
410
 
 
411
  if (count == 0) return true;
 
412
 
 
413
  each_size = obj_reloc_entry_size (abfd);
 
414
  natsize = each_size;
 
415
  natsize *= count;
 
416
  native = (unsigned char *) bfd_zalloc (abfd, natsize);
 
417
  if (!native)
 
418
    return false;
 
419
 
 
420
  generic = section->orelocation;
 
421
 
 
422
  for (natptr = native;
 
423
       count != 0;
 
424
       --count, natptr += each_size, ++generic)
 
425
    riscix_swap_std_reloc_out (abfd, *generic,
 
426
                               (struct reloc_std_external *) natptr);
 
427
 
 
428
  if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
 
429
    {
 
430
      bfd_release (abfd, native);
 
431
      return false;
 
432
    }
 
433
 
 
434
  bfd_release (abfd, native);
 
435
  return true;
 
436
}
 
437
 
 
438
/*
 
439
 * This is just like the standard aoutx.h version but we need to do our
 
440
 * own mapping of external reloc type values to howto entries.
 
441
 */
 
442
long
 
443
MY(canonicalize_reloc) (abfd, section, relptr, symbols)
 
444
      bfd *abfd;
 
445
      sec_ptr section;
 
446
      arelent **relptr;
 
447
      asymbol **symbols;
 
448
{
 
449
  arelent *tblptr = section->relocation;
 
450
  unsigned int count, c;
 
451
  extern reloc_howto_type NAME(aout,std_howto_table)[];
 
452
 
 
453
  /* If we have already read in the relocation table, return the values.  */
 
454
  if (section->flags & SEC_CONSTRUCTOR) {
 
455
    arelent_chain *chain = section->constructor_chain;
 
456
 
 
457
    for (count = 0; count < section->reloc_count; count++) {
 
458
      *relptr++ = &chain->relent;
 
459
      chain = chain->next;
 
460
    }
 
461
    *relptr = 0;
 
462
    return section->reloc_count;
 
463
  }
 
464
  if (tblptr && section->reloc_count) {
 
465
    for (count = 0; count++ < section->reloc_count;)
 
466
      *relptr++ = tblptr++;
 
467
    *relptr = 0;
 
468
    return section->reloc_count;
 
469
  }
 
470
 
 
471
  if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
 
472
    return -1;
 
473
  tblptr = section->relocation;
 
474
 
 
475
  /* fix up howto entries */
 
476
  for (count = 0; count++ < section->reloc_count;)
 
477
    {
 
478
      c = tblptr->howto - NAME(aout,std_howto_table);
 
479
      BFD_ASSERT (c < RISCIX_TABLE_SIZE);
 
480
      tblptr->howto = &riscix_std_reloc_howto[c];
 
481
 
 
482
      *relptr++ = tblptr++;
 
483
    }
 
484
  *relptr = 0;
 
485
  return section->reloc_count;
 
486
}
 
487
 
 
488
/* This is the same as NAME(aout,some_aout_object_p), but has different
 
489
   expansions of the macro definitions.  */
 
490
 
 
491
const bfd_target *
 
492
riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p)
 
493
     bfd *abfd;
 
494
     struct internal_exec *execp;
 
495
     const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
 
496
{
 
497
  struct aout_data_struct *rawptr, *oldrawptr;
 
498
  const bfd_target *result;
 
499
  bfd_size_type amt = sizeof (struct aout_data_struct);
 
500
 
 
501
  rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, amt);
 
502
 
 
503
  if (rawptr == NULL)
 
504
    return 0;
 
505
 
 
506
  oldrawptr = abfd->tdata.aout_data;
 
507
  abfd->tdata.aout_data = rawptr;
 
508
 
 
509
  /* Copy the contents of the old tdata struct.
 
510
     In particular, we want the subformat, since for hpux it was set in
 
511
     hp300hpux.c:swap_exec_header_in and will be used in
 
512
     hp300hpux.c:callback.  */
 
513
  if (oldrawptr != NULL)
 
514
    *abfd->tdata.aout_data = *oldrawptr;
 
515
 
 
516
  abfd->tdata.aout_data->a.hdr = &rawptr->e;
 
517
  *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec
 
518
                                                   struct */
 
519
  execp = abfd->tdata.aout_data->a.hdr;
 
520
 
 
521
  /* Set the file flags */
 
522
  abfd->flags = BFD_NO_FLAGS;
 
523
  if (execp->a_drsize || execp->a_trsize)
 
524
    abfd->flags |= HAS_RELOC;
 
525
  /* Setting of EXEC_P has been deferred to the bottom of this function */
 
526
  if (execp->a_syms)
 
527
    abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
 
528
  if (N_DYNAMIC(*execp))
 
529
    abfd->flags |= DYNAMIC;
 
530
 
 
531
  if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
 
532
                                             (yet)! */
 
533
    {
 
534
      bfd_set_error (bfd_error_wrong_format);
 
535
      return NULL;
 
536
    }
 
537
  else if ((execp->a_info & MF_IS_SL) != 0)     /* Nor are shared libraries */
 
538
    {
 
539
      bfd_set_error (bfd_error_wrong_format);
 
540
      return NULL;
 
541
    }
 
542
  else if (N_MAGIC (*execp) == ZMAGIC)
 
543
    {
 
544
      abfd->flags |= D_PAGED | WP_TEXT;
 
545
      adata (abfd).magic = z_magic;
 
546
    }
 
547
  else if (N_MAGIC (*execp) == NMAGIC)
 
548
    {
 
549
      abfd->flags |= WP_TEXT;
 
550
      adata (abfd).magic = n_magic;
 
551
    }
 
552
  else if (N_MAGIC (*execp) == OMAGIC)
 
553
    adata (abfd).magic = o_magic;
 
554
  else
 
555
    {
 
556
      /* Should have been checked with N_BADMAG before this routine
 
557
         was called.  */
 
558
      abort ();
 
559
    }
 
560
 
 
561
  bfd_get_start_address (abfd) = execp->a_entry;
 
562
 
 
563
  obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
 
564
  bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
 
565
 
 
566
  /* The default relocation entry size is that of traditional V7 Unix.  */
 
567
  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
 
568
 
 
569
  /* The default symbol entry size is that of traditional Unix.  */
 
570
  obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
 
571
 
 
572
  obj_aout_external_syms (abfd) = NULL;
 
573
  obj_aout_external_strings (abfd) = NULL;
 
574
  obj_aout_sym_hashes (abfd) = NULL;
 
575
 
 
576
  if (! NAME(aout,make_sections) (abfd))
 
577
    return NULL;
 
578
 
 
579
  obj_datasec (abfd)->_raw_size = execp->a_data;
 
580
  obj_bsssec (abfd)->_raw_size = execp->a_bss;
 
581
 
 
582
  obj_textsec (abfd)->flags =
 
583
    (execp->a_trsize != 0
 
584
     ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
 
585
     : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
 
586
  obj_datasec (abfd)->flags =
 
587
    (execp->a_drsize != 0
 
588
     ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
 
589
     : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
 
590
  obj_bsssec (abfd)->flags = SEC_ALLOC;
 
591
 
 
592
  result = (*callback_to_real_object_p) (abfd);
 
593
 
 
594
#if defined(MACH) || defined(STAT_FOR_EXEC)
 
595
  /* The original heuristic doesn't work in some important cases. The
 
596
   * a.out file has no information about the text start address. For
 
597
   * files (like kernels) linked to non-standard addresses (ld -Ttext
 
598
   * nnn) the entry point may not be between the default text start
 
599
   * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
 
600
   * This is not just a mach issue. Many kernels are loaded at non
 
601
   * standard addresses.
 
602
   */
 
603
  {
 
604
    struct stat stat_buf;
 
605
    if (abfd->iostream != NULL
 
606
        && (abfd->flags & BFD_IN_MEMORY) == 0
 
607
        && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
 
608
        && ((stat_buf.st_mode & 0111) != 0))
 
609
      abfd->flags |= EXEC_P;
 
610
  }
 
611
#else /* ! MACH */
 
612
  /* Now that the segment addresses have been worked out, take a better
 
613
     guess at whether the file is executable.  If the entry point
 
614
     is within the text segment, assume it is.  (This makes files
 
615
     executable even if their entry point address is 0, as long as
 
616
     their text starts at zero.)
 
617
 
 
618
     At some point we should probably break down and stat the file and
 
619
     declare it executable if (one of) its 'x' bits are on...  */
 
620
  if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
 
621
      (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
 
622
    abfd->flags |= EXEC_P;
 
623
#endif /* MACH */
 
624
  if (result)
 
625
    {
 
626
    }
 
627
  else
 
628
    {
 
629
      free (rawptr);
 
630
      abfd->tdata.aout_data = oldrawptr;
 
631
    }
 
632
  return result;
 
633
}
 
634
 
 
635
static const bfd_target *
 
636
MY(object_p) (abfd)
 
637
     bfd *abfd;
 
638
{
 
639
  struct external_exec exec_bytes;      /* Raw exec header from file */
 
640
  struct internal_exec exec;            /* Cleaned-up exec header */
 
641
  const bfd_target *target;
 
642
 
 
643
  if (bfd_bread ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
 
644
      != EXEC_BYTES_SIZE)
 
645
    {
 
646
      if (bfd_get_error () != bfd_error_system_call)
 
647
        bfd_set_error (bfd_error_wrong_format);
 
648
      return 0;
 
649
    }
 
650
 
 
651
  exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
 
652
 
 
653
  if (N_BADMAG (exec)) return 0;
 
654
#ifdef MACHTYPE_OK
 
655
  if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
 
656
#endif
 
657
 
 
658
  NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
 
659
 
 
660
  target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
 
661
 
 
662
  return target;
 
663
}
 
664
 
 
665
#include "aout-target.h"