X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fi386linux.c;h=ebc938857d810a904c823d787f55b4533a8e7fa7;hb=aca736871c2567ee38bd285afdff62d6339790e4;hp=5390b425af7f221f9846088a4c30c3a275579591;hpb=04003b573d29aabc3f33ca218fb6d998324e42b7;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/i386linux.c b/bfd/i386linux.c index 5390b425af..ebc938857d 100644 --- a/bfd/i386linux.c +++ b/bfd/i386linux.c @@ -1,5 +1,5 @@ /* BFD back-end for linux flavored i386 a.out binaries. - Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -15,14 +15,13 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define PAGE_SIZE 4096 #define ZMAGIC_DISK_BLOCK_SIZE 1024 #define SEGMENT_SIZE 4096 #define TEXT_START_ADDR 0x0 #define N_SHARED_LIB(x) 0 -#define ARCH 32 #define BYTES_IN_WORD 4 #include "bfd.h" @@ -35,7 +34,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define DEFAULT_ARCH bfd_arch_i386 #define MY(OP) CAT(i386linux_,OP) -#define MY_text_includes_header 1 #define TARGETNAME "a.out-i386-linux" /* We always generate QMAGIC files in preference to ZMAGIC files. It @@ -96,6 +94,12 @@ i386linux_write_object_contents (abfd) #define IS_PLT_SYM(name) \ (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0) +/* This string is used to generate specialized error messages. */ + +#ifndef NEEDS_SHRLIB +#define NEEDS_SHRLIB "__NEEDS_SHRLIB_" +#endif + /* This special symbol is a set vector that contains a list of pointers to fixup tables. It will be present in any dynamicly linked file. The linker generated fixup table should also be added @@ -213,7 +217,7 @@ linux_link_hash_table_create (abfd) struct linux_link_hash_table *ret; ret = ((struct linux_link_hash_table *) - malloc (sizeof (struct linux_link_hash_table))); + bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); if (ret == (struct linux_link_hash_table *) NULL) { bfd_set_error (bfd_error_no_memory); @@ -297,9 +301,9 @@ linux_link_create_dynamic_sections (abfd, info) /* Note that we set the SEC_IN_MEMORY flag. */ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - /* We choose to use the name ".dynamic" for the fixup table. Why - not? */ - s = bfd_make_section (abfd, ".dynamic"); + /* We choose to use the name ".linux-dynamic" for the fixup table. + Why not? */ + s = bfd_make_section (abfd, ".linux-dynamic"); if (s == NULL || ! bfd_set_section_flags (abfd, s, flags) || ! bfd_set_section_alignment (abfd, s, 2)) @@ -343,7 +347,9 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string, if (! info->relocateable && linux_hash_table (info)->dynobj == NULL - && strcmp (name, SHARABLE_CONFLICTS) == 0) + && strcmp (name, SHARABLE_CONFLICTS) == 0 + && (flags & BSF_CONSTRUCTOR) != 0 + && abfd->xvec == info->hash->creator) { if (! linux_link_create_dynamic_sections (abfd, info)) return false; @@ -351,20 +357,27 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string, insert = true; } - if (section == &bfd_abs_section - && (IS_GOT_SYM (name) || IS_PLT_SYM (name))) + if (bfd_is_abs_section (section) + && abfd->xvec == info->hash->creator) { h = linux_link_hash_lookup (linux_hash_table (info), name, false, false, false); if (h != NULL - && h->root.root.type == bfd_link_hash_defined) + && (h->root.root.type == bfd_link_hash_defined + || h->root.root.type == bfd_link_hash_defweak)) { - if (new_fixup (info, h, value, ! IS_PLT_SYM(name)) == NULL) + struct fixup *f; + + if (hashp != NULL) + *hashp = (struct bfd_link_hash_entry *) h; + + f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); + if (f == NULL) return false; + f->jump = IS_PLT_SYM (name); + return true; } - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; } /* Do the usual procedure for adding a symbol. */ @@ -382,7 +395,7 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string, /* Here we do our special thing to add the pointer to the dynamic section in the SHARABLE_CONFLICTS set vector. */ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".dynamic"); + ".linux-dynamic"); BFD_ASSERT (s != NULL); if (! (_bfd_generic_link_add_one_symbol @@ -413,6 +426,37 @@ linux_tally_symbols (h, data) struct fixup *f, *f1; int is_plt; struct linux_link_hash_entry *h1, *h2; + boolean exists; + + if (h->root.root.type == bfd_link_hash_undefined + && strncmp (h->root.root.root.string, NEEDS_SHRLIB, + sizeof NEEDS_SHRLIB - 1) == 0) + { + const char *name; + char *p; + char *alloc = NULL; + + name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; + p = strrchr (name, '_'); + if (p != NULL) + alloc = (char *) malloc (strlen (name) + 1); + + /* FIXME! BFD should not call printf! */ + if (p == NULL || alloc == NULL) + fprintf (stderr, "Output file requires shared library `%s'\n", name); + else + { + strcpy (alloc, name); + p = strrchr (alloc, '_'); + *p++ = '\0'; + fprintf (stderr, + "Output file requires shared library `%s.so.%s'\n", + alloc, p); + free (alloc); + } + + abort (); + } /* If this symbol is not a PLT/GOT, we do not even need to look at it */ is_plt = IS_PLT_SYM (h->root.root.root.string); @@ -439,49 +483,63 @@ linux_tally_symbols (h, data) fixup anyway, since there are cases where these symbols come from different shared libraries */ if (h1 != NULL - && ((h1->root.root.type == bfd_link_hash_defined - && h1->root.root.u.def.section != &bfd_abs_section) + && (((h1->root.root.type == bfd_link_hash_defined + || h1->root.root.type == bfd_link_hash_defweak) + && ! bfd_is_abs_section (h1->root.root.u.def.section)) || h2->root.root.type == bfd_link_hash_indirect)) { - f = new_fixup (info, h1, h->root.root.u.def.value, 0); - if (f == NULL) - { - /* FIXME: No way to return error. */ - abort (); - } - f->jump = is_plt; - /* See if there is a "builtin" fixup already present involving this symbol. If so, convert it to a regular fixup. In the end, this relaxes some of the requirements about the order of performing fixups. */ + exists = false; for (f1 = linux_hash_table (info)->fixup_list; f1 != NULL; f1 = f1->next) { - if (f1 == f) - continue; - if (f1->h != h) + if ((f1->h != h && f1->h != h1) + || (! f1->builtin && ! f1->jump)) continue; + if (f1->h == h1) + exists = true; + if (! exists + && bfd_is_abs_section (h->root.root.u.def.section)) + { + f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); + f->jump = is_plt; + } f1->h = h1; f1->jump = is_plt; f1->builtin = 0; + exists = true; + } + if (! exists + && bfd_is_abs_section (h->root.root.u.def.section)) + { + f = new_fixup (info, h1, h->root.root.u.def.value, 0); + if (f == NULL) + { + /* FIXME: No way to return error. */ + abort (); + } + f->jump = is_plt; } } /* Quick and dirty way of stripping these symbols from the symtab. */ - h->root.written = true; + if (bfd_is_abs_section (h->root.root.u.def.section)) + h->root.written = true; } return true; } -/* This is called to set the size of the .dynamic section is. It is - called by the Linux linker emulation before_allocation routine. We - have finished reading all of the input files, and now we just scan - the hash tables to find out how many additional fixups are - required. */ +/* This is called to set the size of the .linux-dynamic section is. + It is called by the Linux linker emulation before_allocation + routine. We have finished reading all of the input files, and now + we just scan the hash tables to find out how many additional fixups + are required. */ boolean bfd_linux_size_dynamic_sections (output_bfd, info) @@ -517,7 +575,8 @@ bfd_linux_size_dynamic_sections (output_bfd, info) } /* Allocate memory for our fixup table. We will fill it in later. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, ".dynamic"); + s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, + ".linux-dynamic"); if (s != NULL) { s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; @@ -527,7 +586,7 @@ bfd_linux_size_dynamic_sections (output_bfd, info) bfd_set_error (bfd_error_no_memory); return false; } - memset (s->contents, 0, s->_raw_size); + memset (s->contents, 0, (size_t) s->_raw_size); } return true; @@ -548,12 +607,13 @@ linux_finish_dynamic_link (output_bfd, info) struct fixup *f; unsigned int new_addr; int section_offset; - int fixups_written; + unsigned int fixups_written; if (linux_hash_table (info)->dynobj == NULL) return true; - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, ".dynamic"); + s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, + ".linux-dynamic"); BFD_ASSERT (s != NULL); os = s->output_section; fixups_written = 0; @@ -574,7 +634,8 @@ linux_finish_dynamic_link (output_bfd, info) if (f->builtin) continue; - if (f->h->root.root.type != bfd_link_hash_defined) + if (f->h->root.root.type != bfd_link_hash_defined + && f->h->root.root.type != bfd_link_hash_defweak) { /* FIXME! */ fprintf (stderr, @@ -624,7 +685,8 @@ linux_finish_dynamic_link (output_bfd, info) if (! f->builtin) continue; - if (f->h->root.root.type != bfd_link_hash_defined) + if (f->h->root.root.type != bfd_link_hash_defined + && f->h->root.root.type != bfd_link_hash_defweak) { /* FIXME! */ fprintf (stderr, @@ -668,7 +730,9 @@ linux_finish_dynamic_link (output_bfd, info) "__BUILTIN_FIXUPS__", false, false, false); - if (h != NULL && h->root.root.type == bfd_link_hash_defined) + if (h != NULL + && (h->root.root.type == bfd_link_hash_defined + || h->root.root.type == bfd_link_hash_defweak)) { is = h->root.root.u.def.section; section_offset = is->output_section->vma + is->output_offset; @@ -697,4 +761,6 @@ linux_finish_dynamic_link (output_bfd, info) #define MY_add_one_symbol linux_add_one_symbol #define MY_finish_dynamic_link linux_finish_dynamic_link +#define MY_zmagic_contiguous 1 + #include "aout-target.h"