⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 anngen

📁 一个用在mips体系结构中的操作系统
💻
字号:
#!/powderkeg/local/bin/perl5 -w## Copyright (C) 1996-1998 by the Board of Trustees#    of Leland Stanford Junior University.# # This file is part of the SimOS distribution. # See LICENSE file for terms of the license. ####### anngen unix annote.def###### Source file annotations:###    /*!anote [B|A] [{cond-expr}] <builtin>   */###    /*!count [B|A] [{cond-expr}] <label>     */###    /*!begin [B|A] [{cond-expr}] <label>     */###    /*!end   [B|A] [{cond-expr}] <label>     */###### Definition file structure:###    file:     <source file>###    func:     <function in current srcfile> [{cond-expr}]###    fbegin:   <function in current srcfile> [{cond-expr}] <builtin>###    fend:     <function in current srcfile> [{cond-expr}] <builtin>###    global:   <global symbol> [{cond-expr}] <builtin>######### Defaults:###    B|A = B######### Global variables:###   $fileinfo : (filename) -> [filenum, PC, seen, inst2line[], funcinfo{}, datainfo{}]###   $globalinfo : (global variable) -> PC###   $numAnn : number of annotations emitted###%fileinfo = ();%globalinfo = ();## commands that can appear in def file%defCommands = ('file',    => ['doFile'],                'global'   => ['doGlobal'],                'func'     => ['doFunc'],                'fbegin'   => ['doFWrapper', 0],                'fend'     => ['doFWrapper', 1],                );                ## commands that can appear in the source file%srcCommands = ('annote' => ['doGeneral', ''],                'count'  => ['doGeneral', 'timing diff '],                'begin'  => ['doGeneral', 'timing beg  '],                'end'    => ['doGeneral', 'timing end  '],                );$unix = ($ARGV[0]) ? $ARGV[0] : "$ENV{'ROOT'}/usr/sysgen/SIMMPboot/unix.kdebug";$deffile = ($ARGV[1]) ? $ARGV[1] : "annote.def";# $deffile = ($ARGV[1]) ? $ARGV[1] : "$ENV{'ROOT'}/kern/annote.def";###### Initialize symbol information### need a slow one if we miss a function name&initGlobalSymbolInfo;###### For each file search for annotations and process them.###open(DEF, "$deffile") || die "Could not find def file, exiting.";$srcfile = 0;while (<DEF>) {    if (/^(\w+):\s*/) {	$cmd = $1;	$rest = $';	chop($rest);                if ($op = $defCommands{$cmd}[0]) {            &$op($cmd, $rest);        } else {            print STDERR "WARNING: possible typo in def file line $., ignored\n$_";        }            } elsif (!/^#/ && !/^-/ && /\S/) {        print STDERR "WARNING: possible typo in def file line $., ignored\n$_";    }}close(DEF);print STDERR "$numAnn annotations found.\n";exit;###### annotation ops###sub doFile {    my($cmd, $rest) = @_;    ###    ### Change current source file.    ###        ($rest =~ /(\S+)/)	|| die "bad file name in def file on line $.\n";    $srcfile = $1;    my(@t) = split("/", $srcfile);    $fname = pop(@t);     ###    ### If we have already seen this file, all we need to do is look    ### at possible annotations in the def file.    ###        if ($fileinfo{$fname}[2]) {	print STDERR "processing file $srcfile again\n";	return;    }        print STDERR "processing file $srcfile\n";                      ###    ### Analyze symbol table info for current source file    ###        &initSourceSymbolInfo($fname);    ###    ### Scan the source file for annotations    ###        open(SRCFILE, "$srcfile") || die "ERROR: Bad file $srcfile\n";        while (<SRCFILE>) {	if (m%/\*\!(\w+)\s*([AB]?)\s+({([^}]*)})?\s*(\w+)\s*([^\*]*)\*/%) {	    $cmd = $1;	    $beforeOrAfter = $2 || "B";	    $cond = $4;	    $label = $5;            $optionalArgs = $6;	    $linenum = $.;            if ($cmd eq "annote") {                print STDERR "found annote in source on line $., $label\n";            }            	    ($op = $srcCommands{$cmd}[0])		|| die "$srcfile:$linenum, bad command\n$_\n";	    &$op($cmd, $beforeOrAfter, $cond, $label, $optionalArgs, $linenum);	    	} elsif (/\/\*(\w+) ([^*]*)\*\//) {	    print STDERR "WARNING: $srcfile:$., possible typo, ignored\n$_";	}    }        close(SRCFILE);    $fileinfo{$fname}[2] = 1;}sub doGlobal {    my($cmd, $rest) = @_;    my($symb, $cond, $PC, $builtin);    ($rest =~ /(\S+)\s*({([^}]*)})?\s*([^%]*)[%]?/) 	|| die "ERROR: bad line in def file on line $.\n";    $symb = $1;    $cond = $3;    $builtin = $4;    $percentOf = $';    ($PC = $globalinfo{$symb})        || die "ERROR: symbol not found on line $.\n";        emitAnn($PC, $symb, $cond, $builtin, $percentOf);}sub doFunc {    my($cmd, $rest) = @_;    my($func, $cond, $PC, $offset, $funcinfo);    ($rest =~ /(\S+)\s*({([^}]*)})?/) 	|| die "ERROR: bad line in def file on line $.\n";    $func = $1;    $cond = $3;    $fname || die "ERROR: file must be first command in def file.\n$_";    ($funcinfo = $fileinfo{$fname}[4]{$func})        || die "ERROR: bad function in def file on line $., $func\n";    ## do begining of function stuff first    $PC = $fileinfo{$fname}[1] + ($$funcinfo[0]*4);    emitAnn($PC, "$func+0", $cond, "timing beg $func", 0);    ## now do end of function stuff    $offset = 4*($$funcinfo[1] - $$funcinfo[0]);     $PC = $fileinfo{$fname}[1] + ($$funcinfo[1]*4);    emitAnn($PC, "$func+$offset", $cond, "timing end $func", 0);}sub doFWrapper {    my($cmd, $rest) = @_;    my($func, $cond, $builtin, $PC, $offset, $begend, $funcinfo);    ($rest =~ /(\S+)\s*({([^}]*)})?/) 	|| die "ERROR: bad line in def file on line $.\n";    $func = $1;    $cond = $3;    $builtin = $';    $fname || die "ERROR: file must be first command in def file.\n$_";    $begend = $defCommands{$cmd}[1];    ($funcinfo = $fileinfo{$fname}[4]{$func})        || die "ERROR: bad function in def file on line $., $func\n";    $offset = 4*($$funcinfo[$begend] - $$funcinfo[0]);     $PC = $fileinfo{$fname}[1] + ($$funcinfo[$begend]*4);    emitAnn($PC, "$func+$offset", $cond, $builtin, 0);}sub doGeneral {    my($cmd, $beforeOrAfter, $cond, $label, $optArgs, $linenum) = @_;    my($func, $offset, $PC);    if ($beforeOrAfter eq "B") {        $offset = &findOffsetBeforeBelowLine($fname, $linenum);    } else {        $offset = &findOffsetAfterAboveLine($fname, $linenum);    }    $func = &offset2Function($fname, $offset);    $PC = $fileinfo{$fname}[1] + ($offset*4);    $offset = 4*($offset - $fileinfo{$fname}[4]{$func}[0]);    emitAnn($PC, "$func+$offset", $cond,            "$srcCommands{$cmd}[1]"."$label", $optArgs);}sub emitAnn {    my($PC, $symb, $cond, $function, $optArgs) = @_;    printf("PC %-18s 0x%8x %s%s%s\n",           $symb, $PC,           $cond ? "{$cond} " : "",           $function,            $optArgs ? " $optArgs" : "");    $numAnn++;}###### symbol table subroutines###sub initGlobalSymbolInfo {    my($file, $PC, $i);       print STDERR "Analyzing kernel symbol table.\n";    ##    ## First get filename -> filenum      ##        open(STINFO, "odump -p -F $unix |");        $i = 0;    while (<STINFO>) {	if (m%([\w\.]+\.[sch])\s*(0x\w+)%) {                $file = $1;            $PC = oct($2);            $fileinfo{$file} = [$i, $PC, 0, [], {}, {}];            $i++;                        <STINFO>;                    } elsif ($i==0) {            # must be using odump vers 3.18,            # it prints a header, just keep going        } else {            die "BAD read from odump\n$_";        }    }        close(STINFO);    ##    ## Now get global variable info    ##        open(GLOBINFO, "stdump -b $unix |");        while (<GLOBINFO>) {        if (/\s*\d+\.\s*\(file\s*\d+\)\s\((\d+)\)\s(\S+)/) {            $PC = $1;            $symb = $2;            $globalinfo{$symb} = $PC;        }    }        close(GLOBINFO);}sub initSourceSymbolInfo {    my($fname) = @_;    my($startPC, $offset, $symbol, $type, $fnum, $i);        $fnum = $fileinfo{$fname}[0];    $startPC = $fileinfo{$fname}[1];    open(SRCINFO, "stdump -chn $fnum $unix |");    ## Phase 1: Parse the symbol information.    while (<SRCINFO>) {        if (/\s*\d+\.\s*\(\s*\d+\)\(\s*(\S+)\)\s(\S+)\s*(\w+)/) {            $offset = $1;            $symbol = $2;            $type = $3;            if (($type eq "Proc") || ($type eq "StaticProc")) {                # $offset is function start PC                $fileinfo{$fname}[4]{$symbol} = [($offset-$startPC)/4, 0];                            } elsif ($type eq "End") {                if ($fileinfo{$fname}[4]{$symbol}) {                    # offset is function length in bytes                    $fileinfo{$fname}[4]{$symbol}[1]                        = $fileinfo{$fname}[4]{$symbol}[0] + ($offset/4) - 1;                }                            } elsif ($type eq "Static") {                # offset is variable PC                $fileinfo{$fname}[5]{$symbol} = $offset;            }        } elsif (/^Lines:/) {            # goto phase 2            last;        }    }    ## Phase 2: Parse the linenum info.    my($inst2line, $instnum) = ($fileinfo{$fname}[3], 0);    while (<SRCINFO>) {        my(@t) = split;        $i = 1;        while ($i <= $#t) {            $$inst2line[$instnum] = $t[$i];                $i += 2;            $instnum++;        }    }    close(SRCINFO);}# Find the offset of the first instruction before all instructions# below src linenum have executed.sub findOffsetBeforeBelowLine {    my($fname, $linenum) = @_;    my($inst2line, $found);    $inst2line = $fileinfo{$fname}[3];    for ($i = 0; $i < @$inst2line; $i++) {        if ($$inst2line[$i] >= $linenum) {            $found = $i;            last;        }    }    $found;}# Find the offset of the first instruction after all instructions# above src linenum have executed.sub findOffsetAfterAboveLine {    my($fname, $linenum) = @_;    my($inst2line, $found);    $inst2line = $fileinfo{$fname}[3];    for ($i = $#$inst2line; $i >= 0; $i--) {        if ($$inst2line[$i-1] < $linenum) {            $found = $i;            last;        }    }    $found;}sub offset2Function {    my($fname, $offset) = @_;    my($funcinfo, $key);    $funcinfo = $fileinfo{$fname}[4];    foreach $key (keys(%$funcinfo)) {        if (($offset >= $$funcinfo{$key}[0]) && ($offset <= $$funcinfo{$key}[1])) {            return $key;        }    }    die "ERROR: bad annotation, line to function.\n";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -