123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /* $Header$ */
- #include <stdio.h>
- #include <assert.h>
- #include <alloc.h>
- #include <out.h>
- #include <stb.h>
- #include "position.h"
- #include "scope.h"
- #include "file.h"
- #include "idf.h"
- #include "symbol.h"
- extern FILE *db_out;
- static p_file mapping;
- static int nfiles = 0;
- /* static p_file get_map_from_addr(t_addr t);
- Returns the file entry that contains the code at the address 't',
- or 0 if there is no information available, or 't' represents an address
- below the start address of the first file.
- */
- static p_file
- get_map_from_addr(t)
- t_addr t;
- {
- register p_file p = mapping, oldp = 0;
- /* linear search is probably acceptable here */
- while (p && p->f_start->on_valu <= t) {
- oldp = p;
- p = p->f_nextmap;
- }
- return oldp ? oldp : p->f_start->on_valu <= t ? p : 0;
- }
- /* extern char *get_filename_from_addr(t_addr t);
- Returns the source filename that contains the code at the address 't',
- or 0 if there is no information available, or 't' represents an address
- below the start address of the first file.
- */
- char *
- get_filename_from_addr(t)
- t_addr t;
- {
- register p_file map = get_map_from_addr(t);
- if (! map) return 0;
- return map->f_sym->sy_idf->id_text;
- }
- /* extern t_lineno get_lineno_from_addr(t_addr t);
- Returns the source line number of the line that contains the code at address
- 't'. 0 is returned if no source line number could be found.
- */
- t_lineno
- get_lineno_from_addr(t)
- t_addr t;
- {
- p_position p;
- p = get_position_from_addr(t);
- return p == 0 ? 0 : p->lineno;
- }
- /* extern p_position get_position_from_addr(t_addr t);
- Returns a pointer to a structure containing the source position of the code
- at address 't'. 0 is returned if no source position could be found.
- */
- p_position
- get_position_from_addr(t)
- t_addr t;
- {
- register p_file map = get_map_from_addr(t);
- static t_position retval;
- register int i,j,m;
- if (! map) return 0;
- i = 0;
- j = map->f_end - map->f_start;
- do {
- m = ((i + j) >> 1) + ((i + j) & 1);
- while ((map->f_start[m].on_type >> 8) != N_SLINE) m++;
- assert(m <= j);
- if (map->f_start[m].on_valu > t) {
- j = m - 1;
- while (j > i && (map->f_start[j].on_type >> 8) != N_SLINE) j--;
- }
- else i = m;
- } while (i < j);
- retval.filename = map->f_sym->sy_idf->id_text;
- retval.lineno = map->f_start[j].on_desc;
- return &retval;
- }
- /* extern t_addr get_addr_from_position(p_position p);
- Returns the address of the code at position 'p', or ILL_ADDR if it could
- not be found. If there is no symbolic information for the filename in
- position 'p', an error message will be given.
- */
- t_addr
- get_addr_from_position(p)
- p_position p;
- {
- register p_symbol sym = Lookup(findidf(p->filename), PervasiveScope, FILESYM);
- if (sym) {
- register unsigned int i;
- register p_file map = sym->sy_file;
- for (i = p->lineno; i > 0; i--) {
- register struct outname *n = map->f_line_addr[HASH(i)];
- while (n) {
- if (n->on_desc == i) return (t_addr) n->on_valu;
- n = next_outname(n);
- }
- }
- return ILL_ADDR;
- }
- error("no symbolic information for file %s", p->filename);
- return ILL_ADDR;
- }
- /* extern add_position_addr(char *filename, struct outname *n);
- Adds the ('filename','lineno'),'t' pair to the mapping information.
- */
- add_position_addr(filename, n)
- char *filename;
- register struct outname *n;
- {
- static char *lastfile = 0;
- static p_file lastmap = 0;
- register p_file map = lastmap;
- if (filename != lastfile) { /* new file ... */
- register p_symbol sym;
- nfiles++;
- lastfile = filename;
- if (! filename) { /* last call */
- return;
- }
- sym = Lookup(findidf(filename), PervasiveScope, FILESYM);
- if (sym) map = sym->sy_file;
- else {
- sym = add_file(filename);
- map = sym->sy_file;
- map->f_scope = FileScope;
- }
- if (! mapping) mapping = map;
- else lastmap->f_nextmap = map;
- lastmap = map;
- map->f_start = n;
- }
- else map = lastmap;
- map->f_end = n;
- setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]);
- map->f_line_addr[HASH(n->on_desc)] = n;
- }
- /* extern struct scope *get_scope_from_position(p_position p);
- Returns the scope of the code at position 'p', or 0 if it could not be found.
- */
- struct scope *
- get_scope_from_position(p)
- p_position p;
- {
- t_addr a = get_addr_from_position(p);
- if (a != ILL_ADDR) {
- return get_scope_from_addr(a);
- }
- return 0;
- }
- /* extern p_position print_position(t_addr a, int print_function);
- Prints position 'a' and returns it. If 'print_function' is set,
- an attempt is made to print the function name as well.
- */
- p_position
- print_position(a, print_function)
- t_addr a;
- int print_function;
- {
- register p_scope sc = base_scope(get_scope_from_addr(a));
- register p_position pos = get_position_from_addr(a);
- if (sc && print_function) {
- fprintf(db_out, "in %s ", sc->sc_definedby->sy_idf->id_text);
- }
- if (pos) fprintf(db_out, "at \"%s\":%u", pos->filename, pos->lineno);
- return pos;
- }
|