position.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* $Header$ */
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <alloc.h>
  5. #include <out.h>
  6. #include <stb.h>
  7. #include "position.h"
  8. #include "scope.h"
  9. #include "file.h"
  10. #include "idf.h"
  11. #include "symbol.h"
  12. extern FILE *db_out;
  13. static p_file mapping;
  14. static int nfiles = 0;
  15. /* static p_file get_map_from_addr(t_addr t);
  16. Returns the file entry that contains the code at the address 't',
  17. or 0 if there is no information available, or 't' represents an address
  18. below the start address of the first file.
  19. */
  20. static p_file
  21. get_map_from_addr(t)
  22. t_addr t;
  23. {
  24. register p_file p = mapping, oldp = 0;
  25. /* linear search is probably acceptable here */
  26. while (p && p->f_start->on_valu <= t) {
  27. oldp = p;
  28. p = p->f_nextmap;
  29. }
  30. return oldp ? oldp : p->f_start->on_valu <= t ? p : 0;
  31. }
  32. /* extern p_position get_position_from_addr(t_addr t);
  33. Returns a pointer to a structure containing the source position of the code
  34. at address 't'. 0 is returned if no source position could be found.
  35. */
  36. p_position
  37. get_position_from_addr(t)
  38. t_addr t;
  39. {
  40. register p_file map = get_map_from_addr(t);
  41. static t_position retval;
  42. register int i,j,m;
  43. if (! map) return 0;
  44. i = 0;
  45. j = map->f_end - map->f_start;
  46. do {
  47. m = ((i + j) >> 1) + ((i + j) & 1);
  48. while ((map->f_start[m].on_type >> 8) != N_SLINE) m++;
  49. assert(m <= j);
  50. if (map->f_start[m].on_valu > t) {
  51. j = m - 1;
  52. while (j > i && (map->f_start[j].on_type >> 8) != N_SLINE) j--;
  53. }
  54. else i = m;
  55. } while (i < j);
  56. retval.filename = map->f_sym->sy_idf->id_text;
  57. retval.lineno = map->f_start[j].on_desc;
  58. return &retval;
  59. }
  60. /* extern t_addr get_addr_from_position(p_position p);
  61. Returns the address of the code at position 'p', or ILL_ADDR if it could
  62. not be found. If there is no symbolic information for the filename in
  63. position 'p', an error message will be given.
  64. */
  65. t_addr
  66. get_addr_from_position(p)
  67. p_position p;
  68. {
  69. register p_symbol sym = Lookup(findidf(p->filename), PervasiveScope, FILESYM);
  70. if (sym) {
  71. register unsigned int i;
  72. register p_file map = sym->sy_file;
  73. for (i = p->lineno; i > 0; i--) {
  74. register struct outname *n = map->f_line_addr[HASH(i)];
  75. while (n) {
  76. if (n->on_desc == i) return (t_addr) n->on_valu;
  77. n = next_outname(n);
  78. }
  79. }
  80. return ILL_ADDR;
  81. }
  82. error("no symbolic information for file %s", p->filename);
  83. return ILL_ADDR;
  84. }
  85. /* extern add_position_addr(char *filename, struct outname *n);
  86. Adds the ('filename','lineno'),'t' pair to the mapping information.
  87. */
  88. add_position_addr(filename, n)
  89. char *filename;
  90. register struct outname *n;
  91. {
  92. static char *lastfile = 0;
  93. static p_file lastmap = 0;
  94. register p_file map = lastmap;
  95. if (filename != lastfile) { /* new file ... */
  96. register p_symbol sym;
  97. nfiles++;
  98. lastfile = filename;
  99. if (! filename) { /* last call */
  100. return;
  101. }
  102. sym = Lookup(findidf(filename), PervasiveScope, FILESYM);
  103. if (sym) map = sym->sy_file;
  104. else {
  105. sym = add_file(filename);
  106. map = sym->sy_file;
  107. map->f_scope = FileScope;
  108. }
  109. if (! mapping) mapping = map;
  110. else lastmap->f_nextmap = map;
  111. lastmap = map;
  112. map->f_start = n;
  113. }
  114. else map = lastmap;
  115. map->f_end = n;
  116. setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]);
  117. map->f_line_addr[HASH(n->on_desc)] = n;
  118. }
  119. /* extern p_position print_position(t_addr a, int print_function);
  120. Prints position 'a' and returns it. If 'print_function' is set,
  121. an attempt is made to print the function name as well.
  122. */
  123. p_position
  124. print_position(a, print_function)
  125. t_addr a;
  126. int print_function;
  127. {
  128. register p_scope sc = base_scope(get_scope_from_addr(a));
  129. register p_position pos = get_position_from_addr(a);
  130. if (sc && print_function) {
  131. fprintf(db_out, "in %s ", sc->sc_definedby->sy_idf->id_text);
  132. }
  133. if (pos) fprintf(db_out, "at \"%s\":%u", pos->filename, pos->lineno);
  134. return pos;
  135. }