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

« back to all changes in this revision

Viewing changes to binutils/bfd/m68klinux.c

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

Show diffs side-by-side

added added

removed removed

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