vax decoding of indexed addressing mode
[deliverable/binutils-gdb.git] / ld / deffilep.y
index 58f3dd27b78bd54fe62504fb7f5ec1422c1a31b8..92116e68a8e6d063704113235e70e8ae71503780 100644 (file)
@@ -1,7 +1,6 @@
 %{ /* deffilep.y - parser for .def files */
 
-/*   Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
-     2007, 2009 Free Software Foundation, Inc.
+/*   Copyright (C) 1995-2019 Free Software Foundation, Inc.
 
      This file is part of GNU Binutils.
 
@@ -24,6 +23,7 @@
 #include "libiberty.h"
 #include "safe-ctype.h"
 #include "bfd.h"
+#include "bfdlink.h"
 #include "ld.h"
 #include "ldmisc.h"
 #include "deffile.h"
 #define        yylval  def_lval
 #define        yychar  def_char
 #define        yydebug def_debug
-#define        yypact  def_pact        
-#define        yyr1    def_r1                  
-#define        yyr2    def_r2                  
-#define        yydef   def_def         
-#define        yychk   def_chk         
-#define        yypgo   def_pgo         
-#define        yyact   def_act         
+#define        yypact  def_pact
+#define        yyr1    def_r1
+#define        yyr2    def_r2
+#define        yydef   def_def
+#define        yychk   def_chk
+#define        yypgo   def_pgo
+#define        yyact   def_act
 #define        yyexca  def_exca
 #define yyerrflag def_errflag
 #define yynerrs        def_nerrs
@@ -94,7 +94,7 @@ static void def_exports (const char *, const char *, int, int, const char *);
 static void def_heapsize (int, int);
 static void def_import (const char *, const char *, const char *, const char *,
                        int, const char *);
-static void def_image_name (const char *, int, int);
+static void def_image_name (const char *, bfd_vma, int);
 static void def_section (const char *, int);
 static void def_section_alt (const char *, const char *);
 static void def_stacksize (int, int);
@@ -113,7 +113,9 @@ static const char *lex_parse_string_end = 0;
 
 %union {
   char *id;
+  const char *id_const;
   int number;
+  bfd_vma vma;
   char *digits;
 };
 
@@ -124,11 +126,13 @@ static const char *lex_parse_string_end = 0;
 %token <id> ID
 %token <digits> DIGITS
 %type  <number> NUMBER
+%type  <vma> VMA opt_base
 %type  <digits> opt_digits
-%type  <number> opt_base opt_ordinal
+%type  <number> opt_ordinal
 %type  <number> attr attr_list opt_number exp_opt_list exp_opt
-%type  <id> opt_name opt_equal_name dot_name anylang_id opt_id
+%type  <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
 %type  <id> opt_equalequal_name
+%type  <id_const> keyword_as_name
 
 %%
 
@@ -136,7 +140,7 @@ start: start command
        | command
        ;
 
-command: 
+command:
                NAME opt_name opt_base { def_image_name ($2, $3, 0); }
        |       LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
        |       DESCRIPTION ID { def_description ($2);}
@@ -145,7 +149,7 @@ command:
        |       CODE attr_list { def_section ("CODE", $2);}
        |       DATAU attr_list  { def_section ("DATA", $2);}
        |       SECTIONS seclist
-       |       EXPORTS explist 
+       |       EXPORTS explist
        |       IMPORTS implist
        |       VERSIONK NUMBER { def_version ($2, 0);}
        |       VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
@@ -164,7 +168,7 @@ expline:
                /* The opt_comma is necessary to support both the usual
                  DEF file syntax as well as .drectve syntax which
                  mandates <expsym>,<expoptlist>.  */
-               dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
+               opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
                        { def_exports ($1, $2, $3, $5, $7); }
        ;
 exp_opt_list:
@@ -184,24 +188,24 @@ exp_opt:
        |       PRIVATEU        { $$ = 8; }
        |       PRIVATEL        { $$ = 8; }
        ;
-implist:       
+implist:
                implist impline
        |       impline
        ;
 
 impline:
-               ID '=' ID '.' ID '.' ID opt_equalequal_name
-                 { def_import ($1, $3, $5, $7, -1, $8); }
+              ID '=' ID '.' ID '.' ID opt_equalequal_name
+                { def_import ($1, $3, $5, $7, -1, $8); }
        |       ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
                                 { def_import ($1, $3, $5,  0, $7, $8); }
        |       ID '=' ID '.' ID opt_equalequal_name
-                 { def_import ($1, $3,  0, $5, -1, $6); }
+                { def_import ($1, $3,  0, $5, -1, $6); }
        |       ID '=' ID '.' NUMBER opt_equalequal_name
-                 { def_import ($1, $3,  0,  0, $5, $6); }
+                { def_import ($1, $3,  0,  0, $5, $6); }
        |       ID '.' ID '.' ID opt_equalequal_name
-                 { def_import( 0, $1, $3, $5, -1, $6); }
+                { def_import( 0, $1, $3, $5, -1, $6); }
        |       ID '.' ID opt_equalequal_name
-                 { def_import ( 0, $1,  0, $3, -1, $4); }
+                { def_import ( 0, $1,  0, $3, -1, $4); }
 ;
 
 seclist:
@@ -221,32 +225,78 @@ attr_list:
 
 opt_comma:
        ','
-       | 
+       |
        ;
 opt_number: ',' NUMBER { $$=$2;}
        |          { $$=-1;}
        ;
-       
+
 attr:
                READ    { $$ = 1;}
-       |       WRITE   { $$ = 2;}      
+       |       WRITE   { $$ = 2;}
        |       EXECUTE { $$=4;}
        |       SHARED  { $$=8;}
        ;
 
-opt_name: ID           { $$ = $1; }
-       | '.' ID
+
+keyword_as_name: BASE { $$ = "BASE"; }
+        | CODE { $$ = "CODE"; }
+        | CONSTANTU { $$ = "CONSTANT"; }
+        | CONSTANTL { $$ = "constant"; }
+        | DATAU { $$ = "DATA"; }
+        | DATAL { $$ = "data"; }
+        | DESCRIPTION { $$ = "DESCRIPTION"; }
+        | DIRECTIVE { $$ = "DIRECTIVE"; }
+        | EXECUTE { $$ = "EXECUTE"; }
+        | EXPORTS { $$ = "EXPORTS"; }
+        | HEAPSIZE { $$ = "HEAPSIZE"; }
+        | IMPORTS { $$ = "IMPORTS"; }
+/* Disable LIBRARY keyword as valid symbol-name.  This is necessary
+   for libtool, which places this command after EXPORTS command.
+   This behavior is illegal by specification, but sadly required by
+   by compatibility reasons.
+   See PR binutils/13710
+        | LIBRARY { $$ = "LIBRARY"; } */
+        | NAME { $$ = "NAME"; }
+        | NONAMEU { $$ = "NONAME"; }
+        | NONAMEL { $$ = "noname"; }
+        | PRIVATEU { $$ = "PRIVATE"; }
+        | PRIVATEL { $$ = "private"; }
+        | READ { $$ = "READ"; }
+        | SHARED  { $$ = "SHARED"; }
+        | STACKSIZE_K { $$ = "STACKSIZE"; }
+        | VERSIONK { $$ = "VERSION"; }
+        | WRITE { $$ = "WRITE"; }
+        ;
+
+opt_name2: ID { $$ = $1; }
+       | '.' keyword_as_name
+         {
+           char *name = xmalloc (strlen ($2) + 2);
+           sprintf (name, ".%s", $2);
+           $$ = name;
+         }
+       | '.' opt_name2
          {
            char *name = def_pool_alloc (strlen ($2) + 2);
            sprintf (name, ".%s", $2);
            $$ = name;
          }
-       | ID '.' ID     
-         { 
+       | keyword_as_name '.' opt_name2
+         {
            char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
            sprintf (name, "%s.%s", $1, $3);
            $$ = name;
          }
+       | ID '.' opt_name2
+         {
+           char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
+           sprintf (name, "%s.%s", $1, $3);
+           $$ = name;
+         }
+       ;
+
+opt_name: opt_name2 { $$ = $1; }
        |               { $$ = ""; }
        ;
 
@@ -254,33 +304,18 @@ opt_equalequal_name: EQUAL ID     { $$ = $2; }
        |                                                       { $$ = 0; }
        ;
 
-opt_ordinal: 
+opt_ordinal:
          '@' NUMBER     { $$ = $2;}
        |                { $$ = -1;}
        ;
 
 opt_equal_name:
-          '=' dot_name { $$ = $2; }
-        |              { $$ =  0; }                     
+         '=' opt_name2 { $$ = $2; }
+       |               { $$ =  0; }
        ;
 
-opt_base: BASE '=' NUMBER      { $$ = $3;}
-       |       { $$ = -1;}
-       ;
-
-dot_name: ID           { $$ = $1; }
-       | '.' ID
-         {
-           char *name = def_pool_alloc (strlen ($2) + 2);
-           sprintf (name, ".%s", $2);
-           $$ = name;
-         }
-       | dot_name '.' ID       
-         { 
-           char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
-           sprintf (name, "%s.%s", $1, $3);
-           $$ = name;
-         }
+opt_base: BASE '=' VMA { $$ = $3;}
+       |       { $$ = (bfd_vma) -1;}
        ;
 
 anylang_id: ID         { $$ = $1; }
@@ -307,6 +342,8 @@ opt_id: ID          { $$ = $1; }
        ;
 
 NUMBER: DIGITS         { $$ = strtoul ($1, 0, 0); }
+       ;
+VMA: DIGITS            { $$ = (bfd_vma) strtoull ($1, 0, 0); }
 
 %%
 
@@ -476,7 +513,11 @@ def_file_print (FILE *file, def_file *fdef)
   if (fdef->is_dll != -1)
     fprintf (file, "  is dll: %s\n", fdef->is_dll ? "yes" : "no");
   if (fdef->base_address != (bfd_vma) -1)
-    fprintf (file, "  base address: 0x%08x\n", fdef->base_address);
+    {
+      fprintf (file, "  base address: 0x");
+      fprintf_vma (file, fdef->base_address);
+      fprintf (file, "\n");
+    }
   if (fdef->description)
     fprintf (file, "  description: `%s'\n", fdef->description);
   if (fdef->stack_reserve != -1)
@@ -594,27 +635,35 @@ find_export_in_list (def_file_export *b, int max,
   if (!max)
     return 0;
   if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
-    return 0;
+    {
+      if (!e)
+       *is_ident = 1;
+      return 0;
+    }
   if (max == 1)
     return 1;
   if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
     return max;
   else if (!e || max == 2)
-    return max - 1;
+    {
+      if (!e)
+       *is_ident = 1;
+      return max - 1;
+    }
   l = 0; r = max - 1;
   while (l < r)
     {
       p = (l + r) / 2;
       e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
       if (!e)
-        {
-          *is_ident = 1;
-          return p;
-        }
+       {
+         *is_ident = 1;
+         return p;
+       }
       else if (e < 0)
-        r = p - 1;
+       r = p - 1;
       else if (e > 0)
-        l = p + 1;
+       l = p + 1;
     }
   if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
     ++l;
@@ -705,13 +754,15 @@ cmp_import_elem (const def_file_import *e, const char *ex_name,
 {
   int r;
 
+  if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
+    return r;
   if ((r = are_names_equal (ex_name, e->name)) != 0)
     return r;
   if ((r = are_names_equal (in_name, e->internal_name)) != 0)
     return r;
   if (ord != e->ordinal)
     return (ord < e->ordinal ? -1 : 1);
-  return are_names_equal (module, (e->module ? e->module->name : NULL));
+  return 0;
 }
 
 /* Search the position of the identical element, or returns the position
@@ -729,27 +780,35 @@ find_import_in_list (def_file_import *b, int max,
   if (!max)
     return 0;
   if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
-    return 0;
+    {
+      if (!e)
+       *is_ident = 1;
+      return 0;
+    }
   if (max == 1)
     return 1;
   if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
     return max;
   else if (!e || max == 2)
-    return max - 1;
+    {
+      if (!e)
+       *is_ident = 1;
+      return max - 1;
+    }
   l = 0; r = max - 1;
   while (l < r)
     {
       p = (l + r) / 2;
       e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
       if (!e)
-        {
-          *is_ident = 1;
-          return p;
-        }
+       {
+         *is_ident = 1;
+         return p;
+       }
       else if (e < 0)
-        r = p - 1;
+       r = p - 1;
       else if (e > 0)
-        l = p + 1;
+       l = p + 1;
     }
   if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
     ++l;
@@ -758,6 +817,26 @@ find_import_in_list (def_file_import *b, int max,
   return l;
 }
 
+static void
+fill_in_import (def_file_import *i,
+               const char *name,
+               def_file_module *module,
+               int ordinal,
+               const char *internal_name,
+               const char *its_name)
+{
+  memset (i, 0, sizeof (def_file_import));
+  if (name)
+    i->name = xstrdup (name);
+  i->module = module;
+  i->ordinal = ordinal;
+  if (internal_name)
+    i->internal_name = xstrdup (internal_name);
+  else
+    i->internal_name = i->name;
+  i->its_name = (its_name ? xstrdup (its_name) : NULL);
+}
+
 def_file_import *
 def_file_add_import (def_file *fdef,
                     const char *name,
@@ -792,18 +871,74 @@ def_file_add_import (def_file *fdef,
     }
   i = fdef->imports + pos;
   if (pos != fdef->num_imports)
-    memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
-  memset (i, 0, sizeof (def_file_import));
-  if (name)
-    i->name = xstrdup (name);
-  if (module)
-    i->module = def_stash_module (fdef, module);
-  i->ordinal = ordinal;
-  if (internal_name)
-    i->internal_name = xstrdup (internal_name);
-  else
-    i->internal_name = i->name;
-  i->its_name = (its_name ? xstrdup (its_name) : NULL);
+    memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
+
+  fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
+                 internal_name, its_name);
+  fdef->num_imports++;
+
+  return i;
+}
+
+int
+def_file_add_import_from (def_file *fdef,
+                         int num_imports,
+                         const char *name,
+                         const char *module,
+                         int ordinal,
+                         const char *internal_name,
+                         const char *its_name ATTRIBUTE_UNUSED)
+{
+  def_file_import *i;
+  int is_dup;
+  int pos;
+  int max_imports = ROUND_UP (fdef->num_imports, 16);
+
+  /* We need to avoid here duplicates.  */
+  is_dup = 0;
+  pos = find_import_in_list (fdef->imports, fdef->num_imports,
+                            name, internal_name ? internal_name : name,
+                            module, ordinal, &is_dup);
+  if (is_dup != 0)
+    return -1;
+  if (fdef->imports && pos != fdef->num_imports)
+    {
+      i = fdef->imports + pos;
+      if (i->module && strcmp (i->module->name, module) == 0)
+       return -1;
+    }
+
+  if (fdef->num_imports + num_imports - 1 >= max_imports)
+    {
+      max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
+
+      if (fdef->imports)
+       fdef->imports = xrealloc (fdef->imports,
+                                max_imports * sizeof (def_file_import));
+      else
+       fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
+    }
+  i = fdef->imports + pos;
+  if (pos != fdef->num_imports)
+    memmove (i + num_imports, i,
+            sizeof (def_file_import) * (fdef->num_imports - pos));
+
+  return pos;
+}
+
+def_file_import *
+def_file_add_import_at (def_file *fdef,
+                       int pos,
+                       const char *name,
+                       const char *module,
+                       int ordinal,
+                       const char *internal_name,
+                       const char *its_name)
+{
+  def_file_import *i = fdef->imports + pos;
+
+  fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
+                 internal_name, its_name);
   fdef->num_imports++;
 
   return i;
@@ -844,10 +979,10 @@ def_file_add_directive (def_file *my_def, const char *param, int len)
        break;
 
       /* Scan forward until we encounter any of:
-          - the end of the buffer
+         - the end of the buffer
          - the start of a new option
-         - a newline seperating options
-          - a NUL seperating options.  */
+         - a newline separating options
+         - a NUL separating options.  */
       for (tend = (char *) (param + 1);
           (tend < pend
            && !(ISSPACE (tend[-1]) && *tend == '-')
@@ -875,13 +1010,20 @@ def_file_add_directive (def_file *my_def, const char *param, int len)
 
       if (!diropts[i].param)
        {
-         char saved;
+         if (tend < pend)
+           {
+             char saved;
 
-         saved = * tend;
-         * tend = 0;
-         /* xgettext:c-format */
-         einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
-         * tend = saved;
+             saved = * tend;
+             * tend = 0;
+             /* xgettext:c-format */
+             einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
+             * tend = saved;
+           }
+         else
+           {
+             einfo (_("Warning: corrupt .drectve at end of def file\n"));
+           }
        }
 
       lex_parse_string = 0;
@@ -895,7 +1037,7 @@ def_file_add_directive (def_file *my_def, const char *param, int len)
 /* Parser Callbacks.  */
 
 static void
-def_image_name (const char *name, int base, int is_dll)
+def_image_name (const char *name, bfd_vma base, int is_dll)
 {
   /* If a LIBRARY or NAME statement is specified without a name, there is nothing
      to do here.  We retain the output filename specified on command line.  */
@@ -909,14 +1051,14 @@ def_image_name (const char *name, int base, int is_dll)
               name);
       if (def->name)
        free (def->name);
-      /* Append the default suffix, if none specified.  */ 
+      /* Append the default suffix, if none specified.  */
       if (strchr (image_name, '.') == 0)
        {
          const char * suffix = is_dll ? ".dll" : ".exe";
 
          def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
          sprintf (def->name, "%s%s", image_name, suffix);
-        }
+       }
       else
        def->name = xstrdup (image_name);
     }
@@ -1064,7 +1206,7 @@ def_import (const char *internal_name,
   char *buf = 0;
   const char *ext = dllext ? dllext : "dll";
   int is_dup = 0;
-   
+
   buf = xmalloc (strlen (module) + strlen (ext) + 2);
   sprintf (buf, "%s.%s", module, ext);
   module = buf;
@@ -1096,7 +1238,7 @@ static void
 def_aligncomm (char *str, int align)
 {
   def_file_aligncomm *c, *p;
-  
+
   p = NULL;
   c = def->aligncomms;
   while (c != NULL)
@@ -1111,7 +1253,7 @@ def_aligncomm (char *str, int align)
            return;
        }
       if (e > 0)
-        break;
+       break;
       c = (p = c)->next;
     }
 
@@ -1302,12 +1444,12 @@ def_lex (void)
 
       if (q == '@')
        {
-          if (ISBLANK (c) ) /* '@' followed by whitespace.  */
+         if (ISBLANK (c) ) /* '@' followed by whitespace.  */
            return (q);
-          else if (ISDIGIT (c)) /* '@' followed by digit.  */
-            {
+         else if (ISDIGIT (c)) /* '@' followed by digit.  */
+           {
              def_ungetc (c);
-              return (q);
+             return (q);
            }
 #if TRACE
          printf ("lex: @ returns itself\n");
@@ -1323,7 +1465,7 @@ def_lex (void)
        def_ungetc (c);
       if (ISALPHA (q)) /* Check for tokens.  */
        {
-          for (i = 0; tokens[i].name; i++)
+         for (i = 0; tokens[i].name; i++)
            if (strcmp (tokens[i].name, buffer) == 0)
              {
 #if TRACE
@@ -1361,12 +1503,12 @@ def_lex (void)
     {
       c = def_getc ();
       if (c == '=')
-        {
+       {
 #if TRACE
-          printf ("lex: `==' returns EQUAL\n");
+         printf ("lex: `==' returns EQUAL\n");
 #endif
-                 return EQUAL;
-        }
+         return EQUAL;
+       }
       def_ungetc (c);
 #if TRACE
       printf ("lex: `=' returns itself\n");
This page took 0.032415 seconds and 4 git commands to generate.