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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* BFD back-end for linux flavored m68k a.out binaries.
2
   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000
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 TARGET_PAGE_SIZE 4096
22
#define ZMAGIC_DISK_BLOCK_SIZE 1024
23
#define SEGMENT_SIZE TARGET_PAGE_SIZE
24
#define TEXT_START_ADDR 0x0
25
#define N_SHARED_LIB(x) 0
26
#define BYTES_IN_WORD 4
27
 
28
#define MACHTYPE_OK(mtype) ((mtype) == M_68020 || (mtype) == M_UNKNOWN)
29
 
30
#include "bfd.h"
31
#include "sysdep.h"
32
#include "libbfd.h"
33
#include "aout/aout64.h"
34
#include "aout/stab_gnu.h"
35
#include "aout/ar.h"
36
#include "libaout.h"           /* BFD a.out internal data structures */
37
 
38
#define TARGET_IS_BIG_ENDIAN_P
39
#define DEFAULT_ARCH bfd_arch_m68k
40
#define MY(OP) CAT(m68klinux_,OP)
41
#define TARGETNAME "a.out-m68k-linux"
42
 
43
extern const bfd_target MY(vec);
44
 
45
/* We always generate QMAGIC files in preference to ZMAGIC files.  It
46
   would be possible to make this a linker option, if that ever
47
   becomes important.  */
48
 
49
static void MY_final_link_callback
50
  PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
51
static boolean m68klinux_bfd_final_link
52
  PARAMS ((bfd *, struct bfd_link_info *));
53
static boolean m68klinux_write_object_contents PARAMS ((bfd *));
54
 
55
static boolean
56
m68klinux_bfd_final_link (abfd, info)
57
     bfd *abfd;
58
     struct bfd_link_info *info;
59
{
60
  obj_aout_subformat (abfd) = q_magic_format;
61
  return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
62
}
63
 
64
#define MY_bfd_final_link m68klinux_bfd_final_link
65
 
66
/* Set the machine type correctly.  */
67
 
68
static boolean
69
m68klinux_write_object_contents (abfd)
70
     bfd *abfd;
71
{
72
  struct external_exec exec_bytes;
73
  struct internal_exec *execp = exec_hdr (abfd);
74
 
75
  N_SET_MACHTYPE (*execp, M_68020);
76
 
77
  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
78
 
79
  WRITE_HEADERS(abfd, execp);
80
 
81
  return true;
82
}
83
 
84
#define MY_write_object_contents m68klinux_write_object_contents
85
 
86
/* Code to link against Linux a.out shared libraries.  */
87
 
88
/* See if a symbol name is a reference to the global offset table.  */
89
 
90
#ifndef GOT_REF_PREFIX
91
#define GOT_REF_PREFIX  "__GOT_"
92
#endif
93
 
94
#define IS_GOT_SYM(name) \
95
  (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
96
 
97
/* See if a symbol name is a reference to the procedure linkage table.  */
98
 
99
#ifndef PLT_REF_PREFIX
100
#define PLT_REF_PREFIX  "__PLT_"
101
#endif
102
 
103
#define IS_PLT_SYM(name) \
104
  (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
105
 
106
/* This string is used to generate specialized error messages.  */
107
 
108
#ifndef NEEDS_SHRLIB
109
#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
110
#endif
111
 
112
/* This special symbol is a set vector that contains a list of
113
   pointers to fixup tables.  It will be present in any dynamicly
114
   linked file.  The linker generated fixup table should also be added
115
   to the list, and it should always appear in the second slot (the
116
   first one is a dummy with a magic number that is defined in
117
   crt0.o).  */
118
 
119
#ifndef SHARABLE_CONFLICTS
120
#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
121
#endif
122
 
123
/* We keep a list of fixups.  The terminology is a bit strange, but
124
   each fixup contains two 32 bit numbers.  A regular fixup contains
125
   an address and a pointer, and at runtime we should store the
126
   address at the location pointed to by the pointer.  A builtin fixup
127
   contains two pointers, and we should read the address using one
128
   pointer and store it at the location pointed to by the other
129
   pointer.  Builtin fixups come into play when we have duplicate
130
   __GOT__ symbols for the same variable.  The builtin fixup will copy
131
   the GOT pointer from one over into the other.  */
132
 
133
struct fixup
134
{
135
  struct fixup *next;
136
  struct linux_link_hash_entry *h;
137
  bfd_vma value;
138
 
139
  /* Nonzero if this is a jump instruction that needs to be fixed,
140
     zero if this is just a pointer */
141
  char jump;
142
 
143
  char builtin;
144
};
145
 
146
/* We don't need a special hash table entry structure, but we do need
147
   to keep some information between linker passes, so we use a special
148
   hash table.  */
149
 
150
struct linux_link_hash_entry
151
{
152
  struct aout_link_hash_entry root;
153
};
154
 
155
struct linux_link_hash_table
156
{
157
  struct aout_link_hash_table root;
158
 
159
  /* First dynamic object found in link.  */
160
  bfd *dynobj;
161
 
162
  /* Number of fixups.  */
163
  size_t fixup_count;
164
 
165
  /* Number of builtin fixups.  */
166
  size_t local_builtins;
167
 
168
  /* List of fixups.  */
169
  struct fixup *fixup_list;
170
};
171
 
172
static struct bfd_hash_entry *linux_link_hash_newfunc
173
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
174
static struct bfd_link_hash_table *linux_link_hash_table_create
175
  PARAMS ((bfd *));
176
static struct fixup *new_fixup
177
  PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
178
           bfd_vma, int));
179
static boolean linux_link_create_dynamic_sections
180
  PARAMS ((bfd *, struct bfd_link_info *));
181
static boolean linux_add_one_symbol
182
  PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
183
           bfd_vma, const char *, boolean, boolean,
184
           struct bfd_link_hash_entry **));
185
static boolean linux_tally_symbols
186
  PARAMS ((struct linux_link_hash_entry *, PTR));
187
static boolean linux_finish_dynamic_link
188
  PARAMS ((bfd *, struct bfd_link_info *));
189
 
190
/* Routine to create an entry in an Linux link hash table.  */
191
 
192
static struct bfd_hash_entry *
193
linux_link_hash_newfunc (entry, table, string)
194
     struct bfd_hash_entry *entry;
195
     struct bfd_hash_table *table;
196
     const char *string;
197
{
198
  struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
199
 
200
  /* Allocate the structure if it has not already been allocated by a
201
     subclass.  */
202
  if (ret == (struct linux_link_hash_entry *) NULL)
203
    ret = ((struct linux_link_hash_entry *)
204
           bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
205
  if (ret == NULL)
206
    return (struct bfd_hash_entry *) ret;
207
 
208
  /* Call the allocation method of the superclass.  */
209
  ret = ((struct linux_link_hash_entry *)
210
         NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
211
                                       table, string));
212
  if (ret != NULL)
213
    {
214
      /* Set local fields; there aren't any.  */
215
    }
216
 
217
  return (struct bfd_hash_entry *) ret;
218
}
219
 
220
/* Create a Linux link hash table.  */
221
 
222
static struct bfd_link_hash_table *
223
linux_link_hash_table_create (abfd)
224
     bfd *abfd;
225
{
226
  struct linux_link_hash_table *ret;
227
 
228
  ret = ((struct linux_link_hash_table *)
229
         bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
230
  if (ret == (struct linux_link_hash_table *) NULL)
231
    {
232
      bfd_set_error (bfd_error_no_memory);
233
      return (struct bfd_link_hash_table *) NULL;
234
    }
235
  if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
236
                                         linux_link_hash_newfunc))
237
    {
238
      free (ret);
239
      return (struct bfd_link_hash_table *) NULL;
240
    }
241
 
242
  ret->dynobj = NULL;
243
  ret->fixup_count = 0;
244
  ret->local_builtins = 0;
245
  ret->fixup_list = NULL;
246
 
247
  return &ret->root.root;
248
}
249
 
250
/* Look up an entry in a Linux link hash table.  */
251
 
252
#define linux_link_hash_lookup(table, string, create, copy, follow) \
253
  ((struct linux_link_hash_entry *) \
254
   aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
255
                          (follow)))
256
 
257
/* Traverse a Linux link hash table.  */
258
 
