* add new program 'symbolizer' which has basically nothing to do with any of the rest of this stuff. but it is wii-related and using Qt, so it ends up here

git-svn-id: http://wiiqt.googlecode.com/svn/trunk@108 389f4c8b-5dfe-645f-db0e-df882bc27289
This commit is contained in:
giantpune 2011-12-12 06:52:50 +00:00
parent b703943847
commit 6e25705126
9 changed files with 2689 additions and 0 deletions

3
symbolizer/be.cpp Normal file
View File

@ -0,0 +1,3 @@
#include "be.h"

83
symbolizer/be.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef BE_H
#define BE_H
#include "../WiiQt/includes.h"
class be64
{
quint64 value; // in big endian;
public:
explicit be64( quint64 v ): value( qFromBigEndian( v ) ) {}
be64(): value( 0 ) {}
quint64 operator*()
{
return to_quint64();
}
quint64 to_quint64() const
{
return qToBigEndian( value );
}
be64 &operator = ( const quint64 &v )
{
value = qFromBigEndian( v );
return *this;
}
};
class be32
{
quint32 value; // in big endian;
public:
explicit be32( quint32 v ): value( qFromBigEndian( v ) ) {}
be32(): value( 0 ) {}
quint32 operator*()
{
return to_quint32();
}
quint32 to_quint32() const
{
return qToBigEndian( value );
}
be32 &operator = ( const quint32 &v )
{
value = qFromBigEndian( v );
return *this;
}
};
class be16
{
quint16 value; // in big endian;
public:
explicit be16( quint16 v ): value( qFromBigEndian( v ) ) {}
be16(): value( 0 ) {}
quint16 operator*()
{
return to_quint16();
}
quint16 to_quint16() const
{
return qToBigEndian( value );
}
be16 &operator = ( const quint16 &v )
{
value = qFromBigEndian( v );
return *this;
}
};
#endif // BE_H

84
symbolizer/dol.cpp Normal file
View File

@ -0,0 +1,84 @@
#include "dol.h"
Dol::Dol( const QByteArray &dol ) : dh( NULL )
{
if( (quint32)dol.size() > sizeof( Dolheader ) )
{
Parse( dol );
}
}
bool Dol::Parse( const QByteArray &dol )
{
dh = NULL;
text.clear();
data.clear();
if( (quint32)dol.size() < sizeof( Dolheader ) )
{
WRN << "dol.size() < sizeof( Dolheader )";
return false;
}
headerBuf = dol.left( sizeof( Dolheader ) );
dh = reinterpret_cast< Dolheader * >( headerBuf.data() );
if( !dh )
{
WRN << "!dh";
return false;
}
//DBG << hex << (*(dh->entrypoint));
for( quint32 i = 0; i < 7; i ++ )
{
quint32 fileOff = (*(dh->offsetText[ i ] ) );
quint32 len = (*(dh->sizeText[ i ] ) );
quint32 addr = (*(dh->addressText[ i ] ) );
if( !fileOff || !len || !addr )
{
continue;
}
if( fileOff + len > (quint32) dol.size() )
{
WRN << "text section is out of range:" << i << hex << fileOff << len;
continue;
}
DolSection sec;
sec.addr = addr;
sec.data = dol.mid( fileOff, len );
text << sec;
}
for( quint32 i = 0; i < 11; i ++ )
{
quint32 fileOff = (*(dh->offsetData[ i ] ) );
quint32 len = (*(dh->sizeData[ i ] ) );
quint32 addr = (*(dh->addressData[ i ] ) );
if( !fileOff || !len || !addr )
{
continue;
}
if( fileOff + len > (quint32) dol.size() )
{
WRN << "data section is out of range:" << i << hex << fileOff << len;
continue;
}
DolSection sec;
sec.addr = addr;
sec.data = dol.mid( fileOff, len );
data << sec;
}
return true;
}
Dol Dol::FakeDol( const QByteArray &mem, quint32 loadAddress )
{
Dol ret;
DolSection sec;
sec.addr = loadAddress;
sec.data = mem;
ret.text << sec;
return ret;
}

