
1: %{ /* deffilep.y - parser for .def files */ 2: 3: /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007 4: Free Software Foundation, Inc. 5: 6: This file is part of GNU Binutils. 7: 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. 12: 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. 17: 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. */ 22: 23: #include "sysdep.h" 24: #include "libiberty.h" 25: #include "safe-ctype.h" 26: #include "bfd.h" 27: #include "ld.h" 28: #include "ldmisc.h" 29: #include "deffile.h" 30: 31: #define TRACE 0 32: 33: #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1)) 34: 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. */ 41: 42: #define yymaxdepth def_maxdepth 43: #define yyparse def_parse 44: #define yylex def_lex 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 50: #define yyr1 def_r1 51: #define yyr2 def_r2 52: #define yydef def_def 53: #define yychk def_chk 54: #define yypgo def_pgo 55: #define yyact def_act 56: #define yyexca def_exca 57: #define yyerrflag def_errflag 58: #define yynerrs def_nerrs 59: #define yyps def_ps 60: #define yypv def_pv 61: #define yys def_s 62: #define yy_yys def_yys 63: #define yystate def_state 64: #define yytmp def_tmp 65: #define yyv def_v 66: #define yy_yyv def_yyv 67: #define yyval def_val 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 80: 81: static void def_description (const char *); 82: static void def_exports (const char *, const char *, int, int); 83: static void def_heapsize (int, int); 84: static void def_import (const char *, const char *, const char *, const char *, 85: int); 86: static void def_image_name (const char *, int, int); 87: static void def_section (const char *, int); 88: static void def_section_alt (const char *, const char *); 89: static void def_stacksize (int, int); 90: static void def_version (int, int); 91: static void def_directive (char *); 92: static int def_parse (void); 93: static int def_error (const char *); 94: static int def_lex (void); 95: 96: static int lex_forced_token = 0; 97: static const char *lex_parse_string = 0; 98: static const char *lex_parse_string_end = 0; 99: 100: %} 101: 102: %union { 103: char *id; 104: int number; 105: }; 106: 107: %token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL 108: %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL 109: %token PRIVATEU PRIVATEL 110: %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE 111: %token <id> ID 112: %token <number> NUMBER 113: %type <number> opt_base opt_ordinal 114: %type <number> attr attr_list opt_number exp_opt_list exp_opt 115: %type <id> opt_name opt_equal_name dot_name 116: 117: %% 118: 119: start: start command 120: | command 121: ; 122: 123: command: 124: NAME opt_name opt_base { def_image_name ($2, $3, 0); } 125: | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); } 126: | DESCRIPTION ID { def_description ($2);} 127: | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);} 128: | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);} 129: | CODE attr_list { def_section ("CODE", $2);} 130: | DATAU attr_list { def_section ("DATA", $2);} 131: | SECTIONS seclist 132: | EXPORTS explist 133: | IMPORTS implist 134: | VERSIONK NUMBER { def_version ($2, 0);} 135: | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);} 136: | DIRECTIVE ID { def_directive ($2);} 137: ; 138: 139: 140: explist: 141: /* EMPTY */ 142: | expline 143: | explist expline 144: ; 145: 146: expline: 147: /* The opt_comma is necessary to support both the usual 148: DEF file syntax as well as .drectve syntax which 149: mandates <expsym>,<expoptlist>. */ 150: dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list 151: { def_exports ($1, $2, $3, $5); } 152: ; 153: exp_opt_list: 154: /* The opt_comma is necessary to support both the usual 155: DEF file syntax as well as .drectve syntax which 156: allows for comma separated opt list. */ 157: exp_opt opt_comma exp_opt_list { $$ = $1 | $3; } 158: | { $$ = 0; } 159: ; 160: exp_opt: 161: NONAMEU { $$ = 1; } 162: | NONAMEL { $$ = 1; } 163: | CONSTANTU { $$ = 2; } 164: | CONSTANTL { $$ = 2; } 165: | DATAU { $$ = 4; } 166: | DATAL { $$ = 4; } 167: | PRIVATEU { $$ = 8; } 168: | PRIVATEL { $$ = 8; } 169: ; 170: implist: 171: implist impline 172: | impline 173: ; 174: 175: impline: 176: ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); } 177: | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); } 178: | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); } 179: | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); } 180: | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); } 181: | ID '.' ID { def_import ( 0, $1, 0, $3, -1); } 182: ; 183: 184: seclist: 185: seclist secline 186: | secline 187: ; 188: 189: secline: 190: ID attr_list { def_section ($1, $2);} 191: | ID ID { def_section_alt ($1, $2);} 192: ; 193: 194: attr_list: 195: attr_list opt_comma attr { $$ = $1 | $3; } 196: | attr { $$ = $1; } 197: ; 198: 199: opt_comma: 200: ',' 201: | 202: ; 203: opt_number: ',' NUMBER { $$=$2;} 204: | { $$=-1;} 205: ; 206: 207: attr: 208: READ { $$ = 1;} 209: | WRITE { $$ = 2;} 210: | EXECUTE { $$=4;} 211: | SHARED { $$=8;} 212: ; 213: 214: opt_name: ID { $$ = $1; } 215: | ID '.' ID 216: { 217: char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1); 218: sprintf (name, "%s.%s", $1, $3); 219: $$ = name; 220: } 221: | { $$ = ""; } 222: ; 223: 224: opt_ordinal: 225: '@' NUMBER { $$ = $2;} 226: | { $$ = -1;} 227: ; 228: 229: opt_equal_name: 230: '=' dot_name { $$ = $2; } 231: | { $$ = 0; } 232: ; 233: 234: opt_base: BASE '=' NUMBER { $$ = $3;} 235: | { $$ = -1;} 236: ; 237: 238: dot_name: ID { $$ = $1; } 239: | dot_name '.' ID 240: { 241: char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1); 242: sprintf (name, "%s.%s", $1, $3); 243: $$ = name; 244: } 245: ; 246: 247: 248: %% 249: 250: /***************************************************************************** 251: API 252: *****************************************************************************/ 253: 254: static FILE *the_file; 255: static const char *def_filename; 256: static int linenumber; 257: static def_file *def; 258: static int saw_newline; 259: 260: struct directive 261: { 262: struct directive *next; 263: char *name; 264: int len; 265: }; 266: 267: static struct directive *directives = 0; 268: 269: def_file * 270: def_file_empty (void) 271: { 272: def_file *rv = xmalloc (sizeof (def_file)); 273: memset (rv, 0, sizeof (def_file)); 274: rv->is_dll = -1; 275: rv->base_address = (bfd_vma) -1; 276: rv->stack_reserve = rv->stack_commit = -1; 277: rv->heap_reserve = rv->heap_commit = -1; 278: rv->version_major = rv->version_minor = -1; 279: return rv; 280: } 281: 282: def_file * 283: def_file_parse (const char *filename, def_file *add_to) 284: { 285: struct directive *d; 286: 287: the_file = fopen (filename, "r"); 288: def_filename = filename; 289: linenumber = 1; 290: if (!the_file) 291: { 292: perror (filename); 293: return 0; 294: } 295: if (add_to) 296: { 297: def = add_to; 298: } 299: else 300: { 301: def = def_file_empty (); 302: } 303: 304: saw_newline = 1; 305: if (def_parse ()) 306: { 307: def_file_free (def); 308: fclose (the_file); 309: return 0; 310: } 311: 312: fclose (the_file); 313: 314: for (d = directives; d; d = d->next) 315: { 316: #if TRACE 317: printf ("Adding directive %08x `%s'\n", d->name, d->name); 318: #endif 319: def_file_add_directive (def, d->name, d->len); 320: } 321: 322: return def; 323: } 324: 325: void 326: def_file_free (def_file *def) 327: { 328: int i; 329: 330: if (!def) 331: return; 332: if (def->name) 333: free (def->name); 334: if (def->description) 335: free (def->description); 336: 337: if (def->section_defs) 338: { 339: for (i = 0; i < def->num_section_defs; i++) 340: { 341: if (def->section_defs[i].name) 342: free (def->section_defs[i].name); 343: if (def->section_defs[i].class) 344: free (def->section_defs[i].class); 345: } 346: free (def->section_defs); 347: } 348: 349: if (def->exports) 350: { 351: for (i = 0; i < def->num_exports; i++) 352: { 353: if (def->exports[i].internal_name 354: && def->exports[i].internal_name != def->exports[i].name) 355: free (def->exports[i].internal_name); 356: if (def->exports[i].name) 357: free (def->exports[i].name); 358: } 359: free (def->exports); 360: } 361: 362: if (def->imports) 363: { 364: for (i = 0; i < def->num_imports; i++) 365: { 366: if (def->imports[i].internal_name 367: && def->imports[i].internal_name != def->imports[i].name) 368: free (def->imports[i].internal_name); 369: if (def->imports[i].name) 370: free (def->imports[i].name); 371: } 372: free (def->imports); 373: } 374: 375: while (def->modules) 376: { 377: def_file_module *m = def->modules; 378: def->modules = def->modules->next; 379: free (m); 380: } 381: 382: free (def); 383: } 384: 385: #ifdef DEF_FILE_PRINT 386: void 387: def_file_print (FILE *file, def_file *def) 388: { 389: int i; 390: 391: fprintf (file, ">>>> def_file at 0x%08x\n", def); 392: if (def->name) 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); 408: 409: if (def->num_section_defs > 0) 410: { 411: fprintf (file, " section defs:\n"); 412: 413: for (i = 0; i < def->num_section_defs; i++) 414: { 415: fprintf (file, " name: `%s', class: `%s', flags:", 416: def->section_defs[i].name, def->section_defs[i].class); 417: if (def->section_defs[i].flag_read) 418: fprintf (file, " R"); 419: if (def->section_defs[i].flag_write) 420: fprintf (file, " W"); 421: if (def->section_defs[i].flag_execute) 422: fprintf (file, " X"); 423: if (def->section_defs[i].flag_shared) 424: fprintf (file, " S"); 425: fprintf (file, "\n"); 426: } 427: } 428: 429: if (def->num_exports > 0) 430: { 431: fprintf (file, " exports:\n"); 432: 433: for (i = 0; i < def->num_exports; i++) 434: { 435: fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:", 436: def->exports[i].name, def->exports[i].internal_name, 437: def->exports[i].ordinal); 438: if (def->exports[i].flag_private) 439: fprintf (file, " P"); 440: if (def->exports[i].flag_constant) 441: fprintf (file, " C"); 442: if (def->exports[i].flag_noname) 443: fprintf (file, " N"); 444: if (def->exports[i].flag_data) 445: fprintf (file, " D"); 446: fprintf (file, "\n"); 447: } 448: } 449: 450: if (def->num_imports > 0) 451: { 452: fprintf (file, " imports:\n"); 453: 454: for (i = 0; i < def->num_imports; i++) 455: { 456: fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n", 457: def->imports[i].internal_name, 458: def->imports[i].module, 459: def->imports[i].name, 460: def->imports[i].ordinal); 461: } 462: } 463: 464: if (def->version_major != -1) 465: fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor); 466: 467: fprintf (file, "<<<< def_file at 0x%08x\n", def); 468: } 469: #endif 470: 471: def_file_export * 472: def_file_add_export (def_file *def, 473: const char *external_name, 474: const char *internal_name, 475: int ordinal) 476: { 477: def_file_export *e; 478: int max_exports = ROUND_UP(def->num_exports, 32); 479: 480: if (def->num_exports >= max_exports) 481: { 482: max_exports = ROUND_UP(def->num_exports + 1, 32); 483: if (def->exports) 484: def->exports = xrealloc (def->exports, 485: max_exports * sizeof (def_file_export)); 486: else 487: def->exports = xmalloc (max_exports * sizeof (def_file_export)); 488: } 489: e = def->exports + def->num_exports; 490: memset (e, 0, sizeof (def_file_export)); 491: if (internal_name && !external_name) 492: external_name = internal_name; 493: if (external_name && !internal_name) 494: internal_name = external_name; 495: e->name = xstrdup (external_name); 496: e->internal_name = xstrdup (internal_name); 497: e->ordinal = ordinal; 498: def->num_exports++; 499: return e; 500: } 501: 502: def_file_module * 503: def_get_module (def_file *def, const char *name) 504: { 505: def_file_module *s; 506: 507: for (s = def->modules; s; s = s->next) 508: if (strcmp (s->name, name) == 0) 509: return s; 510: 511: return NULL; 512: } 513: 514: static def_file_module * 515: def_stash_module (def_file *def, const char *name) 516: { 517: def_file_module *s; 518: 519: if ((s = def_get_module (def, name)) != NULL) 520: return s; 521: s = xmalloc (sizeof (def_file_module) + strlen (name)); 522: s->next = def->modules; 523: def->modules = s; 524: s->user_data = 0; 525: strcpy (s->name, name); 526: return s; 527: } 528: 529: def_file_import * 530: def_file_add_import (def_file *def, 531: const char *name, 532: const char *module, 533: int ordinal, 534: const char *internal_name) 535: { 536: def_file_import *i; 537: int max_imports = ROUND_UP (def->num_imports, 16); 538: 539: if (def->num_imports >= max_imports) 540: { 541: max_imports = ROUND_UP (def->num_imports+1, 16); 542: 543: if (def->imports) 544: def->imports = xrealloc (def->imports, 545: max_imports * sizeof (def_file_import)); 546: else 547: def->imports = xmalloc (max_imports * sizeof (def_file_import)); 548: } 549: i = def->imports + def->num_imports; 550: memset (i, 0, sizeof (def_file_import)); 551: if (name) 552: i->name = xstrdup (name); 553: if (module) 554: i->module = def_stash_module (def, module); 555: i->ordinal = ordinal; 556: if (internal_name) 557: i->internal_name = xstrdup (internal_name); 558: else 559: i->internal_name = i->name; 560: def->num_imports++; 561: 562: return i; 563: } 564: 565: struct 566: { 567: char *param; 568: int token; 569: } 570: diropts[] = 571: { 572: { "-heap", HEAPSIZE }, 573: { "-stack", STACKSIZE }, 574: { "-attr", SECTIONS }, 575: { "-export", EXPORTS }, 576: { 0, 0 } 577: }; 578: 579: void 580: def_file_add_directive (def_file *my_def, const char *param, int len) 581: { 582: def_file *save_def = def; 583: const char *pend = param + len; 584: char * tend = (char *) param; 585: int i; 586: 587: def = my_def; 588: 589: while (param < pend) 590: { 591: while (param < pend 592: && (ISSPACE (*param) || *param == '\n' || *param == 0)) 593: param++; 594: 595: if (param == pend) 596: break; 597: 598: /* Scan forward until we encounter any of: 599: - the end of the buffer 600: - the start of a new option 601: - a newline seperating options 602: - a NUL seperating options. */ 603: for (tend = (char *) (param + 1); 604: (tend < pend 605: && !(ISSPACE (tend[-1]) && *tend == '-') 606: && *tend != '\n' && *tend != 0); 607: tend++) 608: ; 609: 610: for (i = 0; diropts[i].param; i++) 611: { 612: int len = strlen (diropts[i].param); 613: 614: if (tend - param >= len 615: && strncmp (param, diropts[i].param, len) == 0 616: && (param[len] == ':' || param[len] == ' ')) 617: { 618: lex_parse_string_end = tend; 619: lex_parse_string = param + len + 1; 620: lex_forced_token = diropts[i].token; 621: saw_newline = 0; 622: if (def_parse ()) 623: continue; 624: break; 625: } 626: } 627: 628: if (!diropts[i].param) 629: { 630: char saved; 631: 632: saved = * tend; 633: * tend = 0; 634: /* xgettext:c-format */ 635: einfo (_("Warning: .drectve `%s' unrecognized\n"), param); 636: * tend = saved; 637: } 638: 639: lex_parse_string = 0; 640: param = tend; 641: } 642: 643: def = save_def; 644: } 645: 646: /* Parser Callbacks. */ 647: 648: static void 649: def_image_name (const char *name, int base, int is_dll) 650: { 651: /* If a LIBRARY or NAME statement is specified without a name, there is nothing 652: to do here. We retain the output filename specified on command line. */ 653: if (*name) 654: { 655: const char* image_name = lbasename (name); 656: if (image_name != name) 657: einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n", 658: def_filename, linenumber, is_dll ? "LIBRARY" : "NAME", 659: name); 660: if (def->name) 661: free (def->name); 662: /* Append the default suffix, if none specified. */ 663: if (strchr (image_name, '.') == 0) 664: { 665: const char * suffix = is_dll ? ".dll" : ".exe"; 666: 667: def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1); 668: sprintf (def->name, "%s%s", image_name, suffix); 669: } 670: else 671: def->name = xstrdup (image_name); 672: } 673: 674: /* Honor a BASE address statement, even if LIBRARY string is empty. */ 675: def->base_address = base; 676: def->is_dll = is_dll; 677: } 678: 679: static void 680: def_description (const char *text) 681: { 682: int len = def->description ? strlen (def->description) : 0; 683: 684: len += strlen (text) + 1; 685: if (def->description) 686: { 687: def->description = xrealloc (def->description, len); 688: strcat (def->description, text); 689: } 690: else 691: { 692: def->description = xmalloc (len); 693: strcpy (def->description, text); 694: } 695: } 696: 697: static void 698: def_stacksize (int reserve, int commit) 699: { 700: def->stack_reserve = reserve; 701: def->stack_commit = commit; 702: } 703: 704: static void 705: def_heapsize (int reserve, int commit) 706: { 707: def->heap_reserve = reserve; 708: def->heap_commit = commit; 709: } 710: 711: static void 712: def_section (const char *name, int attr) 713: { 714: def_file_section *s; 715: int max_sections = ROUND_UP (def->num_section_defs, 4); 716: 717: if (def->num_section_defs >= max_sections) 718: { 719: max_sections = ROUND_UP (def->num_section_defs+1, 4); 720: 721: if (def->section_defs) 722: def->section_defs = xrealloc (def->section_defs, 723: max_sections * sizeof (def_file_import)); 724: else 725: def->section_defs = xmalloc (max_sections * sizeof (def_file_import)); 726: } 727: s = def->section_defs + def->num_section_defs; 728: memset (s, 0, sizeof (def_file_section)); 729: s->name = xstrdup (name); 730: if (attr & 1) 731: s->flag_read = 1; 732: if (attr & 2) 733: s->flag_write = 1; 734: if (attr & 4) 735: s->flag_execute = 1; 736: if (attr & 8) 737: s->flag_shared = 1; 738: 739: def->num_section_defs++; 740: } 741: 742: static void 743: def_section_alt (const char *name, const char *attr) 744: { 745: int aval = 0; 746: 747: for (; *attr; attr++) 748: { 749: switch (*attr) 750: { 751: case 'R': 752: case 'r': 753: aval |= 1; 754: break; 755: case 'W': 756: case 'w': 757: aval |= 2; 758: break; 759: case 'X': 760: case 'x': 761: aval |= 4; 762: break; 763: case 'S': 764: case 's': 765: aval |= 8; 766: break; 767: } 768: } 769: def_section (name, aval); 770: } 771: 772: static void 773: def_exports (const char *external_name, 774: const char *internal_name, 775: int ordinal, 776: int flags) 777: { 778: def_file_export *dfe; 779: 780: if (!internal_name && external_name) 781: internal_name = external_name; 782: #if TRACE 783: printf ("def_exports, ext=%s int=%s\n", external_name, internal_name); 784: #endif 785: 786: dfe = def_file_add_export (def, external_name, internal_name, ordinal); 787: if (flags & 1) 788: dfe->flag_noname = 1; 789: if (flags & 2) 790: dfe->flag_constant = 1; 791: if (flags & 4) 792: dfe->flag_data = 1; 793: if (flags & 8) 794: dfe->flag_private = 1; 795: } 796: 797: static void 798: def_import (const char *internal_name, 799: const char *module, 800: const char *dllext, 801: const char *name, 802: int ordinal) 803: { 804: char *buf = 0; 805: const char *ext = dllext ? dllext : "dll"; 806: 807: buf = xmalloc (strlen (module) + strlen (ext) + 2); 808: sprintf (buf, "%s.%s", module, ext); 809: module = buf; 810: 811: def_file_add_import (def, name, module, ordinal, internal_name); 812: if (buf) 813: free (buf); 814: }