1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "libiberty.h"
25 #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 typedef
struct def_pool_str
{
82 struct def_pool_str
*next
;
86 static def_pool_str
*pool_strs
= NULL
;
88 static char *def_pool_alloc
(size_t sz
);
89 static char *def_pool_strdup
(const char *str
);
90 static void def_pool_free
(void);
92 static void def_description
(const char *);
93 static void def_exports
(const char *, const char *, int, int, const char *);
94 static void def_heapsize
(int, int);
95 static void def_import
(const char *, const char *, const char *, const char *,
97 static void def_image_name
(const char *, int, int);
98 static void def_section
(const char *, int);
99 static void def_section_alt
(const char *, const char *);
100 static void def_stacksize
(int, int);
101 static void def_version
(int, int);
102 static void def_directive
(char *);
103 static void def_aligncomm
(char *str
, int align
);
104 static int def_parse
(void);
105 static int def_error
(const char *);
106 static int def_lex
(void);
108 static int lex_forced_token
= 0;
109 static const char *lex_parse_string
= 0;
110 static const char *lex_parse_string_end
= 0;
120 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
121 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
122 %token PRIVATEU PRIVATEL ALIGNCOMM
123 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
125 %token
<digits
> DIGITS
126 %type
<number
> NUMBER
127 %type
<digits
> opt_digits
128 %type
<number
> opt_base opt_ordinal
129 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
130 %type
<id
> opt_name opt_equal_name dot_name anylang_id opt_id
131 %type
<id
> opt_equalequal_name
140 NAME opt_name opt_base
{ def_image_name
($2, $3, 0); }
141 | LIBRARY opt_name opt_base
{ def_image_name
($2, $3, 1); }
142 | DESCRIPTION ID
{ def_description
($2);}
143 | STACKSIZE_K NUMBER opt_number
{ def_stacksize
($2, $3);}
144 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
145 | CODE attr_list
{ def_section
("CODE", $2);}
146 | DATAU attr_list
{ def_section
("DATA", $2);}
150 | VERSIONK NUMBER
{ def_version
($2, 0);}
151 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
152 | DIRECTIVE ID
{ def_directive
($2);}
153 | ALIGNCOMM anylang_id
',' NUMBER
{ def_aligncomm
($2, $4);}
164 /* The opt_comma is necessary to support both the usual
165 DEF file syntax as well as .drectve syntax which
166 mandates <expsym>,<expoptlist>. */
167 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
168 { def_exports
($1, $2, $3, $5, $7); }
171 /* The opt_comma is necessary to support both the usual
172 DEF file syntax as well as .drectve syntax which
173 allows for comma separated opt list. */
174 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
179 | NONAMEL
{ $$
= 1; }
180 | CONSTANTU
{ $$
= 2; }
181 | CONSTANTL
{ $$
= 2; }
184 | PRIVATEU
{ $$
= 8; }
185 | PRIVATEL
{ $$
= 8; }
193 ID
'=' ID
'.' ID
'.' ID opt_equalequal_name
194 { def_import
($1, $3, $5, $7, -1, $8); }
195 | ID
'=' ID
'.' ID
'.' NUMBER opt_equalequal_name
196 { def_import
($1, $3, $5, 0, $7, $8); }
197 | ID
'=' ID
'.' ID opt_equalequal_name
198 { def_import
($1, $3, 0, $5, -1, $6); }
199 | ID
'=' ID
'.' NUMBER opt_equalequal_name
200 { def_import
($1, $3, 0, 0, $5, $6); }
201 | ID
'.' ID
'.' ID opt_equalequal_name
202 { def_import
( 0, $1, $3, $5, -1, $6); }
203 | ID
'.' ID opt_equalequal_name
204 { def_import
( 0, $1, 0, $3, -1, $4); }
213 ID attr_list
{ def_section
($1, $2);}
214 | ID ID
{ def_section_alt
($1, $2);}
218 attr_list opt_comma attr
{ $$
= $1 |
$3; }
226 opt_number: ',' NUMBER
{ $$
=$2;}
237 opt_name: ID
{ $$
= $1; }
240 char *name
= def_pool_alloc
(strlen
($2) + 2);
241 sprintf
(name
, ".%s", $2);
246 char *name
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + 1);
247 sprintf
(name
, "%s.%s", $1, $3);
253 opt_equalequal_name: EQUAL ID
{ $$
= $2; }
258 '@' NUMBER
{ $$
= $2;}
263 '=' dot_name
{ $$
= $2; }
267 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
271 dot_name: ID
{ $$
= $1; }
274 char *name
= def_pool_alloc
(strlen
($2) + 2);
275 sprintf
(name
, ".%s", $2);
280 char *name
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + 1);
281 sprintf
(name
, "%s.%s", $1, $3);
286 anylang_id: ID
{ $$
= $1; }
289 char *id
= def_pool_alloc
(strlen
($2) + 2);
290 sprintf
(id
, ".%s", $2);
293 | anylang_id
'.' opt_digits opt_id
295 char *id
= def_pool_alloc
(strlen
($1) + 1 + strlen
($3) + strlen
($4) + 1);
296 sprintf
(id
, "%s.%s%s", $1, $3, $4);
301 opt_digits: DIGITS
{ $$
= $1; }
305 opt_id: ID
{ $$
= $1; }
309 NUMBER: DIGITS
{ $$
= strtoul
($1, 0, 0); }
313 /*****************************************************************************
315 *****************************************************************************/
317 static FILE *the_file
;
318 static const char *def_filename
;
319 static int linenumber
;
320 static def_file
*def
;
321 static int saw_newline
;
325 struct directive
*next
;
330 static struct directive
*directives
= 0;
333 def_file_empty
(void)
335 def_file
*rv
= xmalloc
(sizeof
(def_file
));
336 memset
(rv
, 0, sizeof
(def_file
));
338 rv
->base_address
= (bfd_vma
) -1;
339 rv
->stack_reserve
= rv
->stack_commit
= -1;
340 rv
->heap_reserve
= rv
->heap_commit
= -1;
341 rv
->version_major
= rv
->version_minor
= -1;
346 def_file_parse
(const char *filename
, def_file
*add_to
)
350 the_file
= fopen
(filename
, "r");
351 def_filename
= filename
;
364 def
= def_file_empty
();
378 while
((d
= directives
) != NULL
)
381 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
383 def_file_add_directive
(def
, d
->name
, d
->len
);
384 directives
= d
->next
;
394 def_file_free
(def_file
*fdef
)
402 if
(fdef
->description
)
403 free
(fdef
->description
);
405 if
(fdef
->section_defs
)
407 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
409 if
(fdef
->section_defs
[i
].name
)
410 free
(fdef
->section_defs
[i
].name
);
411 if
(fdef
->section_defs
[i
].class
)
412 free
(fdef
->section_defs
[i
].class
);
414 free
(fdef
->section_defs
);
419 for
(i
= 0; i
< fdef
->num_exports
; i
++)
421 if
(fdef
->exports
[i
].internal_name
422 && fdef
->exports
[i
].internal_name
!= fdef
->exports
[i
].name
)
423 free
(fdef
->exports
[i
].internal_name
);
424 if
(fdef
->exports
[i
].name
)
425 free
(fdef
->exports
[i
].name
);
426 if
(fdef
->exports
[i
].its_name
)
427 free
(fdef
->exports
[i
].its_name
);
429 free
(fdef
->exports
);
434 for
(i
= 0; i
< fdef
->num_imports
; i
++)
436 if
(fdef
->imports
[i
].internal_name
437 && fdef
->imports
[i
].internal_name
!= fdef
->imports
[i
].name
)
438 free
(fdef
->imports
[i
].internal_name
);
439 if
(fdef
->imports
[i
].name
)
440 free
(fdef
->imports
[i
].name
);
441 if
(fdef
->imports
[i
].its_name
)
442 free
(fdef
->imports
[i
].its_name
);
444 free
(fdef
->imports
);
447 while
(fdef
->modules
)
449 def_file_module
*m
= fdef
->modules
;
451 fdef
->modules
= fdef
->modules
->next
;
455 while
(fdef
->aligncomms
)
457 def_file_aligncomm
*c
= fdef
->aligncomms
;
459 fdef
->aligncomms
= fdef
->aligncomms
->next
;
460 free
(c
->symbol_name
);
467 #ifdef DEF_FILE_PRINT
469 def_file_print
(FILE *file
, def_file
*fdef
)
473 fprintf
(file
, ">>>> def_file at 0x%08x\n", fdef
);
475 fprintf
(file
, " name: %s\n", fdef
->name ? fdef
->name
: "(unspecified)");
476 if
(fdef
->is_dll
!= -1)
477 fprintf
(file
, " is dll: %s\n", fdef
->is_dll ?
"yes" : "no");
478 if
(fdef
->base_address
!= (bfd_vma
) -1)
479 fprintf
(file
, " base address: 0x%08x\n", fdef
->base_address
);
480 if
(fdef
->description
)
481 fprintf
(file
, " description: `%s'\n", fdef
->description
);
482 if
(fdef
->stack_reserve
!= -1)
483 fprintf
(file
, " stack reserve: 0x%08x\n", fdef
->stack_reserve
);
484 if
(fdef
->stack_commit
!= -1)
485 fprintf
(file
, " stack commit: 0x%08x\n", fdef
->stack_commit
);
486 if
(fdef
->heap_reserve
!= -1)
487 fprintf
(file
, " heap reserve: 0x%08x\n", fdef
->heap_reserve
);
488 if
(fdef
->heap_commit
!= -1)
489 fprintf
(file
, " heap commit: 0x%08x\n", fdef
->heap_commit
);
491 if
(fdef
->num_section_defs
> 0)
493 fprintf
(file
, " section defs:\n");
495 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
497 fprintf
(file
, " name: `%s', class: `%s', flags:",
498 fdef
->section_defs
[i
].name
, fdef
->section_defs
[i
].class
);
499 if
(fdef
->section_defs
[i
].flag_read
)
500 fprintf
(file
, " R");
501 if
(fdef
->section_defs
[i
].flag_write
)
502 fprintf
(file
, " W");
503 if
(fdef
->section_defs
[i
].flag_execute
)
504 fprintf
(file
, " X");
505 if
(fdef
->section_defs
[i
].flag_shared
)
506 fprintf
(file
, " S");
507 fprintf
(file
, "\n");
511 if
(fdef
->num_exports
> 0)
513 fprintf
(file
, " exports:\n");
515 for
(i
= 0; i
< fdef
->num_exports
; i
++)
517 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
518 fdef
->exports
[i
].name
, fdef
->exports
[i
].internal_name
,
519 fdef
->exports
[i
].ordinal
);
520 if
(fdef
->exports
[i
].flag_private
)
521 fprintf
(file
, " P");
522 if
(fdef
->exports
[i
].flag_constant
)
523 fprintf
(file
, " C");
524 if
(fdef
->exports
[i
].flag_noname
)
525 fprintf
(file
, " N");
526 if
(fdef
->exports
[i
].flag_data
)
527 fprintf
(file
, " D");
528 fprintf
(file
, "\n");
532 if
(fdef
->num_imports
> 0)
534 fprintf
(file
, " imports:\n");
536 for
(i
= 0; i
< fdef
->num_imports
; i
++)
538 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
539 fdef
->imports
[i
].internal_name
,
540 fdef
->imports
[i
].module
,
541 fdef
->imports
[i
].name
,
542 fdef
->imports
[i
].ordinal
);
546 if
(fdef
->version_major
!= -1)
547 fprintf
(file
, " version: %d.%d\n", fdef
->version_major
, fdef
->version_minor
);
549 fprintf
(file
, "<<<< def_file at 0x%08x\n", fdef
);
553 /* Helper routine to check for identity of string pointers,
554 which might be NULL. */
557 are_names_equal
(const char *s1
, const char *s2
)
562 return
(!s1 ?
-1 : 1);
563 return strcmp
(s1
, s2
);
567 cmp_export_elem
(const def_file_export
*e
, const char *ex_name
,
568 const char *in_name
, const char *its_name
,
573 if
((r
= are_names_equal
(ex_name
, e
->name
)) != 0)
575 if
((r
= are_names_equal
(in_name
, e
->internal_name
)) != 0)
577 if
((r
= are_names_equal
(its_name
, e
->its_name
)) != 0)
579 return
(ord
- e
->ordinal
);
582 /* Search the position of the identical element, or returns the position
583 of the next higher element. If last valid element is smaller, then MAX
587 find_export_in_list
(def_file_export
*b
, int max
,
588 const char *ex_name
, const char *in_name
,
589 const char *its_name
, int ord
, int *is_ident
)
596 if
((e
= cmp_export_elem
(b
, ex_name
, in_name
, its_name
, ord
)) <= 0)
600 if
((e
= cmp_export_elem
(b
+ (max
- 1), ex_name
, in_name
, its_name
, ord
)) > 0)
602 else if
(!e || max
== 2)
608 e
= cmp_export_elem
(b
+ p
, ex_name
, in_name
, its_name
, ord
);
619 if
((e
= cmp_export_elem
(b
+ l
, ex_name
, in_name
, its_name
, ord
)) > 0)
627 def_file_add_export
(def_file
*fdef
,
628 const char *external_name
,
629 const char *internal_name
,
631 const char *its_name
,
636 int max_exports
= ROUND_UP
(fdef
->num_exports
, 32);
638 if
(internal_name
&& !external_name
)
639 external_name
= internal_name
;
640 if
(external_name
&& !internal_name
)
641 internal_name
= external_name
;
643 /* We need to avoid duplicates. */
645 pos
= find_export_in_list
(fdef
->exports
, fdef
->num_exports
,
646 external_name
, internal_name
,
647 its_name
, ordinal
, is_dup
);
650 return
(fdef
->exports
+ pos
);
652 if
(fdef
->num_exports
>= max_exports
)
654 max_exports
= ROUND_UP
(fdef
->num_exports
+ 1, 32);
656 fdef
->exports
= xrealloc
(fdef
->exports
,
657 max_exports
* sizeof
(def_file_export
));
659 fdef
->exports
= xmalloc
(max_exports
* sizeof
(def_file_export
));
662 e
= fdef
->exports
+ pos
;
663 if
(pos
!= fdef
->num_exports
)
664 memmove
(&e
[1], e
, (sizeof
(def_file_export
) * (fdef
->num_exports
- pos
)));
665 memset
(e
, 0, sizeof
(def_file_export
));
666 e
->name
= xstrdup
(external_name
);
667 e
->internal_name
= xstrdup
(internal_name
);
668 e
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
669 e
->ordinal
= ordinal
;
675 def_get_module
(def_file
*fdef
, const char *name
)
679 for
(s
= fdef
->modules
; s
; s
= s
->next
)
680 if
(strcmp
(s
->name
, name
) == 0)
686 static def_file_module
*
687 def_stash_module
(def_file
*fdef
, const char *name
)
691 if
((s
= def_get_module
(fdef
, name
)) != NULL
)
693 s
= xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
694 s
->next
= fdef
->modules
;
697 strcpy
(s
->name
, name
);
702 cmp_import_elem
(const def_file_import
*e
, const char *ex_name
,
703 const char *in_name
, const char *module
,
708 if
((r
= are_names_equal
(ex_name
, e
->name
)) != 0)
710 if
((r
= are_names_equal
(in_name
, e
->internal_name
)) != 0)
712 if
(ord
!= e
->ordinal
)
713 return
(ord
< e
->ordinal ?
-1 : 1);
714 return are_names_equal
(module
, (e
->module ? e
->module
->name
: NULL
));
717 /* Search the position of the identical element, or returns the position
718 of the next higher element. If last valid element is smaller, then MAX
722 find_import_in_list
(def_file_import
*b
, int max
,
723 const char *ex_name
, const char *in_name
,
724 const char *module
, int ord
, int *is_ident
)
731 if
((e
= cmp_import_elem
(b
, ex_name
, in_name
, module
, ord
)) <= 0)
735 if
((e
= cmp_import_elem
(b
+ (max
- 1), ex_name
, in_name
, module
, ord
)) > 0)
737 else if
(!e || max
== 2)
743 e
= cmp_import_elem
(b
+ p
, ex_name
, in_name
, module
, ord
);
754 if
((e
= cmp_import_elem
(b
+ l
, ex_name
, in_name
, module
, ord
)) > 0)
762 def_file_add_import
(def_file
*fdef
,
766 const char *internal_name
,
767 const char *its_name
,
772 int max_imports
= ROUND_UP
(fdef
->num_imports
, 16);
774 /* We need to avoid here duplicates. */
776 pos
= find_import_in_list
(fdef
->imports
, fdef
->num_imports
,
778 (!internal_name ? name
: internal_name
),
779 module
, ordinal
, is_dup
);
781 return fdef
->imports
+ pos
;
783 if
(fdef
->num_imports
>= max_imports
)
785 max_imports
= ROUND_UP
(fdef
->num_imports
+1, 16);
788 fdef
->imports
= xrealloc
(fdef
->imports
,
789 max_imports
* sizeof
(def_file_import
));
791 fdef
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
793 i
= fdef
->imports
+ pos
;
794 if
(pos
!= fdef
->num_imports
)
795 memmove
(&i
[1], i
, (sizeof
(def_file_import
) * (fdef
->num_imports
- pos
)));
796 memset
(i
, 0, sizeof
(def_file_import
));
798 i
->name
= xstrdup
(name
);
800 i
->module
= def_stash_module
(fdef
, module
);
801 i
->ordinal
= ordinal
;
803 i
->internal_name
= xstrdup
(internal_name
);
805 i
->internal_name
= i
->name
;
806 i
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
819 { "-heap", HEAPSIZE
},
820 { "-stack", STACKSIZE_K
},
821 { "-attr", SECTIONS
},
822 { "-export", EXPORTS
},
823 { "-aligncomm", ALIGNCOMM
},
828 def_file_add_directive
(def_file
*my_def
, const char *param
, int len
)
830 def_file
*save_def
= def
;
831 const char *pend
= param
+ len
;
832 char * tend
= (char *) param
;
840 && (ISSPACE
(*param
) ||
*param
== '\n' ||
*param
== 0))
846 /* Scan forward until we encounter any of:
847 - the end of the buffer
848 - the start of a new option
849 - a newline seperating options
850 - a NUL seperating options. */
851 for
(tend
= (char *) (param
+ 1);
853 && !(ISSPACE
(tend
[-1]) && *tend
== '-')
854 && *tend
!= '\n' && *tend
!= 0);
858 for
(i
= 0; diropts
[i
].param
; i
++)
860 len
= strlen
(diropts
[i
].param
);
862 if
(tend
- param
>= len
863 && strncmp
(param
, diropts
[i
].param
, len
) == 0
864 && (param
[len
] == ':' || param
[len
] == ' '))
866 lex_parse_string_end
= tend
;
867 lex_parse_string
= param
+ len
+ 1;
868 lex_forced_token
= diropts
[i
].token
;
876 if
(!diropts
[i
].param
)
882 /* xgettext:c-format */
883 einfo
(_
("Warning: .drectve `%s' unrecognized\n"), param
);
887 lex_parse_string
= 0;
895 /* Parser Callbacks. */
898 def_image_name
(const char *name
, int base
, int is_dll
)
900 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
901 to do here. We retain the output filename specified on command line. */
904 const char* image_name
= lbasename
(name
);
906 if
(image_name
!= name
)
907 einfo
("%s:%d: Warning: path components stripped from %s, '%s'\n",
908 def_filename
, linenumber
, is_dll ?
"LIBRARY" : "NAME",
912 /* Append the default suffix, if none specified. */
913 if
(strchr
(image_name
, '.') == 0)
915 const char * suffix
= is_dll ?
".dll" : ".exe";
917 def
->name
= xmalloc
(strlen
(image_name
) + strlen
(suffix
) + 1);
918 sprintf
(def
->name
, "%s%s", image_name
, suffix
);
921 def
->name
= xstrdup
(image_name
);
924 /* Honor a BASE address statement, even if LIBRARY string is empty. */
925 def
->base_address
= base
;
926 def
->is_dll
= is_dll
;
930 def_description
(const char *text
)
932 int len
= def
->description ? strlen
(def
->description
) : 0;
934 len
+= strlen
(text
) + 1;
935 if
(def
->description
)
937 def
->description
= xrealloc
(def
->description
, len
);
938 strcat
(def
->description
, text
);
942 def
->description
= xmalloc
(len
);
943 strcpy
(def
->description
, text
);
948 def_stacksize
(int reserve
, int commit
)
950 def
->stack_reserve
= reserve
;
951 def
->stack_commit
= commit
;
955 def_heapsize
(int reserve
, int commit
)
957 def
->heap_reserve
= reserve
;
958 def
->heap_commit
= commit
;
962 def_section
(const char *name
, int attr
)
965 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
967 if
(def
->num_section_defs
>= max_sections
)
969 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
971 if
(def
->section_defs
)
972 def
->section_defs
= xrealloc
(def
->section_defs
,
973 max_sections
* sizeof
(def_file_import
));
975 def
->section_defs
= xmalloc
(max_sections
* sizeof
(def_file_import
));
977 s
= def
->section_defs
+ def
->num_section_defs
;
978 memset
(s
, 0, sizeof
(def_file_section
));
979 s
->name
= xstrdup
(name
);
989 def
->num_section_defs
++;
993 def_section_alt
(const char *name
, const char *attr
)
997 for
(; *attr
; attr
++)
1019 def_section
(name
, aval
);
1023 def_exports
(const char *external_name
,
1024 const char *internal_name
,
1027 const char *its_name
)
1029 def_file_export
*dfe
;
1032 if
(!internal_name
&& external_name
)
1033 internal_name
= external_name
;
1035 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
1038 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
,
1041 /* We might check here for flag redefinition and warn. For now we
1042 ignore duplicates silently. */
1047 dfe
->flag_noname
= 1;
1049 dfe
->flag_constant
= 1;
1053 dfe
->flag_private
= 1;
1057 def_import
(const char *internal_name
,
1062 const char *its_name
)
1065 const char *ext
= dllext ? dllext
: "dll";
1068 buf
= xmalloc
(strlen
(module
) + strlen
(ext
) + 2);
1069 sprintf
(buf
, "%s.%s", module
, ext
);
1072 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
, its_name
,
1078 def_version
(int major
, int minor
)
1080 def
->version_major
= major
;
1081 def
->version_minor
= minor
;
1085 def_directive
(char *str
)
1087 struct directive
*d
= xmalloc
(sizeof
(struct directive
));
1089 d
->next
= directives
;
1091 d
->name
= xstrdup
(str
);
1092 d
->len
= strlen
(str
);
1096 def_aligncomm
(char *str
, int align
)
1098 def_file_aligncomm
*c
, *p
;
1101 c
= def
->aligncomms
;
1104 int e
= strcmp
(c
->symbol_name
, str
);
1107 /* Not sure if we want to allow here duplicates with
1108 different alignments, but for now we keep them. */
1109 e
= (int) c
->alignment
- align
;
1118 c
= xmalloc
(sizeof
(def_file_aligncomm
));
1119 c
->symbol_name
= xstrdup
(str
);
1120 c
->alignment
= (unsigned int) align
;
1123 c
->next
= def
->aligncomms
;
1124 def
->aligncomms
= c
;
1134 def_error
(const char *err
)
1136 einfo
("%P: %s:%d: %s\n",
1137 def_filename ? def_filename
: "<unknown-file>", linenumber
, err
);
1142 /* Lexical Scanner. */
1147 /* Never freed, but always reused as needed, so no real leak. */
1148 static char *buffer
= 0;
1149 static int buflen
= 0;
1150 static int bufptr
= 0;
1155 if
(bufptr
== buflen
)
1157 buflen
+= 50; /* overly reasonable, eh? */
1159 buffer
= xrealloc
(buffer
, buflen
+ 1);
1161 buffer
= xmalloc
(buflen
+ 1);
1163 buffer
[bufptr
++] = c
;
1164 buffer
[bufptr
] = 0; /* not optimal, but very convenient. */
1176 { "CONSTANT", CONSTANTU
},
1177 { "constant", CONSTANTL
},
1180 { "DESCRIPTION", DESCRIPTION
},
1181 { "DIRECTIVE", DIRECTIVE
},
1182 { "EXECUTE", EXECUTE
},
1183 { "EXPORTS", EXPORTS
},
1184 { "HEAPSIZE", HEAPSIZE
},
1185 { "IMPORTS", IMPORTS
},
1186 { "LIBRARY", LIBRARY
},
1188 { "NONAME", NONAMEU
},
1189 { "noname", NONAMEL
},
1190 { "PRIVATE", PRIVATEU
},
1191 { "private", PRIVATEL
},
1193 { "SECTIONS", SECTIONS
},
1194 { "SEGMENTS", SECTIONS
},
1195 { "SHARED", SHARED
},
1196 { "STACKSIZE", STACKSIZE_K
},
1197 { "VERSION", VERSIONK
},
1207 if
(lex_parse_string
)
1209 if
(lex_parse_string
>= lex_parse_string_end
)
1212 rv
= *lex_parse_string
++;
1216 rv
= fgetc
(the_file
);
1226 if
(lex_parse_string
)
1232 return ungetc
(c
, the_file
);
1240 if
(lex_forced_token
)
1242 i
= lex_forced_token
;
1243 lex_forced_token
= 0;
1245 printf
("lex: forcing token %d\n", i
);
1252 /* Trim leading whitespace. */
1253 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
1259 printf
("lex: EOF\n");
1264 if
(saw_newline
&& c
== ';')
1270 while
(c
!= EOF
&& c
!= '\n');
1276 /* Must be something else. */
1282 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
1289 yylval.digits
= def_pool_strdup
(buffer
);
1291 printf
("lex: `%s' returns DIGITS\n", buffer
);
1296 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
1305 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
1307 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
1313 printf
("lex: @ returns itself\n");
1317 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@<>", c
)))
1324 if
(ISALPHA
(q
)) /* Check for tokens. */
1326 for
(i
= 0; tokens
[i
].name
; i
++)
1327 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1330 printf
("lex: `%s' is a string token\n", buffer
);
1332 return tokens
[i
].token
;
1336 printf
("lex: `%s' returns ID\n", buffer
);
1338 yylval.id
= def_pool_strdup
(buffer
);
1342 if
(c
== '\'' || c
== '"')
1348 while
(c
!= EOF
&& c
!= q
)
1353 yylval.id
= def_pool_strdup
(buffer
);
1355 printf
("lex: `%s' returns ID\n", buffer
);
1366 printf
("lex: `==' returns EQUAL\n");
1372 printf
("lex: `=' returns itself\n");
1376 if
(c
== '.' || c
== ',')
1379 printf
("lex: `%c' returns itself\n", c
);
1390 /*printf ("lex: 0x%02x ignored\n", c); */
1395 def_pool_alloc
(size_t sz
)
1399 e
= (def_pool_str
*) xmalloc
(sizeof
(def_pool_str
) + sz
);
1400 e
->next
= pool_strs
;
1406 def_pool_strdup
(const char *str
)
1412 len
= strlen
(str
) + 1;
1413 s
= def_pool_alloc
(len
);
1414 memcpy
(s
, str
, len
);
1419 def_pool_free
(void)
1422 while
((p
= pool_strs
) != NULL
)
1424 pool_strs
= p
->next
;