diff options
author | Monte Copeland <copelanm@us.ibm.com> | 2012-01-26 10:20:01 -0600 |
---|---|---|
committer | Monte K. Copeland <copelanm@us.ibm.com> | 2012-02-02 12:37:47 -0600 |
commit | 966df7556d9ebd045291921eda8c81bdba9b5d2e (patch) | |
tree | a3d7f4f7dcce07d998e1cfba8f76b577d75e28d7 /src/usr/errl/plugins | |
parent | 06b768407e1d6e212aeed8be23f31dfb27f2a9cc (diff) | |
download | talos-hostboot-966df7556d9ebd045291921eda8c81bdba9b5d2e.tar.gz talos-hostboot-966df7556d9ebd045291921eda8c81bdba9b5d2e.zip |
Hostboot-aware errl tool part 1.
Change-Id: Ibe49dc935206775de032d397b2800a7b83208283
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/630
Tested-by: Jenkins Server
Reviewed-by: Monte K. Copeland <copelanm@us.ibm.com>
Diffstat (limited to 'src/usr/errl/plugins')
-rw-r--r-- | src/usr/errl/plugins/errlParse.C | 254 | ||||
-rw-r--r-- | src/usr/errl/plugins/fips.mk | 45 | ||||
-rw-r--r-- | src/usr/errl/plugins/makefile | 56 | ||||
-rw-r--r-- | src/usr/errl/plugins/plugins.mk | 35 | ||||
-rw-r--r-- | src/usr/errl/plugins/symbols.C | 378 | ||||
-rw-r--r-- | src/usr/errl/plugins/symbols.H | 162 |
6 files changed, 930 insertions, 0 deletions
diff --git a/src/usr/errl/plugins/errlParse.C b/src/usr/errl/plugins/errlParse.C new file mode 100644 index 000000000..a70dc3ab3 --- /dev/null +++ b/src/usr/errl/plugins/errlParse.C @@ -0,0 +1,254 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/errl/plugins/errlParse.C $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2012 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END + + + + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <netinet/in.h> +#include <endian.h> +#include <vector> + +// Get these from a FipS/FSP backing build. +#include <errlplugins.H> +#include <errlusrparser.H> +#include <srcisrc.H> + +// These are from Hostboot. +#include <hbotcompid.H> +#include <hostBootSrcParse.H> +#include <errl/hberrltypes.H> + +// Get these from current directory. +#include "symbols.H" + + + +//------------------------------------------------------------- +// endian switch a uint64 +// TODO all plugins are probably going to want this. + +static uint64_t ntohll( uint64_t i ) +#if __BYTE_ORDER == __LITTLE_ENDIAN +{ + // CONTEXT_x86_nfp + uint64_t hi; + uint64_t lo; + uint32_t * pword = reinterpret_cast<uint32_t*>(&i); + + hi = ntohl( *pword ); + lo = ntohl( *(pword+1) ); + + return (hi<<32)|lo; +} +#elif __BYTE_ORDER == __BIG_ENDIAN +{ + // CONTEXT_ppc (or maybe CONTEXT_aix_nfp) + return i; +} +#else +#error Unexpected endian context. +#endif + + + + +//-------------------------------------------------------------------------- +// Use methods of i_parser such as +// i_parser.PrintString( "label", "datastring" ); +// to format my user-defined data attached to error logs for my component. +// Parameters i_sst (subsection type) and i_ver (version) identify +// the nature of the user-defined data as defined by my component. +// The file $bb/export/x86.nfp/fips/include/errlusrparser.H defines the +// ErrlUsrParser class. +// +// Return true if handled, suppressing the default hex dump of the data. + +static bool myDataParse ( + ErrlUsrParser& i_parser, + void* i_buffer, + uint32_t i_buflen, + errlver_t i_ver, + errlsubsec_t i_sst) +{ + + bool rc = false; + char szWork[ 256 ]; + + + switch( i_sst ) { + case HBERRL_SST_FIRSTLADY: + { + memcpy( szWork, i_buffer, i_buflen ); + szWork[ i_buflen ] = 0; + i_parser.PrintString( "First Lady", szWork ); + rc = true; + } + break; + case HBERRL_SST_PRESIDENT: + { + memcpy( szWork, i_buffer, i_buflen ); + szWork[ i_buflen ] = 0; + i_parser.PrintString( "President", szWork ); + rc = true; + } + break; + case HBERRL_SST_STRING: + { + // How to label this string? + const char * l_pLabel; + switch( i_ver ) + { + case HBERRL_VER_STRINGTASK: + l_pLabel = "Task"; + break; + case HBERRL_VER_STRINGTASKNAME: + l_pLabel = "Task name"; + break; + case HBERRL_VER_STRINGATTRNAME: + l_pLabel = "Attribute name"; + break; + case HBERRL_VER_STRINGFILENAME: + l_pLabel = "File name"; + break; + case HBERRL_VER_STRINGPROCNAME: + l_pLabel = "Procedure name"; + break; + case HBERRL_VER_STRINGNAME: + default: + l_pLabel = "Name"; + break; + } + // Expect to have a null-ended string in the data, + // but add a null for good measure. + int cb = i_buflen + 1; + char * pWork = new char[cb]; + memcpy( pWork, i_buffer, i_buflen ); + pWork[i_buflen] = 0; + i_parser.PrintString( l_pLabel, pWork ); + delete pWork; + rc = true; + } + break; + + case HBERRL_SST_BACKTRACE: + { + // This buffer contains a number of 64-bit frame pointers. + // Awkward because FipS/FSP errl provides no PrintNumber() + // for a 64-bit number as of Jan 2012. + + // Initialize l_the symbol table. + const char * l_pSymFile = "hbicore.syms"; + hbSymbolTable symTab; + int readRC = symTab.readSymbols( l_pSymFile ); + if( readRC ) + { + i_parser.PrintString( "Symbols not found", l_pSymFile ); + // symTab.nearestSymbol() will return NULL because of this. + // Carry on. + } + + const char * l_pErrlEntry = "ErrlEntry::ErrlEntry"; + const char * l_pLabel = "Backtrace"; + + // loop thru the buffer which is an array of 64-bit addresses + uint64_t * p64 = static_cast<uint64_t*>(i_buffer); + int l_count = i_buflen / sizeof( uint64_t ); + for( int i = 0; i < l_count; i++ ) + { + // endian convert the stack address + uint64_t l_addr = ntohll(*p64); + + // get nearest symbol + const char * l_pSymbol = symTab.nearestSymbol( l_addr ); + + if( l_pSymbol ) + { + if( strstr( l_pSymbol, l_pErrlEntry )) + { + // hackish, makes for better looking output + // it's in every backtrace (jan2012) + l_pSymbol = l_pErrlEntry; + } + sprintf( szWork,"#%2d %016llX %s", i, l_addr, l_pSymbol ); + } + else + { + sprintf( szWork,"#%2d %016llX", i, l_addr ); + } + i_parser.PrintString( l_pLabel, szWork ); + + // next stack address in the buffer + p64++; + + // don't print the label for subsequent backtraces + l_pLabel = ""; + } + + rc = true; + } + break; + default: + break; + } + + + return rc; +} + +// Map my Hostboot component ID to the function above. +// static errl::DataPlugin g_DataPlugin( HBERRL_COMP_ID, hberrl_DataParse ); +static errl::DataPlugin g_DataPlugin( HBERRL_COMP_ID, myDataParse ); + + + + +//---------------------------------------------------------------------------- +// Call the code generated by scanforsrc.pl + +static bool hbSrcParse( ErrlUsrParser & i_parser, const SrciSrc & i_src ) +{ + uint32_t src = 0; + + sscanf( i_src.getAsciiString(), "%X", &src ); + + // Call this function in obj/genfiles/hostBootSrcParse.H (a script-generated + // file) which serves for any Hostboot component. This will cause + // the FSP errl tool to add the tagged information to the primary SRC + // section of the error log. For example, the developer description + // (devdesc) tag and associated info as well as the other tags describing + // the userdata1 and userdata2 words. + printErrorTags( i_parser, (src & 0xFFFF), i_src.moduleId() ); + + return false; +} + +// Create an instance of SrcPlugin by type (instead of the usual component). +static errl::SrcPlugin g_SrcPlugin( errl::Plugin::HOSTBOOT_SRCPARSE, hbSrcParse ); + + + diff --git a/src/usr/errl/plugins/fips.mk b/src/usr/errl/plugins/fips.mk new file mode 100644 index 000000000..1db670df3 --- /dev/null +++ b/src/usr/errl/plugins/fips.mk @@ -0,0 +1,45 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/errl/plugins/fips.mk $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END + +# This is a FipS makefile. The 'hb errlparser' step will copy it +# to a FipS build tree and assign a value for HBCOMPS as it is copied. + + +.if ( $(CONTEXT) == "x86.nfp" || $(CONTEXT) == "ppc" ) + +EXPINC_SUBDIRS = $(HBCOMPS) +EXPLIB_SUBDIRS = $(HBCOMPS) +OBJECTS_SUBDIRS = $(HBCOMPS) +SUBDIRS = $(HBCOMPS) +EXPSHLIB_SUBDIRS = $(HBCOMPS) + +.elif ( $(CONTEXT) == "aix.nfp" ) + +EXPINC_SUBDIRS = +EXPLIB_SUBDIRS = +OBJECTS_SUBDIRS = +SUBDIRS = +EXPSHLIB_SUBDIRS = +.endif + +.include <${RULES_MK}> diff --git a/src/usr/errl/plugins/makefile b/src/usr/errl/plugins/makefile new file mode 100644 index 000000000..8bb94fb91 --- /dev/null +++ b/src/usr/errl/plugins/makefile @@ -0,0 +1,56 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/errl/plugins/errl/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END + + +# This is a FipS makefile. This file and C sources will be built +# in a FipS tree. + +# All Hostboot plugins/makefile should .include ../plugins.mk +.include "../plugins.mk" + + +ERRL_PLUGIN = libB-0100 +ERRL_OBJS = errlParse.o symbols.o + + +CFLAGS += -O0 + +.if ( $(CONTEXT) == "x86.nfp" ) + +LIBRARIES = ${ERRL_PLUGIN}.a +EXPLIBS = ${ERRL_PLUGIN}.a +${ERRL_PLUGIN}.a_OFILES = ${ERRL_OBJS} + +.else + +BUILD_SHARED_OBJS = +SHARED_LIBRARIES EXPSHLIBS = ${ERRL_PLUGIN}.so +${ERRL_PLUGIN}.so_EXTRA_LIBS = libbase.so + +${ERRL_PLUGIN}.so_SHLDFLAGS += ${SHLDFLAGS} -Wl,-soname,${.TARGET} + +${ERRL_PLUGIN}.so_OFILES = ${ERRL_OBJS} + +.endif + +.include <${RULES_MK}> diff --git a/src/usr/errl/plugins/plugins.mk b/src/usr/errl/plugins/plugins.mk new file mode 100644 index 000000000..fd1d90b2a --- /dev/null +++ b/src/usr/errl/plugins/plugins.mk @@ -0,0 +1,35 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/errl/plugins/plugins.mk $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END + +# This is a FipS makefile. It will be copied to the directory above +# the directories for Hostboot components that build an errl plugin. + +# Hostboot plugin makefiles should include this makefile with +# .include "../plugins.mk" +# in order to set CFLAGS. Eventually, there may be other global +# settings common to all Hostboot makefiles. This makefile +# provides a common place for such changes. + + +CFLAGS += -DERRL_TOOLS -DPARSER -I${HOSTBOOTROOT}/obj/genfiles -I${HOSTBOOTROOT}/src/include/usr + diff --git a/src/usr/errl/plugins/symbols.C b/src/usr/errl/plugins/symbols.C new file mode 100644 index 000000000..c79059ca4 --- /dev/null +++ b/src/usr/errl/plugins/symbols.C @@ -0,0 +1,378 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/errl/plugins/symbols.C $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2012 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <vector> + +#include "symbols.H" + + +/** + * @file symbols.C + * + * @brief Read HB symbols file and provide a lookup mechanism. + * + */ + + + + +//------------------------------------------------------------------------ +// trim white space from end of s + +static char * trim( char *s ) +{ + char *p = s; + + /* bump to last char */ + while( *p ) p++; + p--; + + /* trim */ + while( p >= s && ( *p == ' ' || *p == '\n' || *p == '\r' || *p == '\t' )) *p-- = 0; + + /* return what was passed in */ + return s; +} + + + +//------------------------------------------------------------------------ +// hbSymbolTable methods + +// Read the syms file, return zero for success. +int hbSymbolTable::readSymbols( const char * i_filename ) +{ + FILE * f = NULL; + + iv_vecSymbols.clear(); + iv_fPopulated = false; + + delete[] iv_pFileName; + iv_pFileName = NULL; + + f = fopen( i_filename, "r" ); + if( !f ) + { + return 2; + } + fclose(f); + + int cb = 1 + strlen( i_filename ); + iv_pFileName = new char[cb]; + strcpy( iv_pFileName, i_filename ); + + populateSymbolVector(); + + return 0; +} + + + + +// private method +// read the syms file, return 0 if OK +int hbSymbolTable::populateSymbolVector() +{ + FILE * f = NULL; + char szWork[ 1024 ]; + + if( NULL == iv_pFileName ) + { + return 2; + } + + f = fopen( iv_pFileName, "r" ); + if( !f ) + { + return 2; + } + + memset(szWork, 0, sizeof(szWork)); + + while( fgets( szWork, sizeof( szWork )-1, f )) + { + // function symbols only + if( 'F' == szWork[0] ) + { + hbSymbol* l_pSymbol = new hbSymbol(); + + int k = 0; + char * pch; + pch = strtok( szWork, "," ); + while( pch ) + { + switch( k ) + { + case 0: + l_pSymbol->setType( *pch ); + break; + case 1: + l_pSymbol->setAddress( pch ); + break; + case 3: + l_pSymbol->setLength( pch ); + break; + case 4: + l_pSymbol->setSymbolName( pch ); + break; + default: + // skipping field 2 for now + break; + } + k++; + pch = strtok( NULL, "," ); + } + + if( l_pSymbol->isValid() ) + { + iv_vecSymbols.push_back( l_pSymbol ); + } + else + { + delete l_pSymbol; + } + } + } + + fclose(f); + + // The Hostboot symbols file is pretty much sorted already, but + // ensure vector is sorted for the sake of binary searching. + + int c = iv_vecSymbols.size() - 1; + bool fSorted = (iv_vecSymbols.size() <= 1); + while( !fSorted ) + { + fSorted = true; + for ( int i = 0; i < c; i++ ) + { + if( iv_vecSymbols[i]->iv_Address > iv_vecSymbols[i+1]->iv_Address ) + { + fSorted = false; + // swap them + hbSymbol * l_tempSymbol; + l_tempSymbol = iv_vecSymbols[i]; + iv_vecSymbols[i] = iv_vecSymbols[i+1]; + iv_vecSymbols[i+1] = l_tempSymbol; + } + } + } + + iv_fPopulated = true; + return 0; +} + + + +// private method +// Given the address, find the vector index of the symbol. +// Return -1 if not found. +// Return 0 for exact match. +// Return 1 for nearest (previous) symbol +int hbSymbolTable::locateSymbol( uint64_t i_address, int &o_index ) +{ + int rc = -1; + int top, bot, mid, i; + int count = iv_vecSymbols.size(); + + if( 0 == count ) + { + return -1; + } + + if( 1 == count ) + { + return 1; + } + + + top = count - 1; + bot = 0; + + while( top >= bot ) + { + mid = (top + bot) / 2; + + uint64_t l_midAddress = iv_vecSymbols[mid]->iv_Address; + + if( i_address > l_midAddress ) + { + /* input address > symtable address */ + bot = mid + 1; + } + else if( i_address < l_midAddress ) + { + /* input address < symtable address */ + top = mid - 1; + } + else + { + /* exact match */ + o_index = mid; + return 0; + } + } + + + /* The binary search above rarely returns with mid pointing to + * the right symbol, so back up a couple of indices and bump along + * until we find the right symbol. + */ + + bot = mid - 2; + if( bot < 0 ) + { + bot = 0; + } + + top = mid + 1; + if( top > count ) + { + top = count; + } + + + for( i = bot; i < top; i++ ) + { + if( ( i_address >= iv_vecSymbols[i]->iv_Address ) && + ( i_address < ( iv_vecSymbols[i]->iv_Address + iv_vecSymbols[i]->iv_Length ))) + { + // this is the one + o_index = i; + + // nearest symbol found + rc = 1; + break; + } + } + return rc; +} + + + + + +// construtor +hbSymbolTable::hbSymbolTable() +{ + iv_pFileName = NULL; + iv_fPopulated = 0; +} + + +hbSymbolTable::~hbSymbolTable() +{ + int c = iv_vecSymbols.size(); + for( int i = 0; i < c; i++ ) + { + delete iv_vecSymbols[i]; + } + delete[] iv_pFileName; +} + + +// public method +char * hbSymbolTable::nearestSymbol( uint64_t i_address ) +{ + // search + int l_index = 0; + int rc = locateSymbol( i_address, l_index ); + if( rc < 0 ) + { + // not found + return NULL; + } + return iv_vecSymbols[l_index]->iv_pszName; +} + + + + + +//------------------------------------------------------------------------ +// hbSymbol methods + + +hbSymbol::hbSymbol() +{ + iv_validationBits = 0; + iv_Type = 0; + iv_Address = 0; + iv_Length = 0; + iv_pszName = NULL; +} + +void hbSymbol::setAddress( const char * i_pszAddress ) +{ + sscanf( i_pszAddress, "%llX", &iv_Address ); + iv_validationBits |= ADDRESS; +} + +void hbSymbol::setLength( const char * i_pszLength ) +{ + sscanf( i_pszLength, "%llX", &iv_Length ); + iv_validationBits |= LENGTH; +} + +void hbSymbol::setType( int i_type ) +{ + iv_Type = i_type; + iv_validationBits |= TYPE; +} + +void hbSymbol::setSymbolName( char * i_pszName ) +{ + trim( i_pszName ); + + delete[] iv_pszName; + int cb = strlen( i_pszName ) + 1; + iv_pszName = new char[cb]; + strcpy( iv_pszName, i_pszName ); + if( cb > 1 ) + { + iv_validationBits |= NAME; + } +} + +bool hbSymbol::isValid() +{ + // ensure somebody called to set address, length, + // name of symbol, and type. This would indicate the + // parsing of the symbols input line went OK. + return ((TYPE|ADDRESS|LENGTH|NAME)==(iv_validationBits)); +} + + +hbSymbol::~hbSymbol() +{ + delete[] iv_pszName; +} + + + + diff --git a/src/usr/errl/plugins/symbols.H b/src/usr/errl/plugins/symbols.H new file mode 100644 index 000000000..4be1512b4 --- /dev/null +++ b/src/usr/errl/plugins/symbols.H @@ -0,0 +1,162 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/errl/plugins/symbols.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2012 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END + + + + + +#ifndef ERRL_PLUGINS_SYMS_H +#define ERRL_PLUGINS_SYMS_H + +/** + * @file symbols.H + * + * @brief read HB symbols file and provide a lookup mechanism. + * + */ + + +/** + * @brief hbSymbol + * + * This class contains the data from a line of the HB syms file. + */ + +class hbSymbol +{ + public: + + // Data from a line from hbicore.syms + uint64_t iv_Address; + uint64_t iv_Length; + char * iv_pszName; + + // The char in column 1 of hbicore.syms + int iv_Type; + + hbSymbol(); + + /** @brief Set the starting address of the symbol. + */ + void setAddress( const char * i_pszAddress ); + + + /** @brief Set the length of the data over which + * this symbol spans. + */ + void setLength( const char * i_pszLength ); + + + /** @brief Set the symbol name. + */ + void setSymbolName( char * i_pszName ); + + + /** @brief Set the type of symbol. This is + * the char found in column 1 of Hostboot + * symbol files. F is function, V is variable. + */ + void setType( int i_type ); + + + /** @brief Checks to see if all four set functions + * have been called. If so, then this symbol is considered + * valid. These symbols are built piecemeal as values are + * scanned from the input line of text. + */ + bool isValid(); + + + ~hbSymbol(); + + // A validation scheme, since instance + // vars are set piecemeal. + enum + { + ADDRESS = 0x0001, + LENGTH = 0x0002, + NAME = 0x0004, + TYPE = 0x0008, + }; + + private: + int iv_validationBits; + +}; + + + + + + +/** + * @brief hbSymbolTable + * + * Container for hbSymbols with methods to initialize and access. + */ + + +class hbSymbolTable +{ + public: + + /** @brief Contructor. To use: create instance, then + * call readSymbols() to populate the symbol table. + * Then call nearestSymbol(). + */ + hbSymbolTable(); + + /** @brief Read the symbols file, return zero for success. + * On success, then you can call nearestSymbol() + */ + int readSymbols( const char * i_filename ); + + /** @brief Find and return the nearest symbol for the address given. + * Returns null when not found. + */ + char * nearestSymbol( uint64_t i_address ); + + /** @brief Destructor. + */ + ~hbSymbolTable(); + + private: + + bool iv_fPopulated; + char * iv_pFileName; + std::vector<hbSymbol*> iv_vecSymbols; + + // Read the file and populate the symbol vector. + int populateSymbolVector(); + + // Given the address, find the vector index of the symbol. + // Return -1 if not found. + // Return 0 for exact match. + // Return 1 for nearest (previous) symbol + int locateSymbol( uint64_t i_address, int & o_index ); +}; + + + +#endif // ERRL_PLUGINS_SYMS_H + |