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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [i386lynx.c] - Blame information for rev 148

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for i386 a.out binaries under LynxOS.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2002,
3
   2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#define TEXT_START_ADDR 0
23
#define TARGET_PAGE_SIZE 4096
24
#define SEGMENT_SIZE TARGET_PAGE_SIZE
25
#define DEFAULT_ARCH bfd_arch_i386
26
 
27
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
28
   remove whitespace added here, and thus will fail to concatenate
29
   the tokens.  */
30
#define MY(OP) CONCAT2 (i386lynx_aout_,OP)
31
#define TARGETNAME "a.out-i386-lynx"
32
 
33
#include "sysdep.h"
34
#include "bfd.h"
35
#include "libbfd.h"
36
 
37
#ifndef WRITE_HEADERS
38
#define WRITE_HEADERS(abfd, execp)                                            \
39
      {                                                                       \
40
        bfd_size_type text_size; /* dummy vars */                             \
41
        file_ptr text_end;                                                    \
42
        if (adata(abfd).magic == undecided_magic)                             \
43
          NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);     \
44
                                                                              \
45
        execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;        \
46
        execp->a_entry = bfd_get_start_address (abfd);                        \
47
                                                                              \
48
        execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                \
49
                           obj_reloc_entry_size (abfd));                      \
50
        execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                \
51
                           obj_reloc_entry_size (abfd));                      \
52
        NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);           \
53
                                                                              \
54
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0                \
55
            || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
56
                          abfd) != EXEC_BYTES_SIZE)                           \
57
          return FALSE;                                                       \
58
        /* Now write out reloc info, followed by syms and strings */          \
59
                                                                              \
60
        if (bfd_get_symcount (abfd) != 0)                                      \
61
            {                                                                 \
62
              if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET)    \
63
                  != 0)                                                        \
64
                return FALSE;                                                 \
65
                                                                              \
66
              if (! NAME(aout,write_syms) (abfd)) return FALSE;               \
67
                                                                              \
68
              if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET)   \
69
                  != 0)                                                        \
70
                return FALSE;                                                 \
71
                                                                              \
72
              if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd)))   \
73
                return FALSE;                                                 \
74
              if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET)   \
75
                  != 0)                                                        \
76
                return 0;                                                      \
77
                                                                              \
78
              if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd)))   \
79
                return FALSE;                                                 \
80
            }                                                                 \
81
      }
82
#endif
83
 
84
#include "libaout.h"
85
#include "aout/aout64.h"
86
 
87
void NAME (lynx,swap_std_reloc_out)
88
  PARAMS ((bfd *, arelent *, struct reloc_std_external *));
89
void NAME (lynx,swap_ext_reloc_out)
90
  PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
91
void NAME (lynx,swap_ext_reloc_in)
92
  PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **,
93
           bfd_size_type));
94
void NAME (lynx,swap_std_reloc_in)
95
  PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
96
           bfd_size_type));
97
bfd_boolean NAME (lynx,slurp_reloc_table)
98
  PARAMS ((bfd *, sec_ptr, asymbol **));
99
bfd_boolean NAME (lynx,squirt_out_relocs)
100
  PARAMS ((bfd *, asection *));
101
long NAME (lynx,canonicalize_reloc)
102
  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
103
 
104
#ifdef LYNX_CORE
105
 
106
char *lynx_core_file_failing_command ();
107
int lynx_core_file_failing_signal ();
108
bfd_boolean lynx_core_file_matches_executable_p ();
109
const bfd_target *lynx_core_file_p ();
110
 
111
#define MY_core_file_failing_command lynx_core_file_failing_command
112
#define MY_core_file_failing_signal lynx_core_file_failing_signal
113
#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
114
#define MY_core_file_p lynx_core_file_p
115
 
116
#endif /* LYNX_CORE */
117
 
118
 
119
#define KEEPIT udata.i
120
 
121
extern reloc_howto_type aout_32_ext_howto_table[];
122
extern reloc_howto_type aout_32_std_howto_table[];
123
 
124
/* Standard reloc stuff */
125
/* Output standard relocation information to a file in target byte order. */
126
 
127
void
128
NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
129
     bfd *abfd;
130
     arelent *g;
131
     struct reloc_std_external *natptr;