259
#define linux_link_hash_traverse(table, func, info)                     \
260
  (aout_link_hash_traverse                                              \
261
   (&(table)->root,                                                     \
262
    (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
263
    (info)))
264
 
265
/* Get the Linux link hash table from the info structure.  This is
266
   just a cast.  */
267
 
268
#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
269
 
270
/* Store the information for a new fixup.  */
271
 
272
static struct fixup *
273
new_fixup (info, h, value, builtin)
274
     struct bfd_link_info *info;
275
     struct linux_link_hash_entry *h;
276
     bfd_vma value;
277
     int builtin;
278
{
279
  struct fixup *f;
280
 
281
  f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
282
                                          sizeof (struct fixup));
283
  if (f == NULL)
284
    return f;
285
  f->next = linux_hash_table (info)->fixup_list;
286
  linux_hash_table (info)->fixup_list = f;
287
  f->h = h;
288
  f->value = value;
289
  f->builtin = builtin;
290
  f->jump = 0;
291
  ++linux_hash_table (info)->fixup_count;
292
  return f;
293
}
294
 
295
/* We come here once we realize that we are going to link to a shared
296
   library.  We need to create a special section that contains the
297
   fixup table, and we ultimately need to add a pointer to this into
298
   the set vector for SHARABLE_CONFLICTS.  At this point we do not
299
   know the size of the section, but that's OK - we just need to
300
   create it for now.  */
301
 
302
static boolean
303
linux_link_create_dynamic_sections (abfd, info)
304
     bfd *abfd;
305
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
306
{
307
  flagword flags;
308
  register asection *s;
309
 
310
  /* Note that we set the SEC_IN_MEMORY flag.  */
311
  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
312
 
313
  /* We choose to use the name ".linux-dynamic" for the fixup table.
314
     Why not? */
315
  s = bfd_make_section (abfd, ".linux-dynamic");
316
  if (s == NULL
317
      || ! bfd_set_section_flags (abfd, s, flags)
318
      || ! bfd_set_section_alignment (abfd, s, 2))
319
    return false;
320
  s->_raw_size = 0;
321
  s->contents = 0;
322
 
323
  return true;
324
}
325
 
326
/* Function to add a single symbol to the linker hash table.  This is
327
   a wrapper around _bfd_generic_link_add_one_symbol which handles the
328
   tweaking needed for dynamic linking support.  */
329
 
330
static boolean
331
linux_add_one_symbol (info, abfd, name, flags, section, value, string,
332
                      copy, collect, hashp)
333
     struct bfd_link_info *info;
334
     bfd *abfd;
335
     const char *name;
336
     flagword flags;
337
     asection *section;
338
     bfd_vma value;
339
     const char *string;
340
     boolean copy;
341
     boolean collect;
342
     struct bfd_link_hash_entry **hashp;
343
{
344
  struct linux_link_hash_entry *h;
345
  boolean insert;
346
 
347
  /* Look up and see if we already have this symbol in the hash table.
348
     If we do, and the defining entry is from a shared library, we
349
     need to create the dynamic sections.
350
 
351
     FIXME: What if abfd->xvec != info->hash->creator?  We may want to
352
     be able to link Linux a.out and ELF objects together, but serious
353
     confusion is possible.  */
354
 
355
  insert = false;
356
 
357
  if (! info->relocateable
358
      && linux_hash_table (info)->dynobj == NULL
359
      && strcmp (name, SHARABLE_CONFLICTS) == 0
360
      && (flags & BSF_CONSTRUCTOR) != 0
361
      && abfd->xvec == info->hash->creator)
362
    {
363
      if (! linux_link_create_dynamic_sections (abfd, info))
364
        return false;
365
      linux_hash_table (info)->dynobj = abfd;
366
      insert = true;
367
    }
368
 
369
  if (bfd_is_abs_section (section)
370
      && abfd->xvec == info->hash->creator)
371
    {
372
      h = linux_link_hash_lookup (linux_hash_table (info), name, false,
373
                                  false, false);
374
      if (h != NULL
375
          && (h->root.root.type == bfd_link_hash_defined
376
              || h->root.root.type == bfd_link_hash_defweak))
377
        {
378
          struct fixup *f;
379
 
380
          if (hashp != NULL)
381
            *hashp = (struct bfd_link_hash_entry *) h;
382
 
383
          f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
384
          if (f == NULL)
385
            return false;
386
          f->jump = IS_PLT_SYM (name);
387
 
388
          return true;
389
        }
390
    }
391
 
392
  /* Do the usual procedure for adding a symbol.  */
393
  if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
394
                                          value, string, copy, collect,
395
                                          hashp))
396
    return false;
397
 
