/[gcl]/gcl/binutils/bfd/sparclinux.c
ViewVC logotype

Diff of /gcl/binutils/bfd/sparclinux.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:35:47 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:15 2005 UTC
# Line 1  Line 1 
1  /* BFD back-end for linux flavored sparc a.out binaries.  /* BFD back-end for linux flavored sparc a.out binaries.
2     Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002     Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
3     Free Software Foundation, Inc.     2003, 2004 Free Software Foundation, Inc.
4    
5  This file is part of BFD, the Binary File Descriptor library.  This file is part of BFD, the Binary File Descriptor library.
6    
# Line 19  along with this program; if not, write t Line 19  along with this program; if not, write t
19  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20  USA.  */  USA.  */
21    
22  #define TARGET_PAGE_SIZE        4096  #define TARGET_PAGE_SIZE        4096
23  #define ZMAGIC_DISK_BLOCK_SIZE 1024  #define ZMAGIC_DISK_BLOCK_SIZE  1024
24  #define SEGMENT_SIZE TARGET_PAGE_SIZE  #define SEGMENT_SIZE            TARGET_PAGE_SIZE
25  #define TEXT_START_ADDR        0x0  #define TEXT_START_ADDR         0x0
26  #define N_SHARED_LIB(x) 0  #define N_SHARED_LIB(x)         0
 #define BYTES_IN_WORD 4  
