symout.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. /* Output GDB-format symbol table information from GNU compiler.
  2. Copyright (C) 1987 Free Software Foundation, Inc.
  3. This file is part of GNU CC.
  4. GNU CC is distributed in the hope that it will be useful,
  5. but WITHOUT ANY WARRANTY. No author or distributor
  6. accepts responsibility to anyone for the consequences of using it
  7. or for whether it serves any particular purpose or works at all,
  8. unless he says so in writing. Refer to the GNU CC General Public
  9. License for full details.
  10. Everyone is granted permission to copy, modify and redistribute
  11. GNU CC, but only under the conditions described in the
  12. GNU CC General Public License. A copy of this license is
  13. supposed to have been given to you along with GNU CC so you
  14. can know your rights and responsibilities. It should be in a
  15. file named COPYING. Among other things, the copyright notice
  16. and this notice must be preserved on all copies. */
  17. #include "config.h"
  18. #include "tree.h"
  19. #include "symseg.h"
  20. #include "rtl.h"
  21. #include <stdio.h>
  22. #include <stab.h>
  23. /* Unix maximum on file name length. Needed for getwd. */
  24. #define MAXNAMLEN 1024
  25. /* Get the number to output for a reference to type TYPE. */
  26. #define TYPE_OUTPUT_ADDRESS(TYPE) \
  27. TYPE_SYMTAB_ADDRESS (TYPE_MAIN_VARIANT (TYPE))
  28. /* Stream for writing symbol table file. */
  29. static FILE *symfile;
  30. /* Stream for writing to assembler file. */
  31. static FILE *asmfile;
  32. /* Address for allocating space in symbol table file.
  33. Changes in this variable are paired globally with writes to symfile,
  34. but often we allocate many structures, advancing next_address,
  35. before writing any of them. */
  36. static int next_address;
  37. struct typevec_elt
  38. {
  39. int address;
  40. struct typevec_elt *next;
  41. };
  42. static struct typevec_elt *typevec;
  43. static int total_types;
  44. struct blockvec_elt
  45. {
  46. int address;
  47. struct blockvec_elt *next;
  48. };
  49. static struct blockvec_elt *blockvec;
  50. static int total_blocks;
  51. static void symout_range_bounds ();
  52. static void symout_array_domain ();
  53. static void symout_record_fields ();
  54. static void symout_enum_values ();
  55. static void symout_record_field_names ();
  56. static void symout_enum_value_names ();
  57. static int subrange_p ();
  58. static void symout_strings_skip ();
  59. static void symout_strings_print ();
  60. /* At the beginning of compilation, start writing the symbol table. */
  61. void
  62. symout_init (filename, asm_file, sourcename)
  63. char *filename;
  64. FILE *asm_file;
  65. char *sourcename;
  66. {
  67. struct symbol_root buffer;
  68. asmfile = asm_file;
  69. fprintf (asmfile, ".text 0\n.gdbbeg 0\n.gdbbeg 1\n");
  70. fprintf (asmfile,
  71. "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
  72. sourcename, N_SO);
  73. fprintf (asmfile, ".data 0\nLdata:\n");
  74. fprintf (asmfile, ".lcomm Lbss,0\n");
  75. fprintf (asmfile, ".gdbsym Ldata,%d\n",
  76. (char *) &buffer.databeg - (char *) &buffer);
  77. fprintf (asmfile, ".gdbsym Lbss,%d\n",
  78. (char *) &buffer.bssbeg - (char *) &buffer);
  79. symfile = fopen (filename, "w");
  80. if (symfile == 0)
  81. {
  82. perror (symfile);
  83. fatal ("Cannot continue compilation.");
  84. }
  85. typevec = 0;
  86. blockvec = 0;
  87. total_types = 0;
  88. total_blocks = 0;
  89. bzero (&buffer, sizeof buffer);
  90. fwrite (&buffer, sizeof buffer, 1, symfile);
  91. next_address = sizeof buffer;
  92. }
  93. /* Functions for outputting strings into the symbol table.
  94. The string to be output is effectively the concatenation of
  95. the two strings P1 and P2. Their lengths are given as S1 and S2.
  96. If P1 or P2 is zero, that string is not used.
  97. A null character is output to terminate the string,
  98. and it is followed by more nulls as padding to a word boundary. */
  99. static void
  100. symout_strings (p1, s1, p2, s2)
  101. char *p1;
  102. int s1;
  103. char *p2;
  104. int s2;
  105. {
  106. symout_strings_print (p1, s1, p2, s2);
  107. symout_strings_skip (p1, s1, p2, s2);
  108. }
  109. /* Similar but only output; do not update next_address. */
  110. static void
  111. symout_strings_print (p1, s1, p2, s2)
  112. char *p1;
  113. int s1;
  114. char *p2;
  115. int s2;
  116. {
  117. register int total;
  118. if (p1 && s1 == 0)
  119. s1 = strlen (p1);
  120. if (p2 && s2 == 0)
  121. s2 = strlen (p2);
  122. if (p1)
  123. fwrite (p1, s1, 1, symfile);
  124. if (p2)
  125. fwrite (p2, s2, 1, symfile);
  126. putc (0, symfile);
  127. total = s1 + s2 + 1;
  128. while (total % sizeof (int))
  129. {
  130. putc (0, symfile);
  131. total++;
  132. }
  133. }
  134. /* Similar but only update next_address; do not output anything. */
  135. static void
  136. symout_strings_skip (p1, s1, p2, s2)
  137. char *p1;
  138. int s1;
  139. char *p2;
  140. int s2;
  141. {
  142. register int total;
  143. if (p1 && s1 == 0)
  144. s1 = strlen (p1);
  145. if (p2 && s2 == 0)
  146. s2 = strlen (p2);
  147. total = s1 + s2 + 1;
  148. while (total % sizeof (int))
  149. total++;
  150. next_address += total;
  151. }
  152. /* Call here to output a chain of types.
  153. After each function, this is done first for the chain of permanent types
  154. made during the function, and then for the chain of temporary types.
  155. This must be done before outputting the symbols and blocks of the function.
  156. At the end of compilation, this is done for all the permanent types
  157. made since the last function.
  158. Each permanent type is done once, at the beginning of the next function,
  159. or at the end of the compilation if no functions follow.
  160. Once a type has been processed here, its TYPE_SYMTAB_ADDRESS remains
  161. set up. */
  162. void
  163. symout_types (types)
  164. tree types;
  165. {
  166. struct typerec
  167. {
  168. int number;
  169. int address;
  170. int nfields;
  171. int fields_address;
  172. int name_address;
  173. char *name;
  174. char *name_prefix;
  175. };
  176. register int n_types, i;
  177. register struct typerec *records;
  178. register tree next;
  179. struct type buffer;
  180. struct field fieldbuf;
  181. for (next = types, n_types = 0;
  182. next;
  183. next = TREE_CHAIN (next), n_types++);
  184. records = (struct typerec *) alloca (n_types * sizeof (struct typerec));
  185. for (next = types, i = 0;
  186. next;
  187. next = TREE_CHAIN (next), i++)
  188. {
  189. register struct typevec_elt *velt
  190. = (struct typevec_elt *) xmalloc (sizeof (struct typevec_elt));
  191. velt->next = typevec;
  192. typevec = velt;
  193. total_types++;
  194. if (TYPE_NAME (next))
  195. {
  196. records[i].name_address = next_address;
  197. if (TREE_CODE (TYPE_NAME (next)) == IDENTIFIER_NODE)
  198. {
  199. records[i].name = IDENTIFIER_POINTER (TYPE_NAME (next));
  200. switch (TREE_CODE (next))
  201. {
  202. case RECORD_TYPE:
  203. records[i].name_prefix = "struct ";
  204. break;
  205. case UNION_TYPE:
  206. records[i].name_prefix = "union ";
  207. break;
  208. case ENUMERAL_TYPE:
  209. records[i].name_prefix = "enum ";
  210. break;
  211. }
  212. }
  213. else
  214. {
  215. records[i].name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (next)));
  216. records[i].name_prefix = 0;
  217. }
  218. symout_strings_skip (records[i].name_prefix, 0,
  219. records[i].name, 0);
  220. }
  221. else
  222. {
  223. records[i].name = 0;
  224. records[i].name_address = 0;
  225. records[i].name_prefix = 0;
  226. }
  227. records[i].address = next_address;
  228. TYPE_SYMTAB_ADDRESS (next) = next_address;
  229. velt->address = next_address;
  230. next_address += sizeof (struct type);
  231. records[i].nfields = 0;
  232. records[i].fields_address = 0;
  233. switch (TREE_CODE (next))
  234. {
  235. case ARRAY_TYPE:
  236. records[i].nfields = ! integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (next)));
  237. break;
  238. case INTEGER_TYPE:
  239. if (subrange_p (next))
  240. buffer.nfields = 2;
  241. break;
  242. case RECORD_TYPE:
  243. case UNION_TYPE:
  244. case ENUMERAL_TYPE:
  245. records[i].nfields = list_length (TYPE_FIELDS (next));
  246. }
  247. if (records[i].nfields)
  248. records[i].fields_address = next_address;
  249. next_address += records[i].nfields * sizeof (struct field);
  250. }
  251. for (next = types, i = 0;
  252. next;
  253. next = TREE_CHAIN (next), i++)
  254. {
  255. if (records[i].name)
  256. symout_strings_print (records[i].name_prefix, 0,
  257. records[i].name, 0);
  258. buffer.length = TREE_INT_CST_LOW (TYPE_SIZE (next)) * TYPE_SIZE_UNIT (next) / BITS_PER_UNIT;
  259. buffer.name = (char *) records[i].name_address;
  260. buffer.target_type = (struct type *) (TREE_TYPE (next) ? TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) : 0);
  261. buffer.pointer_type = 0;
  262. buffer.function_type = 0;
  263. buffer.flags
  264. = ((TREE_CODE (next) == INTEGER_TYPE || TREE_CODE (next) == ENUMERAL_TYPE)
  265. && type_unsigned_p (next))
  266. ? TYPE_FLAG_UNSIGNED : 0;
  267. buffer.nfields = records[i].nfields;
  268. buffer.fields = (struct field *) records[i].fields_address;
  269. switch (TREE_CODE (next))
  270. {
  271. case INTEGER_TYPE:
  272. buffer.code = TYPE_CODE_INT;
  273. if (buffer.nfields)
  274. buffer.code = TYPE_CODE_RANGE;
  275. break;
  276. case REAL_TYPE:
  277. buffer.code = TYPE_CODE_FLT;
  278. break;
  279. case VOID_TYPE:
  280. buffer.code = TYPE_CODE_VOID;
  281. break;
  282. case POINTER_TYPE:
  283. buffer.code = TYPE_CODE_PTR;
  284. break;
  285. case ARRAY_TYPE:
  286. if (buffer.nfields == 0)
  287. buffer.code = TYPE_CODE_ARRAY;
  288. else
  289. buffer.code = TYPE_CODE_PASCAL_ARRAY;
  290. break;
  291. case RECORD_TYPE:
  292. buffer.code = TYPE_CODE_STRUCT;
  293. break;
  294. case UNION_TYPE:
  295. buffer.code = TYPE_CODE_UNION;
  296. break;
  297. case FUNCTION_TYPE:
  298. buffer.code = TYPE_CODE_FUNC;
  299. break;
  300. case ENUMERAL_TYPE:
  301. buffer.code = TYPE_CODE_ENUM;
  302. break;
  303. default:
  304. abort ();
  305. }
  306. fwrite (&buffer, sizeof buffer, 1, symfile);
  307. switch (TREE_CODE (next))
  308. {
  309. case ARRAY_TYPE:
  310. if (buffer.nfields)
  311. symout_array_domain (next);
  312. break;
  313. case RECORD_TYPE:
  314. case UNION_TYPE:
  315. symout_record_fields (next);
  316. break;
  317. case ENUMERAL_TYPE:
  318. symout_enum_values (next);
  319. break;
  320. case INTEGER_TYPE:
  321. if (buffer.nfields)
  322. symout_range_bounds (next);
  323. }
  324. }
  325. for (next = types, i = 0;
  326. next;
  327. next = TREE_CHAIN (next), i++)
  328. {
  329. switch (TREE_CODE (next))
  330. {
  331. case RECORD_TYPE:
  332. case UNION_TYPE:
  333. symout_record_field_names (next);
  334. break;
  335. case ENUMERAL_TYPE:
  336. symout_enum_value_names (next);
  337. break;
  338. }
  339. }
  340. }
  341. /* Return nonzero if TYPE's range of possible values
  342. is not the full range allowed by the number of bits it has.
  343. TYPE is assumed to be an INTEGER_TYPE or ENUMERAL_TYPE. */
  344. static int
  345. subrange_p (type)
  346. tree type;
  347. {
  348. int uns = type_unsigned_p (type);
  349. if (TYPE_PRECISION (type) >= HOST_BITS_PER_INT)
  350. {
  351. if (uns)
  352. return integer_zerop (TYPE_MIN_VALUE (type))
  353. && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
  354. && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
  355. == (1 << (TYPE_PRECISION (type) - HOST_BITS_PER_INT)) - 1);
  356. return TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
  357. && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
  358. && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type))
  359. == (-1) << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT))
  360. && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
  361. == (1 << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT)) - 1);
  362. }
  363. if (uns)
  364. return integer_zerop (TYPE_MIN_VALUE (type))
  365. && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
  366. == (1 << TYPE_PRECISION (type)) - 1);
  367. else
  368. return (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))
  369. == (-1) << (TYPE_PRECISION (type) - 1))
  370. && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
  371. == (1 << (TYPE_PRECISION (type) - 1)) - 1);
  372. }
  373. /* Functions to output the "fields" of various kinds of types.
  374. These assume that next_address has already been incremented to
  375. cover these fields, and the fields of all the other types being
  376. output in this batch; so next_address can be used to allocate
  377. space to store field names, etc. */
  378. static void
  379. symout_array_domain (type)
  380. tree type;
  381. {
  382. struct field buffer;
  383. buffer.bitpos = 0;
  384. buffer.bitsize = 0;
  385. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TYPE_DOMAIN (type));
  386. buffer.name = 0;
  387. fwrite (&buffer, sizeof (struct field), 1, symfile);
  388. }
  389. static void
  390. symout_range_bounds (type)
  391. tree type;
  392. {
  393. struct field buffer;
  394. buffer.bitpos = TREE_INT_CST_LOW (TYPE_MIN_VALUE (type));
  395. buffer.bitsize = 0;
  396. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  397. buffer.name = 0;
  398. fwrite (&buffer, sizeof (struct field), 1, symfile);
  399. buffer.bitpos = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type));
  400. buffer.bitsize = 0;
  401. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  402. buffer.name = 0;
  403. fwrite (&buffer, sizeof (struct field), 1, symfile);
  404. }
  405. static void
  406. symout_record_fields (type)
  407. tree type;
  408. {
  409. struct field buffer;
  410. register tree field;
  411. for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  412. {
  413. buffer.bitpos = DECL_OFFSET (field);
  414. buffer.bitsize
  415. = (TREE_PACKED (field)
  416. ? TYPE_PRECISION (TREE_TYPE (field))
  417. : 0);
  418. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (field));
  419. buffer.name = (char *) next_address;
  420. symout_strings_skip (0, IDENTIFIER_LENGTH (DECL_NAME (field)), 0, 0);
  421. fwrite (&buffer, sizeof (struct field), 1, symfile);
  422. }
  423. }
  424. static void
  425. symout_enum_values (type)
  426. tree type;
  427. {
  428. struct field buffer;
  429. register tree link, value;
  430. for (link = TYPE_VALUES (type); link; link = TREE_CHAIN (link))
  431. {
  432. value = TREE_VALUE (link);
  433. buffer.bitpos = TREE_INT_CST_LOW (value);
  434. buffer.bitsize = 0;
  435. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  436. buffer.name = (char *) next_address;
  437. symout_strings_skip (0, IDENTIFIER_LENGTH (TREE_PURPOSE (link)), 0, 0);
  438. fwrite (&buffer, sizeof buffer, 1, symfile);
  439. }
  440. }
  441. /* Output field names or value names for the fields of a type.
  442. This is called, for the types that need it, after the fields
  443. have been output for all the types in the batch.
  444. We do not update next_address here, because it has already been
  445. updated for all the names in all the fields in all the types. */
  446. static void
  447. symout_record_field_names (type)
  448. tree type;
  449. {
  450. struct field buffer;
  451. register tree field;
  452. for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  453. symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (field)),
  454. IDENTIFIER_LENGTH (DECL_NAME (field)),
  455. 0, 0);
  456. }
  457. static void
  458. symout_enum_value_names (type)
  459. tree type;
  460. {
  461. struct field buffer;
  462. register tree value;
  463. for (value = TYPE_VALUES (type); value; value = TREE_CHAIN (value))
  464. symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (value)),
  465. IDENTIFIER_LENGTH (DECL_NAME (value)),
  466. 0, 0);
  467. }
  468. /* Output the symbols of a block, given the list of decl nodes.
  469. Store the file addresses at which the symbols are output
  470. into ADDR_BUFFER, a vector which has just the right length.
  471. If FILTER is 1, do only the private symbols in DECLS.
  472. If FILTER is 2, do only the public ones (but no externals).
  473. If FILTER is 0, do all (except external functions). */
  474. static int
  475. symout_block_symbols (decls, addr_buffer, filter)
  476. tree decls;
  477. int *addr_buffer;
  478. int filter;
  479. {
  480. register tree decl;
  481. struct symbol buffer;
  482. register int i;
  483. for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  484. {
  485. register name_address = next_address;
  486. if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
  487. continue;
  488. /* Do not mention external functions.
  489. Let their own files mention them.
  490. In the top blocks, don't mention external anything. */
  491. if (TREE_EXTERNAL (decl)
  492. && (filter || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE))
  493. continue;
  494. symout_strings (IDENTIFIER_POINTER (DECL_NAME (decl)),
  495. IDENTIFIER_LENGTH (DECL_NAME (decl)),
  496. 0, 0);
  497. addr_buffer[i] = next_address;
  498. buffer.name = (char *) name_address;
  499. buffer.namespace = VAR_NAMESPACE;
  500. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (decl));
  501. switch (TREE_CODE (decl))
  502. {
  503. case PARM_DECL:
  504. buffer.class = LOC_ARG;
  505. buffer.value.value = DECL_OFFSET (decl) / BITS_PER_UNIT;
  506. break;
  507. case VAR_DECL:
  508. case RESULT_DECL:
  509. if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
  510. {
  511. if (! TREE_PUBLIC (decl) || DECL_INITIAL (decl))
  512. {
  513. char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
  514. fprintf (asmfile, "\t.gdbsym _%s,%d\n", str,
  515. next_address
  516. + (char *)&buffer.value - (char *)&buffer);
  517. buffer.class = LOC_STATIC;
  518. }
  519. else
  520. /* Uninitialized public symbols are output as .comm;
  521. Tell GDB to get address from loader global symbol.
  522. Also come here for symbols declared extern. */
  523. buffer.class = LOC_EXTERNAL;
  524. }
  525. else
  526. {
  527. if (GET_CODE (DECL_RTL (decl)) == REG)
  528. {
  529. buffer.class = LOC_REGISTER;
  530. buffer.value.value = REGNO (DECL_RTL (decl));
  531. /* Detect vars that were optimized entirely away. */
  532. if (buffer.value.value == -1)
  533. buffer.class = LOC_CONST;
  534. }
  535. /* Locals in memory are expected to be addressed as
  536. (PLUS (REG ...) (CONST_INT ...)).
  537. Bomb out if that is not so. */
  538. else if (GET_CODE (DECL_RTL (decl)) == MEM)
  539. {
  540. register rtx addr = XEXP (DECL_RTL (decl), 0);
  541. if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
  542. abort ();
  543. if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
  544. abort ();
  545. buffer.class = LOC_LOCAL;
  546. buffer.value.value = INTVAL (XEXP (addr, 1));
  547. if (GET_CODE (addr) == MINUS)
  548. buffer.value.value = - buffer.value.value;
  549. }
  550. else
  551. abort ();
  552. }
  553. break;
  554. case TYPE_DECL:
  555. buffer.class = LOC_TYPEDEF;
  556. buffer.value.value = 0;
  557. break;
  558. case CONST_DECL:
  559. buffer.class = LOC_CONST;
  560. buffer.value.value = TREE_INT_CST_LOW (DECL_INITIAL (decl));
  561. break;
  562. case FUNCTION_DECL:
  563. if (DECL_INITIAL (decl))
  564. {
  565. buffer.class = LOC_BLOCK;
  566. buffer.value.value = DECL_BLOCK_SYMTAB_ADDRESS (decl);
  567. }
  568. else
  569. buffer.class = LOC_EXTERNAL;
  570. }
  571. fwrite (&buffer, sizeof buffer, 1, symfile);
  572. next_address += sizeof buffer;
  573. i++;
  574. }
  575. }
  576. /* Output the tags (struct, union and enum definitions) for a block,
  577. given a list of them (a chain of TREE_LIST nodes) in TAGS.
  578. STore their addresses in the file into ADDR_BUFFER. */
  579. static int
  580. symout_block_tags (tags, addr_buffer)
  581. tree tags;
  582. int *addr_buffer;
  583. {
  584. register tree tag;
  585. struct symbol buffer;
  586. register int i;
  587. for (tag = tags, i = 0; tag; tag = TREE_CHAIN (tag), i++)
  588. {
  589. buffer.name = (char *) next_address;
  590. symout_strings (IDENTIFIER_POINTER (TREE_PURPOSE (tag)),
  591. IDENTIFIER_LENGTH (TREE_PURPOSE (tag)),
  592. 0, 0);
  593. addr_buffer[i] = next_address;
  594. buffer.namespace = STRUCT_NAMESPACE;
  595. buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_VALUE (tag));
  596. buffer.class = LOC_TYPEDEF;
  597. buffer.value.value = 0;
  598. fwrite (&buffer, sizeof buffer, 1, symfile);
  599. next_address += sizeof buffer;
  600. }
  601. }
  602. /* Output all the data structure for a "block"
  603. (any binding contour).
  604. DECLS is the chain of declarations of variables in this block.
  605. TAGS is the list of struct, union and enum tag definitions of this block.
  606. SUPERBLOCK_ADDRESS is the symtab file address of the containing block's
  607. data structure. */
  608. int
  609. symout_block (decls, tags, args, superblock_address)
  610. tree decls;
  611. tree tags;
  612. tree args;
  613. int superblock_address;
  614. {
  615. register tree decl;
  616. register int i;
  617. register int *addr_buffer;
  618. struct block buffer;
  619. int n_decls, n_tags, n_args, total;
  620. register struct blockvec_elt *velt;
  621. int block_address;
  622. for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  623. if (! TREE_EXTERNAL (decl)
  624. || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE)
  625. i++;
  626. n_decls = i;
  627. for (decl = args, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  628. n_args = i;
  629. for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  630. n_tags = i;
  631. total = n_decls + n_args + n_tags;
  632. addr_buffer = (int *) alloca (total * sizeof (int));
  633. symout_block_symbols (args, addr_buffer, 0);
  634. symout_block_symbols (decls, addr_buffer, n_args);
  635. symout_block_tags (tags, addr_buffer + n_decls + n_args);
  636. velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
  637. velt->next = blockvec;
  638. velt->address = next_address;
  639. blockvec = velt;
  640. buffer.startaddr = 0;
  641. buffer.endaddr = 0;
  642. buffer.superblock = (struct block *) superblock_address;
  643. buffer.function = 0;
  644. buffer.nsyms = total;
  645. block_address = next_address;
  646. fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
  647. next_address += sizeof buffer - sizeof buffer.sym;
  648. fwrite (addr_buffer, sizeof (int), total, symfile);
  649. next_address += total * sizeof (int);
  650. fprintf (asmfile, "\t.gdbblock %d,%d\n", total_blocks + 2, block_address);
  651. total_blocks++;
  652. return block_address;
  653. }
  654. /* Walk STMT, the body of a function, and output symtab data on
  655. all the blocks that compose it and all symbols inside them.
  656. ARGS is a chain of decls for argument variables of the function.
  657. SUPERBLOCK_ADDRESS is the address of symbol data for the
  658. innermost block containing STMT; it is used for recursive calls,
  659. and is always 0 for the outermost call (since the containing
  660. block for a function is output later than the function). */
  661. int
  662. symout_function (stmt, args, superblock_address)
  663. register tree stmt;
  664. tree args;
  665. int superblock_address;
  666. {
  667. register tree decl;
  668. int address = superblock_address;
  669. while (stmt)
  670. {
  671. switch (TREE_CODE (stmt))
  672. {
  673. case COMPOUND_STMT:
  674. case LOOP_STMT:
  675. symout_function (STMT_BODY (stmt), 0, address);
  676. break;
  677. case IF_STMT:
  678. symout_function (STMT_THEN (stmt), 0, address);
  679. symout_function (STMT_ELSE (stmt), 0, address);
  680. break;
  681. case LET_STMT:
  682. address =
  683. symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args,
  684. superblock_address);
  685. symout_function (STMT_BODY (stmt), 0, address);
  686. }
  687. stmt = TREE_CHAIN (stmt);
  688. }
  689. return address;
  690. }
  691. /* Output all the data structure for a top two blocks in a compilation.
  692. The top block is for public (global) symbols;
  693. the next one is for private (this file only) symbols.
  694. DECLS is the chain of declarations of variables in this block.
  695. TAGS is the list of struct, union and enum tag definitions. */
  696. int
  697. symout_top_blocks (decls, tags)
  698. tree decls;
  699. tree tags;
  700. {
  701. register tree decl;
  702. register int i;
  703. register int *addr_buffer;
  704. struct block buffer;
  705. int n_decls, n_tags;
  706. register struct blockvec_elt *velt;
  707. int top_block_addr;
  708. /* First do the public-symbols block. */
  709. for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  710. if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
  711. i++;
  712. n_decls = i;
  713. addr_buffer = (int *) alloca (n_decls * sizeof (int));
  714. symout_block_symbols (decls, addr_buffer, 2);
  715. fprintf (asmfile, ".text 0\n\t.gdbend 0\n");
  716. fprintf (asmfile, "\t.gdbblock 0,%d\n", next_address);
  717. total_blocks++;
  718. velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
  719. velt->next = blockvec;
  720. velt->address = next_address;
  721. blockvec = velt;
  722. top_block_addr = next_address;
  723. buffer.startaddr = 0;
  724. buffer.endaddr = 0;
  725. buffer.superblock = 0;
  726. buffer.function = 0;
  727. buffer.nsyms = n_decls;;
  728. fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
  729. next_address += sizeof buffer - sizeof buffer.sym;
  730. fwrite (addr_buffer, sizeof (int), n_decls, symfile);
  731. next_address += n_decls * sizeof (int);
  732. /* Next do the private-symbols block. */
  733. for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  734. if (! TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
  735. i++;
  736. n_decls = i;
  737. for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  738. n_tags = i;
  739. addr_buffer = (int *) alloca ((n_decls + n_tags) * sizeof (int));
  740. symout_block_symbols (decls, addr_buffer, 1);
  741. symout_block_tags (tags, addr_buffer + n_decls);
  742. fprintf (asmfile, "\t.gdbend 1\n");
  743. fprintf (asmfile, "\t.gdbblock 1,%d\n", next_address);
  744. total_blocks++;
  745. velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
  746. velt->next = blockvec;
  747. velt->address = next_address;
  748. blockvec = velt;
  749. buffer.startaddr = 0;
  750. buffer.endaddr = 0;
  751. buffer.superblock = (struct block *) top_block_addr;
  752. buffer.function = 0;
  753. buffer.nsyms = n_decls + n_tags;;
  754. fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
  755. next_address += sizeof buffer - sizeof buffer.sym;
  756. fwrite (addr_buffer, sizeof (int), n_decls + n_tags, symfile);
  757. next_address += (n_decls + n_tags) * sizeof (int);
  758. }
  759. /* Call here at the end of compilation, after outputting all the
  760. blocks and symbols, to output the blockvector and typevector
  761. and close the symbol table file. FILETIME is source file's
  762. creation time. */
  763. void
  764. symout_finish (filename, filetime)
  765. char *filename;
  766. int filetime;
  767. {
  768. int *blockvector = (int *) alloca ((total_blocks + 1) * sizeof (int));
  769. int *typevector = (int *) alloca ((total_types + 1) * sizeof (int));
  770. int now = time ();
  771. register int i;
  772. struct symbol_root buffer;
  773. char dir[MAXNAMLEN];
  774. buffer.language = language_c;
  775. buffer.blockvector = (struct blockvector *) next_address;
  776. /* The two blocks at the beginning of the chain
  777. are the file's private symbols block and public symbols block.
  778. They belong at the front of the blockvector, in that order. */
  779. blockvector[2] = blockvec->address;
  780. blockvec = blockvec->next;
  781. blockvector[1] = blockvec->address;
  782. blockvec = blockvec->next;
  783. /* The rest of the blocks are in the chain in reverse order. */
  784. for (i = total_blocks; i > 2; i--)
  785. {
  786. blockvector[i] = blockvec->address;
  787. blockvec = blockvec->next;
  788. }
  789. blockvector[0] = total_blocks;
  790. fwrite (blockvector, sizeof (int), total_blocks + 1, symfile);
  791. next_address += sizeof (int) * (total_blocks + 1);
  792. buffer.typevector = (struct typevector *) next_address;
  793. for (i = total_types; i > 0; i--)
  794. {
  795. typevector[i] = typevec->address;
  796. typevec = typevec->next;
  797. }
  798. typevector[0] = total_types;
  799. fwrite (typevector, sizeof (int), total_types + 1, symfile);
  800. next_address += sizeof (int) * (total_types + 1);
  801. buffer.format = 1;
  802. buffer.textrel = 0; /* These four will be set up by linker. */
  803. buffer.datarel = 0; /* Make them 0 now, which is right for */
  804. buffer.bssrel = 0; /* looking at the .o file in gdb. */
  805. buffer.ldsymoff = 0;
  806. buffer.version = (char *) next_address;
  807. symout_strings (ctime (&filetime), 0, 0, 0);
  808. buffer.compilation = (char *) next_address;
  809. symout_strings (ctime (&now), 0, 0, 0);
  810. buffer.filename = (char *) next_address;
  811. symout_strings (filename, 0, 0, 0);
  812. buffer.filedir = (char *) next_address;
  813. getwd (dir);
  814. symout_strings (dir, 0, 0, 0);
  815. fflush (symfile);
  816. buffer.length = next_address;
  817. lseek (fileno (symfile), 0, 0);
  818. write (fileno (symfile), &buffer, sizeof buffer);
  819. close (fileno (symfile));
  820. }