398
  /* Insert a pointer to our table in the set vector.  The dynamic
399
     linker requires this information */
400
  if (insert)
401
    {
402
      asection *s;
403
 
404
      /* Here we do our special thing to add the pointer to the
405
         dynamic section in the SHARABLE_CONFLICTS set vector.  */
406
      s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
407
                                   ".linux-dynamic");
408
      BFD_ASSERT (s != NULL);
409
 
410
      if (! (_bfd_generic_link_add_one_symbol
411
             (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
412
              BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL)))
413
        return false;
414
    }
415
 
416
  return true;
417
}
418
 
419
/* We will crawl the hash table and come here for every global symbol.
420
   We will examine each entry and see if there are indications that we
421
   need to add a fixup.  There are two possible cases - one is where
422
   you have duplicate definitions of PLT or GOT symbols - these will
423
   have already been caught and added as "builtin" fixups.  If we find
424
   that the corresponding non PLT/GOT symbol is also present, we
425
   convert it to a regular fixup instead.
426
 
427
   This function is called via linux_link_hash_traverse.  */
428
 
429
static boolean
430
linux_tally_symbols (h, data)
431
     struct linux_link_hash_entry *h;
432
     PTR data;
433
{
434
  struct bfd_link_info *info = (struct bfd_link_info *) data;
435
  struct fixup *f, *f1;
436
  int is_plt;
437
  struct linux_link_hash_entry *h1, *h2;
438
  boolean exists;
439
 
440
  if (h->root.root.type == bfd_link_hash_undefined
441
      && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
442
                  sizeof NEEDS_SHRLIB - 1) == 0)
443
    {
444
      const char *name;
445
      char *p;
446
      char *alloc = NULL;
447
 
448
      name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
449
      p = strrchr (name, '_');
450
      if (p != NULL)
451
        alloc = (char *) bfd_malloc (strlen (name) + 1);
452
 
453
      if (p == NULL || alloc == NULL)
454
        (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
455
                               name);
456
      else
457
        {
458
          strcpy (alloc, name);
459
          p = strrchr (alloc, '_');
460
          *p++ = '\0';
461
          (*_bfd_error_handler)
462
            (_("Output file requires shared library `%s.so.%s'\n"),
463
             alloc, p);
464
          free (alloc);
465
        }
466
 
467
      abort ();
468
    }
469
 
470
  /* If this symbol is not a PLT/GOT, we do not even need to look at it */
471
  is_plt = IS_PLT_SYM (h->root.root.root.string);
472
 
473
  if (is_plt || IS_GOT_SYM (h->root.root.root.string))
474
    {
475
      /* Look up this symbol twice.  Once just as a regular lookup,
476
         and then again following all of the indirect links until we
477
         reach a real symbol.  */
478
      h1 = linux_link_hash_lookup (linux_hash_table (info),
479
                                   (h->root.root.root.string
480
                                    + sizeof PLT_REF_PREFIX - 1),
481
                                   false, false, true);
482
      /* h2 does not follow indirect symbols.  */
483
      h2 = linux_link_hash_lookup (linux_hash_table (info),
484
                                   (h->root.root.root.string
485
                                    + sizeof PLT_REF_PREFIX - 1),
486
                                   false, false, false);
487
 
488
      /* The real symbol must exist but if it is also an ABS symbol,
489
         there is no need to have a fixup.  This is because they both
490
         came from the same library.  If on the other hand, we had to
491
         use an indirect symbol to get to the real symbol, we add the
492
         fixup anyway, since there are cases where these symbols come
493
         from different shared libraries */
494
      if (h1 != NULL
495
          && (((h1->root.root.type == bfd_link_hash_defined
496
                || h1->root.root.type == bfd_link_hash_defweak)
497
               && ! bfd_is_abs_section (h1->root.root.u.def.section))
498
              || h2->root.root.type == bfd_link_hash_indirect))
499
        {
500
          /* See if there is a "builtin" fixup already present
501
             involving this symbol.  If so, convert it to a regular
502
             fixup.  In the end, this relaxes some of the requirements
503
             about the order of performing fixups.  */
504
          exists = false;
505
          for (f1 = linux_hash_table (info)->fixup_list;
506
               f1 != NULL;
507
               f1 = f1->next)
508
            {
509
              if ((f1->h != h && f1->h != h1)
510
                  || (! f1->builtin && ! f1->jump))
511
                continue;
512
              if (f1->h == h1)
513
                exists = true;
514
              if (! exists
515
                  && bfd_is_abs_section (h->root.root.u.def.section))
516
                {
517
                  f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
518
                  f->jump = is_plt;
519
                }
520
              f1->h = h1;
521
              f1->jump = is_plt;
522
              f1->builtin = 0;
523
              exists = true;
524
            }
525
          if (! exists
526
              && bfd_is_abs_section (h->root.root.u.def.section))
527
            {
528
              f = new_fixup (info, h1, h->root.root.u.def.value, 0);
529
              if (f == NULL)
530
                {
531
                  /* FIXME: No way to return error.  */
532
                  abort ();
533
                }
534
              f->jump = is_plt;
535
            }
536
        }
537
 
538
      /* Quick and dirty way of stripping these symbols from the
539
         symtab.  */
540
      if (bfd_is_abs_section (h->root.root.u.def.section))
541
        h->root.written = true;
542
    }
