📄 etrace.pl
字号:
#!/usr/bin/perl## etrace.pl script# Author: Victor Chudnovsky# Date: March 8, 2004$NM = 'nm '; # unix nm utility to get symbol names and addresses# Output format$TAB1 = "| "; # indentation: function still on the stack $TAB2 = "\\-- "; # indentation: function just placed on the stack$UNDEFINED_SYMBOL = "???"; # when an offset cannot be mapped to a symbol# Input format$FIFO_NAME = "TRACE"; # default FIFO name$REFERENCE_OFFSET = "REFERENCE:"; # marks a known symbol/object pair for dynamic libraries$FUNCTION_ENTRY = "enter"; # marks entry into a function$FUNCTION_EXIT = "exit"; # marks exit from function$END_TRACE = "EXIT"; # end of input$HEX_NUMBER = '0?x?[0-9a-fA-F]+'; # hex number$SYMBOL_NAME = '[\w@.]+'; # valid identifier characters# Global identifiers# %SYMBOLTABLE : a hash array from relative offsets to symbol names# $IS_FIFO : are we reading from a FIFO or a file?# CALL_DATA : file handle to input file/FIFOsub readObjects { $objectFileName = shift; if (-x $objectFileName) { # Object code: extract symbol names via a pipe before parsing $handleName = $NM.$objectFileName.'|'; } else { # A symbol table: simply parse the symbol names $handleName = '<'.$objectFileName; }; open f, $handleName or die "$0: cannot open $objectFileName"; while ($line = <f>) { $line =~ m/^($HEX_NUMBER)\s+.*\s+($SYMBOL_NAME)$/; $hexLocation = $1; $symbolName = $2; $location = hex $hexLocation; $SYMBOLTABLE{$location} = $2 } close f;}sub writeSymbolTable { while ( ($location,$name) = each %SYMBOLTABLE) { print "[$location] => $name\n"; }}; sub establishInput { $inputName = shift; if (!defined($inputName)) { $inputName = $FIFO_NAME; }; if (-p $inputName) { # delete a previously existing FIFO unlink $inputName; }; if (!-e $inputName) { # need to create a FIFO system('mknod', $inputName, 'p') && die "$0: could not create FIFO $inputName\n"; $IS_FIFO = 1; } else { # assume input comes from a file die "$0: file $inputName is not readable" if (!-r $inputName); $IS_FIFO = 0; } $inputName; # return value}sub deleteFifo { if ($IS_FIFO) { $inputName = shift; unlink $inputName or die "$0: could not unlink $inputName\n"; };};sub processCallInfo { $offsetLine = <CALL_DATA>; if ($offsetLine =~ m/^$REFERENCE_OFFSET\s+($SYMBOL_NAME)\s+($HEX_NUMBER)$/) { # This is a dynamic library; need to calculate the load offset $offsetSymbol = $1; $offsetAddress = hex $2; %offsetTable = reverse %SYMBOLTABLE; $baseAddress = $offsetTable{$offsetSymbol} - $offsetAddress; $offsetLine = <CALL_DATA>; } else { # This is static $baseAddress = 0; } while (!($offsetLine =~/^$END_TRACE/)) { if ($offsetLine =~ m/^($FUNCTION_ENTRY|$FUNCTION_EXIT)\s+($HEX_NUMBER)$/) { $action = $1; $offset = hex $2; $address = $offset + $baseaddress; if ($1=~m/$FUNCTION_ENTRY/) { $thisSymbol = $SYMBOLTABLE{$offset+$baseAddress}; if (! defined($thisSymbol)) { $thisSymbol = $UNDEFINED_SYMBOL; }; print $TAB1 x $level . $TAB2 . $thisSymbol . "\n"; $level++; } else { $level--; } } else { if ( (length $offsetLine) > 0 ) { chomp $offsetLine; print "Unrecognized line format: $offsetLine\n"; }; } $offsetLine = <CALL_DATA>; };}# Main functionif (@ARGV==0) { die "Usage: $0 OBJECT [TRACE]\n" . " OBJECT is either the object code or the output of $NM\n" . " TRACE is either the etrace output file or of a FIFO to connect to etrace.\n";};$objectFile = shift @ARGV;$inputFile = shift @ARGV;readObjects $objectFile;$inputFile = establishInput $inputFile;open CALL_DATA,"<$inputFile";processCallInfo;close CALL_DATA;deleteFifo $inputFile;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -