📄 mappings.c
字号:
/*#@(#)mappings.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * 005 - Remove 004. A bad idea, since the path name goes into * * the symbol tables, and may be the only way to tell two * * files apart. As coded, 004 made it impossible to stop in * * any file not compiled in '.'. (jlr, April 11, 1988) * * * * 004 - Only look for the base part of the name in the a.out. * * (jlr, March 17, 1988) * * * * 003 - Re-merged 4.3 changes. (Jon Reeves, May 14, 1987) * * * * 002 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 001 - Removed 1001-function limit. Function table is now * * dynamically allocated. * * (Victoria Holt, June 14, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)mappings.c 4.2 Ultrix 11/9/90";#endif not lint/* * 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 */#define ADDRNOEXEC ((Address) -2) /* line number is not executable */#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. * * Return the index of the line table entry or -1 if none suitable. */private integer findline (addr, exact)Address addr;Boolean exact;{ register Address i, j, k; register Lineno r; register Address a; if (nlhdr.nlines == 0) { r = -1; } else if (addr < linetab[0].addr) { r = exact ? -1 : 0; } else { i = 0; j = nlhdr.nlines - 1; if (addr == linetab[i].addr) { r = i; } else if (addr == linetab[j].addr) { r = j; } else if (addr > linetab[j].addr) { r = exact ? -1 : j; } 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 = k; } else if (exact) { r = -1; } else if (addr > linetab[i].addr) { r = i; } else { r = i - 1; } } } return r;}/* * Lookup the source line number nearest (from below) to an address. * * It is possible (unfortunately) that the compiler will generate * code before line number for a procedure. Therefore we check * to see that the found line is in the same procedure as the given address. * If it isn't, then we walk forward until the first suitable line is found. */public Lineno srcline(addr)Address addr;{ integer i; Lineno r; Symbol f1, f2; i = findline(addr, false); if (i == -1) { r = 0; } else { r = linetab[i].line; if (linetab[i].addr != addr) { f1 = whatblock(addr); if (nosource(f1)) { r = 0; } else { f2 = whatblock(linetab[i].addr + 1); if (f1 != f2) { do { ++i; } while (linetab[i].addr < addr and i < nlhdr.nlines); r = linetab[i].line; } } } } return r;}/* * Look for a line exactly corresponding to the given address. */public Lineno linelookup(addr)Address addr;{ integer i; Lineno r; i = findline(addr, true); if (i == -1) { r = 0; } else { r = linetab[i].line; } return r;}/* * 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, start, end; 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; start = i = ftp->lineindex; if (ftp == &filetab[nlhdr.nfiles-1]) { j = nlhdr.nlines; } else { j = (ftp + 1)->lineindex; } end = 0; while (i < j) { if (linetab[i].line == line) { return linetab[i].addr; } else if (!linetab[i].line && !end) { end = i -1; } i++; } } } if (not foundfile) { error("source file \"%s\" not compiled with -g", name); } if(line > linetab[start].line && line < linetab[end].line) return ADDRNOEXEC; else return NOADDR;}/* * Table for going from object addresses to the functions in which they belong. */#define NFUNCS 500 /* initial size of function table */typedef struct { Symbol func; Address addr;} AddrOfFunc;private AddrOfFunc *functab;private int nfuncs = 0;private int functablesize = 0;/* * Insert a new function into the table. */public newfunc(f, addr)Symbol f;Address addr;{ register AddrOfFunc *af; register int i; AddrOfFunc *newfunctab; if (nfuncs >= functablesize) { if (functablesize == 0) { functab = newarr(AddrOfFunc, NFUNCS); functablesize = NFUNCS; } else { functablesize *= 2; newfunctab = newarr(AddrOfFunc, functablesize); bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc)); dispose(functab); functab = newfunctab; } } 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 function table. */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 + -