543
 
544
  return true;
545
}
546
 
547
/* This is called to set the size of the .linux-dynamic section is.
548
   It is called by the Linux linker emulation before_allocation
549
   routine.  We have finished reading all of the input files, and now
550
   we just scan the hash tables to find out how many additional fixups
551
   are required.  */
552
 
553
boolean
554
bfd_m68klinux_size_dynamic_sections (output_bfd, info)
555
     bfd *output_bfd;
556
     struct bfd_link_info *info;
557
{
558
  struct fixup *f;
559
  asection *s;
560
 
561
  if (output_bfd->xvec != &MY(vec))
562
    return true;
563
 
564
  /* First find the fixups...  */
565
  linux_link_hash_traverse (linux_hash_table (info),
566
                            linux_tally_symbols,
567
                            (PTR) info);
568
 
569
  /* If there are builtin fixups, leave room for a marker.  This is
570
     used by the dynamic linker so that it knows that all that follow
571
     are builtin fixups instead of regular fixups.  */
572
  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
573
    {
574
      if (f->builtin)
575
        {
576
          ++linux_hash_table (info)->fixup_count;
577
          ++linux_hash_table (info)->local_builtins;
578
          break;
579
        }
580
    }
581
 
582
  if (linux_hash_table (info)->dynobj == NULL)
583
    {
584
      if (linux_hash_table (info)->fixup_count > 0)
585
        abort ();
586
      return true;
587
    }
588
 
589
  /* Allocate memory for our fixup table.  We will fill it in later.  */
590
  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
591
                               ".linux-dynamic");
592
  if (s != NULL)
593
    {
594
      s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
595
      s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
596
      if (s->contents == NULL)
597
        {
598
          bfd_set_error (bfd_error_no_memory);
599
          return false;
600
        }
601
      memset (s->contents, 0, (size_t) s->_raw_size);
602
    }
603
 
604
  return true;
605
}
606
 
607
/* We come here once we are ready to actually write the fixup table to
608
   the output file.  Scan the fixup tables and so forth and generate
609
   the stuff we need.  */
610
 
611
static boolean
612
linux_finish_dynamic_link (output_bfd, info)
613
     bfd *output_bfd;
614
     struct bfd_link_info *info;
615
{
616
  asection *s, *os, *is;
617
  bfd_byte *fixup_table;
618
  struct linux_link_hash_entry *h;
619
  struct fixup *f;
620
  unsigned int new_addr;
621
  int section_offset;
622
  unsigned int fixups_written;
623
 
624
  if (linux_hash_table (info)->dynobj == NULL)
625
    return true;
626
 
627
  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
628
                               ".linux-dynamic");
629
  BFD_ASSERT (s != NULL);
630
  os = s->output_section;
631
  fixups_written = 0;
632
 
633
#ifdef LINUX_LINK_DEBUG
634
  printf ("Fixup table file offset: %x  VMA: %x\n",
635
          os->filepos + s->output_offset,
636
          os->vma + s->output_offset);
637
#endif
638
 
639
  fixup_table = s->contents;
640
  bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table);
641
  fixup_table += 4;
642
 
643
  /* Fill in fixup table.  */
644
  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