58
symbolizer/dol.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef DOL_H
#define DOL_H
#include "../WiiQt/includes.h"
#include "../WiiQt/tools.h"
#include "be.h"
struct Dolheader
{
be32 offsetText[ 7 ]; // 0 // 0000
be32 offsetData[ 11 ]; // 28 // 0012
be32 addressText[ 7 ]; // 72 // 0048
be32 addressData[ 11 ]; // 100 // 0064
be32 sizeText[ 7 ]; // 144 // 0090
be32 sizeData[ 11 ]; // 172 // 00ac
be32 addressBSS; // 216 // 00d8
be32 sizeBSS; // 220 // 00dc
be32 entrypoint; // 224 // 00e0
};
struct DolSection
{
quint32 addr;
QByteArray data;
DolSection() : addr( 0 )
{
}
};
class Dol
{
public:
Dol( const QByteArray &dol = QByteArray() );
const Dolheader *Header() const { return dh; }
const QList< DolSection > &TextSections() const { return text; }
const QList< DolSection > &DataSections() const { return data; }
bool Parse( const QByteArray &dol );
// create a fake dol from a memory buffer
//! Header() will return NULL, and it will create only 1 text section with the load address and no data sections
//! added just for convenience
static Dol FakeDol( const QByteArray &mem, quint32 loadAddress = 0x80000000 );
private:
Dolheader *dh;
QList< DolSection >text;
QList< DolSection >data;
QByteArray headerBuf;
};
#endif // DOL_H

625
symbolizer/elfparser.cpp Normal file
View File

