1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995, 1997, 1998, 1999 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 int def_lex
();
82 static void def_description PARAMS
((const char *));
83 static void def_exports PARAMS
((const char *, const char *, int, int));
84 static void def_heapsize PARAMS
((int, int));
85 static void def_import
86 PARAMS
((const char *, const char *, const char *, const char *, int));
87 static void def_library PARAMS
((const char *, int));
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 *));
97 static int def_lex PARAMS
((void));
99 static int lex_forced_token
= 0;
100 static const char *lex_parse_string
= 0;
101 static const char *lex_parse_string_end
= 0;
110 %token NAME
, LIBRARY
, DESCRIPTION
, STACKSIZE
, HEAPSIZE
, CODE
, DATA
111 %token SECTIONS
, EXPORTS
, IMPORTS
, VERSIONK
, BASE
, CONSTANT
, PRIVATE
112 %token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
114 %token
<number
> NUMBER
115 %type
<number
> opt_base opt_ordinal
116 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
117 %type
<id
> opt_name opt_equal_name
126 NAME opt_name opt_base
{ def_name
($2, $3); }
127 | LIBRARY opt_name opt_base
{ def_library
($2, $3); }
128 | DESCRIPTION ID
{ def_description
($2);}
129 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
130 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
131 | CODE attr_list
{ def_section
("CODE", $2);}
132 | DATA attr_list
{ def_section
("DATA", $2);}
136 | VERSIONK NUMBER
{ def_version
($2, 0);}
137 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
138 | DIRECTIVE ID
{ def_directive
($2);}
149 ID opt_equal_name opt_ordinal exp_opt_list
150 { def_exports
($1, $2, $3, $4); }
153 exp_opt exp_opt_list
{ $$
= $1 |
$2; }
158 | CONSTANT
{ $$
= 2; }
160 | PRIVATE
{ $$
= 8; }
168 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
169 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
170 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
171 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
172 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
173 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
182 ID attr_list
{ def_section
($1, $2);}
183 | ID ID
{ def_section_alt
($1, $2);}
187 attr_list opt_comma attr
{ $$
= $1 |
$3; }
195 opt_number: ',' NUMBER
{ $$
=$2;}
206 opt_name: ID
{ $$
= $1; }
211 '@' NUMBER
{ $$
= $2;}
220 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
228 /*****************************************************************************
230 *****************************************************************************/
232 static FILE *the_file
;
233 static const char *def_filename
;
234 static int linenumber
;
235 static def_file
*def
;
236 static int saw_newline
;
240 struct directive
*next
;
245 static struct directive
*directives
= 0;
250 def_file
*rv
= (def_file
*) xmalloc
(sizeof
(def_file
));
251 memset
(rv
, 0, sizeof
(def_file
));
253 rv
->base_address
= (bfd_vma
) (-1);
254 rv
->stack_reserve
= rv
->stack_commit
= -1;
255 rv
->heap_reserve
= rv
->heap_commit
= -1;
256 rv
->version_major
= rv
->version_minor
= -1;
261 def_file_parse
(filename
, add_to
)
262 const char *filename
;
267 the_file
= fopen
(filename
, "r");
268 def_filename
= filename
;
281 def
= def_file_empty
();
294 for
(d
= directives
; d
; d
= d
->next
)
297 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
299 def_file_add_directive
(def
, d
->name
, d
->len
);
314 if
(def
->description
)
315 free
(def
->description
);
317 if
(def
->section_defs
)
319 for
(i
= 0; i
< def
->num_section_defs
; i
++)
321 if
(def
->section_defs
[i
].name
)
322 free
(def
->section_defs
[i
].name
);
323 if
(def
->section_defs
[i
].class
)
324 free
(def
->section_defs
[i
].class
);
326 free
(def
->section_defs
);
331 for
(i
= 0; i
< def
->num_exports
; i
++)
333 if
(def
->exports
[i
].internal_name
334 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
335 free
(def
->exports
[i
].internal_name
);
336 if
(def
->exports
[i
].name
)
337 free
(def
->exports
[i
].name
);
344 for
(i
= 0; i
< def
->num_imports
; i
++)
346 if
(def
->imports
[i
].internal_name
347 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
348 free
(def
->imports
[i
].internal_name
);
349 if
(def
->imports
[i
].name
)
350 free
(def
->imports
[i
].name
);
357 def_file_module
*m
= def
->modules
;
358 def
->modules
= def
->modules
->next
;
365 #ifdef DEF_FILE_PRINT
367 def_file_print
(file
, def
)
372 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
374 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
375 if
(def
->is_dll
!= -1)
376 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
377 if
(def
->base_address
!= (bfd_vma
) (-1))
378 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
379 if
(def
->description
)
380 fprintf
(file
, " description: `%s'\n", def
->description
);
381 if
(def
->stack_reserve
!= -1)
382 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
383 if
(def
->stack_commit
!= -1)
384 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
385 if
(def
->heap_reserve
!= -1)
386 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
387 if
(def
->heap_commit
!= -1)
388 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
390 if
(def
->num_section_defs
> 0)
392 fprintf
(file
, " section defs:\n");
393 for
(i
= 0; i
< def
->num_section_defs
; i
++)
395 fprintf
(file
, " name: `%s', class: `%s', flags:",
396 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
397 if
(def
->section_defs
[i
].flag_read
)
398 fprintf
(file
, " R");
399 if
(def
->section_defs
[i
].flag_write
)
400 fprintf
(file
, " W");
401 if
(def
->section_defs
[i
].flag_execute
)
402 fprintf
(file
, " X");
403 if
(def
->section_defs
[i
].flag_shared
)
404 fprintf
(file
, " S");
405 fprintf
(file
, "\n");
409 if
(def
->num_exports
> 0)
411 fprintf
(file
, " exports:\n");
412 for
(i
= 0; i
< def
->num_exports
; i
++)
414 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
415 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
416 def
->exports
[i
].ordinal
);
417 if
(def
->exports
[i
].flag_private
)
418 fprintf
(file
, " P");
419 if
(def
->exports
[i
].flag_constant
)
420 fprintf
(file
, " C");
421 if
(def
->exports
[i
].flag_noname
)
422 fprintf
(file
, " N");
423 if
(def
->exports
[i
].flag_data
)
424 fprintf
(file
, " D");
425 fprintf
(file
, "\n");
429 if
(def
->num_imports
> 0)
431 fprintf
(file
, " imports:\n");
432 for
(i
= 0; i
< def
->num_imports
; i
++)
434 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
435 def
->imports
[i
].internal_name
,
436 def
->imports
[i
].module
,
437 def
->imports
[i
].name
,
438 def
->imports
[i
].ordinal
);
441 if
(def
->version_major
!= -1)
442 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
443 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
448 def_file_add_export
(def
, external_name
, internal_name
, ordinal
)
450 const char *external_name
;
451 const char *internal_name
;
455 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
456 if
(def
->num_exports
>= max_exports
)
458 max_exports
= ROUND_UP
(def
->num_exports
+1, 32);
460 def
->exports
= (def_file_export
*) xrealloc
(def
->exports
, max_exports
* sizeof
(def_file_export
));
462 def
->exports
= (def_file_export
*) xmalloc
(max_exports
* sizeof
(def_file_export
));
464 e
= def
->exports
+ def
->num_exports
;
465 memset
(e
, 0, sizeof
(def_file_export
));
466 if
(internal_name
&& !external_name
)
467 external_name
= internal_name
;
468 if
(external_name
&& !internal_name
)
469 internal_name
= external_name
;
470 e
->name
= xstrdup
(external_name
);
471 e
->internal_name
= xstrdup
(internal_name
);
472 e
->ordinal
= ordinal
;
477 static def_file_module
*
478 def_stash_module
(def
, name
)
483 for
(s
=def
->modules
; s
; s
=s
->next
)
484 if
(strcmp
(s
->name
, name
) == 0)
486 s
= (def_file_module
*) xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
487 s
->next
= def
->modules
;
490 strcpy
(s
->name
, name
);
495 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
)
500 const char *internal_name
;
503 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
504 if
(def
->num_imports
>= max_imports
)
506 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
508 def
->imports
= (def_file_import
*) xrealloc
(def
->imports
, max_imports
* sizeof
(def_file_import
));
510 def
->imports
= (def_file_import
*) xmalloc
(max_imports
* sizeof
(def_file_import
));
512 i
= def
->imports
+ def
->num_imports
;
513 memset
(i
, 0, sizeof
(def_file_import
));
515 i
->name
= xstrdup
(name
);
517 i
->module
= def_stash_module
(def
, module
);
518 i
->ordinal
= ordinal
;
520 i
->internal_name
= xstrdup
(internal_name
);
522 i
->internal_name
= i
->name
;
534 { "-heap", HEAPSIZE
},
535 { "-stack", STACKSIZE
},
536 { "-attr", SECTIONS
},
537 { "-export", EXPORTS
},
542 def_file_add_directive
(my_def
, param
, len
)
547 def_file
*save_def
= def
;
548 const char *pend
= param
+ len
;
549 const char *tend
= param
;
556 while
(param
< pend
&& isspace
(*param
))
558 for
(tend
= param
+ 1;
559 tend
< pend
&& !(isspace
(tend
[-1]) && *tend
== '-');
562 for
(i
= 0; diropts
[i
].param
; i
++)
564 int len
= strlen
(diropts
[i
].param
);
565 if
(tend
- param
>= len
566 && strncmp
(param
, diropts
[i
].param
, len
) == 0
567 && (param
[len
] == ':' || param
[len
] == ' '))
569 lex_parse_string_end
= tend
;
570 lex_parse_string
= param
+ len
+ 1;
571 lex_forced_token
= diropts
[i
].token
;
578 if
(!diropts
[i
].param
)
580 /* xgettext:c-format */
581 einfo
(_
("Warning: .drectve `%.*s' unrecognized\n"),
582 tend
- param
, param
);
584 lex_parse_string
= 0;
591 /*****************************************************************************
593 *****************************************************************************/
596 def_name
(name
, base
)
602 def
->name
= xstrdup
(name
);
603 def
->base_address
= base
;
608 def_library
(name
, base
)
614 def
->name
= xstrdup
(name
);
615 def
->base_address
= base
;
620 def_description
(text
)
623 int len
= def
->description ? strlen
(def
->description
) : 0;
624 len
+= strlen
(text
) + 1;
625 if
(def
->description
)
627 def
->description
= (char *) xrealloc
(def
->description
, len
);
628 strcat
(def
->description
, text
);
632 def
->description
= (char *) xmalloc
(len
);
633 strcpy
(def
->description
, text
);
638 def_stacksize
(reserve
, commit
)
642 def
->stack_reserve
= reserve
;
643 def
->stack_commit
= commit
;
647 def_heapsize
(reserve
, commit
)
651 def
->heap_reserve
= reserve
;
652 def
->heap_commit
= commit
;
656 def_section
(name
, attr
)
661 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
662 if
(def
->num_section_defs
>= max_sections
)
664 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
665 if
(def
->section_defs
)
666 def
->section_defs
= (def_file_section
*) xrealloc
(def
->section_defs
, max_sections
* sizeof
(def_file_import
));
668 def
->section_defs
= (def_file_section
*) xmalloc
(max_sections
* sizeof
(def_file_import
));
670 s
= def
->section_defs
+ def
->num_section_defs
;
671 memset
(s
, 0, sizeof
(def_file_section
));
672 s
->name
= xstrdup
(name
);
682 def
->num_section_defs
++;
686 def_section_alt
(name
, attr
)
691 for
(; *attr
; attr
++)
713 def_section
(name
, aval
);
717 def_exports
(external_name
, internal_name
, ordinal
, flags
)
718 const char *external_name
;
719 const char *internal_name
;
723 def_file_export
*dfe
;
725 if
(!internal_name
&& external_name
)
726 internal_name
= external_name
;
728 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
731 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
733 dfe
->flag_noname
= 1;
735 dfe
->flag_constant
= 1;
739 dfe
->flag_private
= 1;
743 def_import
(internal_name
, module
, dllext
, name
, ordinal
)
744 const char *internal_name
;
754 buf
= (char *) xmalloc
(strlen
(module
) + strlen
(dllext
) + 2);
755 sprintf
(buf
, "%s.%s", module
, dllext
);
759 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
765 def_version
(major
, minor
)
769 def
->version_major
= major
;
770 def
->version_minor
= minor
;
777 struct directive
*d
= (struct directive
*) xmalloc
(sizeof
(struct directive
));
778 d
->next
= directives
;
780 d
->name
= xstrdup
(str
);
781 d
->len
= strlen
(str
);
788 einfo
("%P: %s:%d: %s\n", def_filename
, linenumber
, err
);
794 /*****************************************************************************
796 *****************************************************************************/
801 /* Never freed, but always reused as needed, so no real leak */
802 static char *buffer
= 0;
803 static int buflen
= 0;
804 static int bufptr
= 0;
810 if
(bufptr
== buflen
)
812 buflen
+= 50; /* overly reasonable, eh? */
814 buffer
= (char *) xrealloc
(buffer
, buflen
+ 1);
816 buffer
= (char *) xmalloc
(buflen
+ 1);
818 buffer
[bufptr
++] = c
;
819 buffer
[bufptr
] = 0; /* not optimal, but very convenient */
831 { "CONSTANT", CONSTANT
},
833 { "DESCRIPTION", DESCRIPTION
},
834 { "DIRECTIVE", DIRECTIVE
},
835 { "EXECUTE", EXECUTE
},
836 { "EXPORTS", EXPORTS
},
837 { "HEAPSIZE", HEAPSIZE
},
838 { "IMPORTS", IMPORTS
},
839 { "LIBRARY", LIBRARY
},
841 { "NONAME", NONAME
},
842 { "PRIVATE", PRIVATE
},
844 { "SECTIONS", SECTIONS
},
845 { "SEGMENTS", SECTIONS
},
846 { "SHARED", SHARED
},
847 { "STACKSIZE", STACKSIZE
},
848 { "VERSION", VERSIONK
},
857 if
(lex_parse_string
)
859 if
(lex_parse_string
>= lex_parse_string_end
)
862 rv
= *lex_parse_string
++;
866 rv
= fgetc
(the_file
);
877 if
(lex_parse_string
)
883 return ungetc
(c
, the_file
);
891 if
(lex_forced_token
)
893 i
= lex_forced_token
;
894 lex_forced_token
= 0;
896 printf
("lex: forcing token %d\n", i
);
903 /* trim leading whitespace */
904 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
910 printf
("lex: EOF\n");
915 if
(saw_newline
&& c
== ';')
921 while
(c
!= EOF
&& c
!= '\n');
926 /* must be something else */
932 while
(c
!= EOF
&& (isxdigit
(c
) ||
(c
== 'x')))
939 yylval.number
= strtoul
(buffer
, 0, 0);
941 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
946 if
(isalpha
(c
) || strchr
("$:-_?", c
))
949 while
(c
!= EOF
&& (isalnum
(c
) || strchr
("$:-_?/@", c
)))
956 for
(i
= 0; tokens
[i
].name
; i
++)
957 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
960 printf
("lex: `%s' is a string token\n", buffer
);
962 return tokens
[i
].token
;
965 printf
("lex: `%s' returns ID\n", buffer
);
967 yylval.id
= xstrdup
(buffer
);
971 if
(c
== '\'' || c
== '"')
976 while
(c
!= EOF
&& c
!= q
)
981 yylval.id
= xstrdup
(buffer
);
983 printf
("lex: `%s' returns ID\n", buffer
);
988 if
(c
== '=' || c
== '.' || c
== '@' || c
== ',')
991 printf
("lex: `%c' returns itself\n", c
);
1002 /*printf ("lex: 0x%02x ignored\n", c); */