📄 mappings.c
字号:
/*#@(#)mappings.c 4.1 Ultrix 7/17/90*//* Copyright (c) 1982 Regents of the University of California */static char sccsid[] = "@(#)mappings.c 1.4 8/10/83";static char rcsid[] = "$Header: mappings.c,v 1.3 84/03/27 10:21:54 linton Exp $";/* * Source-to-object and vice versa mappings. */#include "defs.h"#include "mappings.h"#include "symbols.h"#include "source.h"#include "object.h"#include "machine.h"#ifndef public#include "machine.h"#include "source.h"#include "symbols.h"typedef struct { Address addr; String filename; Lineno lineindex; /* index to first linetab entry */} Filetab;typedef struct { Lineno line; Address addr;} Linetab;Filetab *filetab;Linetab *linetab;#define NOADDR ((Address) -1) /* no address for line or procedure */#endif/* * Get the source file name associated with a given address. */public String srcfilename(addr)Address addr;{ register Address i, j, k; Address a; Filetab *ftp; String s; s = nil; if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) { i = 0; j = nlhdr.nfiles - 1; while (i < j) { k = (i + j) / 2; ftp = &filetab[k]; a = ftp->addr; if (a == addr) { s = ftp->filename; break; } else if (addr > a) { i = k + 1; } else { j = k - 1; } } if (s == nil) { if (addr >= filetab[i].addr) { s = filetab[i].filename; } else { s = filetab[i-1].filename; } } } return s;}/* * Find the line associated with the given address. * If the second parameter is true, then the address must match * a source line exactly. Otherwise the nearest source line * below the given address is returned. In any case, if no suitable * line exists, 0 is returned. */private Lineno findline(addr, exact)Address addr;Boolean exact;{ register Address i, j, k; register Lineno r; register Address a; if (nlhdr.nlines == 0 or addr < linetab[0].addr) { r = 0; } else { i = 0; j = nlhdr.nlines - 1; if (addr == linetab[i].addr) { r = linetab[i].line; } else if (addr == linetab[j].addr) { r = linetab[j].line; } else if (addr > linetab[j].addr) { r = exact ? 0 : linetab[j].line; } else { do { k = (i + j) div 2; a = linetab[k].addr; if (a == addr) break; if (addr > a) { i = k + 1; } else { j = k - 1; } } while (i <= j); if (a == addr) { r = linetab[k].line; } else if (exact) { r = 0; } else if (addr > linetab[i].addr) { r = linetab[i].line; } else { r = linetab[i-1].line; } } } return r;}/* * Lookup the source line number nearest from below to an address. */public Lineno srcline(addr)Address addr;{ return findline(addr, false);}/* * Look for a line exactly corresponding to the given address. */public Lineno linelookup(addr)Address addr;{ return findline(addr, true);}/* * Lookup the object address of a given line from the named file. * * Potentially all files in the file table need to be checked * until the line is found since a particular file name may appear * more than once in the file table (caused by includes). */public Address objaddr(line, name)Lineno line;String name;{ register Filetab *ftp; register Lineno i, j; Boolean foundfile; if (nlhdr.nlines == 0) { return NOADDR; } if (name == nil) { name = cursource; } foundfile = false; for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { if (streq(ftp->filename, name)) { foundfile = true; i = ftp->lineindex; if (ftp == &filetab[nlhdr.nfiles-1]) { j = nlhdr.nlines; } else { j = (ftp + 1)->lineindex; } while (i < j) { if (linetab[i].line == line) { return linetab[i].addr; } i++; } } } if (not foundfile) { error("unknown source file \"%s\"", name); } return NOADDR;}/* * Table for going from object addresses to the functions in which they belong. */#define MAXNFUNCS 1001 /* maximum number of functions allowed */typedef struct { Symbol func; Address addr;} AddrOfFunc;private AddrOfFunc functab[MAXNFUNCS];private int nfuncs;/* * Insert a new function into the table. * The table is ordered by object address. */public newfunc(f, addr)Symbol f;Address addr;{ register AddrOfFunc *af; if (nfuncs >= MAXNFUNCS) { panic("too many procedures/functions"); } af = &functab[nfuncs]; af->func = f; af->addr = addr; ++nfuncs;}/* * Return the function that begins at the given address. */public Symbol whatblock(addr)Address addr;{ register int i, j, k; Address a; i = 0; j = nfuncs - 1; if (addr < functab[i].addr) { return program; } else if (addr == functab[i].addr) { return functab[i].func; } else if (addr >= functab[j].addr) { return functab[j].func; } while (i <= j) { k = (i + j) / 2; a = functab[k].addr; if (a == addr) { return functab[k].func; } else if (addr > a) { i = k+1; } else { j = k-1; } } if (addr > functab[i].addr) { return functab[i].func; } else { return functab[i-1].func; } /* NOTREACHED */}/* * Order the functab. */private int cmpfunc(f1, f2)AddrOfFunc *f1, *f2;{ register Address a1, a2; a1 = (*f1).addr; a2 = (*f2).addr; return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );}public ordfunctab(){ qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);}/* * Clear out the functab, used when re-reading the object information. */public clrfunctab(){ nfuncs = 0;}public dumpfunctab(){ int i; for (i = 0; i < nfuncs; i++) { psym(functab[i].func); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -