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