1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "libiberty.h"
24 #include "safe-ctype.h"
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
45 #define yyerror def_error
46 #define yylval def_lval
47 #define yychar def_char
48 #define yydebug def_debug
49 #define yypact def_pact
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
62 #define yy_yys def_yys
63 #define yystate def_state
66 #define yy_yyv def_yyv
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined */
70 #define yytoks def_toks /* With YYDEBUG defined */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
81 static void def_description PARAMS
((const char *));
82 static void def_exports PARAMS
((const char *, const char *, int, int));
83 static void def_heapsize PARAMS
((int, int));
84 static void def_import
85 PARAMS
((const char *, const char *, const char *, const char *, int));
86 static void def_library PARAMS
((const char *, int));
87 static def_file_module
*def_stash_module PARAMS
((def_file
*, const char *));
88 static void def_name PARAMS
((const char *, int));
89 static void def_section PARAMS
((const char *, int));
90 static void def_section_alt PARAMS
((const char *, const char *));
91 static void def_stacksize PARAMS
((int, int));
92 static void def_version PARAMS
((int, int));
93 static void def_directive PARAMS
((char *));
94 static int def_parse PARAMS
((void));
95 static int def_error PARAMS
((const char *));
96 static void put_buf PARAMS
((char));
97 static int def_getc PARAMS
((void));
98 static int def_ungetc PARAMS
((int));
99 static int def_lex PARAMS
((void));
101 static int lex_forced_token
= 0;
102 static const char *lex_parse_string
= 0;
103 static const char *lex_parse_string_end
= 0;
112 %token NAME
, LIBRARY
, DESCRIPTION
, STACKSIZE
, HEAPSIZE
, CODE
, DATAU
, DATAL
113 %token SECTIONS
, EXPORTS
, IMPORTS
, VERSIONK
, BASE
, CONSTANTU
, CONSTANTL
114 %token PRIVATEU
, PRIVATEL
115 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
117 %token
<number
> NUMBER
118 %type
<number
> opt_base opt_ordinal
119 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
120 %type
<id
> opt_name opt_equal_name
129 NAME opt_name opt_base
{ def_name
($2, $3); }
130 | LIBRARY opt_name opt_base
{ def_library
($2, $3); }
131 | DESCRIPTION ID
{ def_description
($2);}
132 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
133 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
134 | CODE attr_list
{ def_section
("CODE", $2);}
135 | DATAU attr_list
{ def_section
("DATA", $2);}
139 | VERSIONK NUMBER
{ def_version
($2, 0);}
140 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
141 | DIRECTIVE ID
{ def_directive
($2);}
152 /* The opt_comma is necessary to support both the usual
153 DEF file syntax as well as .drectve syntax which
154 mandates <expsym>,<expoptlist>. */
155 ID opt_equal_name opt_ordinal opt_comma exp_opt_list
156 { def_exports
($1, $2, $3, $5); }
159 /* The opt_comma is necessary to support both the usual
160 DEF file syntax as well as .drectve syntax which
161 allows for comma separated opt list. */
162 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
167 | NONAMEL
{ $$
= 1; }
168 | CONSTANTU
{ $$
= 2; }
169 | CONSTANTL
{ $$
= 2; }
172 | PRIVATEU
{ $$
= 8; }
173 | PRIVATEL
{ $$
= 8; }
181 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
182 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
183 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
184 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
185 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
186 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
195 ID attr_list
{ def_section
($1, $2);}
196 | ID ID
{ def_section_alt
($1, $2);}
200 attr_list opt_comma attr
{ $$
= $1 |
$3; }
208 opt_number: ',' NUMBER
{ $$
=$2;}
219 opt_name: ID
{ $$
= $1; }
222 char * name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
223 sprintf
(name
, "%s.%s", $1, $3);
230 '@' NUMBER
{ $$
= $2;}
239 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
247 /*****************************************************************************
249 *****************************************************************************/
251 static FILE *the_file
;
252 static const char *def_filename
;
253 static int linenumber
;
254 static def_file
*def
;
255 static int saw_newline
;
259 struct directive
*next
;
264 static struct directive
*directives
= 0;
269 def_file
*rv
= (def_file
*) xmalloc
(sizeof
(def_file
));
270 memset
(rv
, 0, sizeof
(def_file
));
272 rv
->base_address
= (bfd_vma
) (-1);
273 rv
->stack_reserve
= rv
->stack_commit
= -1;
274 rv
->heap_reserve
= rv
->heap_commit
= -1;
275 rv
->version_major
= rv
->version_minor
= -1;
280 def_file_parse
(filename
, add_to
)
281 const char *filename
;
286 the_file
= fopen
(filename
, "r");
287 def_filename
= filename
;
300 def
= def_file_empty
();
313 for
(d
= directives
; d
; d
= d
->next
)
316 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
318 def_file_add_directive
(def
, d
->name
, d
->len
);
333 if
(def
->description
)
334 free
(def
->description
);
336 if
(def
->section_defs
)
338 for
(i
= 0; i
< def
->num_section_defs
; i
++)
340 if
(def
->section_defs
[i
].name
)
341 free
(def
->section_defs
[i
].name
);
342 if
(def
->section_defs
[i
].class
)
343 free
(def
->section_defs
[i
].class
);
345 free
(def
->section_defs
);
350 for
(i
= 0; i
< def
->num_exports
; i
++)
352 if
(def
->exports
[i
].internal_name
353 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
354 free
(def
->exports
[i
].internal_name
);
355 if
(def
->exports
[i
].name
)
356 free
(def
->exports
[i
].name
);
363 for
(i
= 0; i
< def
->num_imports
; i
++)
365 if
(def
->imports
[i
].internal_name
366 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
367 free
(def
->imports
[i
].internal_name
);
368 if
(def
->imports
[i
].name
)
369 free
(def
->imports
[i
].name
);
376 def_file_module
*m
= def
->modules
;
377 def
->modules
= def
->modules
->next
;
384 #ifdef DEF_FILE_PRINT
386 def_file_print
(file
, def
)
391 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
393 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
394 if
(def
->is_dll
!= -1)
395 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
396 if
(def
->base_address
!= (bfd_vma
) (-1))
397 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
398 if
(def
->description
)
399 fprintf
(file
, " description: `%s'\n", def
->description
);
400 if
(def
->stack_reserve
!= -1)
401 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
402 if
(def
->stack_commit
!= -1)
403 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
404 if
(def
->heap_reserve
!= -1)
405 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
406 if
(def
->heap_commit
!= -1)
407 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
409 if
(def
->num_section_defs
> 0)
411 fprintf
(file
, " section defs:\n");
412 for
(i
= 0; i
< def
->num_section_defs
; i
++)
414 fprintf
(file
, " name: `%s', class: `%s', flags:",
415 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
416 if
(def
->section_defs
[i
].flag_read
)
417 fprintf
(file
, " R");
418 if
(def
->section_defs
[i
].flag_write
)
419 fprintf
(file
, " W");
420 if
(def
->section_defs
[i
].flag_execute
)
421 fprintf
(file
, " X");
422 if
(def
->section_defs
[i
].flag_shared
)
423 fprintf
(file
, " S");
424 fprintf
(file
, "\n");
428 if
(def
->num_exports
> 0)
430 fprintf
(file
, " exports:\n");
431 for
(i
= 0; i
< def
->num_exports
; i
++)
433 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
434 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
435 def
->exports
[i
].ordinal
);
436 if
(def
->exports
[i
].flag_private
)
437 fprintf
(file
, " P");
438 if
(def
->exports
[i
].flag_constant
)
439 fprintf
(file
, " C");
440 if
(def
->exports
[i
].flag_noname
)
441 fprintf
(file
, " N");
442 if
(def
->exports
[i
].flag_data
)
443 fprintf
(file
, " D");
444 fprintf
(file
, "\n");
448 if
(def
->num_imports
> 0)
450 fprintf
(file
, " imports:\n");
451 for
(i
= 0; i
< def
->num_imports
; i
++)
453 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
454 def
->imports
[i
].internal_name
,
455 def
->imports
[i
].module
,
456 def
->imports
[i
].name
,
457 def
->imports
[i
].ordinal
);
460 if
(def
->version_major
!= -1)
461 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
462 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
467 def_file_add_export
(def
, external_name
, internal_name
, ordinal
)
469 const char *external_name
;
470 const char *internal_name
;
474 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
475 if
(def
->num_exports
>= max_exports
)
477 max_exports
= ROUND_UP
(def
->num_exports
+1, 32);
479 def
->exports
= (def_file_export
*) xrealloc
(def
->exports
, max_exports
* sizeof
(def_file_export
));
481 def
->exports
= (def_file_export
*) xmalloc
(max_exports
* sizeof
(def_file_export
));
483 e
= def
->exports
+ def
->num_exports
;
484 memset
(e
, 0, sizeof
(def_file_export
));
485 if
(internal_name
&& !external_name
)
486 external_name
= internal_name
;
487 if
(external_name
&& !internal_name
)
488 internal_name
= external_name
;
489 e
->name
= xstrdup
(external_name
);
490 e
->internal_name
= xstrdup
(internal_name
);
491 e
->ordinal
= ordinal
;
496 static def_file_module
*
497 def_stash_module
(def
, name
)
502 for
(s
=def
->modules
; s
; s
=s
->next
)
503 if
(strcmp
(s
->name
, name
) == 0)
505 s
= (def_file_module
*) xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
506 s
->next
= def
->modules
;
509 strcpy
(s
->name
, name
);
514 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
)
519 const char *internal_name
;
522 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
523 if
(def
->num_imports
>= max_imports
)
525 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
527 def
->imports
= (def_file_import
*) xrealloc
(def
->imports
, max_imports
* sizeof
(def_file_import
));
529 def
->imports
= (def_file_import
*) xmalloc
(max_imports
* sizeof
(def_file_import
));
531 i
= def
->imports
+ def
->num_imports
;
532 memset
(i
, 0, sizeof
(def_file_import
));
534 i
->name
= xstrdup
(name
);
536 i
->module
= def_stash_module
(def
, module
);
537 i
->ordinal
= ordinal
;
539 i
->internal_name
= xstrdup
(internal_name
);
541 i
->internal_name
= i
->name
;
553 { "-heap", HEAPSIZE
},
554 { "-stack", STACKSIZE
},
555 { "-attr", SECTIONS
},
556 { "-export", EXPORTS
},
561 def_file_add_directive
(my_def
, param
, len
)
566 def_file
*save_def
= def
;
567 const char *pend
= param
+ len
;
568 const char *tend
= param
;
575 while
(param
< pend
&& ISSPACE
(*param
))
577 for
(tend
= param
+ 1;
578 tend
< pend
&& !(ISSPACE
(tend
[-1]) && *tend
== '-');
581 for
(i
= 0; diropts
[i
].param
; i
++)
583 int len
= strlen
(diropts
[i
].param
);
584 if
(tend
- param
>= len
585 && strncmp
(param
, diropts
[i
].param
, len
) == 0
586 && (param
[len
] == ':' || param
[len
] == ' '))
588 lex_parse_string_end
= tend
;
589 lex_parse_string
= param
+ len
+ 1;
590 lex_forced_token
= diropts
[i
].token
;
597 if
(!diropts
[i
].param
)
599 /* xgettext:c-format */
600 einfo
(_
("Warning: .drectve `%.*s' unrecognized\n"),
601 tend
- param
, param
);
603 lex_parse_string
= 0;
610 /*****************************************************************************
612 *****************************************************************************/
615 def_name
(name
, base
)
621 def
->name
= xstrdup
(name
);
622 def
->base_address
= base
;
627 def_library
(name
, base
)
633 def
->name
= xstrdup
(name
);
634 def
->base_address
= base
;
639 def_description
(text
)
642 int len
= def
->description ? strlen
(def
->description
) : 0;
643 len
+= strlen
(text
) + 1;
644 if
(def
->description
)
646 def
->description
= (char *) xrealloc
(def
->description
, len
);
647 strcat
(def
->description
, text
);
651 def
->description
= (char *) xmalloc
(len
);
652 strcpy
(def
->description
, text
);
657 def_stacksize
(reserve
, commit
)
661 def
->stack_reserve
= reserve
;
662 def
->stack_commit
= commit
;
666 def_heapsize
(reserve
, commit
)
670 def
->heap_reserve
= reserve
;
671 def
->heap_commit
= commit
;
675 def_section
(name
, attr
)
680 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
681 if
(def
->num_section_defs
>= max_sections
)
683 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
684 if
(def
->section_defs
)
685 def
->section_defs
= (def_file_section
*) xrealloc
(def
->section_defs
, max_sections
* sizeof
(def_file_import
));
687 def
->section_defs
= (def_file_section
*) xmalloc
(max_sections
* sizeof
(def_file_import
));
689 s
= def
->section_defs
+ def
->num_section_defs
;
690 memset
(s
, 0, sizeof
(def_file_section
));
691 s
->name
= xstrdup
(name
);
701 def
->num_section_defs
++;
705 def_section_alt
(name
, attr
)
710 for
(; *attr
; attr
++)
732 def_section
(name
, aval
);
736 def_exports
(external_name
, internal_name
, ordinal
, flags
)
737 const char *external_name
;
738 const char *internal_name
;
742 def_file_export
*dfe
;
744 if
(!internal_name
&& external_name
)
745 internal_name
= external_name
;
747 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
750 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
752 dfe
->flag_noname
= 1;
754 dfe
->flag_constant
= 1;
758 dfe
->flag_private
= 1;
762 def_import
(internal_name
, module
, dllext
, name
, ordinal
)
763 const char *internal_name
;
773 buf
= (char *) xmalloc
(strlen
(module
) + strlen
(dllext
) + 2);
774 sprintf
(buf
, "%s.%s", module
, dllext
);
778 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
784 def_version
(major
, minor
)
788 def
->version_major
= major
;
789 def
->version_minor
= minor
;
796 struct directive
*d
= (struct directive
*) xmalloc
(sizeof
(struct directive
));
797 d
->next
= directives
;
799 d
->name
= xstrdup
(str
);
800 d
->len
= strlen
(str
);
807 einfo
("%P: %s:%d: %s\n", def_filename
, linenumber
, err
);
813 /*****************************************************************************
815 *****************************************************************************/
820 /* Never freed, but always reused as needed, so no real leak */
821 static char *buffer
= 0;
822 static int buflen
= 0;
823 static int bufptr
= 0;
829 if
(bufptr
== buflen
)
831 buflen
+= 50; /* overly reasonable, eh? */
833 buffer
= (char *) xrealloc
(buffer
, buflen
+ 1);
835 buffer
= (char *) xmalloc
(buflen
+ 1);
837 buffer
[bufptr
++] = c
;
838 buffer
[bufptr
] = 0; /* not optimal, but very convenient */
850 { "CONSTANT", CONSTANTU
},
851 { "constant", CONSTANTL
},
854 { "DESCRIPTION", DESCRIPTION
},
855 { "DIRECTIVE", DIRECTIVE
},
856 { "EXECUTE", EXECUTE
},
857 { "EXPORTS", EXPORTS
},
858 { "HEAPSIZE", HEAPSIZE
},
859 { "IMPORTS", IMPORTS
},
860 { "LIBRARY", LIBRARY
},
862 { "NONAME", NONAMEU
},
863 { "noname", NONAMEL
},
864 { "PRIVATE", PRIVATEU
},
865 { "private", PRIVATEL
},
867 { "SECTIONS", SECTIONS
},
868 { "SEGMENTS", SECTIONS
},
869 { "SHARED", SHARED
},
870 { "STACKSIZE", STACKSIZE
},
871 { "VERSION", VERSIONK
},
880 if
(lex_parse_string
)
882 if
(lex_parse_string
>= lex_parse_string_end
)
885 rv
= *lex_parse_string
++;
889 rv
= fgetc
(the_file
);
900 if
(lex_parse_string
)
906 return ungetc
(c
, the_file
);
914 if
(lex_forced_token
)
916 i
= lex_forced_token
;
917 lex_forced_token
= 0;
919 printf
("lex: forcing token %d\n", i
);
926 /* trim leading whitespace */
927 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
933 printf
("lex: EOF\n");
938 if
(saw_newline
&& c
== ';')
944 while
(c
!= EOF
&& c
!= '\n');
949 /* must be something else */
955 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
962 yylval.number
= strtoul
(buffer
, 0, 0);
964 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
969 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
978 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
980 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
986 printf
("lex: @ returns itself\n");
990 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@", c
)))
997 if
(ISALPHA
(q
)) /* Check for tokens. */
999 for
(i
= 0; tokens
[i
].name
; i
++)
1000 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1003 printf
("lex: `%s' is a string token\n", buffer
);
1005 return tokens
[i
].token
;
1009 printf
("lex: `%s' returns ID\n", buffer
);
1011 yylval.id
= xstrdup
(buffer
);
1015 if
(c
== '\'' || c
== '"')
1020 while
(c
!= EOF
&& c
!= q
)
1025 yylval.id
= xstrdup
(buffer
);
1027 printf
("lex: `%s' returns ID\n", buffer
);
1032 if
(c
== '=' || c
== '.' || c
== ',')
1035 printf
("lex: `%c' returns itself\n", c
);
1046 /*printf ("lex: 0x%02x ignored\n", c); */