27    
28  #define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)  #define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)
29    
# Line 52  extern const bfd_target MY(vec); Line 51  extern const bfd_target MY(vec);
51  static void MY_final_link_callback  static void MY_final_link_callback
52    PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));    PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
53    
54  static boolean sparclinux_bfd_final_link  static bfd_boolean sparclinux_bfd_final_link
55    PARAMS ((bfd *abfd, struct bfd_link_info *info));    PARAMS ((bfd *abfd, struct bfd_link_info *info));
56    
57  static boolean  static bfd_boolean
58  sparclinux_bfd_final_link (abfd, info)  sparclinux_bfd_final_link (abfd, info)
59       bfd *abfd;       bfd *abfd;
60       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 68  sparclinux_bfd_final_link (abfd, info) Line 67  sparclinux_bfd_final_link (abfd, info)
67    
68  /* Set the machine type correctly.  */  /* Set the machine type correctly.  */
69    
70  static boolean sparclinux_write_object_contents PARAMS ((bfd *abfd));  static bfd_boolean sparclinux_write_object_contents PARAMS ((bfd *abfd));
71    
72  static boolean  static bfd_boolean
73  sparclinux_write_object_contents (abfd)  sparclinux_write_object_contents (abfd)
74       bfd *abfd;       bfd *abfd;
75  {  {
# Line 83  sparclinux_write_object_contents (abfd) Line 82  sparclinux_write_object_contents (abfd)
82    
83    WRITE_HEADERS(abfd, execp);    WRITE_HEADERS(abfd, execp);
84    
85    return true;    return TRUE;
86  }  }
87    
88  #define MY_write_object_contents sparclinux_write_object_contents  #define MY_write_object_contents sparclinux_write_object_contents
# Line 92  sparclinux_write_object_contents (abfd) Line 91  sparclinux_write_object_contents (abfd)
91  /* See if a symbol name is a reference to the global offset table.  */  /* See if a symbol name is a reference to the global offset table.  */
92    
93  #ifndef GOT_REF_PREFIX  #ifndef GOT_REF_PREFIX
94  #define        GOT_REF_PREFIX  "__GOT_"  #define GOT_REF_PREFIX  "__GOT_"
95  #endif  #endif
96    
97  #define IS_GOT_SYM(name) \  #define IS_GOT_SYM(name) \
# Line 101  sparclinux_write_object_contents (abfd) Line 100  sparclinux_write_object_contents (abfd)
100  /* See if a symbol name is a reference to the procedure linkage table.  */  /* See if a symbol name is a reference to the procedure linkage table.  */
101    
102  #ifndef PLT_REF_PREFIX  #ifndef PLT_REF_PREFIX
103  #define        PLT_REF_PREFIX  "__PLT_"  #define PLT_REF_PREFIX  "__PLT_"
104  #endif  #endif
105    
106  #define IS_PLT_SYM(name) \  #define IS_PLT_SYM(name) \
# Line 114  sparclinux_write_object_contents (abfd) Line 113  sparclinux_write_object_contents (abfd)
113  #endif  #endif
114    
115  /* This special symbol is a set vector that contains a list of  /* This special symbol is a set vector that contains a list of
116     pointers to fixup tables.  It will be present in any dynamicly     pointers to fixup tables.  It will be present in any dynamically
117     linked file.  The linker generated fixup table should also be added     linked file.  The linker generated fixup table should also be added
118     to the list, and it should always appear in the second slot (the     to the list, and it should always appear in the second slot (the
119     first one is a dummy with a magic number that is defined in     first one is a dummy with a magic number that is defined in
# Line 179  static struct bfd_link_hash_table *linux Line 178  static struct bfd_link_hash_table *linux
178    PARAMS ((bfd *));    PARAMS ((bfd *));
179  static struct fixup *new_fixup  static struct fixup *new_fixup
180    PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,    PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
181            bfd_vma, int));            bfd_vma, int));
182  static boolean linux_link_create_dynamic_sections  static bfd_boolean linux_link_create_dynamic_sections
183    PARAMS ((bfd *, struct bfd_link_info *));    PARAMS ((bfd *, struct bfd_link_info *));
184  static boolean linux_add_one_symbol  static bfd_boolean linux_add_one_symbol
185    PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,    PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
186            bfd_vma, const char *, boolean, boolean,            bfd_vma, const char *, bfd_boolean, bfd_boolean,
187            struct bfd_link_hash_entry **));            struct bfd_link_hash_entry **));
188  static boolean linux_tally_symbols  static bfd_boolean linux_tally_symbols
189    PARAMS ((struct linux_link_hash_entry *, PTR));    PARAMS ((struct linux_link_hash_entry *, PTR));
190  static boolean linux_finish_dynamic_link  static bfd_boolean linux_finish_dynamic_link
191    PARAMS ((bfd *, struct bfd_link_info *));    PARAMS ((bfd *, struct bfd_link_info *));
192    
193  /* Routine to create an entry in an Linux link hash table.  */  /* Routine to create an entry in an Linux link hash table.  */
# Line 205  linux_link_hash_newfunc (entry, table, s Line 204  linux_link_hash_newfunc (entry, table, s
204       subclass.  */       subclass.  */
205    if (ret == (struct linux_link_hash_entry *) NULL)    if (ret == (struct linux_link_hash_entry *) NULL)
206      ret = ((struct linux_link_hash_entry *)      ret = ((struct linux_link_hash_entry *)
207            bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));             bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
208    if (ret == NULL)    if (ret == NULL)
209      return (struct bfd_hash_entry *) ret;      return (struct bfd_hash_entry *) ret;
210    
211    /* Call the allocation method of the superclass.  */    /* Call the allocation method of the superclass.  */
212    ret = ((struct linux_link_hash_entry *)    ret = ((struct linux_link_hash_entry *)
213          NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,           NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
214                                        table, string));                                         table, string));
215    if (ret != NULL)    if (ret != NULL)
216      {      {
217        /* Set local fields; there aren't any.  */        /* Set local fields; there aren't any.  */
# Line 234  linux_link_hash_table_create (abfd) Line 233  linux_link_hash_table_create (abfd)
233    if (ret == (struct linux_link_hash_table *) NULL)    if (ret == (struct linux_link_hash_table *) NULL)
234      return (struct bfd_link_hash_table *) NULL;      return (struct bfd_link_hash_table *) NULL;
235    if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,    if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
236                                          linux_link_hash_newfunc))                                           linux_link_hash_newfunc))
237      {      {
238        free (ret);        free (ret);
239        return (struct bfd_link_hash_table *) NULL;        return (struct bfd_link_hash_table *) NULL;
# Line 253  linux_link_hash_table_create (abfd) Line 252  linux_link_hash_table_create (abfd)
252  #define linux_link_hash_lookup(table, string, create, copy, follow) \  #define linux_link_hash_lookup(table, string, create, copy, follow) \
253    ((struct linux_link_hash_entry *) \    ((struct linux_link_hash_entry *) \
254     aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\     aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
255                           (follow)))                            (follow)))
256    
257  /* Traverse a Linux link hash table.  */  /* Traverse a Linux link hash table.  */
258    
259  #define linux_link_hash_traverse(table, func, info)                    \  #define linux_link_hash_traverse(table, func, info)                    \
260    (aout_link_hash_traverse                                             \    (aout_link_hash_traverse                                             \
261     (&(table)->root,                                                    \     (&(table)->root,                                                    \
262      (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \      (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
263      (info)))      (info)))
264    
265  /* Get the Linux link hash table from the info structure.  This is  /* Get the Linux link hash table from the info structure.  This is
# Line 280  new_fixup (info, h, value, builtin) Line 279  new_fixup (info, h, value, builtin)
279    struct fixup *f;    struct fixup *f;
280    
281    f = (struct fixup *) bfd_hash_allocate (&info->hash->table,    f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
282                                           sizeof (struct fixup));                                            sizeof (struct fixup));
283    if (f == NULL)    if (f == NULL)
284      return f;      return f;
285    f->next = linux_hash_table (info)->fixup_list;    f->next = linux_hash_table (info)->fixup_list;
# Line 300  new_fixup (info, h, value, builtin) Line 299  new_fixup (info, h, value, builtin)
299     know the size of the section, but that's OK - we just need to     know the size of the section, but that's OK - we just need to
300     create it for now.  */     create it for now.  */
301    
302  static boolean  static bfd_boolean
303  linux_link_create_dynamic_sections (abfd, info)  linux_link_create_dynamic_sections (abfd, info)
304       bfd *abfd;       bfd *abfd;
305       struct bfd_link_info *info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
# Line 312  linux_link_create_dynamic_sections (abfd Line 311  linux_link_create_dynamic_sections (abfd
311    flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;    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.    /* We choose to use the name ".linux-dynamic" for the fixup table.
314       Why not? */       Why not?  */
315    s = bfd_make_section (abfd, ".linux-dynamic");    s = bfd_make_section (abfd, ".linux-dynamic");
316    if (s == NULL    if (s == NULL
317        || ! bfd_set_section_flags (abfd, s, flags)        || ! bfd_set_section_flags (abfd, s, flags)
318        || ! bfd_set_section_alignment (abfd, s, 2))        || ! bfd_set_section_alignment (abfd, s, 2))
319      return false;      return FALSE;
320    s->_raw_size = 0;    s->size = 0;
321    s->contents = 0;    s->contents = 0;
322    
323    return true;    return TRUE;
324  }  }
325    
326  /* Function to add a single symbol to the linker hash table.  This is  /* 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     a wrapper around _bfd_generic_link_add_one_symbol which handles the
328     tweaking needed for dynamic linking support.  */     tweaking needed for dynamic linking support.  */
329    
330  static boolean  static bfd_boolean
331  linux_add_one_symbol (info, abfd, name, flags, section, value, string,  linux_add_one_symbol (info, abfd, name, flags, section, value, string,
332                       copy, collect, hashp)                        copy, collect, hashp)
333       struct bfd_link_info *info;       struct bfd_link_info *info;
334       bfd *abfd;       bfd *abfd;
335       const char *name;       const char *name;
# Line 338  linux_add_one_symbol (info, abfd, name, Line 337  linux_add_one_symbol (info, abfd, name,
337       asection *section;       asection *section;
338       bfd_vma value;       bfd_vma value;
339       const char *string;       const char *string;
340       boolean copy;       bfd_boolean copy;
341       boolean collect;       bfd_boolean collect;
342       struct bfd_link_hash_entry **hashp;       struct bfd_link_hash_entry **hashp;
343  {  {
344    struct linux_link_hash_entry *h;    struct linux_link_hash_entry *h;
345    boolean insert;    bfd_boolean insert;
346    
347    /* Look up and see if we already have this symbol in the hash table.    /* 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       If we do, and the defining entry is from a shared library, we
# Line 353  linux_add_one_symbol (info, abfd, name, Line 352  linux_add_one_symbol (info, abfd, name,
352       be able to link Linux a.out and ELF objects together, but serious       be able to link Linux a.out and ELF objects together, but serious
353       confusion is possible.  */       confusion is possible.  */
354    
355    insert = false;    insert = FALSE;
356    
357    if (! info->relocateable    if (! info->relocatable
358        && linux_hash_table (info)->dynobj == NULL        && linux_hash_table (info)->dynobj == NULL
359        && strcmp (name, SHARABLE_CONFLICTS) == 0        && strcmp (name, SHARABLE_CONFLICTS) == 0
360        && (flags & BSF_CONSTRUCTOR) != 0        && (flags & BSF_CONSTRUCTOR) != 0
361        && abfd->xvec == info->hash->creator)        && abfd->xvec == info->hash->creator)
362      {      {
363        if (! linux_link_create_dynamic_sections (abfd, info))        if (! linux_link_create_dynamic_sections (abfd, info))
364         return false;          return FALSE;
365        linux_hash_table (info)->dynobj = abfd;        linux_hash_table (info)->dynobj = abfd;
366        insert = true;        insert = TRUE;
367      }      }
368    
369    if (bfd_is_abs_section (section)    if (bfd_is_abs_section (section)
370        && abfd->xvec == info->hash->creator)        && abfd->xvec == info->hash->creator)
371      {      {
372        h = linux_link_hash_lookup (linux_hash_table (info), name, false,        h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE,
373                                   false, false);                                    FALSE, FALSE);
374        if (h != NULL        if (h != NULL
375           && (h->root.root.type == bfd_link_hash_defined            && (h->root.root.type == bfd_link_hash_defined
376               || h->root.root.type == bfd_link_hash_defweak))                || h->root.root.type == bfd_link_hash_defweak))
377         {          {
378           struct fixup *f;            struct fixup *f;
379    
380           if (hashp != NULL)            if (hashp != NULL)
381             *hashp = (struct bfd_link_hash_entry *) h;              *hashp = (struct bfd_link_hash_entry *) h;
382    
383           f = new_fixup (info, h, value, ! IS_PLT_SYM (name));            f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
384           if (f == NULL)            if (f == NULL)
385             return false;              return FALSE;
386           f->jump = IS_PLT_SYM (name);            f->jump = IS_PLT_SYM (name);
387    
388           return true;            return TRUE;
389         }          }
390      }      }
391    
392    /* Do the usual procedure for adding a symbol.  */    /* Do the usual procedure for adding a symbol.  */
393    if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,    if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
394                                           value, string, copy, collect,                                            value, string, copy, collect,
395                                           hashp))                                            hashp))
396      return false;      return FALSE;
397    
398    /* Insert a pointer to our table in the set vector.  The dynamic    /* Insert a pointer to our table in the set vector.  The dynamic
399       linker requires this information */       linker requires this information.  */
400    if (insert)    if (insert)
401      {      {
402        asection *s;        asection *s;
403    
404        /* Here we do our special thing to add the pointer to the        /* Here we do our special thing to add the pointer to the
405          dynamic section in the SHARABLE_CONFLICTS set vector.  */           dynamic section in the SHARABLE_CONFLICTS set vector.  */
406        s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,        s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
407                                    ".linux-dynamic");                                     ".linux-dynamic");
408        BFD_ASSERT (s != NULL);        BFD_ASSERT (s != NULL);
409    
410        if (! (_bfd_generic_link_add_one_symbol        if (! (_bfd_generic_link_add_one_symbol
411              (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,               (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
412               BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,                BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,
413               false, false, NULL)))                FALSE, FALSE, NULL)))
414         return false;          return FALSE;
415      }      }
416    
417    return true;    return TRUE;
418  }  }
419    
420  /* We will crawl the hash table and come here for every global symbol.  /* We will crawl the hash table and come here for every global symbol.
# Line 428  linux_add_one_symbol (info, abfd, name, Line 427  linux_add_one_symbol (info, abfd, name,
427    
428     This function is called via linux_link_hash_traverse.  */     This function is called via linux_link_hash_traverse.  */
429    
430  static boolean  static bfd_boolean
431  linux_tally_symbols (h, data)  linux_tally_symbols (h, data)
432       struct linux_link_hash_entry *h;       struct linux_link_hash_entry *h;
433       PTR data;       PTR data;
# Line 437  linux_tally_symbols (h, data) Line 436  linux_tally_symbols (h, data)
436    struct fixup *f, *f1;    struct fixup *f, *f1;
437    int is_plt;    int is_plt;
438    struct linux_link_hash_entry *h1, *h2;    struct linux_link_hash_entry *h1, *h2;
439    boolean exists;    bfd_boolean exists;
440    
441    if (h->root.root.type == bfd_link_hash_warning)    if (h->root.root.type == bfd_link_hash_warning)
442      h = (struct linux_link_hash_entry *) h->root.root.u.i.link;      h = (struct linux_link_hash_entry *) h->root.root.u.i.link;
443    
444    if (h->root.root.type == bfd_link_hash_undefined    if (h->root.root.type == bfd_link_hash_undefined
445        && strncmp (h->root.root.root.string, NEEDS_SHRLIB,        && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
446                   sizeof NEEDS_SHRLIB - 1) == 0)                    sizeof NEEDS_SHRLIB - 1) == 0)
447      {      {
448        const char *name;        const char *name;
449        char *p;        char *p;
# Line 453  linux_tally_symbols (h, data) Line 452  linux_tally_symbols (h, data)
452        name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;        name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
453        p = strrchr (name, '_');        p = strrchr (name, '_');
454        if (p != NULL)        if (p != NULL)
455         alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);          alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);
456    
457        if (p == NULL || alloc == NULL)        if (p == NULL || alloc == NULL)
458         (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),          (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
459                                name);                                 name);
460        else        else
461         {          {
462           strcpy (alloc, name);            strcpy (alloc, name);
463           p = strrchr (alloc, '_');            p = strrchr (alloc, '_');
464           *p++ = '\0';            *p++ = '\0';
465           (*_bfd_error_handler)            (*_bfd_error_handler)
466             (_("Output file requires shared library `%s.so.%s'\n"),              (_("Output file requires shared library `%s.so.%s'\n"),
467              alloc, p);               alloc, p);
468           free (alloc);            free (alloc);
469         }          }
470    
471        abort ();        abort ();
472      }      }
# Line 479  linux_tally_symbols (h, data) Line 478  linux_tally_symbols (h, data)
478    if (is_plt || IS_GOT_SYM (h->root.root.root.string))    if (is_plt || IS_GOT_SYM (h->root.root.root.string))
479      {      {
480        /* Look up this symbol twice.  Once just as a regular lookup,        /* Look up this symbol twice.  Once just as a regular lookup,
481          and then again following all of the indirect links until we           and then again following all of the indirect links until we
482          reach a real symbol.  */           reach a real symbol.  */
483        h1 = linux_link_hash_lookup (linux_hash_table (info),        h1 = linux_link_hash_lookup (linux_hash_table (info),
484                                    (h->root.root.root.string                                     (h->root.root.root.string
485                                     + sizeof PLT_REF_PREFIX - 1),                                      + sizeof PLT_REF_PREFIX - 1),
486                                    false, false, true);                                     FALSE, FALSE, TRUE);
487        /* h2 does not follow indirect symbols.  */        /* h2 does not follow indirect symbols.  */
488        h2 = linux_link_hash_lookup (linux_hash_table (info),        h2 = linux_link_hash_lookup (linux_hash_table (info),
489                                    (h->root.root.root.string                                     (h->root.root.root.string
490                                     + sizeof PLT_REF_PREFIX - 1),                                      + sizeof PLT_REF_PREFIX - 1),
491                                    false, false, false);                                     FALSE, FALSE, FALSE);
492    
493        /* The real symbol must exist but if it is also an ABS symbol,        /* The real symbol must exist but if it is also an ABS symbol,
494          there is no need to have a fixup.  This is because they both           there is no need to have a fixup.  This is because they both
495          came from the same library.  If on the other hand, we had to           came from the same library.  If on the other hand, we had to
496          use an indirect symbol to get to the real symbol, we add the           use an indirect symbol to get to the real symbol, we add the
497          fixup anyway, since there are cases where these symbols come           fixup anyway, since there are cases where these symbols come
498          from different shared libraries */           from different shared libraries */
499        if (h1 != NULL        if (h1 != NULL
500           && (((h1->root.root.type == bfd_link_hash_defined            && (((h1->root.root.type == bfd_link_hash_defined
501                 || h1->root.root.type == bfd_link_hash_defweak)                  || h1->root.root.type == bfd_link_hash_defweak)
502                && ! bfd_is_abs_section (h1->root.root.u.def.section))                 && ! bfd_is_abs_section (h1->root.root.u.def.section))
503               || h2->root.root.type == bfd_link_hash_indirect))                || h2->root.root.type == bfd_link_hash_indirect))
504         {          {
505           /* See if there is a "builtin" fixup already present            /* See if there is a "builtin" fixup already present
506              involving this symbol.  If so, convert it to a regular               involving this symbol.  If so, convert it to a regular
507              fixup.  In the end, this relaxes some of the requirements               fixup.  In the end, this relaxes some of the requirements
508              about the order of performing fixups.  */               about the order of performing fixups.  */
509           exists = false;            exists = FALSE;
510           for (f1 = linux_hash_table (info)->fixup_list;            for (f1 = linux_hash_table (info)->fixup_list;
511                f1 != NULL;                 f1 != NULL;
512                f1 = f1->next)                 f1 = f1->next)
513             {              {
514               if ((f1->h != h && f1->h != h1)                if ((f1->h != h && f1->h != h1)
515                   || (! f1->builtin && ! f1->jump))                    || (! f1->builtin && ! f1->jump))
516                 continue;                  continue;
517               if (f1->h == h1)                if (f1->h == h1)
518                exists = true;                  exists = TRUE;
519               if (! exists                if (! exists
520                   && bfd_is_abs_section (h->root.root.u.def.section))                    && bfd_is_abs_section (h->root.root.u.def.section))
521                 {                  {
522                   f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);                    f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
523                   f->jump = is_plt;                    f->jump = is_plt;
524                 }                  }
525               f1->h = h1;                f1->h = h1;
526               f1->jump = is_plt;                f1->jump = is_plt;
527               f1->builtin = 0;                f1->builtin = 0;
528               exists = true;                exists = TRUE;
529             }              }
530           if (! exists            if (! exists
531               && bfd_is_abs_section (h->root.root.u.def.section))                && bfd_is_abs_section (h->root.root.u.def.section))
532             {              {
533               f = new_fixup (info, h1, h->root.root.u.def.value, 0);                f = new_fixup (info, h1, h->root.root.u.def.value, 0);
534               if (f == NULL)                if (f == NULL)
535                 {                  {
536                   /* FIXME: No way to return error.  */                    /* FIXME: No way to return error.  */
537                   abort ();                    abort ();
538                 }                  }
539               f->jump = is_plt;                f->jump = is_plt;
540             }              }
541         }          }
542    
543        /* Quick and dirty way of stripping these symbols from the        /* Quick and dirty way of stripping these symbols from the
544          symtab.  */           symtab.  */
545        if (bfd_is_abs_section (h->root.root.u.def.section))        if (bfd_is_abs_section (h->root.root.u.def.section))
546         h->root.written = true;          h->root.written = TRUE;
547      }      }
548    
549    return true;    return TRUE;
550  }  }
551    
552  /* This is called to set the size of the .linux-dynamic section is.  /* This is called to set the size of the .linux-dynamic section is.
# Line 556  linux_tally_symbols (h, data) Line 555  linux_tally_symbols (h, data)
555     we just scan the hash tables to find out how many additional fixups     we just scan the hash tables to find out how many additional fixups
556     are required.  */     are required.  */
557    
558  boolean  bfd_boolean
559  bfd_sparclinux_size_dynamic_sections (output_bfd, info)  bfd_sparclinux_size_dynamic_sections (output_bfd, info)
560       bfd *output_bfd;       bfd *output_bfd;
561       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 565  bfd_sparclinux_size_dynamic_sections (ou Line 564  bfd_sparclinux_size_dynamic_sections (ou
564    asection *s;    asection *s;
565    
566    if (output_bfd->xvec != &MY(vec))    if (output_bfd->xvec != &MY(vec))
567      return true;      return TRUE;
568    
569    /* First find the fixups...  */    /* First find the fixups...  */
570    linux_link_hash_traverse (linux_hash_table (info),    linux_link_hash_traverse (linux_hash_table (info),
571                             linux_tally_symbols,                              linux_tally_symbols,
572                             (PTR) info);                              (PTR) info);
573    
574    /* If there are builtin fixups, leave room for a marker.  This is    /* If there are builtin fixups, leave room for a marker.  This is
575       used by the dynamic linker so that it knows that all that follow       used by the dynamic linker so that it knows that all that follow
# Line 578  bfd_sparclinux_size_dynamic_sections (ou Line 577  bfd_sparclinux_size_dynamic_sections (ou
577    for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)    for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
578      {      {
579        if (f->builtin)        if (f->builtin)
580         {          {
581           ++linux_hash_table (info)->fixup_count;            ++linux_hash_table (info)->fixup_count;
582           ++linux_hash_table (info)->local_builtins;            ++linux_hash_table (info)->local_builtins;
583           break;            break;
584         }          }
585      }      }
586    
587    if (linux_hash_table (info)->dynobj == NULL)    if (linux_hash_table (info)->dynobj == NULL)
588      {      {
589        if (linux_hash_table (info)->fixup_count > 0)        if (linux_hash_table (info)->fixup_count > 0)
590        abort ();          abort ();
591        return true;        return TRUE;
592      }      }
593    
594    /* Allocate memory for our fixup table.  We will fill it in later.  */    /* Allocate memory for our fixup table.  We will fill it in later.  */
595    s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,    s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
596                                ".linux-dynamic");                                 ".linux-dynamic");
597    if (s != NULL)    if (s != NULL)
598      {      {
599        s->_raw_size = linux_hash_table (info)->fixup_count + 1;        s->size = linux_hash_table (info)->fixup_count + 1;
600        s->_raw_size *= 8;        s->size *= 8;
601        s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);        s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->size);
602        if (s->contents == NULL)        if (s->contents == NULL)
603         return false;          return FALSE;
604      }      }
605    
606    return true;    return TRUE;
607  }  }
608    
609  /* We come here once we are ready to actually write the fixup table to  /* We come here once we are ready to actually write the fixup table to
610     the output file.  Scan the fixup tables and so forth and generate     the output file.  Scan the fixup tables and so forth and generate
611     the stuff we need.  */     the stuff we need.  */
612    
613  static boolean  static bfd_boolean
614  linux_finish_dynamic_link (output_bfd, info)  linux_finish_dynamic_link (output_bfd, info)
615       bfd *output_bfd;       bfd *output_bfd;
616       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 625  linux_finish_dynamic_link (output_bfd, i Line 624  linux_finish_dynamic_link (output_bfd, i
624    unsigned int fixups_written;    unsigned int fixups_written;
625    
626    if (linux_hash_table (info)->dynobj == NULL)    if (linux_hash_table (info)->dynobj == NULL)
627      return true;      return TRUE;
628    
629    s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,    s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
630                                ".linux-dynamic");                                 ".linux-dynamic");
631    BFD_ASSERT (s != NULL);    BFD_ASSERT (s != NULL);
632    os = s->output_section;    os = s->output_section;
633    fixups_written = 0;    fixups_written = 0;
634    
635  #ifdef LINUX_LINK_DEBUG  #ifdef LINUX_LINK_DEBUG
636    printf ("Fixup table file offset: %x  VMA: %x\n",    printf ("Fixup table file offset: %x  VMA: %x\n",
637           os->filepos + s->output_offset,            os->filepos + s->output_offset,
638           os->vma + s->output_offset);            os->vma + s->output_offset);
639  #endif  #endif
640    
641    fixup_table = s->contents;    fixup_table = s->contents;
# Line 648  linux_finish_dynamic_link (output_bfd, i Line 647  linux_finish_dynamic_link (output_bfd, i
647    for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)    for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
648      {      {
649        if (f->builtin)        if (f->builtin)
650         continue;          continue;
651    
652        if (f->h->root.root.type != bfd_link_hash_defined        if (f->h->root.root.type != bfd_link_hash_defined
653           && f->h->root.root.type != bfd_link_hash_defweak)            && f->h->root.root.type != bfd_link_hash_defweak)
654         {          {
655           (*_bfd_error_handler)            (*_bfd_error_handler)
656             (_("Symbol %s not defined for fixups\n"),              (_("Symbol %s not defined for fixups\n"),
657              f->h->root.root.root.string);               f->h->root.root.root.string);
658           continue;            continue;
659         }          }
660    
661        is = f->h->root.root.u.def.section;        is = f->h->root.root.u.def.section;
662        section_offset = is->output_section->vma + is->output_offset;        section_offset = is->output_section->vma + is->output_offset;
# Line 665  linux_finish_dynamic_link (output_bfd, i Line 664  linux_finish_dynamic_link (output_bfd, i
664    
665  #ifdef LINUX_LINK_DEBUG  #ifdef LINUX_LINK_DEBUG
666        printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,        printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
667               new_addr, f->value);                new_addr, f->value);
668  #endif  #endif
669    
670        if (f->jump)        if (f->jump)
671         {          {
672           /* Relative address */            /* Relative address */
673           new_addr = new_addr - (f->value + 5);            new_addr = new_addr - (f->value + 5);
674           bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);            bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
675           fixup_table += 4;            fixup_table += 4;
676           bfd_put_32 (output_bfd, f->value + 1, fixup_table);            bfd_put_32 (output_bfd, f->value + 1, fixup_table);
677           fixup_table += 4;            fixup_table += 4;
678         }          }
679        else        else
680         {          {
681           bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);            bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
682           fixup_table += 4;            fixup_table += 4;
683           bfd_put_32 (output_bfd, f->value, fixup_table);            bfd_put_32 (output_bfd, f->value, fixup_table);
684           fixup_table += 4;            fixup_table += 4;
685         }          }
686        ++fixups_written;        ++fixups_written;
687      }      }
688    
# Line 696  linux_finish_dynamic_link (output_bfd, i Line 695  linux_finish_dynamic_link (output_bfd, i
695        fixup_table += 4;        fixup_table += 4;
696        ++fixups_written;        ++fixups_written;
697        for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)        for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
698         {          {
699           if (! f->builtin)            if (! f->builtin)
700             continue;              continue;
701    
702           if (f->h->root.root.type != bfd_link_hash_defined            if (f->h->root.root.type != bfd_link_hash_defined
703               && f->h->root.root.type != bfd_link_hash_defweak)                && f->h->root.root.type != bfd_link_hash_defweak)
704             {              {
705               (*_bfd_error_handler)                (*_bfd_error_handler)
706                 (_("Symbol %s not defined for fixups\n"),                  (_("Symbol %s not defined for fixups\n"),
707                  f->h->root.root.root.string);                   f->h->root.root.root.string);
708               continue;                continue;
709             }              }
710    
711           is = f->h->root.root.u.def.section;            is = f->h->root.root.u.def.section;
712           section_offset = is->output_section->vma + is->output_offset;            section_offset = is->output_section->vma + is->output_offset;
713           new_addr = f->h->root.root.u.def.value + section_offset;            new_addr = f->h->root.root.u.def.value + section_offset;
714    
715  #ifdef LINUX_LINK_DEBUG  #ifdef LINUX_LINK_DEBUG
716           printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,            printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
717                   new_addr, f->value);                    new_addr, f->value);
718  #endif  #endif
719    
720           bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);            bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
721           fixup_table += 4;            fixup_table += 4;
722           bfd_put_32 (output_bfd, f->value, fixup_table);            bfd_put_32 (output_bfd, f->value, fixup_table);
723           fixup_table += 4;            fixup_table += 4;
724           ++fixups_written;            ++fixups_written;
725         }          }
726    }      }
727    
728    if (linux_hash_table (info)->fixup_count != fixups_written)    if (linux_hash_table (info)->fixup_count != fixups_written)
729      {      {
730        (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));        (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
731        while (linux_hash_table (info)->fixup_count > fixups_written)        while (linux_hash_table (info)->fixup_count > fixups_written)
732         {          {
733           bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);            bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
734           fixup_table += 4;            fixup_table += 4;
735           bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);            bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
736           fixup_table += 4;            fixup_table += 4;
737           ++fixups_written;            ++fixups_written;
738         }          }
739      }      }
740    
741    h = linux_link_hash_lookup (linux_hash_table (info),    h = linux_link_hash_lookup (linux_hash_table (info),
742                               "__BUILTIN_FIXUPS__",                                "__BUILTIN_FIXUPS__",
743                               false, false, false);                                FALSE, FALSE, FALSE);
744    
745    if (h != NULL    if (h != NULL
746        && (h->root.root.type == bfd_link_hash_defined        && (h->root.root.type == bfd_link_hash_defined
747           || h->root.root.type == bfd_link_hash_defweak))            || h->root.root.type == bfd_link_hash_defweak))
748      {      {
749        is = h->root.root.u.def.section;        is = h->root.root.u.def.section;
750        section_offset = is->output_section->vma + is->output_offset;        section_offset = is->output_section->vma + is->output_offset;
# Line 762  linux_finish_dynamic_link (output_bfd, i Line 761  linux_finish_dynamic_link (output_bfd, i
761    
762    if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),    if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
763                  SEEK_SET) != 0)                  SEEK_SET) != 0)
764      return false;      return FALSE;
765    
766    if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd)    if (bfd_bwrite ((PTR) s->contents, s->size, output_bfd) != s->size)
767        != s->_raw_size)      return FALSE;
     return false;  
768    
769    return true;    return TRUE;
770  }  }
771    
772  #define MY_bfd_link_hash_table_create linux_link_hash_table_create  #define MY_bfd_link_hash_table_create linux_link_hash_table_create

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26