* lib/ld-lib.exp (run_dump_test): Add -L$srcdir/$subdir.
[external/binutils.git] / ld / deffilep.y
index c0f350b..51d17f8 100644 (file)
@@ -1,6 +1,7 @@
 %{ /* deffilep.y - parser for .def files */
 
-/*   Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+/*   Copyright 1995, 1997, 1998, 1999, 2000, 2001
+     Free Software Foundation, Inc.
 
 This file is part of GNU Binutils.
 
@@ -19,14 +20,18 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <stdio.h>
-#include <ctype.h>
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "bfd.h"
+#include "sysdep.h"
 #include "ld.h"
+#include "ldmisc.h"
 #include "deffile.h"
 
 #define TRACE 0
 
+#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
+
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
    yacc generated parsers in ld.  Note that these are only the variables
@@ -73,14 +78,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define yytable         def_yytable
 #define yycheck         def_yycheck
 
-static int def_lex ();
-
 static void def_description PARAMS ((const char *));
 static void def_exports PARAMS ((const char *, const char *, int, int));
 static void def_heapsize PARAMS ((int, int));
 static void def_import
   PARAMS ((const char *, const char *, const char *, const char *, int));
 static void def_library PARAMS ((const char *, int));
+static def_file_module *def_stash_module PARAMS ((def_file *, const char *));
 static void def_name PARAMS ((const char *, int));
 static void def_section PARAMS ((const char *, int));
 static void def_section_alt PARAMS ((const char *, const char *));
@@ -89,7 +93,9 @@ static void def_version PARAMS ((int, int));
 static void def_directive PARAMS ((char *));
 static int def_parse PARAMS ((void));
 static int def_error PARAMS ((const char *));
-static int def_debug;
+static void put_buf PARAMS ((char));
+static int def_getc PARAMS ((void));
+static int def_ungetc PARAMS ((int));
 static int def_lex PARAMS ((void));
 
 static int lex_forced_token = 0;
@@ -103,9 +109,10 @@ static const char *lex_parse_string_end = 0;
   int number;
 };
 
-%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
-%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE
-%token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
+%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATAU, DATAL
+%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANTU, CONSTANTL
+%token PRIVATEU, PRIVATEL
+%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
 %token <id> ID
 %token <number> NUMBER
 %type  <number> opt_base opt_ordinal
@@ -125,7 +132,7 @@ command:
        |       STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
        |       HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
        |       CODE attr_list { def_section ("CODE", $2);}
-       |       DATA attr_list  { def_section ("DATA", $2);}
+       |       DATAU attr_list  { def_section ("DATA", $2);}
        |       SECTIONS seclist
        |       EXPORTS explist 
        |       IMPORTS implist
@@ -142,18 +149,28 @@ explist:
        ;
 
 expline:
-               ID opt_equal_name opt_ordinal exp_opt_list
-                       { def_exports ($1, $2, $3, $4); }
+               /* The opt_comma is necessary to support both the usual
+                 DEF file syntax as well as .drectve syntax which
+                 mandates <expsym>,<expoptlist>.  */
+               ID opt_equal_name opt_ordinal opt_comma exp_opt_list
+                       { def_exports ($1, $2, $3, $5); }
        ;
 exp_opt_list:
-               exp_opt exp_opt_list { $$ = $1 | $2; }
+               /* The opt_comma is necessary to support both the usual
+                  DEF file syntax as well as .drectve syntax which
+                  allows for comma separated opt list.  */
+               exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
        |       { $$ = 0; }
        ;
 exp_opt:
-               NONAME          { $$ = 1; }
-       |       CONSTANT        { $$ = 2; }
-       |       DATA            { $$ = 4; }
-       |       PRIVATE         { $$ = 8; }
+               NONAMEU         { $$ = 1; }
+       |       NONAMEL         { $$ = 1; }
+       |       CONSTANTU       { $$ = 2; }
+       |       CONSTANTL       { $$ = 2; }
+       |       DATAU           { $$ = 4; }
+       |       DATAL           { $$ = 4; }
+       |       PRIVATEU        { $$ = 8; }
+       |       PRIVATEL        { $$ = 8; }
        ;
 implist:       
                implist impline
@@ -200,7 +217,13 @@ attr:
        ;
 
 opt_name: ID           { $$ = $1; }
-       |               { $$ = 0; }
+       | ID '.' ID     
+         { 
+           char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
+           sprintf (name, "%s.%s", $1, $3);
+           $$ = name;
+         }
+       |               { $$ = ""; }
        ;
 
 opt_ordinal: 
@@ -229,7 +252,6 @@ static FILE *the_file;
 static const char *def_filename;
 static int linenumber;
 static def_file *def;
-static int max_exports, max_imports, max_sections;
 static int saw_newline;
 
 struct directive
@@ -246,7 +268,6 @@ def_file_empty ()
 {
   def_file *rv = (def_file *) xmalloc (sizeof (def_file));
   memset (rv, 0, sizeof (def_file));
-  max_exports = max_imports = max_sections = 0;
   rv->is_dll = -1;
   rv->base_address = (bfd_vma) (-1);
   rv->stack_reserve = rv->stack_commit = -1;
@@ -273,9 +294,6 @@ def_file_parse (filename, add_to)
   if (add_to)
     {
       def = add_to;
-      max_exports = def->num_exports;
-      max_imports = def->num_imports;
-      max_sections = def->num_section_defs;
     }
   else
     {
@@ -295,7 +313,7 @@ def_file_parse (filename, add_to)
   for (d = directives; d; d = d->next)
     {
 #if TRACE
-      printf ("Adding directive `%s'\n", d->name);
+      printf ("Adding directive %08x `%s'\n", d->name, d->name);
 #endif
       def_file_add_directive (def, d->name, d->len);
     }
@@ -349,12 +367,17 @@ def_file_free (def)
            free (def->imports[i].internal_name);
          if (def->imports[i].name)
            free (def->imports[i].name);
-         if (def->imports[i].module)
-           free (def->imports[i].module);
        }
       free (def->imports);
     }
 
+  while (def->modules)
+    {
+      def_file_module *m = def->modules;
+      def->modules = def->modules->next;
+      free (m);
+    }
+
   free (def);
 }
 