132
{
133
  int r_index;
134
  asymbol *sym = *(g->sym_ptr_ptr);
135
  int r_extern;
136
  unsigned int r_length;
137
  int r_pcrel;
138
  int r_baserel, r_jmptable, r_relative;
139
  asection *output_section = sym->section->output_section;
140
 
141
  PUT_WORD (abfd, g->address, natptr->r_address);
142
 
143
  r_length = g->howto->size;    /* Size as a power of two */
144
  r_pcrel = (int) g->howto->pc_relative;        /* Relative to PC? */
145
  /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
146
  r_baserel = 0;
147
  r_jmptable = 0;
148
  r_relative = 0;
149
 
150
  /* name was clobbered by aout_write_syms to be symbol index */
151
 
152
  /* If this relocation is relative to a symbol then set the
153
     r_index to the symbols index, and the r_extern bit.
154
 
155
     Absolute symbols can come in in two ways, either as an offset
156
     from the abs section, or as a symbol which has an abs value.
157
     check for that here
158
  */
159
 
160
 
161
  if (bfd_is_com_section (output_section)
162
      || bfd_is_abs_section (output_section)
163
      || bfd_is_und_section (output_section))
164
    {
165
      if (bfd_abs_section_ptr->symbol == sym)
166
        {
167
          /* Whoops, looked like an abs symbol, but is really an offset
168
             from the abs section */
169
          r_index = 0;
170
          r_extern = 0;
171
        }
172
      else
173
        {
174
          /* Fill in symbol */
175
          r_extern = 1;
176
          r_index = (*g->sym_ptr_ptr)->KEEPIT;
177
        }
178
    }
179
  else
180
    {
181
      /* Just an ordinary section */
182
      r_extern = 0;
183
      r_index = output_section->target_index;
184
    }
185
 
186
  /* now the fun stuff */
187
  if (bfd_header_big_endian (abfd))
188
    {
189
      natptr->r_index[0] = r_index >> 16;
190
      natptr->r_index[1] = r_index >> 8;
191
      natptr->r_index[2] = r_index;
192
      natptr->r_type[0] =
193
        (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
194
        | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
195
        | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
196
        | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
197
        | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
198
        | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
199
    }
200
  else
201
    {
202
      natptr->r_index[2] = r_index >> 16;
203
      natptr->r_index[1] = r_index >> 8;
204
      natptr->r_index[0] = r_index;
205
      natptr->r_type[0] =
206
        (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
207
        | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
208
        | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
209
        | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
210
        | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
211
        | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
212
    }
213
}
214
 
215
 
216
/* Extended stuff */
217
/* Output extended relocation information to a file in target byte order. */
218
 
219
void
220
NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
221
     bfd *abfd;
222
     arelent *g;
223
     register struct reloc_ext_external *natptr;
224
{
225
  int r_index;
226
  int r_extern;
227
  unsigned int r_type;
228
  unsigned int r_addend;
229
  asymbol *sym = *(g->sym_ptr_ptr);
230
  asection *output_section = sym->section->output_section;
231
 
232
  PUT_WORD (abfd, g->address, natptr->r_address);
233
 
234
  r_type = (unsigned int) g->howto->type;
235
 
236
  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
237
 
238
 
239
  /* If this relocation is relative to a symbol then set the
240
     r_index to the symbols index, and the r_extern bit.
241
 
242
     Absolute symbols can come in in two ways, either as an offset
243
     from the abs section, or as a symbol which has an abs value.
244
     check for that here
245
     */
246
 
247
  if (bfd_is_com_section (output_section)
248
      || bfd_is_abs_section (output_section)
249
      || bfd_is_und_section (output_section))
250
    {
251
      if (bfd_abs_section_ptr->symbol == sym)
252
        {
253
          /* Whoops, looked like an abs symbol, but is really an offset
254
         from the abs section */
255
          r_index = 0;
256
          r_extern = 0;
257
        }
258
      else
259
        {
260
          r_extern = 1;
261
          r_index = (*g->sym_ptr_ptr)->KEEPIT;
262
        }
263
    }
264
  else
265
    {
266
      /* Just an ordinary section */
267
      r_extern = 0;
268
      r_index = output_section->target_index;
269
    }
270
 
271
 
272
  /* now the fun stuff */
273
  if (bfd_header_big_endian (abfd))
274
    {
275
      natptr->r_index[0] = r_index >> 16;
276
      natptr->r_index[1] = r_index >> 8;
277
      natptr->r_index[2] = r_index;
278
      natptr->r_type[0] =
279
        (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
280
        | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
281
    }
282
  else
283
    {
284
      natptr->r_index[2] = r_index >> 16;
285
      natptr->r_index[1] = r_index >> 8;
286
      natptr->r_index[0] = r_index;
287
      natptr->r_type[0] =
288
        (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
289
        | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
290
    }
291
 
292
  PUT_WORD (abfd, r_addend, natptr->r_addend);
293
}
294
 
295
/* BFD deals internally with all things based from the section they're
296
   in. so, something in 10 bytes into a text section  with a base of
297
   50 would have a symbol (.text+10) and know .text vma was 50.
298
 
299
   Aout keeps all it's symbols based from zero, so the symbol would
300
   contain 60. This macro subs the base of each section from the value
301
   to give the true offset from the section */
302
 
303
 
304
#define MOVE_ADDRESS(ad)                                                \
305
  if (r_extern) {                                                       \
306
   /* undefined symbol */                                               \
307
     cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
308
     cache_ptr->addend = ad;                                            \
309
     } else {                                                           \
310
    /* defined, section relative. replace symbol with pointer to        \
311
       symbol which points to section  */                               \
312
    switch (r_index) {                                                  \
313
    case N_TEXT:                                                        \
314
    case N_TEXT | N_EXT:                                                \
315
      cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
316
      cache_ptr->addend = ad  - su->textsec->vma;                       \
317
      break;                                                            \
318
    case N_DATA:                                                        \
319
    case N_DATA | N_EXT:                                                \
320
      cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
321
      cache_ptr->addend = ad - su->datasec->vma;                        \
322
      break;                                                            \
323
    case N_BSS:                                                         \
324
    case N_BSS | N_EXT:                                                 \
325
      cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
326
      cache_ptr->addend = ad - su->bsssec->vma;                         \
327
      break;                                                            \
328
    default:                                                            \
329
    case N_ABS:                                                         \
330
    case N_ABS | N_EXT:                                                 \
331
     cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;      \
332
      cache_ptr->addend = ad;                                           \
333
      break;                                                            \
334
    }                                                                   \
335
  }                                                                     \
336
 
337
void
338
NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
339
     bfd *abfd;
340
     struct reloc_ext_external *bytes;
341
     arelent *cache_ptr;
342
     asymbol **symbols;
343
     bfd_size_type symcount ATTRIBUTE_UNUSED;
344
{
345
  int r_index;
346
  int r_extern;
347
  unsigned int r_type;
348
  struct aoutdata *su = &(abfd->tdata.aout_data->a);
349
 
350
  cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
351
 
352
  r_index = bytes->r_index[1];
353
  r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
354
  r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
355
    >> RELOC_EXT_BITS_TYPE_SH_BIG;
356
 
357
  cache_ptr->howto = aout_32_ext_howto_table + r_type;
358
  MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
359
}
360
 
361
void
362
NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
363
     bfd *abfd;
364
     struct reloc_std_external *bytes;
365
     arelent *cache_ptr;
366
     asymbol **symbols;
367
     bfd_size_type symcount ATTRIBUTE_UNUSED;
368
{
369
  int r_index;
370
  int r_extern;
371
  unsigned int r_length;
372
  int r_pcrel;
373
  struct aoutdata *su = &(abfd->tdata.aout_data->a);
374
 
375
  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
376
 
377
  r_index = bytes->r_index[1];
378
  r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
379
  r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
380
  r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
381
    >> RELOC_STD_BITS_LENGTH_SH_BIG;
382
 
383
  cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
384
  /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
385
 
386
  MOVE_ADDRESS (0);
387
}
388
 
389
/* Reloc hackery */
390
 
391
bfd_boolean
392
NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
393
     bfd *abfd;
394
     sec_ptr asect;
395
     asymbol **symbols;
396
{
397
  bfd_size_type count;
398
  bfd_size_type reloc_size;
399
  PTR relocs;
400
  arelent *reloc_cache;
401
  size_t each_size;
402
 
403
  if (asect->relocation)
404
    return TRUE;
405
 
406
  if (asect->flags & SEC_CONSTRUCTOR)
407
    return TRUE;
408
 
409
  if (asect == obj_datasec (abfd))
410
    {
411
      reloc_size = exec_hdr (abfd)->a_drsize;
412
      goto doit;
413
    }
414
 
415
  if (asect == obj_textsec (abfd))
416
    {
417
      reloc_size = exec_hdr (abfd)->a_trsize;
418
      goto doit;
419
    }
420
 
421
  bfd_set_error (bfd_error_invalid_operation);
422
  return FALSE;
423
 
424
doit:
425
  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
426
    return FALSE;
427
  each_size = obj_reloc_entry_size (abfd);
428
 
429
  count = reloc_size / each_size;
430
 
431
 
432
  reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
433
  if (!reloc_cache && count != 0)
434
    return FALSE;
435
 
436
  relocs = (PTR) bfd_alloc (abfd, reloc_size);
437
  if (!relocs && reloc_size != 0)
438
    {
439
      free (reloc_cache);
440
      return FALSE;
441
    }
442
 
443
  if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
444
    {
445
      bfd_release (abfd, relocs);
446
      free (reloc_cache);
447
      return FALSE;
448
    }
449
 
450
  if (each_size == RELOC_EXT_SIZE)
451
    {
452
      register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
453
      unsigned int counter = 0;
454
      arelent *cache_ptr = reloc_cache;
455
 
456
      for (; counter < count; counter++, rptr++, cache_ptr++)
457
        {
458
          NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
459
                                        (bfd_size_type) bfd_get_symcount (abfd));
460
        }
461
    }
462
  else
463
    {
464
      register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
465
      unsigned int counter = 0;
466
      arelent *cache_ptr = reloc_cache;
467
 
468
      for (; counter < count; counter++, rptr++, cache_ptr++)
469
        {
470
          NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
471
                                        (bfd_size_type) bfd_get_symcount (abfd));
472
        }
473
 
474
    }
475
 
476
  bfd_release (abfd, relocs);
477
  asect->relocation = reloc_cache;
478
  asect->reloc_count = count;
479
  return TRUE;
480
}
481
 
482
 
483
 
484
/* Write out a relocation section into an object file.  */
485
 
486
bfd_boolean
487
NAME(lynx,squirt_out_relocs) (abfd, section)
488
     bfd *abfd;
489
     asection *section;
490
{
491
  arelent **generic;
492
  unsigned char *native, *natptr;
493
  size_t each_size;
494
 
495
  unsigned int count = section->reloc_count;
496
  bfd_size_type natsize;
497
 
498
  if (count == 0)
499
    return TRUE;
500
 
501
  each_size = obj_reloc_entry_size (abfd);
502
  natsize = count;
503
  natsize *= each_size;
504
  native = (unsigned char *) bfd_zalloc (abfd, natsize);
505
  if (!native)
506
    return FALSE;
507
 
508
  generic = section->orelocation;
509
 
510
  if (each_size == RELOC_EXT_SIZE)
511
    {
512
      for (natptr = native;
513
           count != 0;
514
           --count, natptr += each_size, ++generic)
515
        NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
516
    }
517
  else
518
    {
519
      for (natptr = native;
520
           count != 0;
521
           --count, natptr += each_size, ++generic)
522
        NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
523
    }
524
 
525
  if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
526
    {
527
      bfd_release (abfd, native);
528
      return FALSE;
529
    }
530
  bfd_release (abfd, native);
531
 
532
  return TRUE;
533
}
534
 
535
/* This is stupid.  This function should be a boolean predicate */
536
long
537
NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
538
     bfd *abfd;
539
     sec_ptr section;
540
     arelent **relptr;
541
     asymbol **symbols;
542
{
543
  arelent *tblptr = section->relocation;
544
  unsigned int count;
545
 
546
  if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
547
    return -1;
548
 
549
  if (section->flags & SEC_CONSTRUCTOR)
550
    {
551
      arelent_chain *chain = section->constructor_chain;
552
      for (count = 0; count < section->reloc_count; count++)
553
        {
554
          *relptr++ = &chain->relent;
555
          chain = chain->next;
556
        }
557
    }
558
  else
559
    {
560
      tblptr = section->relocation;
561
 
562
      for (count = 0; count++ < section->reloc_count;)
563
        {
564
          *relptr++ = tblptr++;
565
        }
566
    }
567
  *relptr = 0;
568
 
569
  return section->reloc_count;
570
}
571
 
572
#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
573
 
574
#include "aout-target.h"

powered by: WebSVN 2.1.0

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