1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "libiberty.h"
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
35 as well as gratuitiously global symbol names, so we can have multiple
36 yacc generated parsers in ld. Note that these are only the variables
37 produced by yacc. If other parser generators (bison, byacc, etc) produce
38 additional global names that conflict at link time, then those parser
39 generators need to be fixed instead of adding those names to this list. */
41 #define yymaxdepth def_maxdepth
42 #define yyparse def_parse
44 #define yyerror def_error
45 #define yylval def_lval
46 #define yychar def_char
47 #define yydebug def_debug
48 #define yypact def_pact
55 #define yyexca def_exca
56 #define yyerrflag def_errflag
57 #define yynerrs def_nerrs
61 #define yy_yys def_yys
62 #define yystate def_state
65 #define yy_yyv def_yyv
67 #define yylloc def_lloc
68 #define yyreds def_reds /* With YYDEBUG defined */
69 #define yytoks def_toks /* With YYDEBUG defined */
70 #define yylhs def_yylhs
71 #define yylen def_yylen
72 #define yydefred def_yydefred
73 #define yydgoto def_yydgoto
74 #define yysindex def_yysindex
75 #define yyrindex def_yyrindex
76 #define yygindex def_yygindex
77 #define yytable def_yytable
78 #define yycheck def_yycheck
80 static void def_description PARAMS
((const char *));
81 static void def_exports PARAMS
((const char *, const char *, int, int));
82 static void def_heapsize PARAMS
((int, int));
83 static void def_import
84 PARAMS
((const char *, const char *, const char *, const char *, int));
85 static void def_library PARAMS
((const char *, int));
86 static def_file_module
*def_stash_module PARAMS
((def_file
*, char *));
87 static void def_name PARAMS
((const char *, int));
88 static void def_section PARAMS
((const char *, int));
89 static void def_section_alt PARAMS
((const char *, const char *));
90 static void def_stacksize PARAMS
((int, int));
91 static void def_version PARAMS
((int, int));
92 static void def_directive PARAMS
((char *));
93 static int def_parse PARAMS
((void));
94 static int def_error PARAMS
((const char *));
95 static void put_buf PARAMS
((char));
96 static int def_getc PARAMS
((void));
97 static int def_ungetc PARAMS
((int));
98 static int def_lex PARAMS
((void));
100 static int lex_forced_token
= 0;
101 static const char *lex_parse_string
= 0;
102 static const char *lex_parse_string_end
= 0;
111 %token NAME
, LIBRARY
, DESCRIPTION
, STACKSIZE
, HEAPSIZE
, CODE
, DATAU
, DATAL
112 %token SECTIONS
, EXPORTS
, IMPORTS
, VERSIONK
, BASE
, CONSTANTU
, CONSTANTL
113 %token PRIVATEU
, PRIVATEL
114 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
116 %token
<number
> NUMBER
117 %type
<number
> opt_base opt_ordinal
118 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
119 %type
<id
> opt_name opt_equal_name
128 NAME opt_name opt_base
{ def_name
($2, $3); }
129 | LIBRARY opt_name opt_base
{ def_library
($2, $3); }
130 | DESCRIPTION ID
{ def_description
($2);}
131 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
132 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
133 | CODE attr_list
{ def_section
("CODE", $2);}
134 | DATAU attr_list
{ def_section
("DATA", $2);}
138 | VERSIONK NUMBER
{ def_version
($2, 0);}
139 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
140 | DIRECTIVE ID
{ def_directive
($2);}
151 /* The opt_comma is necessary to support both the usual
152 DEF file syntax as well as .drectve syntax which
153 mandates <expsym>,<expoptlist>. */
154 ID opt_equal_name opt_ordinal opt_comma exp_opt_list
155 { def_exports
($1, $2, $3, $5); }
158 /* The opt_comma is necessary to support both the usual
159 DEF file syntax as well as .drectve syntax which
160 allows for comma separated opt list. */
161 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
166 | NONAMEL
{ $$
= 1; }
167 | CONSTANTU
{ $$
= 2; }
168 | CONSTANTL
{ $$
= 2; }
171 | PRIVATEU
{ $$
= 8; }
172 | PRIVATEL
{ $$
= 8; }
180 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
181 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
182 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
183 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
184 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
185 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
194 ID attr_list
{ def_section
($1, $2);}
195 | ID ID
{ def_section_alt
($1, $2);}
199 attr_list opt_comma attr
{ $$
= $1 |
$3; }
207 opt_number: ',' NUMBER
{ $$
=$2;}
218 opt_name: ID
{ $$
= $1; }
221 char * name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
222 sprintf
(name
, "%s.%s", $1, $3);
229 '@' NUMBER
{ $$
= $2;}
238 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
246 /*****************************************************************************
248 *****************************************************************************/
250 static FILE *the_file
;
251 static const char *def_filename
;
252 static int linenumber
;
253 static def_file
*def
;
254 static int saw_newline
;
258 struct directive
*next
;
263 static struct directive
*directives
= 0;
268 def_file
*rv
= (def_file
*) xmalloc
(sizeof
(def_file
));
269 memset
(rv
, 0, sizeof
(def_file
));
271 rv
->base_address
= (bfd_vma
) (-1);
272 rv
->stack_reserve
= rv
->stack_commit
= -1;
273 rv
->heap_reserve
= rv
->heap_commit
= -1;
274 rv
->version_major
= rv
->version_minor
= -1;
279 def_file_parse
(filename
, add_to
)
280 const char *filename
;
285 the_file
= fopen
(filename
, "r");
286 def_filename
= filename
;
299 def
= def_file_empty
();
312 for
(d
= directives
; d
; d
= d
->next
)
315 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
317 def_file_add_directive
(def
, d
->name
, d
->len
);
332 if
(def
->description
)
333 free
(def
->description
);
335 if
(def
->section_defs
)
337 for
(i
= 0; i
< def
->num_section_defs
; i
++)
339 if
(def
->section_defs
[i
].name
)
340 free
(def
->section_defs
[i
].name
);
341 if
(def
->section_defs
[i
].class
)
342 free
(def
->section_defs
[i
].class
);
344 free
(def
->section_defs
);
349 for
(i
= 0; i
< def
->num_exports
; i
++)
351 if
(def
->exports
[i
].internal_name
352 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
353 free
(def
->exports
[i
].internal_name
);
354 if
(def
->exports
[i
].name
)
355 free
(def
->exports
[i
].name
);
362 for
(i
= 0; i
< def
->num_imports
; i
++)
364 if
(def
->imports
[i
].internal_name
365 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
366 free
(def
->imports
[i
].internal_name
);
367 if
(def
->imports
[i
].name
)
368 free
(def
->imports
[i
].name
);
375 def_file_module
*m
= def
->modules
;
376 def
->modules
= def
->modules
->next
;
383 #ifdef DEF_FILE_PRINT
385 def_file_print
(file
, def
)
390 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
392 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
393 if
(def
->is_dll
!= -1)
394 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
395 if
(def
->base_address
!= (bfd_vma
) (-1))
396 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
397 if
(def
->description
)
398 fprintf
(file
, " description: `%s'\n", def
->description
);
399 if
(def
->stack_reserve
!= -1)
400 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
401 if
(def
->stack_commit
!= -1)
402 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
403 if
(def
->heap_reserve
!= -1)
404 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
405 if
(def
->heap_commit
!= -1)
406 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
408 if
(def
->num_section_defs
> 0)
410 fprintf
(file
, " section defs:\n");
411 for
(i
= 0; i
< def
->num_section_defs
; i
++)
413 fprintf
(file
, " name: `%s', class: `%s', flags:",
414 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
415 if
(def
->section_defs
[i
].flag_read
)
416 fprintf
(file
, " R");
417 if
(def
->section_defs
[i
].flag_write
)
418 fprintf
(file
, " W");
419 if
(def
->section_defs
[i
].flag_execute
)
420 fprintf
(file
, " X");
421 if
(def
->section_defs
[i
].flag_shared
)
422 fprintf
(file
, " S");
423 fprintf
(file
, "\n");
427 if
(def
->num_exports
> 0)
429 fprintf
(file
, " exports:\n");
430 for
(i
= 0; i
< def
->num_exports
; i
++)
432 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
433 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
434 def
->exports
[i
].ordinal
);
435 if
(def
->exports
[i
].flag_private
)
436 fprintf
(file
, " P");
437 if
(def
->exports
[i
].flag_constant
)
438 fprintf
(file
, " C");
439 if
(def
->exports
[i
].flag_noname
)
440 fprintf
(file
, " N");
441 if
(def
->exports
[i
].flag_data
)
442 fprintf
(file
, " D");
443 fprintf
(file
, "\n");
447 if
(def
->num_imports
> 0)
449 fprintf
(file
, " imports:\n");
450 for
(i
= 0; i
< def
->num_imports
; i
++)
452 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
453 def
->imports
[i
].internal_name
,
454 def
->imports
[i
].module
,
455 def
->imports
[i
].name
,
456 def
->imports
[i
].ordinal
);
459 if
(def
->version_major
!= -1)
460 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
461 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
466 def_file_add_export
(def
, external_name
, internal_name
, ordinal
)
468 const char *external_name
;
469 const char *internal_name
;
473 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
474 if
(def
->num_exports
>= max_exports
)
476 max_exports
= ROUND_UP
(def
->num_exports
+1, 32);
478 def
->exports
= (def_file_export
*) xrealloc
(def
->exports
, max_exports
* sizeof
(def_file_export
));
480 def
->exports
= (def_file_export
*) xmalloc
(max_exports
* sizeof
(def_file_export
));
482 e
= def
->exports
+ def
->num_exports
;
483 memset
(e
, 0, sizeof
(def_file_export
));
484 if
(internal_name
&& !external_name
)
485 external_name
= internal_name
;
486 if
(external_name
&& !internal_name
)
487 internal_name
= external_name
;
488 e
->name
= xstrdup
(external_name
);
489 e
->internal_name
= xstrdup
(internal_name
);
490 e
->ordinal
= ordinal
;
495 static def_file_module
*
496 def_stash_module
(def
, name
)
501 for
(s
=def
->modules
; s
; s
=s
->next
)
502 if
(strcmp
(s
->name
, name
) == 0)
504 s
= (def_file_module
*) xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
505 s
->next
= def
->modules
;
508 strcpy
(s
->name
, name
);
513 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
)
518 const char *internal_name
;
521 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
522 if
(def
->num_imports
>= max_imports
)
524 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
526 def
->imports
= (def_file_import
*) xrealloc
(def
->imports
, max_imports
* sizeof
(def_file_import
));
528 def
->imports
= (def_file_import
*) xmalloc
(max_imports
* sizeof
(def_file_import
));
530 i
= def
->imports
+ def
->num_imports
;
531 memset
(i
, 0, sizeof
(def_file_import
));
533 i
->name
= xstrdup
(name
);
535 i
->module
= def_stash_module
(def
, module
);
536 i
->ordinal
= ordinal
;
538 i
->internal_name
= xstrdup
(internal_name
);
540 i
->internal_name
= i
->name
;
552 { "-heap", HEAPSIZE
},
553 { "-stack", STACKSIZE
},
554 { "-attr", SECTIONS
},
555 { "-export", EXPORTS
},
560 def_file_add_directive
(my_def
, param
, len
)
565 def_file
*save_def
= def
;
566 const char *pend
= param
+ len
;
567 const char *tend
= param
;
574 while
(param
< pend
&& isspace
(*param
))
576 for
(tend
= param
+ 1;
577 tend
< pend
&& !(isspace
(tend
[-1]) && *tend
== '-');
580 for
(i
= 0; diropts
[i
].param
; i
++)
582 int len
= strlen
(diropts
[i
].param
);
583 if
(tend
- param
>= len
584 && strncmp
(param
, diropts
[i
].param
, len
) == 0
585 && (param
[len
] == ':' || param
[len
] == ' '))
587 lex_parse_string_end
= tend
;
588 lex_parse_string
= param
+ len
+ 1;
589 lex_forced_token
= diropts
[i
].token
;
596 if
(!diropts
[i
].param
)
598 /* xgettext:c-format */
599 einfo
(_
("Warning: .drectve `%.*s' unrecognized\n"),
600 tend
- param
, param
);
602 lex_parse_string
= 0;
609 /*****************************************************************************
611 *****************************************************************************/
614 def_name
(name
, base
)
620 def
->name
= xstrdup
(name
);
621 def
->base_address
= base
;
626 def_library
(name
, base
)
632 def
->name
= xstrdup
(name
);
633 def
->base_address
= base
;
638 def_description
(text
)
641 int len
= def
->description ? strlen
(def
->description
) : 0;
642 len
+= strlen
(text
) + 1;
643 if
(def
->description
)
645 def
->description
= (char *) xrealloc
(def
->description
, len
);
646 strcat
(def
->description
, text
);
650 def
->description
= (char *) xmalloc
(len
);
651 strcpy
(def
->description
, text
);
656 def_stacksize
(reserve
, commit
)
660 def
->stack_reserve
= reserve
;
661 def
->stack_commit
= commit
;
665 def_heapsize
(reserve
, commit
)
669 def
->heap_reserve
= reserve
;
670 def
->heap_commit
= commit
;
674 def_section
(name
, attr
)
679 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
680 if
(def
->num_section_defs
>= max_sections
)
682 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
683 if
(def
->section_defs
)
684 def
->section_defs
= (def_file_section
*) xrealloc
(def
->section_defs
, max_sections
* sizeof
(def_file_import
));
686 def
->section_defs
= (def_file_section
*) xmalloc
(max_sections
* sizeof
(def_file_import
));
688 s
= def
->section_defs
+ def
->num_section_defs
;
689 memset
(s
, 0, sizeof
(def_file_section
));
690 s
->name
= xstrdup
(name
);
700 def
->num_section_defs
++;
704 def_section_alt
(name
, attr
)
709 for
(; *attr
; attr
++)
731 def_section
(name
, aval
);
735 def_exports
(external_name
, internal_name
, ordinal
, flags
)
736 const char *external_name
;
737 const char *internal_name
;
741 def_file_export
*dfe
;
743 if
(!internal_name
&& external_name
)
744 internal_name
= external_name
;
746 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
749 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
751 dfe
->flag_noname
= 1;
753 dfe
->flag_constant
= 1;
757 dfe
->flag_private
= 1;
761 def_import
(internal_name
, module
, dllext
, name
, ordinal
)
762 const char *internal_name
;
772 buf
= (char *) xmalloc
(strlen
(module
) + strlen
(dllext
) + 2);
773 sprintf
(buf
, "%s.%s", module
, dllext
);
777 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
783 def_version
(major
, minor
)
787 def
->version_major
= major
;
788 def
->version_minor
= minor
;
795 struct directive
*d
= (struct directive
*) xmalloc
(sizeof
(struct directive
));
796 d
->next
= directives
;
798 d
->name
= xstrdup
(str
);
799 d
->len
= strlen
(str
);
806 einfo
("%P: %s:%d: %s\n", def_filename
, linenumber
, err
);
812 /*****************************************************************************
814 *****************************************************************************/
819 /* Never freed, but always reused as needed, so no real leak */
820 static char *buffer
= 0;
821 static int buflen
= 0;
822 static int bufptr
= 0;
828 if
(bufptr
== buflen
)
830 buflen
+= 50; /* overly reasonable, eh? */
832 buffer
= (char *) xrealloc
(buffer
, buflen
+ 1);
834 buffer
= (char *) xmalloc
(buflen
+ 1);
836 buffer
[bufptr
++] = c
;
837 buffer
[bufptr
] = 0; /* not optimal, but very convenient */
849 { "CONSTANT", CONSTANTU
},
850 { "constant", CONSTANTL
},
853 { "DESCRIPTION", DESCRIPTION
},
854 { "DIRECTIVE", DIRECTIVE
},
855 { "EXECUTE", EXECUTE
},
856 { "EXPORTS", EXPORTS
},
857 { "HEAPSIZE", HEAPSIZE
},
858 { "IMPORTS", IMPORTS
},
859 { "LIBRARY", LIBRARY
},
861 { "NONAME", NONAMEU
},
862 { "noname", NONAMEL
},
863 { "PRIVATE", PRIVATEU
},
864 { "private", PRIVATEL
},
866 { "SECTIONS", SECTIONS
},
867 { "SEGMENTS", SECTIONS
},
868 { "SHARED", SHARED
},
869 { "STACKSIZE", STACKSIZE
},
870 { "VERSION", VERSIONK
},
879 if
(lex_parse_string
)
881 if
(lex_parse_string
>= lex_parse_string_end
)
884 rv
= *lex_parse_string
++;
888 rv
= fgetc
(the_file
);
899 if
(lex_parse_string
)
905 return ungetc
(c
, the_file
);
913 if
(lex_forced_token
)
915 i
= lex_forced_token
;
916 lex_forced_token
= 0;
918 printf
("lex: forcing token %d\n", i
);
925 /* trim leading whitespace */
926 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
932 printf
("lex: EOF\n");
937 if
(saw_newline
&& c
== ';')
943 while
(c
!= EOF
&& c
!= '\n');
948 /* must be something else */
954 while
(c
!= EOF
&& (isxdigit
(c
) ||
(c
== 'x')))
961 yylval.number
= strtoul
(buffer
, 0, 0);
963 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
968 if
(isalpha
(c
) || strchr
("$:-_?", c
))
971 while
(c
!= EOF
&& (isalnum
(c
) || strchr
("$:-_?/@", c
)))
978 for
(i
= 0; tokens
[i
].name
; i
++)
979 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
982 printf
("lex: `%s' is a string token\n", buffer
);
984 return tokens
[i
].token
;
987 printf
("lex: `%s' returns ID\n", buffer
);
989 yylval.id
= xstrdup
(buffer
);
993 if
(c
== '\'' || c
== '"')
998 while
(c
!= EOF
&& c
!= q
)
1003 yylval.id
= xstrdup
(buffer
);
1005 printf
("lex: `%s' returns ID\n", buffer
);
1010 if
(c
== '=' || c
== '.' || c
== '@' || c
== ',')
1013 printf
("lex: `%c' returns itself\n", c
);
1024 /*printf ("lex: 0x%02x ignored\n", c); */