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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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