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