📄 deffilep.y
字号:
%{ /* deffilep.y - parser for .def files *//* Copyright 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.This file is part of GNU Binutils.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <stdio.h>#include <ctype.h>#include "libiberty.h"#include "bfd.h"#include "sysdep.h"#include "ld.h"#include "ldmisc.h"#include "deffile.h"#define TRACE 0#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), as well as gratuitiously global symbol names, so we can have multiple yacc generated parsers in ld. Note that these are only the variables produced by yacc. If other parser generators (bison, byacc, etc) produce additional global names that conflict at link time, then those parser generators need to be fixed instead of adding those names to this list. */#define yymaxdepth def_maxdepth#define yyparse def_parse#define yylex def_lex#define yyerror def_error#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 yyexca def_exca#define yyerrflag def_errflag#define yynerrs def_nerrs#define yyps def_ps#define yypv def_pv#define yys def_s#define yy_yys def_yys#define yystate def_state#define yytmp def_tmp#define yyv def_v#define yy_yyv def_yyv#define yyval def_val#define yylloc def_lloc#define yyreds def_reds /* With YYDEBUG defined */#define yytoks def_toks /* With YYDEBUG defined */#define yylhs def_yylhs#define yylen def_yylen#define yydefred def_yydefred#define yydgoto def_yydgoto#define yysindex def_yysindex#define yyrindex def_yyrindex#define yygindex def_yygindex#define yytable def_yytable#define yycheck def_yycheckstatic int def_lex ();static void def_description PARAMS ((const char *));static void def_exports PARAMS ((const char *, const char *, int, int));static void def_heapsize PARAMS ((int, int));static void def_import PARAMS ((const char *, const char *, const char *, const char *, int));static void def_library PARAMS ((const char *, int));static void def_name PARAMS ((const char *, int));static void def_section PARAMS ((const char *, int));static void def_section_alt PARAMS ((const char *, const char *));static void def_stacksize PARAMS ((int, int));static void def_version PARAMS ((int, int));static void def_directive PARAMS ((char *));static int def_parse PARAMS ((void));static int def_error PARAMS ((const char *));static int def_lex PARAMS ((void));static int lex_forced_token = 0;static const char *lex_parse_string = 0;static const char *lex_parse_string_end = 0;%}%union { char *id; int number;};%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATAU, DATAL%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANTU, CONSTANTL%token PRIVATEU, PRIVATEL%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE%token <id> ID%token <number> NUMBER%type <number> opt_base opt_ordinal%type <number> attr attr_list opt_number exp_opt_list exp_opt%type <id> opt_name opt_equal_name %%start: start command | command ;command: NAME opt_name opt_base { def_name ($2, $3); } | LIBRARY opt_name opt_base { def_library ($2, $3); } | DESCRIPTION ID { def_description ($2);} | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);} | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);} | CODE attr_list { def_section ("CODE", $2);} | DATAU attr_list { def_section ("DATA", $2);} | SECTIONS seclist | EXPORTS explist | IMPORTS implist | VERSIONK NUMBER { def_version ($2, 0);} | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);} | DIRECTIVE ID { def_directive ($2);} ;explist: /* EMPTY */ | expline | explist expline ;expline: /* The opt_comma is necessary to support both the usual DEF file syntax as well as .drectve syntax which mandates <expsym>,<expoptlist>. */ ID opt_equal_name opt_ordinal opt_comma exp_opt_list { def_exports ($1, $2, $3, $5); } ;exp_opt_list: /* The opt_comma is necessary to support both the usual DEF file syntax as well as .drectve syntax which allows for comma separated opt list. */ exp_opt opt_comma exp_opt_list { $$ = $1 | $3; } | { $$ = 0; } ;exp_opt: NONAMEU { $$ = 1; } | NONAMEL { $$ = 1; } | CONSTANTU { $$ = 2; } | CONSTANTL { $$ = 2; } | DATAU { $$ = 4; } | DATAL { $$ = 4; } | PRIVATEU { $$ = 8; } | PRIVATEL { $$ = 8; } ;implist: implist impline | impline ;impline: ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); } | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); } | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); } | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); } | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); } | ID '.' ID { def_import ( 0, $1, 0, $3, -1); };seclist: seclist secline | secline ;secline: ID attr_list { def_section ($1, $2);} | ID ID { def_section_alt ($1, $2);} ;attr_list: attr_list opt_comma attr { $$ = $1 | $3; } | attr { $$ = $1; } ;opt_comma: ',' | ;opt_number: ',' NUMBER { $$=$2;} | { $$=-1;} ; attr: READ { $$ = 1;} | WRITE { $$ = 2;} | EXECUTE { $$=4;} | SHARED { $$=8;} ;opt_name: ID { $$ = $1; } | ID '.' ID { char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1); sprintf (name, "%s.%s", $1, $3); $$ = name; } | { $$ = ""; } ;opt_ordinal: '@' NUMBER { $$ = $2;} | { $$ = -1;} ;opt_equal_name: '=' ID { $$ = $2; } | { $$ = 0; } ;opt_base: BASE '=' NUMBER { $$ = $3;} | { $$ = 0;} ; %%/***************************************************************************** API *****************************************************************************/static FILE *the_file;static const char *def_filename;static int linenumber;static def_file *def;static int saw_newline;struct directive { struct directive *next; char *name; int len; };static struct directive *directives = 0;def_file *def_file_empty (){ def_file *rv = (def_file *) xmalloc (sizeof (def_file)); memset (rv, 0, sizeof (def_file)); rv->is_dll = -1; rv->base_address = (bfd_vma) (-1); rv->stack_reserve = rv->stack_commit = -1; rv->heap_reserve = rv->heap_commit = -1; rv->version_major = rv->version_minor = -1; return rv;}def_file *def_file_parse (filename, add_to) const char *filename; def_file *add_to;{ struct directive *d; the_file = fopen (filename, "r"); def_filename = filename; linenumber = 1; if (!the_file) { perror (filename); return 0; } if (add_to) { def = add_to; } else { def = def_file_empty (); } saw_newline = 1; if (def_parse ()) { def_file_free (def); fclose (the_file); return 0; } fclose (the_file); for (d = directives; d; d = d->next) {#if TRACE printf ("Adding directive %08x `%s'\n", d->name, d->name);#endif def_file_add_directive (def, d->name, d->len); } return def;}voiddef_file_free (def) def_file *def;{ int i; if (!def) return; if (def->name) free (def->name); if (def->description) free (def->description); if (def->section_defs) { for (i = 0; i < def->num_section_defs; i++) { if (def->section_defs[i].name) free (def->section_defs[i].name); if (def->section_defs[i].class) free (def->section_defs[i].class); } free (def->section_defs); } if (def->exports) { for (i = 0; i < def->num_exports; i++) { if (def->exports[i].internal_name && def->exports[i].internal_name != def->exports[i].name) free (def->exports[i].internal_name); if (def->exports[i].name) free (def->exports[i].name); } free (def->exports); } if (def->imports) { for (i = 0; i < def->num_imports; i++) { if (def->imports[i].internal_name && def->imports[i].internal_name != def->imports[i].name) free (def->imports[i].internal_name); if (def->imports[i].name) free (def->imports[i].name); } free (def->imports); } while (def->modules) { def_file_module *m = def->modules; def->modules = def->modules->next; free (m); } free (def);}#ifdef DEF_FILE_PRINTvoiddef_file_print (file, def) FILE *file; def_file *def;{ int i; fprintf (file, ">>>> def_file at 0x%08x\n", def); if (def->name) fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)"); if (def->is_dll != -1) fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no"); if (def->base_address != (bfd_vma) (-1)) fprintf (file, " base address: 0x%08x\n", def->base_address); if (def->description) fprintf (file, " description: `%s'\n", def->description); if (def->stack_reserve != -1) fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve); if (def->stack_commit != -1) fprintf (file, " stack commit: 0x%08x\n", def->stack_commit); if (def->heap_reserve != -1) fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve); if (def->heap_commit != -1) fprintf (file, " heap commit: 0x%08x\n", def->heap_commit); if (def->num_section_defs > 0) { fprintf (file, " section defs:\n"); for (i = 0; i < def->num_section_defs; i++) { fprintf (file, " name: `%s', class: `%s', flags:", def->section_defs[i].name, def->section_defs[i].class); if (def->section_defs[i].flag_read) fprintf (file, " R"); if (def->section_defs[i].flag_write) fprintf (file, " W"); if (def->section_defs[i].flag_execute) fprintf (file, " X"); if (def->section_defs[i].flag_shared) fprintf (file, " S"); fprintf (file, "\n"); } } if (def->num_exports > 0) { fprintf (file, " exports:\n"); for (i = 0; i < def->num_exports; i++) { fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:", def->exports[i].name, def->exports[i].internal_name, def->exports[i].ordinal); if (def->exports[i].flag_private) fprintf (file, " P"); if (def->exports[i].flag_constant) fprintf (file, " C"); if (def->exports[i].flag_noname) fprintf (file, " N"); if (def->exports[i].flag_data) fprintf (file, " D"); fprintf (file, "\n"); } } if (def->num_imports > 0) { fprintf (file, " imports:\n"); for (i = 0; i < def->num_imports; i++) { fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n", def->imports[i].internal_name, def->imports[i].module, def->imports[i].name, def->imports[i].ordinal); } } if (def->version_major != -1) fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor); fprintf (file, "<<<< def_file at 0x%08x\n", def);}#endifdef_file_export *def_file_add_export (def, external_name, internal_name, ordinal) def_file *def; const char *external_name; const char *internal_name; int ordinal;{ def_file_export *e; int max_exports = ROUND_UP(def->num_exports, 32); if (def->num_exports >= max_exports) { max_exports = ROUND_UP(def->num_exports+1, 32); if (def->exports) def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export)); else def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export)); } e = def->exports + def->num_exports; memset (e, 0, sizeof (def_file_export)); if (internal_name && !external_name) external_name = internal_name; if (external_name && !internal_name) internal_name = external_name; e->name = xstrdup (external_name); e->internal_name = xstrdup (internal_name); e->ordinal = ordinal; def->num_exports++; return e;}static def_file_module *def_stash_module (def, name) def_file *def; char *name;{ def_file_module *s; for (s=def->modules; s; s=s->next) if (strcmp (s->name, name) == 0) return s; s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name)); s->next = def->modules; def->modules = s; s->user_data = 0; strcpy (s->name, name); return s;}def_file_import *def_file_add_import (def, name, module, ordinal, internal_name) def_file *def; const char *name;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -