diff options
author | Monte Copeland <copelanm@us.ibm.com> | 2011-10-24 09:30:49 -0500 |
---|---|---|
committer | Monte K. Copeland <copelanm@us.ibm.com> | 2011-10-31 11:07:10 -0500 |
commit | 723239d5a14fe82713a2aa57fef3130534b15a41 (patch) | |
tree | b6d19b1d1d66ec9ea4acd19c0dfdb47bcf86babd /src/usr/errl/parser/errlparser.C | |
parent | f2794eed87ca9c35140c601dfcbb5baf299d834b (diff) | |
download | talos-hostboot-723239d5a14fe82713a2aa57fef3130534b15a41.tar.gz talos-hostboot-723239d5a14fe82713a2aa57fef3130534b15a41.zip |
Error log changes for Sprint 6
Change-Id: I44ad678cfae8cd84e5370391dc7e20d74f59c9ca
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/449
Tested-by: Jenkins Server
Reviewed-by: Mark W. Wenning <wenning@us.ibm.com>
Reviewed-by: Monte K. Copeland <copelanm@us.ibm.com>
Diffstat (limited to 'src/usr/errl/parser/errlparser.C')
-rw-r--r-- | src/usr/errl/parser/errlparser.C | 631 |
1 files changed, 421 insertions, 210 deletions
diff --git a/src/usr/errl/parser/errlparser.C b/src/usr/errl/parser/errlparser.C index 5880e6db2..ccf9bf915 100644 --- a/src/usr/errl/parser/errlparser.C +++ b/src/usr/errl/parser/errlparser.C @@ -20,11 +20,33 @@ // Origin: 30 // // IBM_PROLOG_END + + /** * @file errlparser.C * - * @brief Parse and display committed error logs. Enter - * errlparser ? (or -? or -h or --help) to print help. + * @brief Builds a program to display committed Hostboot error logs. + * Enter errlparser ? (or -? or -h or --help) to print help. + * This program can be run standalone using a Simics + * L3 memory image and the HB syms file, however it is more likely + * spawned as "simcis> hb-errl" from the Hostboot/Simics python + * script. + * + * This program spawns the FSP x86 version of errl and fsp-trace + * which may or may not be in your $PATH. Candidates are: + * + * Classic FSP errl: + * /esw/fips730/Builds/b0829a_1130.730/obj/x86.nfp/errl/nfp/tool/errl + * + * Or this version in Monte's sandbox which is more Hostboot aware: + * /gsa/ausgsa/home/c/o/copelanm/public/bin/errl + * + * Building Blocks version of fsp-trace: + * /opt/mcp/shared/fr_DEV-37/opt/fsp/usr/bin/fsp-trace + * + * Camvan has a solution for PATHing to fsp-trace when in Simics. + * TODO Will need a copy of FSP x86 errl too in the near future. + * */ @@ -37,32 +59,41 @@ #include <errno.h> #include <assert.h> #include <string> +#include <vector> using namespace std; #include <errl/errltypes.H> #include <hbotcompid.H> + + +// Include the file that was generated by scanforsrcs.pl #include <hostBootSrcParse.H> + + using namespace ERRORLOG; + #define USAGE "\ Usage:\n\ \n\ -errlparser [-i] <imagefile> [[-s] <symsfile>] [-l | -d [<logid>|all]] [-v]\n\ +errlparser [-i]<image> [[-s]<syms>] [-l|-d[<logid>|all]] [-t <stringfile>]\n\ \n\ Arguments:\n\ - <imagefile> data file name\n\ - <symsfile> symbols file name\n\ + <image> data file name\n\ + <syms> symbols file name\n\ -l summarize all error logs (default)\n\ -d id print detail from specific error log\n\ - -s name explicitly name the symbols file\n\ -i name explicitly name the image file\n\ + -s name explicitly name the symbols file\n\ + -t name name the hbotStringFile\n\ -v verbose output to stdout\n\ \n\ Sample command lines:\n\ errlparser image.bin hbicore.syms # list logs from a full L3 image\n\ - errlparser image.bin hbicore.syms -d 1 # print detail about log 1\n\ + errlparser image.bin hbicore.syms -d 1 # display log 1\n\ + errlparser image.bin hbicore.syms -d 1 -t hbotStringFile # display traces\n\ errlparser buffer.bin # list logs from pre-extracted storage buffer\n\ errlparser buffer.bin -d 1 # detail log 1 from pre-extracted storage buffer\n\ \n\ @@ -74,9 +105,13 @@ Remarks:\n\ [] '-s' is optional if the symbols file name contains 'syms'\n\ [] '-i' can be optional in most cases\n\ \n\ +Developer switches:\n\ + -p -o <dirname> Extract all as PEL binaries to output <dirname>\n\ Contact: Monte Copeland\n\ " + + //------------------------------------------------------------------------ // Stop the program with a message. This message is often USAGE. Since // this program will be spawned from traceHB.py, I think we're better @@ -84,6 +119,7 @@ Contact: Monte Copeland\n\ // think Simics is piping stderr to its console. void halt( const char * msg ) { + // stdout out because Simics does not appear to display stderr (?) fprintf( stdout, "%s", msg ); // exit the process with a non-zero process exit level. @@ -111,6 +147,8 @@ ERRLCOMPNAME_t g_errlcompnames[] = { #include <comps.C> }; + +//------------------------------------------------------------- // Given a reason code which has a comp id mangled into // it, return a char* to the component name. Return // null if not found, which printf seems to handle @@ -133,157 +171,110 @@ const char * FindComp( uint16_t reasoncode ) -//------------------------------------------------------------ -// Print a hex dump of the input buffer to the output file -// given, probably stdout. -int FormatBytes( FILE * f, char * pchInput, int count, int indent ) +//------------------------------------------------------------- +// endian switch a uint64 +uint64_t ntohll( uint64_t i ) { - char szChars[ 80 ]; - char szHex[ 80 ]; - char szOffset[ 64 ]; - char szWork[ 256 ]; - int i; - unsigned int ul; - char * pch; - char * pchLine; - int cb; - char * pszIndent = NULL; - - - - pszIndent = static_cast<char*>(malloc( indent+1 )); - memset( pszIndent, 0, indent+1 ); - memset( pszIndent, ' ', indent ); - - - - pchLine = pchInput; - - - while( pchLine < pchInput + count ) - { - /* current offset */ - ul = pchLine - pchInput; - - sprintf( szOffset, "%08X", ul ); - - memset( szHex, ' ', sizeof( szHex )); - pch = szHex; - - cb = ((pchInput+count)-pchLine) > 16 ? 16 : ((pchInput+count)-pchLine); - - for( i = 0; i < cb; i++ ) - { - ul = (unsigned char) pchLine[ i ]; - - sprintf( szWork, "%02x", ul ); - memcpy( pch, szWork, 2 ); + uint64_t hi; + uint64_t lo; + uint32_t * pword = reinterpret_cast<uint32_t*>(&i); - pch += 3; - } + hi = ntohl( *pword ); + lo = ntohl( *(pword+1) ); - szHex[ 23 ] = '-'; - szHex[ 48 ] = 0; + return (hi<<32)|lo; +} - memset( szChars, 0, sizeof( szChars )); - for( i = 0; i < cb; i++ ) - { - szChars[i] = '.'; - int t = pchLine[i]; - if( t > 31 ) - { - szChars[i] = pchLine[ i ]; - } - } - sprintf( szWork, "%s %s %s", szOffset, szHex, szChars ); - fprintf( f, "%s%s\n", pszIndent, szWork ); - fflush( f ); - pchLine += 16; - } - return 0; +//------------------------------------------------------------- +// endian stuff, convert a errl storage marker in place +marker_t* ConvertMarker( marker_t* p) +{ + p->offsetNext = ntohl( p->offsetNext ); + p->length = ntohl( p->length ); + return p; } - //------------------------------------------------------------- -// endian stuff -section_header_t* ConvertSectionHeader( section_header_t* p) +// endian stuff, convert the data stored at the beginning of the +// errl storage buffer +storage_header_t * ConvertStorageHeader( storage_header_t * p ) { - p->cbHeader = ntohl( p->cbHeader ); - p->cbSection = ntohl( p->cbSection ); - p->compId = ntohs( p->compId ); - // sctnVer is byte long - // subSect is byte long + p->cbStorage = ntohl( p->cbStorage ); + p->cInserted = ntohl( p->cInserted ); + p->offsetMarker = ntohl( p->offsetMarker ); + p->offsetStart = ntohl( p->offsetStart ); return p; } - //------------------------------------------------------------- -// endian stuff -marker_t* ConvertMarker( marker_t* p) +// endian stuff,convert in place, return a pointer to what +// you passed in. PEL is made up of multiple sections, each +// one starting with a header that has these 8 bytes. +pelSectionHeader_t * ConvertPELSectionHeader( pelSectionHeader_t * p ) { - p->offsetNext = ntohl( p->offsetNext ); - p->length = ntohl( p->length ); + p->sid = ntohs( p->sid ); + p->len = ntohs( p->len ); + // byte: p->ver + // byte: p->sst + p->compId = ntohs( p->compId ); return p; } - //------------------------------------------------------------- -// endian switch a uint64 -uint64_t ntohll( uint64_t i ) +// endian stuff, convert in place. This converts the first section +// encountered in PEL, the PH section (private header). +pelPrivateHeaderSection_t* ConvertPrivateHeader(pelPrivateHeaderSection_t* p) { - 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; + ConvertPELSectionHeader( &p->sectionheader ); + p->creationTime = ntohll( p->creationTime ); + p->commitTime = ntohll( p->commitTime ); + p->creatorImplementation = ntohll( p->creatorImplementation ); + p->plid = ntohl( p->plid ); + p->eid = ntohl( p->eid ); + return p; } //------------------------------------------------------------- -// endian stuff -errl_header_t* ConvertErrlHeader( errl_header_t* p ) +// endian stuff, convert in place. Convert the 2nd section in PEL, +// the UH (user header). +pelUserHeaderSection_t * ConvertUserHeader( pelUserHeaderSection_t * p ) { - p->cbytes = ntohl( p->cbytes ); - p->csections = ntohl( p->csections ); - p->reasonCode = ntohs( p->reasonCode ); - // p->modId is a byte - // p->sev is a byte - // p->eventType is a byte - // p->subSys is a byte - // p->srcType is a byte - p->termState = ntohl( p->termState ); - p->logId = ntohl( p->logId ); - p->user1 = ntohll( p->user1 ); - p->user2 = ntohll( p->user2 ); - p->CreationTime = ntohll( p->CreationTime ); + ConvertPELSectionHeader( &p->sectionheader ); + // mostly byte sized stuff + p->actions = ntohs( p->actions ); return p; } - //------------------------------------------------------------- -// endian stuff -storage_header_t * ConvertStorageHeader( storage_header_t * p ) +// endian stuff, convert in place. The PS (primary SRC) section +// in PEL is the 3rd section. +pelSRCSection_t * ConvertSRC( pelSRCSection_t * p ) { - p->cbStorage = ntohl( p->cbStorage ); - p->cInserted = ntohl( p->cInserted ); - p->offsetMarker = ntohl( p->offsetMarker ); - p->offsetStart = ntohl( p->offsetStart ); + ConvertPELSectionHeader( &p->sectionheader ); + // mostly byte sized stuff + p->srcLength = ntohs( p->srcLength ); + p->reserved1 = ntohs( p->reserved1 ); + p->word2 = ntohl( p->word2 ); + p->word3 = ntohs( p->word3 ); + p->word4 = ntohl( p->word4 ); + p->word5 = ntohl( p->word5 ); + p->word6 = ntohll( p->word6 ); + p->word8 = ntohll( p->word8 ); return p; } + //----------------------------------------------------------------------- // Given the binary image file name, return the errl storage part of the file. // Caller must endian convert anything/everything in the output buffer. @@ -418,6 +409,7 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch ) pch = strstr( szWork, pszSearch ); if( pch ) { + // tease out the address for this symbol pszAddr = szWork + 2; pch = strchr( pszAddr, ',' ); assert( pch ); @@ -433,6 +425,7 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch ) exit(2); } + // Convert ascii hex representation of address to a unsigned long int c = sscanf( pszAddr, "%x", &ulAddr ); if( 1 != c ) { @@ -446,103 +439,111 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch ) -// -------------------------------------------------------------------------- -// Print a summary of the error log, no user-defined data nor detail. -// perrlog is already endian converted +//----------------------------------------------------------------------------- +// Output a vector of endian-converted PEL sections, without altering the caller's +// pchNativePEL input buffer. The vector will have pointers to PEL section +// headers, and the user of the vector contents will have to cast according to +// pelSectionHeader_t.sid (section id ). -void PrintErrlSummary( errl_header_t * perrlog ) +bool ParseForPEL( char * i_pchNativePEL, + int i_cbPEL, + vector<pelSectionHeader_t*> &o_vector ) { - // print headline - // comp id sev rc mod evt u1 u2 csec - printf( "%-7s %10s %4s %-6s %-4s %-4s %-18s %-18s %5s\n", - "comp", - "logid", - "sev", - "reason", - "mod", - "evnt", - "user1", - "user2", - "csect" ); - - - // comp id sev reason mod event user1 user2 csec - // code - printf( "%-7s %10d 0x%02x 0x%04x 0x%02x 0x%02x 0x%016llx 0x%016llx %5d\n", - FindComp( perrlog->reasonCode ), - perrlog->logId, - perrlog->sev, - perrlog->reasonCode, - perrlog->modId, - perrlog->eventType, - perrlog->user1, - perrlog->user2, - perrlog->csections // count of sections - ); -} - + // use pch to bump along through the PEL sections + char * pch = i_pchNativePEL; -//--------------------------------------------------------------------------- -// -// -void PrintErrlDetail( errl_header_t * perrlog ) -{ + while( pch < (i_pchNativePEL+i_cbPEL)) + { + void * pvoid; + pelSectionHeader_t sectionHeader; - // print the summary line - PrintErrlSummary( perrlog ); + // Convert a copy of just the PEL section header so I can look at the + // sid (section id/type) and the overall section length. + memcpy( §ionHeader, pch, sizeof( pelSectionHeader_t )); + ConvertPELSectionHeader( §ionHeader ); - // print the Errorlog tags - printErrorTags( perrlog->reasonCode, - perrlog->modId ); - // print sections if any - if( perrlog->csections ) - { - int i; - section_header_t* psect; + // For each section, allocate space for it, endian convert the + // section, then insert into output vector. + switch( sectionHeader.sid ) { + case ERRL_SID_PRIVATE_HEADER: + { + pvoid = malloc(sectionHeader.len); + pelPrivateHeaderSection_t * p; + p = static_cast<pelPrivateHeaderSection_t*>(pvoid); + memcpy( p, pch, sectionHeader.len ); + ConvertPrivateHeader( p ); + o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) ); + } + break; + case ERRL_SID_USER_HEADER: + { + pvoid = malloc(sectionHeader.len); + pelUserHeaderSection_t * p; + p = static_cast<pelUserHeaderSection_t*>(pvoid); + memcpy( p, pch, sectionHeader.len ); + ConvertUserHeader( p ); + o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) ); + } + break; + case ERRL_SID_PRIMARY_SRC: + { + pvoid = malloc(sectionHeader.len); + pelSRCSection_t * p; + p = static_cast<pelSRCSection_t*>(pvoid); + memcpy( p, pch, sectionHeader.len ); + ConvertSRC( p ); + o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) ); + } + break; + case ERRL_SID_USER_DEFINED: + { + pvoid = malloc(sectionHeader.len); + pelSectionHeader_t * p; + p = static_cast<pelSectionHeader_t*>(pvoid); + memcpy( p, pch, sectionHeader.len ); + // Only converts the PEL section header, but none of the + // user-defined content. No way to know what's in there. + ConvertPELSectionHeader(p); + o_vector.push_back(p); + } + break; + default: + assert( 0 ); + break; + } - // first section header resides just past the errl_header_t - psect = reinterpret_cast<section_header_t*>(perrlog+1); + pch += sectionHeader.len; + } - // Endian convert it - ConvertSectionHeader( psect ); + return true; +} - i = 0; - do - { - printf( - "\nSection %d: %-8s len=0x%04x, ver=0x%04x, subsection=0x%04x\n", - i, - FindComp( psect->compId ), - psect->cbSection, - psect->sctnVer, - psect->subSect - ); - // The user-provided data resides just past the section header. - char * pUserData = reinterpret_cast<char*>(psect+1); - // Print a hex dump (for now) of the user-provided data. - FormatBytes( stdout, pUserData, (int)psect->cbSection, 4 ); - i++; - if( i >= perrlog->csections ) - { - // Leave the loop, and do not ConvertSectionHeader(). - break; - } +//----------------------------------------------------------------------------- +// Scan the vector of endian-converted PEL sections. Locate the target section +// and return it. Return NULL if not found. Caller will have to cast +// the returned section header pointer to the desired PEL section struct. - // There's more; point to the next section. - int cb = psect->cbHeader + psect->cbSection; - char * p = (reinterpret_cast<char*>(psect)) + cb; - psect = reinterpret_cast<section_header_t*>(p); +pelSectionHeader_t * FindPELSection( unsigned int i_target, + vector<pelSectionHeader_t*> &o_vector ) +{ + pelSectionHeader_t * p = NULL; - // Endian convert it. - ConvertSectionHeader( psect ); + vector<pelSectionHeader_t*>::iterator it; + for( it = o_vector.begin(); it != o_vector.end(); it++ ) + { + if( (*it)->sid == i_target ) + { + p = *it; + break; } - while( 1 ); } + + return p; } @@ -550,13 +551,25 @@ void PrintErrlDetail( errl_header_t * perrlog ) + + + + + + //------------------------------------------------------------- int main( int argc, char *argv[] ) { char * pch; + char * pchNativePEL; + const char * pszErrlTool = NULL; char * pszImageFile = NULL; char * pszSymbolFile = NULL; + char * pszStringFile = NULL; + char * pszOutputDir = NULL; char szWork[ 1024 ]; + char szTmpFilename[ 1024 ]; + char szCommand[ 128 ]; unsigned char * puch; char * pszSearch; char * pszAddr = NULL; @@ -579,13 +592,17 @@ int main( int argc, char *argv[] ) off_t offsetEnd; int fVerbose = 0; int fList = 1; + int fListHead = 0; int fDetail = 0; int fAll = 0; int fFound = 0; + int fExtractPEL = 0; + void * pvoid; + struct stat statbuffer; // build a =========== divider for printfing - cb = 84; + cb = 78; assert( cb < sizeof( szDivider )); memset( szDivider, '=', sizeof( szDivider )); szDivider[ cb ] = 0; @@ -634,6 +651,41 @@ int main( int argc, char *argv[] ) } pszImageFile = strdup( argv[i] ); } + else if( 0 == strcmp( "-o", argv[i] )) + { + i++; + if( i >= argc ) + { + fprintf( stdout, "Provide -o <dirname>\n" ); + exit( 2 ); + } + pszOutputDir = strdup( argv[i] ); + } + else if( 0 == strcmp( "-p", argv[i] )) + { + fExtractPEL = 1; + fList = 0; + fDetail = 0; + } + else if( 0 == strcmp( "-t", argv[i] )) + { + i++; + if( i >= argc ) + { + fprintf( stdout, "Provide -t <string file>\n" ); + exit( 2 ); + } + pszStringFile = strdup( argv[i] ); + + // errl messes up ~ somehow, I thought bash + // would substitute this. + pch = strchr( pszStringFile, '~' ); + if( pch ) + { + printf( "Don't use ~ for file naming.\n" ); + exit(2); + } + } else if( 0 == strcmp( "-s", argv[i] )) { i++; @@ -694,6 +746,56 @@ int main( int argc, char *argv[] ) halt( USAGE ); } + if(( fExtractPEL ) && ( NULL == pszOutputDir )) + { + printf( "Provide output dir for PEL extraction.\n" ); + exit(1); + } + + // TODO Need to put a copy of FSP x86 errl tool in the simics path. + // Try for Monte's sandbox copy, temporary for Sprint 6. + pszErrlTool = "/gsa/ausgsa/home/c/o/copelanm/public/bin/errl"; + + rc = stat( pszErrlTool, &statbuffer ); + if( -1 == rc ) + { + // Not found, so this one should be found for most users. + pszErrlTool = + "/esw/fips730/Builds/b0829a_1130.730/obj/x86.nfp/errl/nfp/tool/errl"; + + rc = stat( pszErrlTool, &statbuffer ); + if( -1 == rc ) + { + printf( "Unable to find a copy of errl, including %s.\n", + pszErrlTool ); + exit(2); + } + } + + if( fVerbose ) + { + printf( "Using errl tool %s\n", pszErrlTool ); + } + + + if( pszStringFile ) + { + int fd = open( pszStringFile, O_RDONLY ); + if( -1 == fd ) + { + printf( "String file %s not found.\n", pszStringFile ); + exit(2); + } + rc = fstat( fd, &statbuffer ); + close(fd); + if( ( -1 == rc ) || !(S_ISREG(statbuffer.st_mode))) + { + printf( "String file %s is not valid.\n", pszStringFile ); + exit(2); + } + } + + if( pszSymbolFile ) { @@ -717,7 +819,6 @@ int main( int argc, char *argv[] ) } } - // Given the image file, read the portion that contains the // error log storage buffer. pchBuffer = ReadStorageBuffer( pszImageFile, ulAddr, cbBuffer ); @@ -770,7 +871,6 @@ int main( int argc, char *argv[] ) if( pMarker->offsetNext == 0 ) { // This is the list-ending marker. - printf( "%s\n", szDivider ); break; } @@ -778,24 +878,135 @@ int main( int argc, char *argv[] ) logcount++; - // Flattened struct of an error log resides just past marker. - errl_header_t* perr = reinterpret_cast<errl_header_t*>(pMarker+1); - ConvertErrlHeader( perr ); + // Flattened PEL of an error log resides just past marker + // for a length of pMarker->length. It is "native" meaning big endian. + pchNativePEL = reinterpret_cast<char*>(pMarker+1); + + // Make a copy of PH that I can endian convert without screwing up + // the native one. + pvoid = malloc( pMarker->length ); + pelPrivateHeaderSection_t * pPrivateHdr; + pPrivateHdr = static_cast<pelPrivateHeaderSection_t*>(pvoid); + memcpy( pPrivateHdr, pchNativePEL, pMarker->length ); + + // Convert the PEL private header copy to local endianness. + ConvertPrivateHeader( pPrivateHdr ); if( fList ) { - // Just list the error log headers. - printf( "%s\n", szDivider ); - PrintErrlSummary( perr ); + // print a simple list of error log IDs + if( !fListHead ) + { + // print a head line + printf( "%-16s %8s\n", "Component", "PLID" ); + printf( "%s\n", szDivider ); + fListHead = 1; + } + printf( "%-16s %8d\n", + FindComp(pPrivateHdr->sectionheader.compId), + pPrivateHdr->plid ); } - else if(( fDetail ) && (( perr->logId == ulLogId ) || (fAll))) + else if(( fDetail ) && (( pPrivateHdr->plid == ulLogId ) || (fAll))) { - // Print the detail for the one error log. - printf( "%s\n", szDivider ); - PrintErrlDetail( perr ); + // Write the native PEL to a temporary file + // for x86 errl tool to display. + sprintf( szTmpFilename, "/tmp/pel%d.bin", pPrivateHdr->plid ); + + int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 ); + if( -1 == fd ) + { + printf( "Unable to write %s. Exiting.\n", szTmpFilename ); + exit(2); + } + cb = write( fd, pchNativePEL, pMarker->length ); + assert( cb == pMarker->length ); + close(fd); + + // Spawn the FSP x86 errl tool to display + // the detail for this error log. + cb=sprintf(szCommand,"%s -d --file=%s",pszErrlTool,szTmpFilename); + if( pszStringFile ) + { + sprintf( &szCommand[cb], " --trace=%s", pszStringFile ); + } + + // Run errl -d to display the error log. + system( szCommand ); + + + // Build a vector containing pointers to each PEL section + // in the error log. On return, each section will be endian + // converted as much as possible. Do not alter the endianness + // of the native pel buffer, however. + vector<pelSectionHeader_t*> vectorPEL; + ParseForPEL( pchNativePEL, pMarker->length, vectorPEL ); + assert( vectorPEL.size() ); + + + + // Print the tag detail gleaned from the code by + // the errl tag parser. That requires getting the reason + // code and module ID from the error log. They live in + // the Primary SRC section. + uint32_t l_reasonCode = 0; + + + // Find the PS section in the vector of PEL sections. + pelSectionHeader_t* pPELHead; + pPELHead = FindPELSection( ERRL_SID_PRIMARY_SRC, vectorPEL ); + assert( pPELHead ); + + // Cast to Primary SRC section. + pelSRCSection_t * pSRCSection; + pSRCSection = reinterpret_cast<pelSRCSection_t*>(pPELHead); + +#if 0 + // reasonCode has been "stringified" into the SRC string + pch = strchr( pSRCSection->srcString, ' ' ); + assert( pch ); + *pch = 0; + assert( 8 == strlen( pSRCSection->srcString)); + sscanf( pSRCSection->srcString + 4, "%X", &l_reasonCode ); +#else + // I have cheated and put reasonCode here: + l_reasonCode = pSRCSection->reserved1; +#endif + + printf( "%-20s%s\n", + "Component", + FindComp(pPrivateHdr->sectionheader.compId)); + + // print the Errorlog tags from scanforsrcs.pl + printErrorTags( l_reasonCode, pSRCSection->moduleId ); + + // done with this tmp file + unlink( szTmpFilename ); + + // found at least one fFound = 1; } + + if( fExtractPEL ) + { + // Write the native PEL to a temporary file for debug later. + sprintf( szTmpFilename, "%s/pel%d.bin", pszOutputDir, pPrivateHdr->plid ); + + int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 ); + if( -1 == fd ) + { + printf( "Unable to write %s. Exiting.\n", szTmpFilename ); + exit(2); + } + cb = write( fd, pchNativePEL, pMarker->length ); + assert( cb == pMarker->length ); + close(fd); + + printf( "Saved as %s\n", szTmpFilename ); + } + + + // next marker/error log pMarker = ConvertMarker( OFFSET2MARKER(pMarker->offsetNext) ); } |