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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [insight/] [bfd/] [i386lynx.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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