645
    {
646
      if (f->builtin)
647
        continue;
648
 
649
      if (f->h->root.root.type != bfd_link_hash_defined
650
          && f->h->root.root.type != bfd_link_hash_defweak)
651
        {
652
          (*_bfd_error_handler)
653
            (_("Symbol %s not defined for fixups\n"),
654
             f->h->root.root.root.string);
655
          continue;
656
        }
657
 
658
      is = f->h->root.root.u.def.section;
659
      section_offset = is->output_section->vma + is->output_offset;
660
      new_addr = f->h->root.root.u.def.value + section_offset;
661
 
662
#ifdef LINUX_LINK_DEBUG
663
      printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
664
              new_addr, f->value);
665
#endif
666
 
667
      if (f->jump)
668
        {
669
          bfd_put_32 (output_bfd, new_addr, fixup_table);
670
          fixup_table += 4;
671
          bfd_put_32 (output_bfd, f->value + 2, fixup_table);
672
          fixup_table += 4;
673
        }
674
      else
675
        {
676
          bfd_put_32 (output_bfd, new_addr, fixup_table);
677
          fixup_table += 4;
678
          bfd_put_32 (output_bfd, f->value, fixup_table);
679
          fixup_table += 4;
680
        }
681
      ++fixups_written;
682
    }
683
 
684
  if (linux_hash_table (info)->local_builtins != 0)
685
    {
686
      /* Special marker so we know to switch to the other type of fixup */
687
      bfd_put_32 (output_bfd, 0, fixup_table);
688
      fixup_table += 4;
689
      bfd_put_32 (output_bfd, 0, fixup_table);
690
      fixup_table += 4;
691
      ++fixups_written;
692
      for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
693
        {
694
          if (! f->builtin)
695
            continue;
696
 
697
          if (f->h->root.root.type != bfd_link_hash_defined
698
              && f->h->root.root.type != bfd_link_hash_defweak)
699
            {
700
              (*_bfd_error_handler)
701
                (_("Symbol %s not defined for fixups\n"),
702
                 f->h->root.root.root.string);
703
              continue;
704
            }
705
 
706
          is = f->h->root.root.u.def.section;
707
          section_offset = is->output_section->vma + is->output_offset;
708
          new_addr = f->h->root.root.u.def.value + section_offset;
709
 
710
#ifdef LINUX_LINK_DEBUG
711
          printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
712
                  new_addr, f->value);
713
#endif
714
 
715
          bfd_put_32 (output_bfd, new_addr, fixup_table);
716
          fixup_table += 4;
717
          bfd_put_32 (output_bfd, f->value, fixup_table);
718
          fixup_table += 4;
719
          ++fixups_written;
720
        }
721
  }
722
 
723
  if (linux_hash_table (info)->fixup_count != fixups_written)
724
    {
725
      (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
726
      while (linux_hash_table (info)->fixup_count > fixups_written)
727
        {
728
          bfd_put_32 (output_bfd, 0, fixup_table);
729
          fixup_table += 4;
730
          bfd_put_32 (output_bfd, 0, fixup_table);
731
          fixup_table += 4;
732
          ++fixups_written;
733
        }
734
    }
735
 
736
  h = linux_link_hash_lookup (linux_hash_table (info),
737
                              "__BUILTIN_FIXUPS__",
738
                              false, false, false);
739
 
740
  if (h != NULL
741
      && (h->root.root.type == bfd_link_hash_defined
742
          || h->root.root.type == bfd_link_hash_defweak))
743
    {
744
      is = h->root.root.u.def.section;
745
      section_offset = is->output_section->vma + is->output_offset;
746
      new_addr = h->root.root.u.def.value + section_offset;
747
 
748
#ifdef LINUX_LINK_DEBUG
749
      printf ("Builtin fixup table at %x\n", new_addr);
750
#endif
751
 
752
      bfd_put_32 (output_bfd, new_addr, fixup_table);
753
    }
754
  else
755
    bfd_put_32 (output_bfd, 0, fixup_table);
756
 
757
  if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)
758
    return false;
759
 
760
  if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd)
761
      != s->_raw_size)
762
    return false;
763
 
764
  return true;
765
}
766
 
767
#define MY_bfd_link_hash_table_create linux_link_hash_table_create
768
#define MY_add_one_symbol linux_add_one_symbol
769
#define MY_finish_dynamic_link linux_finish_dynamic_link
770
 
771
#define MY_zmagic_contiguous 1
772
 
773
#include "aout-target.h"

powered by: WebSVN 2.1.0

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