deffilep.y 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493
  1. %{ /* deffilep.y - parser for .def files */
  2. /* Copyright (C) 1995-2015 Free Software Foundation, Inc.
  3. This file is part of GNU Binutils.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  15. MA 02110-1301, USA. */
  16. #include "sysdep.h"
  17. #include "libiberty.h"
  18. #include "safe-ctype.h"
  19. #include "bfd.h"
  20. #include "ld.h"
  21. #include "ldmisc.h"
  22. #include "deffile.h"
  23. #define TRACE 0
  24. #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
  25. /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
  26. as well as gratuitiously global symbol names, so we can have multiple
  27. yacc generated parsers in ld. Note that these are only the variables
  28. produced by yacc. If other parser generators (bison, byacc, etc) produce
  29. additional global names that conflict at link time, then those parser
  30. generators need to be fixed instead of adding those names to this list. */
  31. #define yymaxdepth def_maxdepth
  32. #define yyparse def_parse
  33. #define yylex def_lex
  34. #define yyerror def_error
  35. #define yylval def_lval
  36. #define yychar def_char
  37. #define yydebug def_debug
  38. #define yypact def_pact
  39. #define yyr1 def_r1
  40. #define yyr2 def_r2
  41. #define yydef def_def
  42. #define yychk def_chk
  43. #define yypgo def_pgo
  44. #define yyact def_act
  45. #define yyexca def_exca
  46. #define yyerrflag def_errflag
  47. #define yynerrs def_nerrs
  48. #define yyps def_ps
  49. #define yypv def_pv
  50. #define yys def_s
  51. #define yy_yys def_yys
  52. #define yystate def_state
  53. #define yytmp def_tmp
  54. #define yyv def_v
  55. #define yy_yyv def_yyv
  56. #define yyval def_val
  57. #define yylloc def_lloc
  58. #define yyreds def_reds /* With YYDEBUG defined. */
  59. #define yytoks def_toks /* With YYDEBUG defined. */
  60. #define yylhs def_yylhs
  61. #define yylen def_yylen
  62. #define yydefred def_yydefred
  63. #define yydgoto def_yydgoto
  64. #define yysindex def_yysindex
  65. #define yyrindex def_yyrindex
  66. #define yygindex def_yygindex
  67. #define yytable def_yytable
  68. #define yycheck def_yycheck
  69. typedef struct def_pool_str {
  70. struct def_pool_str *next;
  71. char data[1];
  72. } def_pool_str;
  73. static def_pool_str *pool_strs = NULL;
  74. static char *def_pool_alloc (size_t sz);
  75. static char *def_pool_strdup (const char *str);
  76. static void def_pool_free (void);
  77. static void def_description (const char *);
  78. static void def_exports (const char *, const char *, int, int, const char *);
  79. static void def_heapsize (int, int);
  80. static void def_import (const char *, const char *, const char *, const char *,
  81. int, const char *);
  82. static void def_image_name (const char *, bfd_vma, int);
  83. static void def_section (const char *, int);
  84. static void def_section_alt (const char *, const char *);
  85. static void def_stacksize (int, int);
  86. static void def_version (int, int);
  87. static void def_directive (char *);
  88. static void def_aligncomm (char *str, int align);
  89. static int def_parse (void);
  90. static int def_error (const char *);
  91. static int def_lex (void);
  92. static int lex_forced_token = 0;
  93. static const char *lex_parse_string = 0;
  94. static const char *lex_parse_string_end = 0;
  95. %}
  96. %union {
  97. char *id;
  98. const char *id_const;
  99. int number;
  100. bfd_vma vma;
  101. char *digits;
  102. };
  103. %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
  104. %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
  105. %token PRIVATEU PRIVATEL ALIGNCOMM
  106. %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
  107. %token <id> ID
  108. %token <digits> DIGITS
  109. %type <number> NUMBER
  110. %type <vma> VMA opt_base
  111. %type <digits> opt_digits
  112. %type <number> opt_ordinal
  113. %type <number> attr attr_list opt_number exp_opt_list exp_opt
  114. %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
  115. %type <id> opt_equalequal_name
  116. %type <id_const> keyword_as_name
  117. %%
  118. start: start command
  119. | command
  120. ;
  121. command:
  122. NAME opt_name opt_base { def_image_name ($2, $3, 0); }
  123. | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
  124. | DESCRIPTION ID { def_description ($2);}
  125. | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
  126. | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
  127. | CODE attr_list { def_section ("CODE", $2);}
  128. | DATAU attr_list { def_section ("DATA", $2);}
  129. | SECTIONS seclist
  130. | EXPORTS explist
  131. | IMPORTS implist
  132. | VERSIONK NUMBER { def_version ($2, 0);}
  133. | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
  134. | DIRECTIVE ID { def_directive ($2);}
  135. | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
  136. ;
  137. explist:
  138. /* EMPTY */
  139. | expline
  140. | explist expline
  141. ;
  142. expline:
  143. /* The opt_comma is necessary to support both the usual
  144. DEF file syntax as well as .drectve syntax which
  145. mandates <expsym>,<expoptlist>. */
  146. opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
  147. { def_exports ($1, $2, $3, $5, $7); }
  148. ;
  149. exp_opt_list:
  150. /* The opt_comma is necessary to support both the usual
  151. DEF file syntax as well as .drectve syntax which
  152. allows for comma separated opt list. */
  153. exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
  154. | { $$ = 0; }
  155. ;
  156. exp_opt:
  157. NONAMEU { $$ = 1; }
  158. | NONAMEL { $$ = 1; }
  159. | CONSTANTU { $$ = 2; }
  160. | CONSTANTL { $$ = 2; }
  161. | DATAU { $$ = 4; }
  162. | DATAL { $$ = 4; }
  163. | PRIVATEU { $$ = 8; }
  164. | PRIVATEL { $$ = 8; }
  165. ;
  166. implist:
  167. implist impline
  168. | impline
  169. ;
  170. impline:
  171. ID '=' ID '.' ID '.' ID opt_equalequal_name
  172. { def_import ($1, $3, $5, $7, -1, $8); }
  173. | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
  174. { def_import ($1, $3, $5, 0, $7, $8); }
  175. | ID '=' ID '.' ID opt_equalequal_name
  176. { def_import ($1, $3, 0, $5, -1, $6); }
  177. | ID '=' ID '.' NUMBER opt_equalequal_name
  178. { def_import ($1, $3, 0, 0, $5, $6); }
  179. | ID '.' ID '.' ID opt_equalequal_name
  180. { def_import( 0, $1, $3, $5, -1, $6); }
  181. | ID '.' ID opt_equalequal_name
  182. { def_import ( 0, $1, 0, $3, -1, $4); }
  183. ;
  184. seclist:
  185. seclist secline
  186. | secline
  187. ;
  188. secline:
  189. ID attr_list { def_section ($1, $2);}
  190. | ID ID { def_section_alt ($1, $2);}
  191. ;
  192. attr_list:
  193. attr_list opt_comma attr { $$ = $1 | $3; }
  194. | attr { $$ = $1; }
  195. ;
  196. opt_comma:
  197. ','
  198. |
  199. ;
  200. opt_number: ',' NUMBER { $$=$2;}
  201. | { $$=-1;}
  202. ;
  203. attr:
  204. READ { $$ = 1;}
  205. | WRITE { $$ = 2;}
  206. | EXECUTE { $$=4;}
  207. | SHARED { $$=8;}
  208. ;
  209. keyword_as_name: BASE { $$ = "BASE"; }
  210. | CODE { $$ = "CODE"; }
  211. | CONSTANTU { $$ = "CONSTANT"; }
  212. | CONSTANTL { $$ = "constant"; }
  213. | DATAU { $$ = "DATA"; }
  214. | DATAL { $$ = "data"; }
  215. | DESCRIPTION { $$ = "DESCRIPTION"; }
  216. | DIRECTIVE { $$ = "DIRECTIVE"; }
  217. | EXECUTE { $$ = "EXECUTE"; }
  218. | EXPORTS { $$ = "EXPORTS"; }
  219. | HEAPSIZE { $$ = "HEAPSIZE"; }
  220. | IMPORTS { $$ = "IMPORTS"; }
  221. /* Disable LIBRARY keyword as valid symbol-name. This is necessary
  222. for libtool, which places this command after EXPORTS command.
  223. This behavior is illegal by specification, but sadly required by
  224. by compatibility reasons.
  225. See PR binutils/13710
  226. | LIBRARY { $$ = "LIBRARY"; } */
  227. | NAME { $$ = "NAME"; }
  228. | NONAMEU { $$ = "NONAME"; }
  229. | NONAMEL { $$ = "noname"; }
  230. | PRIVATEU { $$ = "PRIVATE"; }
  231. | PRIVATEL { $$ = "private"; }
  232. | READ { $$ = "READ"; }
  233. | SHARED { $$ = "SHARED"; }
  234. | STACKSIZE_K { $$ = "STACKSIZE"; }
  235. | VERSIONK { $$ = "VERSION"; }
  236. | WRITE { $$ = "WRITE"; }
  237. ;
  238. opt_name2: ID { $$ = $1; }
  239. | '.' keyword_as_name
  240. {
  241. char *name = xmalloc (strlen ($2) + 2);
  242. sprintf (name, ".%s", $2);
  243. $$ = name;
  244. }
  245. | '.' opt_name2
  246. {
  247. char *name = def_pool_alloc (strlen ($2) + 2);
  248. sprintf (name, ".%s", $2);
  249. $$ = name;
  250. }
  251. | keyword_as_name '.' opt_name2
  252. {
  253. char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
  254. sprintf (name, "%s.%s", $1, $3);
  255. $$ = name;
  256. }
  257. | ID '.' opt_name2
  258. {
  259. char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
  260. sprintf (name, "%s.%s", $1, $3);
  261. $$ = name;
  262. }
  263. ;
  264. opt_name: opt_name2 { $$ = $1; }
  265. | { $$ = ""; }
  266. ;
  267. opt_equalequal_name: EQUAL ID { $$ = $2; }
  268. | { $$ = 0; }
  269. ;
  270. opt_ordinal:
  271. '@' NUMBER { $$ = $2;}
  272. | { $$ = -1;}
  273. ;
  274. opt_equal_name:
  275. '=' opt_name2 { $$ = $2; }
  276. | { $$ = 0; }
  277. ;
  278. opt_base: BASE '=' VMA { $$ = $3;}
  279. | { $$ = (bfd_vma) -1;}
  280. ;
  281. anylang_id: ID { $$ = $1; }
  282. | '.' ID
  283. {
  284. char *id = def_pool_alloc (strlen ($2) + 2);
  285. sprintf (id, ".%s", $2);
  286. $$ = id;
  287. }
  288. | anylang_id '.' opt_digits opt_id
  289. {
  290. char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
  291. sprintf (id, "%s.%s%s", $1, $3, $4);
  292. $$ = id;
  293. }
  294. ;
  295. opt_digits: DIGITS { $$ = $1; }
  296. | { $$ = ""; }
  297. ;
  298. opt_id: ID { $$ = $1; }
  299. | { $$ = ""; }
  300. ;
  301. NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
  302. ;
  303. VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
  304. %%
  305. /*****************************************************************************
  306. API
  307. *****************************************************************************/
  308. static FILE *the_file;
  309. static const char *def_filename;
  310. static int linenumber;
  311. static def_file *def;
  312. static int saw_newline;
  313. struct directive
  314. {
  315. struct directive *next;
  316. char *name;
  317. int len;
  318. };
  319. static struct directive *directives = 0;
  320. def_file *
  321. def_file_empty (void)
  322. {
  323. def_file *rv = xmalloc (sizeof (def_file));
  324. memset (rv, 0, sizeof (def_file));
  325. rv->is_dll = -1;
  326. rv->base_address = (bfd_vma) -1;
  327. rv->stack_reserve = rv->stack_commit = -1;
  328. rv->heap_reserve = rv->heap_commit = -1;
  329. rv->version_major = rv->version_minor = -1;
  330. return rv;
  331. }
  332. def_file *
  333. def_file_parse (const char *filename, def_file *add_to)
  334. {
  335. struct directive *d;
  336. the_file = fopen (filename, "r");
  337. def_filename = filename;
  338. linenumber = 1;
  339. if (!the_file)
  340. {
  341. perror (filename);
  342. return 0;
  343. }
  344. if (add_to)
  345. {
  346. def = add_to;
  347. }
  348. else
  349. {
  350. def = def_file_empty ();
  351. }
  352. saw_newline = 1;
  353. if (def_parse ())
  354. {
  355. def_file_free (def);
  356. fclose (the_file);
  357. def_pool_free ();
  358. return 0;
  359. }
  360. fclose (the_file);
  361. while ((d = directives) != NULL)
  362. {
  363. #if TRACE
  364. printf ("Adding directive %08x `%s'\n", d->name, d->name);
  365. #endif
  366. def_file_add_directive (def, d->name, d->len);
  367. directives = d->next;
  368. free (d->name);
  369. free (d);
  370. }
  371. def_pool_free ();
  372. return def;
  373. }
  374. void
  375. def_file_free (def_file *fdef)
  376. {
  377. int i;
  378. if (!fdef)
  379. return;
  380. if (fdef->name)
  381. free (fdef->name);
  382. if (fdef->description)
  383. free (fdef->description);
  384. if (fdef->section_defs)
  385. {
  386. for (i = 0; i < fdef->num_section_defs; i++)
  387. {
  388. if (fdef->section_defs[i].name)
  389. free (fdef->section_defs[i].name);
  390. if (fdef->section_defs[i].class)
  391. free (fdef->section_defs[i].class);
  392. }
  393. free (fdef->section_defs);
  394. }
  395. if (fdef->exports)
  396. {
  397. for (i = 0; i < fdef->num_exports; i++)
  398. {
  399. if (fdef->exports[i].internal_name
  400. && fdef->exports[i].internal_name != fdef->exports[i].name)
  401. free (fdef->exports[i].internal_name);
  402. if (fdef->exports[i].name)
  403. free (fdef->exports[i].name);
  404. if (fdef->exports[i].its_name)
  405. free (fdef->exports[i].its_name);
  406. }
  407. free (fdef->exports);
  408. }
  409. if (fdef->imports)
  410. {
  411. for (i = 0; i < fdef->num_imports; i++)
  412. {
  413. if (fdef->imports[i].internal_name
  414. && fdef->imports[i].internal_name != fdef->imports[i].name)
  415. free (fdef->imports[i].internal_name);
  416. if (fdef->imports[i].name)
  417. free (fdef->imports[i].name);
  418. if (fdef->imports[i].its_name)
  419. free (fdef->imports[i].its_name);
  420. }
  421. free (fdef->imports);
  422. }
  423. while (fdef->modules)
  424. {
  425. def_file_module *m = fdef->modules;
  426. fdef->modules = fdef->modules->next;
  427. free (m);
  428. }
  429. while (fdef->aligncomms)
  430. {
  431. def_file_aligncomm *c = fdef->aligncomms;
  432. fdef->aligncomms = fdef->aligncomms->next;
  433. free (c->symbol_name);
  434. free (c);
  435. }
  436. free (fdef);
  437. }
  438. #ifdef DEF_FILE_PRINT
  439. void
  440. def_file_print (FILE *file, def_file *fdef)
  441. {
  442. int i;
  443. fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
  444. if (fdef->name)
  445. fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
  446. if (fdef->is_dll != -1)
  447. fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
  448. if (fdef->base_address != (bfd_vma) -1)
  449. {
  450. fprintf (file, " base address: 0x");
  451. fprintf_vma (file, fdef->base_address);
  452. fprintf (file, "\n");
  453. }
  454. if (fdef->description)
  455. fprintf (file, " description: `%s'\n", fdef->description);
  456. if (fdef->stack_reserve != -1)
  457. fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
  458. if (fdef->stack_commit != -1)
  459. fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
  460. if (fdef->heap_reserve != -1)
  461. fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
  462. if (fdef->heap_commit != -1)
  463. fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
  464. if (fdef->num_section_defs > 0)
  465. {
  466. fprintf (file, " section defs:\n");
  467. for (i = 0; i < fdef->num_section_defs; i++)
  468. {
  469. fprintf (file, " name: `%s', class: `%s', flags:",
  470. fdef->section_defs[i].name, fdef->section_defs[i].class);
  471. if (fdef->section_defs[i].flag_read)
  472. fprintf (file, " R");
  473. if (fdef->section_defs[i].flag_write)
  474. fprintf (file, " W");
  475. if (fdef->section_defs[i].flag_execute)
  476. fprintf (file, " X");
  477. if (fdef->section_defs[i].flag_shared)
  478. fprintf (file, " S");
  479. fprintf (file, "\n");
  480. }
  481. }
  482. if (fdef->num_exports > 0)
  483. {
  484. fprintf (file, " exports:\n");
  485. for (i = 0; i < fdef->num_exports; i++)
  486. {
  487. fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
  488. fdef->exports[i].name, fdef->exports[i].internal_name,
  489. fdef->exports[i].ordinal);
  490. if (fdef->exports[i].flag_private)
  491. fprintf (file, " P");
  492. if (fdef->exports[i].flag_constant)
  493. fprintf (file, " C");
  494. if (fdef->exports[i].flag_noname)
  495. fprintf (file, " N");
  496. if (fdef->exports[i].flag_data)
  497. fprintf (file, " D");
  498. fprintf (file, "\n");
  499. }
  500. }
  501. if (fdef->num_imports > 0)
  502. {
  503. fprintf (file, " imports:\n");
  504. for (i = 0; i < fdef->num_imports; i++)
  505. {
  506. fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
  507. fdef->imports[i].internal_name,
  508. fdef->imports[i].module,
  509. fdef->imports[i].name,
  510. fdef->imports[i].ordinal);
  511. }
  512. }
  513. if (fdef->version_major != -1)
  514. fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
  515. fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
  516. }
  517. #endif
  518. /* Helper routine to check for identity of string pointers,
  519. which might be NULL. */
  520. static int
  521. are_names_equal (const char *s1, const char *s2)
  522. {
  523. if (!s1 && !s2)
  524. return 0;
  525. if (!s1 || !s2)
  526. return (!s1 ? -1 : 1);
  527. return strcmp (s1, s2);
  528. }
  529. static int
  530. cmp_export_elem (const def_file_export *e, const char *ex_name,
  531. const char *in_name, const char *its_name,
  532. int ord)
  533. {
  534. int r;
  535. if ((r = are_names_equal (ex_name, e->name)) != 0)
  536. return r;
  537. if ((r = are_names_equal (in_name, e->internal_name)) != 0)
  538. return r;
  539. if ((r = are_names_equal (its_name, e->its_name)) != 0)
  540. return r;
  541. return (ord - e->ordinal);
  542. }
  543. /* Search the position of the identical element, or returns the position
  544. of the next higher element. If last valid element is smaller, then MAX
  545. is returned. */
  546. static int
  547. find_export_in_list (def_file_export *b, int max,
  548. const char *ex_name, const char *in_name,
  549. const char *its_name, int ord, int *is_ident)
  550. {
  551. int e, l, r, p;
  552. *is_ident = 0;
  553. if (!max)
  554. return 0;
  555. if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
  556. {
  557. if (!e)
  558. *is_ident = 1;
  559. return 0;
  560. }
  561. if (max == 1)
  562. return 1;
  563. if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
  564. return max;
  565. else if (!e || max == 2)
  566. {
  567. if (!e)
  568. *is_ident = 1;
  569. return max - 1;
  570. }
  571. l = 0; r = max - 1;
  572. while (l < r)
  573. {
  574. p = (l + r) / 2;
  575. e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
  576. if (!e)
  577. {
  578. *is_ident = 1;
  579. return p;
  580. }
  581. else if (e < 0)
  582. r = p - 1;
  583. else if (e > 0)
  584. l = p + 1;
  585. }
  586. if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
  587. ++l;
  588. else if (!e)
  589. *is_ident = 1;
  590. return l;
  591. }
  592. def_file_export *
  593. def_file_add_export (def_file *fdef,
  594. const char *external_name,
  595. const char *internal_name,
  596. int ordinal,
  597. const char *its_name,
  598. int *is_dup)
  599. {
  600. def_file_export *e;
  601. int pos;
  602. int max_exports = ROUND_UP(fdef->num_exports, 32);
  603. if (internal_name && !external_name)
  604. external_name = internal_name;
  605. if (external_name && !internal_name)
  606. internal_name = external_name;
  607. /* We need to avoid duplicates. */
  608. *is_dup = 0;
  609. pos = find_export_in_list (fdef->exports, fdef->num_exports,
  610. external_name, internal_name,
  611. its_name, ordinal, is_dup);
  612. if (*is_dup != 0)
  613. return (fdef->exports + pos);
  614. if (fdef->num_exports >= max_exports)
  615. {
  616. max_exports = ROUND_UP(fdef->num_exports + 1, 32);
  617. if (fdef->exports)
  618. fdef->exports = xrealloc (fdef->exports,
  619. max_exports * sizeof (def_file_export));
  620. else
  621. fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
  622. }
  623. e = fdef->exports + pos;
  624. if (pos != fdef->num_exports)
  625. memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
  626. memset (e, 0, sizeof (def_file_export));
  627. e->name = xstrdup (external_name);
  628. e->internal_name = xstrdup (internal_name);
  629. e->its_name = (its_name ? xstrdup (its_name) : NULL);
  630. e->ordinal = ordinal;
  631. fdef->num_exports++;
  632. return e;
  633. }
  634. def_file_module *
  635. def_get_module (def_file *fdef, const char *name)
  636. {
  637. def_file_module *s;
  638. for (s = fdef->modules; s; s = s->next)
  639. if (strcmp (s->name, name) == 0)
  640. return s;
  641. return NULL;
  642. }
  643. static def_file_module *
  644. def_stash_module (def_file *fdef, const char *name)
  645. {
  646. def_file_module *s;
  647. if ((s = def_get_module (fdef, name)) != NULL)
  648. return s;
  649. s = xmalloc (sizeof (def_file_module) + strlen (name));
  650. s->next = fdef->modules;
  651. fdef->modules = s;
  652. s->user_data = 0;
  653. strcpy (s->name, name);
  654. return s;
  655. }
  656. static int
  657. cmp_import_elem (const def_file_import *e, const char *ex_name,
  658. const char *in_name, const char *module,
  659. int ord)
  660. {
  661. int r;
  662. if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
  663. return r;
  664. if ((r = are_names_equal (ex_name, e->name)) != 0)
  665. return r;
  666. if ((r = are_names_equal (in_name, e->internal_name)) != 0)
  667. return r;
  668. if (ord != e->ordinal)
  669. return (ord < e->ordinal ? -1 : 1);
  670. return 0;
  671. }
  672. /* Search the position of the identical element, or returns the position
  673. of the next higher element. If last valid element is smaller, then MAX
  674. is returned. */
  675. static int
  676. find_import_in_list (def_file_import *b, int max,
  677. const char *ex_name, const char *in_name,
  678. const char *module, int ord, int *is_ident)
  679. {
  680. int e, l, r, p;
  681. *is_ident = 0;
  682. if (!max)
  683. return 0;
  684. if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
  685. {
  686. if (!e)
  687. *is_ident = 1;
  688. return 0;
  689. }
  690. if (max == 1)
  691. return 1;
  692. if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
  693. return max;
  694. else if (!e || max == 2)
  695. {
  696. if (!e)
  697. *is_ident = 1;
  698. return max - 1;
  699. }
  700. l = 0; r = max - 1;
  701. while (l < r)
  702. {
  703. p = (l + r) / 2;
  704. e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
  705. if (!e)
  706. {
  707. *is_ident = 1;
  708. return p;
  709. }
  710. else if (e < 0)
  711. r = p - 1;
  712. else if (e > 0)
  713. l = p + 1;
  714. }
  715. if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
  716. ++l;
  717. else if (!e)
  718. *is_ident = 1;
  719. return l;
  720. }
  721. def_file_import *
  722. def_file_add_import (def_file *fdef,
  723. const char *name,
  724. const char *module,
  725. int ordinal,
  726. const char *internal_name,
  727. const char *its_name,
  728. int *is_dup)
  729. {
  730. def_file_import *i;
  731. int pos;
  732. int max_imports = ROUND_UP (fdef->num_imports, 16);
  733. /* We need to avoid here duplicates. */
  734. *is_dup = 0;
  735. pos = find_import_in_list (fdef->imports, fdef->num_imports,
  736. name,
  737. (!internal_name ? name : internal_name),
  738. module, ordinal, is_dup);
  739. if (*is_dup != 0)
  740. return fdef->imports + pos;
  741. if (fdef->num_imports >= max_imports)
  742. {
  743. max_imports = ROUND_UP (fdef->num_imports+1, 16);
  744. if (fdef->imports)
  745. fdef->imports = xrealloc (fdef->imports,
  746. max_imports * sizeof (def_file_import));
  747. else
  748. fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
  749. }
  750. i = fdef->imports + pos;
  751. if (pos != fdef->num_imports)
  752. memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
  753. memset (i, 0, sizeof (def_file_import));
  754. if (name)
  755. i->name = xstrdup (name);
  756. if (module)
  757. i->module = def_stash_module (fdef, module);
  758. i->ordinal = ordinal;
  759. if (internal_name)
  760. i->internal_name = xstrdup (internal_name);
  761. else
  762. i->internal_name = i->name;
  763. i->its_name = (its_name ? xstrdup (its_name) : NULL);
  764. fdef->num_imports++;
  765. return i;
  766. }
  767. struct
  768. {
  769. char *param;
  770. int token;
  771. }
  772. diropts[] =
  773. {
  774. { "-heap", HEAPSIZE },
  775. { "-stack", STACKSIZE_K },
  776. { "-attr", SECTIONS },
  777. { "-export", EXPORTS },
  778. { "-aligncomm", ALIGNCOMM },
  779. { 0, 0 }
  780. };
  781. void
  782. def_file_add_directive (def_file *my_def, const char *param, int len)
  783. {
  784. def_file *save_def = def;
  785. const char *pend = param + len;
  786. char * tend = (char *) param;
  787. int i;
  788. def = my_def;
  789. while (param < pend)
  790. {
  791. while (param < pend
  792. && (ISSPACE (*param) || *param == '\n' || *param == 0))
  793. param++;
  794. if (param == pend)
  795. break;
  796. /* Scan forward until we encounter any of:
  797. - the end of the buffer
  798. - the start of a new option
  799. - a newline seperating options
  800. - a NUL seperating options. */
  801. for (tend = (char *) (param + 1);
  802. (tend < pend
  803. && !(ISSPACE (tend[-1]) && *tend == '-')
  804. && *tend != '\n' && *tend != 0);
  805. tend++)
  806. ;
  807. for (i = 0; diropts[i].param; i++)
  808. {
  809. len = strlen (diropts[i].param);
  810. if (tend - param >= len
  811. && strncmp (param, diropts[i].param, len) == 0
  812. && (param[len] == ':' || param[len] == ' '))
  813. {
  814. lex_parse_string_end = tend;
  815. lex_parse_string = param + len + 1;
  816. lex_forced_token = diropts[i].token;
  817. saw_newline = 0;
  818. if (def_parse ())
  819. continue;
  820. break;
  821. }
  822. }
  823. if (!diropts[i].param)
  824. {
  825. if (tend < pend)
  826. {
  827. char saved;
  828. saved = * tend;
  829. * tend = 0;
  830. /* xgettext:c-format */
  831. einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
  832. * tend = saved;
  833. }
  834. else
  835. {
  836. einfo (_("Warning: corrupt .drectve at end of def file\n"));
  837. }
  838. }
  839. lex_parse_string = 0;
  840. param = tend;
  841. }
  842. def = save_def;
  843. def_pool_free ();
  844. }
  845. /* Parser Callbacks. */
  846. static void
  847. def_image_name (const char *name, bfd_vma base, int is_dll)
  848. {
  849. /* If a LIBRARY or NAME statement is specified without a name, there is nothing
  850. to do here. We retain the output filename specified on command line. */
  851. if (*name)
  852. {
  853. const char* image_name = lbasename (name);
  854. if (image_name != name)
  855. einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
  856. def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
  857. name);
  858. if (def->name)
  859. free (def->name);
  860. /* Append the default suffix, if none specified. */
  861. if (strchr (image_name, '.') == 0)
  862. {
  863. const char * suffix = is_dll ? ".dll" : ".exe";
  864. def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
  865. sprintf (def->name, "%s%s", image_name, suffix);
  866. }
  867. else
  868. def->name = xstrdup (image_name);
  869. }
  870. /* Honor a BASE address statement, even if LIBRARY string is empty. */
  871. def->base_address = base;
  872. def->is_dll = is_dll;
  873. }
  874. static void
  875. def_description (const char *text)
  876. {
  877. int len = def->description ? strlen (def->description) : 0;
  878. len += strlen (text) + 1;
  879. if (def->description)
  880. {
  881. def->description = xrealloc (def->description, len);
  882. strcat (def->description, text);
  883. }
  884. else
  885. {
  886. def->description = xmalloc (len);
  887. strcpy (def->description, text);
  888. }
  889. }
  890. static void
  891. def_stacksize (int reserve, int commit)
  892. {
  893. def->stack_reserve = reserve;
  894. def->stack_commit = commit;
  895. }
  896. static void
  897. def_heapsize (int reserve, int commit)
  898. {
  899. def->heap_reserve = reserve;
  900. def->heap_commit = commit;
  901. }
  902. static void
  903. def_section (const char *name, int attr)
  904. {
  905. def_file_section *s;
  906. int max_sections = ROUND_UP (def->num_section_defs, 4);
  907. if (def->num_section_defs >= max_sections)
  908. {
  909. max_sections = ROUND_UP (def->num_section_defs+1, 4);
  910. if (def->section_defs)
  911. def->section_defs = xrealloc (def->section_defs,
  912. max_sections * sizeof (def_file_import));
  913. else
  914. def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
  915. }
  916. s = def->section_defs + def->num_section_defs;
  917. memset (s, 0, sizeof (def_file_section));
  918. s->name = xstrdup (name);
  919. if (attr & 1)
  920. s->flag_read = 1;
  921. if (attr & 2)
  922. s->flag_write = 1;
  923. if (attr & 4)
  924. s->flag_execute = 1;
  925. if (attr & 8)
  926. s->flag_shared = 1;
  927. def->num_section_defs++;
  928. }
  929. static void
  930. def_section_alt (const char *name, const char *attr)
  931. {
  932. int aval = 0;
  933. for (; *attr; attr++)
  934. {
  935. switch (*attr)
  936. {
  937. case 'R':
  938. case 'r':
  939. aval |= 1;
  940. break;
  941. case 'W':
  942. case 'w':
  943. aval |= 2;
  944. break;
  945. case 'X':
  946. case 'x':
  947. aval |= 4;
  948. break;
  949. case 'S':
  950. case 's':
  951. aval |= 8;
  952. break;
  953. }
  954. }
  955. def_section (name, aval);
  956. }
  957. static void
  958. def_exports (const char *external_name,
  959. const char *internal_name,
  960. int ordinal,
  961. int flags,
  962. const char *its_name)
  963. {
  964. def_file_export *dfe;
  965. int is_dup = 0;
  966. if (!internal_name && external_name)
  967. internal_name = external_name;
  968. #if TRACE
  969. printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
  970. #endif
  971. dfe = def_file_add_export (def, external_name, internal_name, ordinal,
  972. its_name, &is_dup);
  973. /* We might check here for flag redefinition and warn. For now we
  974. ignore duplicates silently. */
  975. if (is_dup)
  976. return;
  977. if (flags & 1)
  978. dfe->flag_noname = 1;
  979. if (flags & 2)
  980. dfe->flag_constant = 1;
  981. if (flags & 4)
  982. dfe->flag_data = 1;
  983. if (flags & 8)
  984. dfe->flag_private = 1;
  985. }
  986. static void
  987. def_import (const char *internal_name,
  988. const char *module,
  989. const char *dllext,
  990. const char *name,
  991. int ordinal,
  992. const char *its_name)
  993. {
  994. char *buf = 0;
  995. const char *ext = dllext ? dllext : "dll";
  996. int is_dup = 0;
  997. buf = xmalloc (strlen (module) + strlen (ext) + 2);
  998. sprintf (buf, "%s.%s", module, ext);
  999. module = buf;
  1000. def_file_add_import (def, name, module, ordinal, internal_name, its_name,
  1001. &is_dup);
  1002. free (buf);
  1003. }
  1004. static void
  1005. def_version (int major, int minor)
  1006. {
  1007. def->version_major = major;
  1008. def->version_minor = minor;
  1009. }
  1010. static void
  1011. def_directive (char *str)
  1012. {
  1013. struct directive *d = xmalloc (sizeof (struct directive));
  1014. d->next = directives;
  1015. directives = d;
  1016. d->name = xstrdup (str);
  1017. d->len = strlen (str);
  1018. }
  1019. static void
  1020. def_aligncomm (char *str, int align)
  1021. {
  1022. def_file_aligncomm *c, *p;
  1023. p = NULL;
  1024. c = def->aligncomms;
  1025. while (c != NULL)
  1026. {
  1027. int e = strcmp (c->symbol_name, str);
  1028. if (!e)
  1029. {
  1030. /* Not sure if we want to allow here duplicates with
  1031. different alignments, but for now we keep them. */
  1032. e = (int) c->alignment - align;
  1033. if (!e)
  1034. return;
  1035. }
  1036. if (e > 0)
  1037. break;
  1038. c = (p = c)->next;
  1039. }
  1040. c = xmalloc (sizeof (def_file_aligncomm));
  1041. c->symbol_name = xstrdup (str);
  1042. c->alignment = (unsigned int) align;
  1043. if (!p)
  1044. {
  1045. c->next = def->aligncomms;
  1046. def->aligncomms = c;
  1047. }
  1048. else
  1049. {
  1050. c->next = p->next;
  1051. p->next = c;
  1052. }
  1053. }
  1054. static int
  1055. def_error (const char *err)
  1056. {
  1057. einfo ("%P: %s:%d: %s\n",
  1058. def_filename ? def_filename : "<unknown-file>", linenumber, err);
  1059. return 0;
  1060. }
  1061. /* Lexical Scanner. */
  1062. #undef TRACE
  1063. #define TRACE 0
  1064. /* Never freed, but always reused as needed, so no real leak. */
  1065. static char *buffer = 0;
  1066. static int buflen = 0;
  1067. static int bufptr = 0;
  1068. static void
  1069. put_buf (char c)
  1070. {
  1071. if (bufptr == buflen)
  1072. {
  1073. buflen += 50; /* overly reasonable, eh? */
  1074. if (buffer)
  1075. buffer = xrealloc (buffer, buflen + 1);
  1076. else
  1077. buffer = xmalloc (buflen + 1);
  1078. }
  1079. buffer[bufptr++] = c;
  1080. buffer[bufptr] = 0; /* not optimal, but very convenient. */
  1081. }
  1082. static struct
  1083. {
  1084. char *name;
  1085. int token;
  1086. }
  1087. tokens[] =
  1088. {
  1089. { "BASE", BASE },
  1090. { "CODE", CODE },
  1091. { "CONSTANT", CONSTANTU },
  1092. { "constant", CONSTANTL },
  1093. { "DATA", DATAU },
  1094. { "data", DATAL },
  1095. { "DESCRIPTION", DESCRIPTION },
  1096. { "DIRECTIVE", DIRECTIVE },
  1097. { "EXECUTE", EXECUTE },
  1098. { "EXPORTS", EXPORTS },
  1099. { "HEAPSIZE", HEAPSIZE },
  1100. { "IMPORTS", IMPORTS },
  1101. { "LIBRARY", LIBRARY },
  1102. { "NAME", NAME },
  1103. { "NONAME", NONAMEU },
  1104. { "noname", NONAMEL },
  1105. { "PRIVATE", PRIVATEU },
  1106. { "private", PRIVATEL },
  1107. { "READ", READ },
  1108. { "SECTIONS", SECTIONS },
  1109. { "SEGMENTS", SECTIONS },
  1110. { "SHARED", SHARED },
  1111. { "STACKSIZE", STACKSIZE_K },
  1112. { "VERSION", VERSIONK },
  1113. { "WRITE", WRITE },
  1114. { 0, 0 }
  1115. };
  1116. static int
  1117. def_getc (void)
  1118. {
  1119. int rv;
  1120. if (lex_parse_string)
  1121. {
  1122. if (lex_parse_string >= lex_parse_string_end)
  1123. rv = EOF;
  1124. else
  1125. rv = *lex_parse_string++;
  1126. }
  1127. else
  1128. {
  1129. rv = fgetc (the_file);
  1130. }
  1131. if (rv == '\n')
  1132. saw_newline = 1;
  1133. return rv;
  1134. }
  1135. static int
  1136. def_ungetc (int c)
  1137. {
  1138. if (lex_parse_string)
  1139. {
  1140. lex_parse_string--;
  1141. return c;
  1142. }
  1143. else
  1144. return ungetc (c, the_file);
  1145. }
  1146. static int
  1147. def_lex (void)
  1148. {
  1149. int c, i, q;
  1150. if (lex_forced_token)
  1151. {
  1152. i = lex_forced_token;
  1153. lex_forced_token = 0;
  1154. #if TRACE
  1155. printf ("lex: forcing token %d\n", i);
  1156. #endif
  1157. return i;
  1158. }
  1159. c = def_getc ();
  1160. /* Trim leading whitespace. */
  1161. while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
  1162. c = def_getc ();
  1163. if (c == EOF)
  1164. {
  1165. #if TRACE
  1166. printf ("lex: EOF\n");
  1167. #endif
  1168. return 0;
  1169. }
  1170. if (saw_newline && c == ';')
  1171. {
  1172. do
  1173. {
  1174. c = def_getc ();
  1175. }
  1176. while (c != EOF && c != '\n');
  1177. if (c == '\n')
  1178. return def_lex ();
  1179. return 0;
  1180. }
  1181. /* Must be something else. */
  1182. saw_newline = 0;
  1183. if (ISDIGIT (c))
  1184. {
  1185. bufptr = 0;
  1186. while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
  1187. {
  1188. put_buf (c);
  1189. c = def_getc ();
  1190. }
  1191. if (c != EOF)
  1192. def_ungetc (c);
  1193. yylval.digits = def_pool_strdup (buffer);
  1194. #if TRACE
  1195. printf ("lex: `%s' returns DIGITS\n", buffer);
  1196. #endif
  1197. return DIGITS;
  1198. }
  1199. if (ISALPHA (c) || strchr ("$:-_?@", c))
  1200. {
  1201. bufptr = 0;
  1202. q = c;
  1203. put_buf (c);
  1204. c = def_getc ();
  1205. if (q == '@')
  1206. {
  1207. if (ISBLANK (c) ) /* '@' followed by whitespace. */
  1208. return (q);
  1209. else if (ISDIGIT (c)) /* '@' followed by digit. */
  1210. {
  1211. def_ungetc (c);
  1212. return (q);
  1213. }
  1214. #if TRACE
  1215. printf ("lex: @ returns itself\n");
  1216. #endif
  1217. }
  1218. while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
  1219. {
  1220. put_buf (c);
  1221. c = def_getc ();
  1222. }
  1223. if (c != EOF)
  1224. def_ungetc (c);
  1225. if (ISALPHA (q)) /* Check for tokens. */
  1226. {
  1227. for (i = 0; tokens[i].name; i++)
  1228. if (strcmp (tokens[i].name, buffer) == 0)
  1229. {
  1230. #if TRACE
  1231. printf ("lex: `%s' is a string token\n", buffer);
  1232. #endif
  1233. return tokens[i].token;
  1234. }
  1235. }
  1236. #if TRACE
  1237. printf ("lex: `%s' returns ID\n", buffer);
  1238. #endif
  1239. yylval.id = def_pool_strdup (buffer);
  1240. return ID;
  1241. }
  1242. if (c == '\'' || c == '"')
  1243. {
  1244. q = c;
  1245. c = def_getc ();
  1246. bufptr = 0;
  1247. while (c != EOF && c != q)
  1248. {
  1249. put_buf (c);
  1250. c = def_getc ();
  1251. }
  1252. yylval.id = def_pool_strdup (buffer);
  1253. #if TRACE
  1254. printf ("lex: `%s' returns ID\n", buffer);
  1255. #endif
  1256. return ID;
  1257. }
  1258. if ( c == '=')
  1259. {
  1260. c = def_getc ();
  1261. if (c == '=')
  1262. {
  1263. #if TRACE
  1264. printf ("lex: `==' returns EQUAL\n");
  1265. #endif
  1266. return EQUAL;
  1267. }
  1268. def_ungetc (c);
  1269. #if TRACE
  1270. printf ("lex: `=' returns itself\n");
  1271. #endif
  1272. return '=';
  1273. }
  1274. if (c == '.' || c == ',')
  1275. {
  1276. #if TRACE
  1277. printf ("lex: `%c' returns itself\n", c);
  1278. #endif
  1279. return c;
  1280. }
  1281. if (c == '\n')
  1282. {
  1283. linenumber++;
  1284. saw_newline = 1;
  1285. }
  1286. /*printf ("lex: 0x%02x ignored\n", c); */
  1287. return def_lex ();
  1288. }
  1289. static char *
  1290. def_pool_alloc (size_t sz)
  1291. {
  1292. def_pool_str *e;
  1293. e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
  1294. e->next = pool_strs;
  1295. pool_strs = e;
  1296. return e->data;
  1297. }
  1298. static char *
  1299. def_pool_strdup (const char *str)
  1300. {
  1301. char *s;
  1302. size_t len;
  1303. if (!str)
  1304. return NULL;
  1305. len = strlen (str) + 1;
  1306. s = def_pool_alloc (len);
  1307. memcpy (s, str, len);
  1308. return s;
  1309. }
  1310. static void
  1311. def_pool_free (void)
  1312. {
  1313. def_pool_str *p;
  1314. while ((p = pool_strs) != NULL)
  1315. {
  1316. pool_strs = p->next;
  1317. free (p);
  1318. }
  1319. }