@ -0,0 +1,625 @@
#include "../WiiQt/tools.h"
#include "elfparser.h"
ElfParser::ElfParser( const QString &stuff ) : error( false )
{
ParseText( stuff );
}
bool ElfParser::ParseText( const QString &str )
{
QString fileName;
QStringList fileLines;
QMap< QString, QStringList >rawFiles;
QMap< QString, QStringList >rawSections;
QMap< QString, QStringList >rawSymbolTable;
QStringList lines = str.split( '\n', QString::KeepEmptyParts );
quint32 lineCnt = lines.size();
for( quint32 i = 0; i < lineCnt; i++ )
{
const QString &line = lines.at( i );
// start of a new file
if( line.contains( ": file format" ) )
{
// add existing file to the list
if( !fileName.isEmpty() && fileLines.size() )
{
rawFiles[ fileName ] = fileLines;
}
fileLines.clear();
fileName.clear();
fileName = line.left( line.indexOf( ": file format" ) );
//qDebug() << "starting file" << fileName;
// read symbol table
for( ; i < lineCnt; i++ )
{
if( lines.at( i ).startsWith( "SYMBOL TABLE:" ) )
{
//qDebug() << "lines.at( i )" << lines.at( i );
break;
}
}
QStringList symbolListLines;
for( ; i < lineCnt && !lines.at( i ).isEmpty(); i++ )
{
symbolListLines << lines.at( i );
}
rawSymbolTable[ fileName ] = symbolListLines;
// read hex dump
for( ; i < lineCnt; i++ )
{
if( lines.at( i ).startsWith( "Contents of section " ) )
{
//qDebug() << "lines.at( i )" << lines.at( i );
break;
}
}
QStringList secList;
for( ; i < lineCnt && !lines.at( i ).isEmpty(); i++ )
{
secList << lines.at( i );
}
//qDebug() << "section" << fileName << secList.size();
rawSections[ fileName ] = secList;
for( ; i < lineCnt - 1; i++ )
{
if( lines.at( i + 1 ).startsWith( "Disassembly of section" ) )
{
break;
}
if( lines.at( i + 1 ).contains( ": file format" ) )// happens if the .o doesnt contain any rode
{
break;
}
}
continue;
}
if( line.startsWith( "Disassembly of section" ) )
{
continue;
}
fileLines << line;
}
// add the last file in there
if( !fileName.isEmpty() && fileLines.size() )
{
rawFiles[ fileName ] = fileLines;
}
QMapIterator< QString, QStringList > it( rawFiles );
while( it.hasNext() )
{
it.next();
//qDebug() << "File:" << it.key() << it.value().size();
File file( it.key() );
if( !ParseFileText( it.value(), rawSections.find( it.key() ).value(), rawSymbolTable.find( it.key() ).value(), file ) )
{
error = true;
return false;
}
files << file;
}
foreach( const File &f, files )
{
//qDebug() << f.Name();
/*foreach( const Function &fun, f.Functions() )
{
//qDebug() << " " << fun.Name();
foreach( const SymRef &ref, fun.References() )
{
//qDebug() << " " << hex << ref.off << ref.name;
}
}*/
/*foreach( const SymAlias &alias, f.Aliases() )
{
qDebug() << " " << alias.name << alias.containerName;
}*/
}
//exit( 0 );
return true;
}
QList< SymAlias > ElfParser::ParseSymbolTable( const QStringList &lines )
{
QList< SymAlias >ret;
foreach( const QString &line, lines )
{
if( line.size() < 19 )// too small
{
continue;
}
int tab = line.indexOf( '\t' );
if( tab < 17 || line.size() < tab + 11 )
{
continue;
}
bool ok;
SymAlias ref;
ref.containerName = line.mid( 17, tab - 17 );
// filter out certain sections
if( ref.containerName.startsWith( '*' )
|| ref.containerName.startsWith( ".text" )
|| ref.containerName.startsWith( ".debug" )
|| ref.containerName.startsWith( ".comment" )
|| ref.containerName.startsWith( ".gnu" )
|| ref.containerName.startsWith( ".init" ) )
{
continue;
}
ref.offset = line.left( 8 ).toUInt( &ok, 16 );
if( !ok )
{
continue;
}
ref.size = line.mid( tab + 1, 8 ).toUInt( &ok, 16 );
if( !ok )
{
continue;
}
//qDebug() << line.mid( tab + 1, 8 );
if( !ref.offset && !ref.size )
{
continue;
}
ref.name = line.mid( tab + 10 );
//qDebug() << hex << QString( "%1" ).arg( ref.offset, 8, 16, QChar( QChar( '0' ) ) )
// << ref.containerName
// << QString( "%1" ).arg( ref.size, 8, 16, QChar( QChar( '0' ) ) )
// << ref.name;
ret << ref;
}
return ret;
}
QMap< QString, QByteArray > ElfParser::ParseSectionText( const QStringList &list )
{
QMap< QString, QByteArray >ret;
QMap< QString, QByteArray >ret2;
QByteArray ba;
QString name;
for( quint32 i = 0; i < (quint32)list.size(); i++ )
{
const QString &line = list.at( i );
if( line.startsWith( "Contents of section " ) )
{
if( !name.isEmpty() && ba.size() )
{
ret[ name ] = ba;
}
ba.clear();
name = line.mid( 20 );
name.resize( name.size() - 1 );
//DBG << name;
continue;
}
QString hexS = line.mid( 6, 35 );
QByteArray hexA = hexS.toLatin1();
hexA = QByteArray::fromHex( hexA );
ba += hexA;
}
if( !name.isEmpty() && ba.size() )
{
ret[ name ] = ba;
}
// remove unwanted sections
QMapIterator< QString, QByteArray > it( ret );
while( it.hasNext() )
{
it.next();
if( !it.key().contains( ".text" )
&& !it.key().startsWith( ".init" )
&& !it.key().startsWith( ".ctors" )
&& !it.key().startsWith( ".dtors" )
&& !it.key().startsWith( ".debug" )
&& !it.key().startsWith( ".comment" )
&& !it.key().startsWith( "extab" ))
{
ret2[ it.key() ] = it.value();
}
}
// debug
/*QMapIterator< QString, QByteArray > it2( ret2 );
while( it2.hasNext() )
{
it2.next();
qDebug() << it2.key();
hexdump( it2.value() );
}*/
return ret2;
}
bool ElfParser::ParseFileText( const QStringList &strs, const QStringList &sectionStrs, const QStringList &symbolStrs, ElfParser::File &file )
{
quint32 cnt = strs.size();
quint32 fOff = 0;
quint32 fStart = 0;
QString name;
QString pattern;
QList< SymRef > refs;
//DBG << file.Name() << sectionStrs.size() << symbolStrs.size() << strs.size();
QMap< QString, QByteArray >sections = ParseSectionText( sectionStrs );
QList< SymAlias > aliases = ParseSymbolTable( symbolStrs );
//DBG << file.Name() << sections.size() << aliases.size();
for( quint32 i = 0; i < cnt; i++ )
{
const QString &str = strs.at( i );
/*if( name == "WII_Initialize" )
{
qDebug() << str;
}*/
// start a new funciton
if( IsFunctionStart( str, &fStart ) )
{
// add this function to the list
if( !name.isEmpty() && fOff )
{
Function fun( name );
fun.references = refs;
fun.pattern = pattern;
fun.file = &file;
file.functions << fun;
//qDebug() << "pattern:" << pattern;
}
//qDebug() << GetFunctionName( str );
name = GetFunctionName( str );
//DBG << name;
if( fOff != (quint32)pattern.size() / 2 )
{
qDebug() << "size bad";
exit( 0 );
}
fOff = 0;
pattern.clear();
refs.clear();
sections.remove( name );// remove functions from the section list
continue;
}
if( name.isEmpty() )
{
continue;
}
if( IsBlank( str ) )
{
//qDebug() << str << "is blank";
continue;
}
if( IsSymbolLine( str ) )
{
//qDebug() << str << "IsSymbolLine";
continue;
}
QString hex;
QString oper;
QString symbol;
quint32 refOff = 0xdeadbeef;
if( !ParseOpLine( str, hex, oper ) )
{
qDebug() << str << strs.at( i - 1 );
return false;
}
/*if( name == "WII_Initialize" )
{
qDebug() << "hex" << hex;
}*/
if( ( i < cnt - 1 ) && IsSymbolLine( strs.at( i + 1 ) ) )
{
SymRef::Type refType;
symbol = GetNonOperRef( strs.at( i + 1 ), &refOff, &refType );
if( refOff < fStart )
{
WRN << "refOff < fStart" << str;
return false;
}
SymRef ref;
quint32 deRef;
ref.name = DeReferenceSymbol( symbol, &deRef );
ref.symOff = deRef;
switch( refType )
{
case SymRef::R_PPC_ADDR16_HI:
case SymRef::R_PPC_ADDR16_LO:
{
hex[ 4 ] = '.';
hex[ 5 ] = '.';
hex[ 6 ] = '.';
hex[ 7 ] = '.';
}
break;
case SymRef::R_PPC_REL24:
case SymRef::R_PPC_EMB_SDA21:
{
hex[ 1 ] = '.';
hex[ 2 ] = '.';
hex[ 3 ] = '.';
hex[ 4 ] = '.';
hex[ 5 ] = '.';
hex[ 6 ] = '.';
hex[ 7 ] = '.';
}
break;
case SymRef::R_PPC_SDAREL16:
{
hex = "........";
}
break;
default:
WRN << "unhandled reference type";
return false;
break;
}
ref.type = refType;
ref.off = refOff - fStart;
refs << ref;
if( ref.off & 0xff000000 )
{
qDebug() << "ref.off is busted 1" << name << str;
qDebug() << ::hex << refOff << fStart;
exit( 0 );
}
}
else if( OpNeedsWildCard( oper ) )
{
//DBG << "bl called without symbol reference\n" << str;
hex = "........";
if( symbol.isEmpty() )
{
symbol = GetOpersymRef( str );
}
SymRef ref;
ref.name = symbol;
ref.off = (quint32)(pattern.size());
ref.type = SymRef::R_PPC_REL24;
refs << ref;
if( ref.off & 0xff000000 )
{
DBG << "ref.off is busted 2" << name << str;
exit( 0 );
}
}
pattern += hex.toUpper();
/*if( name == "WII_Initialize" )
{
qDebug() << "hex" << pattern;
}*/
fOff += 4;
}
if( !name.isEmpty() )
{
Function fun( name );
fun.references = refs;
fun.pattern = pattern;
fun.file = &file;
file.functions << fun;
}
file.sections = sections;
file.aliases = aliases;
return true;
}
bool ElfParser::IsFunctionStart( const QString &str, quint32 *start )
{
bool ok;
quint32 s;
if( str.size() < 12 )
{
return false;
}
if( str.startsWith( ' ' ) )
{
return false;
}
if( !str.endsWith( ">:" ) )
{
return false;
}
s = str.left( 8 ).toUInt( &ok, 16 );
if( !ok )
{
return false;
}
int o = str.indexOf( '<' );
if( o < 9 )
{
return false;
}
if( start )
{
*start = s;
}
return true;
}
QString ElfParser::GetFunctionName( const QString &str )
{
QString ret = str;
ret.remove( 0, ret.indexOf( '<' ) + 1 );
ret.resize( ret.size() - 2 );
return ret;
}
bool ElfParser::IsSymbolLine( const QString & str )
{
if( str.startsWith( "\t\t\t" ) && str.indexOf( '\t', 3 ) > 4 )
{
return true;
}
return false;
}
bool ElfParser::IsBlank( const QString & str )
{
QString sim = str.simplified();
return sim.isEmpty() || sim == "...";
}
bool ElfParser::ParseOpLine( const QString &str, QString &hex, QString &oper )
{
// 1c74: 41 82 01 54 beq-
int tab = str.indexOf( '\t', 3 );
if( tab < 0 || str.size() < tab + 15 || str.at( tab + 3 ) != ' ' || str.at( tab + 6 ) != ' ' || str.at( tab + 9 ) != ' ' || str.at( tab + 12 ) != ' ' )
{
qDebug() << str << "is not an opline";
qDebug() << hex << oper;
return false;
}
// " 0: 94 21 ff f0 stwu r1,-16(r1)"
hex = str.mid( tab + 1, 11 );
hex.remove( ' ' );
oper = str.mid( tab + 14 );
int i = oper.indexOf( ' ' );
if( i > 0 )
{
oper.resize( i );
}
//qDebug() << str << '\n' << hex << oper;
//exit( 0 );
return true;
}
bool ElfParser::OpNeedsWildCard( const QString &str )
{
if( str == "bl" )
{
return true;
}
return false;
}
QString ElfParser::GetNonOperRef( const QString &str, quint32 *off, SymRef::Type *type )
{
int i = str.lastIndexOf( '\t' );
if( i < 0 )
{
return QString();
}
if( off )// get offset
{
bool ok;
QString n = str.mid( 3 );
{
n.resize( n.indexOf( ':' ) );
}
*off = n.toUInt( &ok, 16 );
if( !ok )
{
*off = 0xdeadbeef;
DBG << "error converting\n" << str << '\n' << n;
exit( 0 );
}
}
if( type )
{
if( str.contains( "R_PPC_REL24" ) )
{
*type = SymRef::R_PPC_REL24;
}
else if( str.contains( "R_PPC_ADDR16_LO" ) )
{
*type = SymRef::R_PPC_ADDR16_LO;
}
else if( str.contains( "R_PPC_EMB_SDA21" ) )
{
*type = SymRef::R_PPC_EMB_SDA21;
}
else if( str.contains( "R_PPC_ADDR16_HA" ) || str.contains( "R_PPC_ADDR16_HI" ) )
{
*type = SymRef::R_PPC_ADDR16_HI;
}
else if( str.contains( "R_PPC_SDAREL16" ) )
{
*type = SymRef::R_PPC_SDAREL16;
}
else
{
*type = SymRef::R_PPC_WTF;
DBG << "*type = SymRef::R_PPC_WTF" << str;
exit( 0 );
}
}
return str.mid( i + 1 );
}
QString ElfParser::GetOpersymRef( const QString &str )
{
QString ret;
int o = str.indexOf( '<' );
if( o < 0 )
{
return QString();
}
ret = str.mid( o + 1 );
if( !ret.endsWith( '>' ) )
{
return QString();
}
ret.resize( ret.size() - 1 );
return ret;
}
QString ElfParser::DeReferenceSymbol( const QString &reference, quint32 *offset )
{
// .rodata.str1.1+0x5
QString ret;
if( offset )
{
*offset = 0;
}
int o = reference.indexOf( "+0x" );
if( o < 0 )
{
return reference;
}
ret = reference.left( o );
bool ok;
quint32 d = reference.mid( o + 3 ).toUInt( &ok, 16 );
if( !ok )
{
return reference;
}
if( offset )
{
*offset = d;
}
return ret;
}

