i386linux.c (78828) | i386linux.c (89857) |
---|---|
1/* BFD back-end for linux flavored i386 a.out binaries. | 1/* BFD back-end for linux flavored i386 a.out binaries. |
2 Copyright 1992, 1993, 1994, 1995, 1996, 1997 | 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2001 |
3 Free Software Foundation, Inc. 4 5This file is part of BFD, the Binary File Descriptor library. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2 of the License, or 10(at your option) any later version. --- 20 unchanged lines hidden (view full) --- 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 DEFAULT_ARCH bfd_arch_i386 | 3 Free Software Foundation, Inc. 4 5This file is part of BFD, the Binary File Descriptor library. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2 of the License, or 10(at your option) any later version. --- 20 unchanged lines hidden (view full) --- 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 DEFAULT_ARCH bfd_arch_i386 |
39#define MY(OP) CAT(i386linux_,OP) | 39 40/* Do not "beautify" the CONCAT* macro args. Traditional C will not 41 remove whitespace added here, and thus will fail to concatenate 42 the tokens. */ 43#define MY(OP) CONCAT2 (i386linux_,OP) |
40#define TARGETNAME "a.out-i386-linux" 41 42extern const bfd_target MY(vec); 43 44/* We always generate QMAGIC files in preference to ZMAGIC files. It 45 would be possible to make this a linker option, if that ever 46 becomes important. */ 47 --- 170 unchanged lines hidden (view full) --- 218 219/* Create a Linux link hash table. */ 220 221static struct bfd_link_hash_table * 222linux_link_hash_table_create (abfd) 223 bfd *abfd; 224{ 225 struct linux_link_hash_table *ret; | 44#define TARGETNAME "a.out-i386-linux" 45 46extern const bfd_target MY(vec); 47 48/* We always generate QMAGIC files in preference to ZMAGIC files. It 49 would be possible to make this a linker option, if that ever 50 becomes important. */ 51 --- 170 unchanged lines hidden (view full) --- 222 223/* Create a Linux link hash table. */ 224 225static struct bfd_link_hash_table * 226linux_link_hash_table_create (abfd) 227 bfd *abfd; 228{ 229 struct linux_link_hash_table *ret; |
230 bfd_size_type amt = sizeof (struct linux_link_hash_table); |
|
226 | 231 |
227 ret = ((struct linux_link_hash_table *) 228 bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); | 232 ret = (struct linux_link_hash_table *) bfd_alloc (abfd, amt); |
229 if (ret == (struct linux_link_hash_table *) NULL) 230 return (struct bfd_link_hash_table *) NULL; 231 if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, 232 linux_link_hash_newfunc)) 233 { 234 free (ret); 235 return (struct bfd_link_hash_table *) NULL; 236 } --- 163 unchanged lines hidden (view full) --- 400 /* Here we do our special thing to add the pointer to the 401 dynamic section in the SHARABLE_CONFLICTS set vector. */ 402 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 403 ".linux-dynamic"); 404 BFD_ASSERT (s != NULL); 405 406 if (! (_bfd_generic_link_add_one_symbol 407 (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, | 233 if (ret == (struct linux_link_hash_table *) NULL) 234 return (struct bfd_link_hash_table *) NULL; 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 } --- 163 unchanged lines hidden (view full) --- 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, |
408 BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) | 412 BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL, 413 false, false, NULL))) |
409 return false; 410 } 411 412 return true; 413} 414 415/* We will crawl the hash table and come here for every global symbol. 416 We will examine each entry and see if there are indications that we --- 22 unchanged lines hidden (view full) --- 439 { 440 const char *name; 441 char *p; 442 char *alloc = NULL; 443 444 name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; 445 p = strrchr (name, '_'); 446 if (p != NULL) | 414 return false; 415 } 416 417 return true; 418} 419 420/* We will crawl the hash table and come here for every global symbol. 421 We will examine each entry and see if there are indications that we --- 22 unchanged lines hidden (view full) --- 444 { 445 const char *name; 446 char *p; 447 char *alloc = NULL; 448 449 name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; 450 p = strrchr (name, '_'); 451 if (p != NULL) |
447 alloc = (char *) bfd_malloc (strlen (name) + 1); | 452 alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1); |
448 449 if (p == NULL || alloc == NULL) 450 (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"), 451 name); 452 else 453 { 454 strcpy (alloc, name); 455 p = strrchr (alloc, '_'); --- 15 unchanged lines hidden (view full) --- 471 /* Look up this symbol twice. Once just as a regular lookup, 472 and then again following all of the indirect links until we 473 reach a real symbol. */ 474 h1 = linux_link_hash_lookup (linux_hash_table (info), 475 (h->root.root.root.string 476 + sizeof PLT_REF_PREFIX - 1), 477 false, false, true); 478 /* h2 does not follow indirect symbols. */ | 453 454 if (p == NULL || alloc == NULL) 455 (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"), 456 name); 457 else 458 { 459 strcpy (alloc, name); 460 p = strrchr (alloc, '_'); --- 15 unchanged lines hidden (view full) --- 476 /* Look up this symbol twice. Once just as a regular lookup, 477 and then again following all of the indirect links until we 478 reach a real symbol. */ 479 h1 = linux_link_hash_lookup (linux_hash_table (info), 480 (h->root.root.root.string 481 + sizeof PLT_REF_PREFIX - 1), 482 false, false, true); 483 /* h2 does not follow indirect symbols. */ |
479 h2 = linux_link_hash_lookup (linux_hash_table (info), | 484 h2 = linux_link_hash_lookup (linux_hash_table (info), |
480 (h->root.root.root.string 481 + sizeof PLT_REF_PREFIX - 1), 482 false, false, false); 483 484 /* The real symbol must exist but if it is also an ABS symbol, 485 there is no need to have a fixup. This is because they both 486 came from the same library. If on the other hand, we had to 487 use an indirect symbol to get to the real symbol, we add the --- 94 unchanged lines hidden (view full) --- 582 return true; 583 } 584 585 /* Allocate memory for our fixup table. We will fill it in later. */ 586 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 587 ".linux-dynamic"); 588 if (s != NULL) 589 { | 485 (h->root.root.root.string 486 + sizeof PLT_REF_PREFIX - 1), 487 false, false, false); 488 489 /* The real symbol must exist but if it is also an ABS symbol, 490 there is no need to have a fixup. This is because they both 491 came from the same library. If on the other hand, we had to 492 use an indirect symbol to get to the real symbol, we add the --- 94 unchanged lines hidden (view full) --- 587 return true; 588 } 589 590 /* Allocate memory for our fixup table. We will fill it in later. */ 591 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 592 ".linux-dynamic"); 593 if (s != NULL) 594 { |
590 s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; | 595 s->_raw_size = linux_hash_table (info)->fixup_count + 1; 596 s->_raw_size *= 8; |
591 s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); 592 if (s->contents == NULL) 593 return false; 594 memset (s->contents, 0, (size_t) s->_raw_size); 595 } 596 597 return true; 598} --- 20 unchanged lines hidden (view full) --- 619 620 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 621 ".linux-dynamic"); 622 BFD_ASSERT (s != NULL); 623 os = s->output_section; 624 fixups_written = 0; 625 626#ifdef LINUX_LINK_DEBUG | 597 s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); 598 if (s->contents == NULL) 599 return false; 600 memset (s->contents, 0, (size_t) s->_raw_size); 601 } 602 603 return true; 604} --- 20 unchanged lines hidden (view full) --- 625 626 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 627 ".linux-dynamic"); 628 BFD_ASSERT (s != NULL); 629 os = s->output_section; 630 fixups_written = 0; 631 632#ifdef LINUX_LINK_DEBUG |
627 printf ("Fixup table file offset: %x VMA: %x\n", | 633 printf ("Fixup table file offset: %x VMA: %x\n", |
628 os->filepos + s->output_offset, 629 os->vma + s->output_offset); 630#endif 631 632 fixup_table = s->contents; | 634 os->filepos + s->output_offset, 635 os->vma + s->output_offset); 636#endif 637 638 fixup_table = s->contents; |
633 bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); | 639 bfd_put_32 (output_bfd, 640 (bfd_vma) linux_hash_table (info)->fixup_count, fixup_table); |
634 fixup_table += 4; 635 636 /* Fill in fixup table. */ 637 for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) 638 { 639 if (f->builtin) 640 continue; 641 --- 13 unchanged lines hidden (view full) --- 655#ifdef LINUX_LINK_DEBUG 656 printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, 657 new_addr, f->value); 658#endif 659 660 if (f->jump) 661 { 662 /* Relative address */ | 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 --- 13 unchanged lines hidden (view full) --- 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 /* Relative address */ |
663 new_addr = new_addr - (f->value + 5); 664 bfd_put_32 (output_bfd, new_addr, fixup_table); | 670 new_addr = new_addr - (f->value + 5); 671 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); |
665 fixup_table += 4; 666 bfd_put_32 (output_bfd, f->value + 1, fixup_table); 667 fixup_table += 4; 668 } 669 else 670 { | 672 fixup_table += 4; 673 bfd_put_32 (output_bfd, f->value + 1, fixup_table); 674 fixup_table += 4; 675 } 676 else 677 { |
671 bfd_put_32 (output_bfd, new_addr, fixup_table); | 678 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); |
672 fixup_table += 4; 673 bfd_put_32 (output_bfd, f->value, fixup_table); 674 fixup_table += 4; 675 } 676 ++fixups_written; 677 } 678 679 if (linux_hash_table (info)->local_builtins != 0) 680 { 681 /* Special marker so we know to switch to the other type of fixup */ | 679 fixup_table += 4; 680 bfd_put_32 (output_bfd, f->value, fixup_table); 681 fixup_table += 4; 682 } 683 ++fixups_written; 684 } 685 686 if (linux_hash_table (info)->local_builtins != 0) 687 { 688 /* Special marker so we know to switch to the other type of fixup */ |
682 bfd_put_32 (output_bfd, 0, fixup_table); | 689 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); |
683 fixup_table += 4; | 690 fixup_table += 4; |
684 bfd_put_32 (output_bfd, 0, fixup_table); | 691 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); |
685 fixup_table += 4; 686 ++fixups_written; 687 for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) 688 { 689 if (! f->builtin) 690 continue; 691 692 if (f->h->root.root.type != bfd_link_hash_defined --- 9 unchanged lines hidden (view full) --- 702 section_offset = is->output_section->vma + is->output_offset; 703 new_addr = f->h->root.root.u.def.value + section_offset; 704 705#ifdef LINUX_LINK_DEBUG 706 printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, 707 new_addr, f->value); 708#endif 709 | 692 fixup_table += 4; 693 ++fixups_written; 694 for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) 695 { 696 if (! f->builtin) 697 continue; 698 699 if (f->h->root.root.type != bfd_link_hash_defined --- 9 unchanged lines hidden (view full) --- 709 section_offset = is->output_section->vma + is->output_offset; 710 new_addr = f->h->root.root.u.def.value + section_offset; 711 712#ifdef LINUX_LINK_DEBUG 713 printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, 714 new_addr, f->value); 715#endif 716 |
710 bfd_put_32 (output_bfd, new_addr, fixup_table); | 717 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); |
711 fixup_table += 4; 712 bfd_put_32 (output_bfd, f->value, fixup_table); 713 fixup_table += 4; 714 ++fixups_written; 715 } 716 } 717 718 if (linux_hash_table (info)->fixup_count != fixups_written) 719 { 720 (*_bfd_error_handler) (_("Warning: fixup count mismatch\n")); 721 while (linux_hash_table (info)->fixup_count > fixups_written) 722 { | 718 fixup_table += 4; 719 bfd_put_32 (output_bfd, f->value, fixup_table); 720 fixup_table += 4; 721 ++fixups_written; 722 } 723 } 724 725 if (linux_hash_table (info)->fixup_count != fixups_written) 726 { 727 (*_bfd_error_handler) (_("Warning: fixup count mismatch\n")); 728 while (linux_hash_table (info)->fixup_count > fixups_written) 729 { |
723 bfd_put_32 (output_bfd, 0, fixup_table); | 730 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); |
724 fixup_table += 4; | 731 fixup_table += 4; |
725 bfd_put_32 (output_bfd, 0, fixup_table); | 732 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); |
726 fixup_table += 4; 727 ++fixups_written; 728 } 729 } 730 | 733 fixup_table += 4; 734 ++fixups_written; 735 } 736 } 737 |
731 h = linux_link_hash_lookup (linux_hash_table (info), | 738 h = linux_link_hash_lookup (linux_hash_table (info), |
732 "__BUILTIN_FIXUPS__", 733 false, false, false); 734 735 if (h != NULL 736 && (h->root.root.type == bfd_link_hash_defined 737 || h->root.root.type == bfd_link_hash_defweak)) 738 { 739 is = h->root.root.u.def.section; 740 section_offset = is->output_section->vma + is->output_offset; 741 new_addr = h->root.root.u.def.value + section_offset; 742 743#ifdef LINUX_LINK_DEBUG 744 printf ("Builtin fixup table at %x\n", new_addr); 745#endif 746 | 739 "__BUILTIN_FIXUPS__", 740 false, false, false); 741 742 if (h != NULL 743 && (h->root.root.type == bfd_link_hash_defined 744 || h->root.root.type == bfd_link_hash_defweak)) 745 { 746 is = h->root.root.u.def.section; 747 section_offset = is->output_section->vma + is->output_offset; 748 new_addr = h->root.root.u.def.value + section_offset; 749 750#ifdef LINUX_LINK_DEBUG 751 printf ("Builtin fixup table at %x\n", new_addr); 752#endif 753 |
747 bfd_put_32 (output_bfd, new_addr, fixup_table); | 754 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); |
748 } 749 else | 755 } 756 else |
750 bfd_put_32 (output_bfd, 0, fixup_table); | 757 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); |
751 | 758 |
752 if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0) | 759 if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset), 760 SEEK_SET) != 0) |
753 return false; 754 | 761 return false; 762 |
755 if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) 756 != s->_raw_size) | 763 if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd) != s->_raw_size) |
757 return false; 758 759 return true; 760} 761 762#define MY_bfd_link_hash_table_create linux_link_hash_table_create 763#define MY_add_one_symbol linux_add_one_symbol 764#define MY_finish_dynamic_link linux_finish_dynamic_link 765 766#define MY_zmagic_contiguous 1 767 768#include "aout-target.h" | 764 return false; 765 766 return true; 767} 768 769#define MY_bfd_link_hash_table_create linux_link_hash_table_create 770#define MY_add_one_symbol linux_add_one_symbol 771#define MY_finish_dynamic_link linux_finish_dynamic_link 772 773#define MY_zmagic_contiguous 1 774 775#include "aout-target.h" |