home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / ld / ldctor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  3.9 KB  |  157 lines

  1. /* Copyright (C) 1991 Free Software Foundation, Inc.
  2.    
  3. This file is part of GLD, the Gnu Linker.
  4.  
  5. GLD is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. GLD is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with GLD; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /*
  20.  * By steve chamberlain
  21.  * steve@cygnus.com
  22.  */
  23.  
  24. #include "bfd.h"
  25. #include "sysdep.h" 
  26. #include "ld.h"
  27. #include "ldlang.h"
  28. #include "ldsym.h"
  29. #include "ldmisc.h"
  30. #include "ldexp.h"
  31. #include "ldgram.h"
  32.  
  33. /* exported list of statements needed to handle constructors */
  34. lang_statement_list_type constructor_list;
  35.  
  36.  
  37.  
  38. typedef struct constructor_list 
  39. {
  40.    CONST char *name;
  41.     struct constructor_list *next;
  42. }  constructor_list_type;
  43.    
  44. static constructor_list_type *constructor_name_list;
  45.  
  46. static void
  47. DEFUN(add_constructor_name, (name),
  48.      CONST char *name)
  49. {
  50.     register constructor_list_type *ptr = constructor_name_list;
  51.     for (; ptr != (constructor_list_type *)NULL; ptr = ptr->next) {
  52.     if (strcmp (ptr->name, name) == 0) 
  53.         return;
  54.     }
  55.  
  56.     /* There isn't an entry, so add one */
  57.     ptr = (constructor_list_type *) ldmalloc (sizeof(constructor_list_type));
  58.     ptr->next = constructor_name_list;
  59.     ptr->name = name;
  60.     constructor_name_list = ptr;
  61. }
  62.  
  63. void
  64. DEFUN(ldlang_add_constructor,(name),
  65. ldsym_type *name)
  66. {
  67.   if (name->flags & SYM_CONSTRUCTOR) return;
  68.   add_constructor_name (name->name);
  69.   name->flags |= SYM_CONSTRUCTOR;
  70. }
  71.  
  72.  
  73. /* this function looks through the sections attached to the supplied
  74.    bfd to see if any of them are magical constructor sections. If so
  75.    their names are remembered and added to the list of constructors */
  76.  
  77. void
  78. DEFUN(ldlang_check_for_constructors, (entry),
  79. struct lang_input_statement_struct *entry)
  80. {
  81.     asection *section;
  82.  
  83.     for (section = entry->the_bfd->sections;
  84.      section != (asection *)NULL;
  85.      section = section->next) 
  86.     {
  87.     if (section->flags & SEC_CONSTRUCTOR) 
  88.         add_constructor_name (section->name);
  89.     }
  90. }
  91.  
  92.  
  93. /* run through the symbol table, find all the symbols which are
  94.    constructors and for each one, create statements to do something
  95.    like..
  96.  
  97.    for something like "__CTOR_LIST__, foo" in the assembler
  98.  
  99.    __CTOR_LIST__ = . ;
  100.    LONG(__CTOR_LIST_END - . / 4 - 2)
  101.    *(foo)
  102.    __CTOR_LIST_END= .
  103.  
  104.    Put these statements onto a special list.
  105.  
  106. */
  107.  
  108.  
  109. extern lang_statement_list_type *stat_ptr;
  110. void
  111. DEFUN_VOID(find_constructors) 
  112. {
  113.     lang_statement_list_type *old = stat_ptr;
  114.     constructor_list_type *p = constructor_name_list;
  115.     stat_ptr = & constructor_list;
  116.     lang_list_init(stat_ptr);
  117.     while (p != (constructor_list_type *)NULL) 
  118.     {
  119.     /* Have we already done this one ? */
  120.     CONST char *name = p->name;
  121.     ldsym_type *lookup = ldsym_get_soft(name);
  122.  
  123.     /* If ld is invoked from collect, then the constructor list
  124.        will already have been defined, so don't do it again. */
  125.  
  126.     if (lookup->sdefs_chain == (asymbol **)NULL) 
  127.         {
  128.         size_t len = strlen(name);
  129.         char *end = ldmalloc(len+3);
  130.         strcpy(end, name);
  131.         strcat(end,"$e");
  132.  
  133.         lang_add_assignment
  134.             ( exp_assop('=',name, exp_nameop(NAME,".")));
  135.  
  136.         lang_add_data
  137.             (LONG, exp_binop('-',
  138.                      exp_binop ( '/',
  139.                         exp_binop ( '-',
  140.                                exp_nameop(NAME, end),
  141.                                exp_nameop(NAME,".")),
  142.                         exp_intop(4)),
  143.  
  144.                      exp_intop(2)));
  145.  
  146.                       
  147.         lang_add_wild(name, (char *)NULL);
  148.         lang_add_data(LONG, exp_intop(0));
  149.         lang_add_assignment
  150.             (exp_assop('=', end, exp_nameop(NAME,".")));
  151.         }
  152.     p = p->next;            
  153.     }
  154.     stat_ptr = old;
  155. }
  156.  
  157.