135
symbolizer/elfparser.h Normal file
View File

@ -0,0 +1,135 @@
#ifndef ELFPARSER_H
#define ELFPARSER_H
#include "../WiiQt/includes.h"
// class to parse the output of "objdump -xds someLib.a"
//! specifically wii PPC libs
struct SymRef
{
enum Type
{
R_PPC_ADDR16_HI, // reference to the upper 16 bits of the variable. ie "lis"
R_PPC_ADDR16_LO, // refers to the lower 16 bits. ie "addi"
R_PPC_REL24, // refers by branching. ie "bl"
R_PPC_SDAREL16, // no clue wtf this one does
R_PPC_EMB_SDA21, // referenced by lwz/stw r13 or r2. these are converted at link time
R_PPC_WTF // something went wrong
};
quint32 off; // offset within the function where the reference occurs
quint32 symOff; // offset from the referenced symbol. ie stringTable + 0x10
Type type;
QString name; // name of the symbol referenced
SymRef() : off( 0 ), symOff( 0 ), type( R_PPC_WTF )
{
}
};
// ninty's compiler seems to lump a bunch of data together in 1 section and then offer names to it
// gcc seems to give each piece of data its own section
struct SymAlias
{
QString name;
QString containerName;
quint32 offset;
quint32 size;
SymAlias() : offset( 0 ), size( 0 )
{
}
};
class ElfParser
{
public:
class File;
class Function
{
public:
Function( const QString &n = QString() ) : name( n )
{
}
const QString &Name() const { return name; }
const QString &Pattern() const { return pattern; }
const QList< SymRef > &References() const { return references; }
const File *PFile() const { return file; }
private:
friend class ElfParser;
QString name;
QString pattern;
File *file;
QList< SymRef > references;
};
class File
{
public:
File( const QString &n = QString() ) : name( n )
{
}
const QString &Name() const { return name; }
const QList< Function > &Functions() const { return functions; }
// doesnt contain the ".text" section, since that is already parsed and turned into functions
//! this is for data and rodata and stuff
const QMap< QString, QByteArray > &Sections() const { return sections; }
const QList< SymAlias > &Aliases() const { return aliases; }
private:
friend class ElfParser;
QString name;
QList< Function > functions;
QMap< QString, QByteArray >sections;
QList< SymAlias >aliases;
};
ElfParser( const QString &stuff );
//const QList< File >Files() const { return files; }
bool Error() const { return error; }
const QList< File > Files() const { return files; }
private:
bool error;
QList< File >files;
// takes the entire dump and separetes it into files
bool ParseText( const QString &str );
// takes each file and separetes it into functions
bool ParseFileText( const QStringList &strs, const QStringList &sectionStrs, const QStringList &symbolStrs, File &file );
QRegExp funcStart;
bool IsFunctionStart( const QString &str, quint32 *start = NULL );
// extract function name from the line that starts it
QString GetFunctionName( const QString &str );
// check if operation is one that should be wildcarded
bool OpNeedsWildCard( const QString & str );
// check if this is a symbol line or opcode
bool IsSymbolLine( const QString & str );
bool IsBlank( const QString & str );
bool ParseOpLine( const QString &str, QString &hex, QString &oper );
// returns stuff in <***> at the end of a line
QString GetOpersymRef( const QString &str );
// returns the string referenced by an extra line and the type of reference
QString GetNonOperRef( const QString &str, quint32 *off = NULL, SymRef::Type *type = NULL );
// parses the hex dump text of sections
QMap< QString, QByteArray >ParseSectionText( const QStringList &list );
QString DeReferenceSymbol( const QString &reference, quint32 *offset = NULL );
// parse symbol table
QList< SymAlias >ParseSymbolTable( const QStringList &lines );
};
#endif // ELFPARSER_H