@@ -448,9 +471,10 @@ def_file_add_export (def, external_name, internal_name, ordinal)
      int ordinal;
 {
   def_file_export *e;
+  int max_exports = ROUND_UP(def->num_exports, 32);
   if (def->num_exports >= max_exports)
     {
-      max_exports = def->num_exports + 50;
+      max_exports = ROUND_UP(def->num_exports+1, 32);
       if (def->exports)
        def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
       else
@@ -469,6 +493,23 @@ def_file_add_export (def, external_name, internal_name, ordinal)
   return e;
 }
 
+static def_file_module *
+def_stash_module (def, name)
+     def_file *def;
+     const char *name;
+{
+  def_file_module *s;
+  for (s=def->modules; s; s=s->next)
+    if (strcmp (s->name, name) == 0)
+      return s;
+  s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
+  s->next = def->modules;
+  def->modules = s;
+  s->user_data = 0;
+  strcpy (s->name, name);
+  return s;
+}
+
 def_file_import *
 def_file_add_import (def, name, module, ordinal, internal_name)
      def_file *def;
@@ -478,9 +519,10 @@ def_file_add_import (def, name, module, ordinal, internal_name)
      const char *internal_name;
 {
   def_file_import *i;
+  int max_imports = ROUND_UP(def->num_imports, 16);
   if (def->num_imports >= max_imports)
     {
-      max_imports = def->num_imports + 50;
+      max_imports = ROUND_UP(def->num_imports+1, 16);
       if (def->imports)
        def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
       else
@@ -491,7 +533,7 @@ def_file_add_import (def, name, module, ordinal, internal_name)
   if (name)
     i->name = xstrdup (name);
   if (module)
-    i->module = xstrdup (module);
+    i->module = def_stash_module (def, module);
   i->ordinal = ordinal;
   if (internal_name)
     i->internal_name = xstrdup (internal_name);
@@ -515,7 +557,7 @@ diropts[] =
   { 0, 0 }
 };
 
-int
+void
 def_file_add_directive (my_def, param, len)
      def_file *my_def;
      const char *param;
@@ -524,17 +566,16 @@ def_file_add_directive (my_def, param, len)
   def_file *save_def = def;
   const char *pend = param + len;
   const char *tend = param;
-  unsigned int sh_reserve, sh_commit;
-  int i, j;
+  int i;
 
   def = my_def;
 
   while (param < pend)
     {
-      while (param < pend && isspace (*param))
+      while (param < pend && ISSPACE (*param))
        param++;
       for (tend = param + 1;
-          tend < pend && !(isspace (tend[-1]) && *tend == '-');
+          tend < pend && !(ISSPACE (tend[-1]) && *tend == '-');
           tend++);
 
       for (i = 0; diropts[i].param; i++)
@@ -636,9 +677,10 @@ def_section (name, attr)
      int attr;
 {
   def_file_section *s;
+  int max_sections = ROUND_UP(def->num_section_defs, 4);
   if (def->num_section_defs >= max_sections)
     {
-      max_sections = def->num_section_defs + 50;
+      max_sections = ROUND_UP(def->num_section_defs+1, 4);
       if (def->section_defs)
        def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
       else
@@ -805,8 +847,10 @@ tokens[] =
 {
   { "BASE", BASE },
   { "CODE", CODE },
-  { "CONSTANT", CONSTANT },
-  { "DATA", DATA },
+  { "CONSTANT", CONSTANTU },
+  { "constant", CONSTANTL },
+  { "DATA", DATAU },
+  { "data", DATAL },
   { "DESCRIPTION", DESCRIPTION },
   { "DIRECTIVE", DIRECTIVE },
   { "EXECUTE", EXECUTE },
@@ -815,8 +859,10 @@ tokens[] =
   { "IMPORTS", IMPORTS },
   { "LIBRARY", LIBRARY },
   { "NAME", NAME },
-  { "NONAME", NONAME },
-  { "PRIVATE", PRIVATE },
+  { "NONAME", NONAMEU },
+  { "noname", NONAMEL },
+  { "PRIVATE", PRIVATEU },
+  { "private", PRIVATEL },
   { "READ", READ },
   { "SECTIONS", SECTIONS },
   { "SEGMENTS", SECTIONS },
@@ -852,7 +898,10 @@ def_ungetc (c)
      int c;
 {
   if (lex_parse_string)
-    lex_parse_string--;
+    {
+      lex_parse_string--;
+      return c;
+    }
   else
     return ungetc (c, the_file);
 }
@@ -900,10 +949,10 @@ def_lex ()
   /* must be something else */
   saw_newline = 0;
 
-  if (isdigit (c))
+  if (ISDIGIT (c))
     {
       bufptr = 0;
-      while (c != EOF && isxdigit (c) || (c == 'x'))
+      while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
        {
          put_buf (c);
          c = def_getc ();
@@ -917,10 +966,10 @@ def_lex ()
       return NUMBER;
     }
 
-  if (isalpha (c) || strchr ("$:-_?", c))
+  if (ISALPHA (c) || strchr ("$:-_?", c))
     {
       bufptr = 0;
-      while (c != EOF && isalnum (c) || strchr ("$:-_?/@", c))
+      while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
        {
          put_buf (c);
          c = def_getc ();