dbxread.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* $Header$
  2. Read the symbol table from an ACK a.out format file.
  3. */
  4. #include <stb.h>
  5. #include <alloc.h>
  6. #include <assert.h>
  7. #include "position.h"
  8. #include "file.h"
  9. #include "symbol.h"
  10. #include "idf.h"
  11. #include "scope.h"
  12. #include "rd.h"
  13. extern char *Malloc();
  14. extern char *strindex();
  15. extern struct outname *DbxString();
  16. int saw_code = 0;
  17. static char *AckStrings; /* ACK a.out string table */
  18. static struct outname *AckNames; /* ACK a.out symbol table entries */
  19. static unsigned int NAckNames; /* Number of ACK symbol table entries */
  20. static struct outname *EndAckNames; /* &AckNames[NAckNames] */
  21. /* Read the symbol table from file 'f', which is supposed to be an
  22. ACK a.out format file. Offer DBX strings to the DBX string parser.
  23. */
  24. int
  25. DbxRead(f)
  26. char *f;
  27. {
  28. struct outhead h;
  29. register struct outname *n;
  30. register struct outname *line_file = 0;
  31. long OffsetStrings;
  32. int had_lbrac = 0;
  33. /* Open file, read header, and check magic word */
  34. if (! rd_open(f)) {
  35. fatal("%s: not an ACK object file", f);
  36. }
  37. rd_ohead(&h);
  38. if (BADMAGIC(h) && h.oh_magic != O_CONVERTED) {
  39. fatal("%s: not an ACK object file", f);
  40. }
  41. /* Allocate space for name table and read it */
  42. AckNames = (struct outname *)
  43. Malloc((unsigned)(sizeof(struct outname) * h.oh_nname));
  44. AckStrings = Malloc((unsigned) h.oh_nchar);
  45. rd_name(AckNames, h.oh_nname);
  46. rd_string(AckStrings, h.oh_nchar);
  47. /* Adjust file offsets in name table to point at strings */
  48. OffsetStrings = OFF_CHAR(h);
  49. NAckNames = h.oh_nname;
  50. EndAckNames = &AckNames[h.oh_nname];
  51. for (n = EndAckNames; --n >= AckNames;) {
  52. if (n->on_foff) {
  53. if ((unsigned)(n->on_foff - OffsetStrings) >= h.oh_nchar) {
  54. fatal("%s: error in object file", f);
  55. }
  56. n->on_mptr = AckStrings + (n->on_foff - OffsetStrings);
  57. }
  58. else n->on_mptr = 0;
  59. }
  60. /* Offer strings to the DBX string parser if they contain a ':'.
  61. Also offer filename-line number information to add_position_addr().
  62. Here, the order may be important.
  63. */
  64. for (n = &AckNames[0]; n < EndAckNames; n++) {
  65. int tp = n->on_type >> 8;
  66. register p_symbol sym;
  67. if (tp & (S_STB >> 8)) {
  68. switch(tp) {
  69. #ifdef N_BINCL
  70. case N_BINCL:
  71. n->on_valu = (long) line_file;
  72. line_file = n;
  73. break;
  74. case N_EINCL:
  75. if (line_file) {
  76. line_file = (struct outname *) line_file->on_valu;
  77. }
  78. break;
  79. #endif
  80. case N_SO:
  81. if (n->on_mptr[strlen(n->on_mptr)-1] == '/') {
  82. /* another N_SO follows ... */
  83. break;
  84. }
  85. while (CurrentScope != PervasiveScope) {
  86. close_scope();
  87. }
  88. saw_code = 0;
  89. sym = add_file(n->on_mptr);
  90. if (! currfile) newfile(sym->sy_idf);
  91. open_scope(sym, 0);
  92. sym->sy_file->f_scope = CurrentScope;
  93. FileScope = CurrentScope;
  94. clean_tp_tab();
  95. /* fall through */
  96. case N_SOL:
  97. if (! line_file) line_file = n;
  98. else line_file->on_mptr = n->on_mptr;
  99. break;
  100. case N_MAIN:
  101. newfile(FileScope->sc_definedby->sy_idf);
  102. break;
  103. case N_SLINE:
  104. assert(line_file);
  105. if (! saw_code && !CurrentScope->sc_bp_opp) {
  106. CurrentScope->sc_bp_opp = n->on_valu;
  107. if (! CurrentScope->sc_start) {
  108. CurrentScope->sc_start = n->on_valu;
  109. if (CurrentScope->sc_has_activation_record) {
  110. add_scope_addr(CurrentScope);
  111. }
  112. }
  113. }
  114. saw_code = 1;
  115. add_position_addr(line_file->on_mptr, n);
  116. break;
  117. case N_LBRAC: /* block, desc = nesting level */
  118. if (had_lbrac) {
  119. open_scope((p_symbol) 0, 0);
  120. saw_code = 0;
  121. }
  122. else {
  123. register p_scope sc =
  124. get_scope_from_addr(n->on_valu);
  125. if (!sc || sc->sc_bp_opp) {
  126. had_lbrac = 1;
  127. }
  128. else CurrentScope = sc;
  129. }
  130. break;
  131. #ifdef N_SCOPE
  132. case N_SCOPE:
  133. if (n->on_mptr && strindex(n->on_mptr, ':')) {
  134. n = DbxString(n);
  135. }
  136. break;
  137. #endif
  138. case N_RBRAC: /* end block, desc = nesting level */
  139. had_lbrac = 0;
  140. if (CurrentScope != FileScope) close_scope();
  141. saw_code = 0;
  142. break;
  143. case N_FUN: /* function, value = address */
  144. case N_GSYM: /* global variable */
  145. case N_STSYM: /* data, static, value = address */
  146. case N_LCSYM: /* bss, static, value = address */
  147. case N_RSYM: /* register var, value = reg number */
  148. case N_SSYM: /* struct/union el, value = offset */
  149. case N_PSYM: /* parameter, value = offset from AP */
  150. case N_LSYM: /* local sym, value = offset from FP */
  151. if (had_lbrac) {
  152. open_scope((p_symbol) 0, 0);
  153. saw_code = 0;
  154. had_lbrac = 0;
  155. }
  156. if (n->on_mptr && strindex(n->on_mptr, ':')) {
  157. n = DbxString(n);
  158. }
  159. break;
  160. default:
  161. /*
  162. if (n->on_mptr && (n->on_type&S_TYP) >= S_MIN) {
  163. struct idf *id = str2idf(n->on_mptr, 0);
  164. sym = new_symbol();
  165. sym->sy_next = id->id_def;
  166. id->id_def = sym;
  167. sym->sy_class = SYMENTRY;
  168. sym->sy_onam = *n;
  169. sym->sy_idf = id;
  170. }
  171. */
  172. break;
  173. }
  174. }
  175. }
  176. close_scope();
  177. add_position_addr((char *) 0, (struct outname *) 0);
  178. rd_close();
  179. return (h.oh_magic == O_CONVERTED);
  180. }