1516
symbolizer/main.cpp Normal file

File diff suppressed because it is too large Load Diff

28
symbolizer/symbolizer.pro Normal file
View File

@ -0,0 +1,28 @@
#-------------------------------------------------
#
# Project created by QtCreator 2011-12-12T00:35:52
#
#-------------------------------------------------
QT += core
#QT -= gui
TARGET = symbolizer
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp\
../WiiQt/tools.cpp \
../WiiQt/aes.c \
elfparser.cpp \
dol.cpp \
be.cpp
HEADERS += ../WiiQt/tools.h \
../WiiQt/aes.h \
elfparser.h \
dol.h \
be.h

View File

@ -0,0 +1,157 @@
<!DOCTYPE QtCreatorProject>
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value key="EditorConfiguration.AutoIndent" type="bool">true</value>
<value key="EditorConfiguration.AutoSpacesForTabs" type="bool">false</value>
<value key="EditorConfiguration.Codec" type="QByteArray">UTF-8</value>
<value key="EditorConfiguration.DoubleIndentBlocks" type="bool">false</value>
<value key="EditorConfiguration.IndentBraces" type="bool">false</value>
<value key="EditorConfiguration.IndentSize" type="int">4</value>
<value key="EditorConfiguration.MouseNavigation" type="bool">true</value>
<value key="EditorConfiguration.PaddingMode" type="int">2</value>
<value key="EditorConfiguration.ScrollWheelZooming" type="bool">false</value>
<value key="EditorConfiguration.SmartBackspace" type="bool">true</value>
<value key="EditorConfiguration.SpacesForTabs" type="bool">false</value>
<value key="EditorConfiguration.TabKeyBehavior" type="int">0</value>
<value key="EditorConfiguration.TabSize" type="int">4</value>
<value key="EditorConfiguration.UseGlobal" type="bool">true</value>
<value key="EditorConfiguration.Utf8BomBehavior" type="int">1</value>
<value key="EditorConfiguration.addFinalNewLine" type="bool">true</value>
<value key="EditorConfiguration.cleanIndentation" type="bool">true</value>
<value key="EditorConfiguration.cleanWhitespace" type="bool">true</value>
<value key="EditorConfiguration.inEntireDocument" type="bool">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Desktop</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Desktop</value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.DesktopTarget</value>
<value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">0</value>
<value key="ProjectExplorer.Target.ActiveDeployConfiguration" type="int">0</value>
<value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
<valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
<value key="ProjectExplorer.BuildCOnfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.</value>
<valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.0" type="QVariantMap">
<valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">qmake</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">QtProjectManager.QMakeBuildStep</value>
<value key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary" type="bool">false</value>
<value key="QtProjectManager.QMakeBuildStep.QMakeArguments" type="QString"></value>
<value key="QtProjectManager.QMakeBuildStep.QMakeForced" type="bool">false</value>
</valuemap>
<valuemap key="ProjectExplorer.BuildStepList.Step.1" type="QVariantMap">
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
<value key="Qt4ProjectManager.MakeStep.Clean" type="bool">false</value>
<value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString">-j3</value>
<value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
</valuemap>
<value key="ProjectExplorer.BuildStepList.StepsCount" type="int">2</value>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Build</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.1" type="QVariantMap">
<valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
<value key="Qt4ProjectManager.MakeStep.Clean" type="bool">true</value>
<value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString">clean</value>
<value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
</valuemap>
<value key="ProjectExplorer.BuildStepList.StepsCount" type="int">1</value>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Clean</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value key="ProjectExplorer.BuildConfiguration.BuildStepListCount" type="int">2</value>
<value key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment" type="bool">false</value>
<valuelist key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges" type="QVariantList"/>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Qt in PATH Release</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration" type="int">0</value>
<value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/j/c/WiiQt/93/symbolizer</value>
<value key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId" type="int">2</value>
<value key="Qt4ProjectManager.Qt4BuildConfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.</value>
<value key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild" type="bool">false</value>
</valuemap>
<value key="ProjectExplorer.Target.BuildConfigurationCount" type="int">1</value>
<valuemap key="ProjectExplorer.Target.DeployConfiguration.0" type="QVariantMap">
<valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.0" type="QVariantMap">
<value key="ProjectExplorer.BuildStepList.StepsCount" type="int">0</value>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Deploy</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value key="ProjectExplorer.BuildConfiguration.BuildStepListCount" type="int">1</value>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">No deployment</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value key="ProjectExplorer.Target.DeployConfigurationCount" type="int">1</value>
<valuemap key="ProjectExplorer.Target.RunConfiguration.0" type="QVariantMap">
<valuelist key="Analyzer.Valgrind.AddedSupressionFiles" type="QVariantList"/>
<value key="Analyzer.Valgrind.FilterExternalIssues" type="bool">true</value>
<value key="Analyzer.Valgrind.NumCallers" type="int">25</value>
<valuelist key="Analyzer.Valgrind.RemovedSupressionFiles" type="QVariantList"/>
<value key="Analyzer.Valgrind.TrackOrigins" type="bool">true</value>
<value key="Analyzer.Valgrind.ValgrindExecutable" type="QString">valgrind</value>
<valuelist key="Analyzer.Valgrind.VisibleErrorKinds" type="QVariantList">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">symbolizer</value>
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4RunConfiguration</value>
<value key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase" type="int">2</value>
<value key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments" type="QString">./mario.dol /home/j/c/NINTENDO_Revolution_SDK_2.1_Wii-SYNDiCATE/RVL_SDK-2_1-060821/RVL_SDK/RVL/lib/ ./testing.idc</value>
<value key="Qt4ProjectManager.Qt4RunConfiguration.ProFile" type="QString">symbolizer.pro</value>
<value key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix" type="bool">false</value>
<value key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal" type="bool">false</value>
<valuelist key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges" type="QVariantList"/>
<value key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory" type="QString"></value>
<value key="RunConfiguration.QmlDebugServerPort" type="uint">3768</value>
<value key="RunConfiguration.UseCppDebugger" type="bool">true</value>
<value key="RunConfiguration.UseQmlDebugger" type="bool">false</value>
</valuemap>
<value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{dd2f24c7-c64b-41bd-8686-5d5bbb908d16}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">9</value>
</data>
</qtcreator>