blob: ef7bced2301da7f833bc27b702eeb2cad944c359 [file] [log] [blame]
/*
* Copyright (c) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package org.eclipse.cdt.debug.edc.tests;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.internal.HostOS;
import org.eclipse.cdt.debug.edc.internal.PathUtils;
import org.eclipse.cdt.debug.edc.internal.services.dsf.EDCSymbolReader;
import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols;
import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType;
import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider;
import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfInfoReader;
import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope;
import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider;
import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader;
import org.eclipse.cdt.debug.edc.symbols.IFunctionScope;
import org.eclipse.cdt.debug.edc.symbols.IModuleScope;
import org.eclipse.cdt.debug.edc.symbols.IScope;
import org.eclipse.cdt.debug.edc.symbols.IType;
import org.eclipse.cdt.debug.edc.symbols.IVariable;
import org.eclipse.cdt.debug.edc.symbols.TypeUtils;
import org.eclipse.cdt.utils.Addr32;
import org.eclipse.core.runtime.IPath;
import org.junit.Before;
/**
*
*/
public abstract class AbstractDwarfReaderTest extends BaseDwarfTestCase {
protected static final String[] symFilesToTest = {
"BlackFlagMinGW.exe",
"BlackFlag_gcce.sym",
"BlackFlag_linuxgcc.exe",
"BlackFlag_rvct.sym",
"BlackFlag_gcce_343.sym",
"HelloWorld_rvct_2_2.exe.sym",
"HelloWorld_rvct_4_0.exe.sym",
"QtConsole_gcce_343.sym",
"SimpleCpp_rvct_22.sym",
"SimpleCpp_rvct_40.sym",
"SimpleCpp_gcce_432.sym",
"SimpleCpp_gcc_x86.exe",
};
/** Bag of data for testing sym files. The key is 'symFile' and other
* elements are used by specific tests.
*/
protected static class TestInfo {
public IPath symFile;
IPath exeFile;
int numberOfSources;
int numberOfModuleScopeChildren;
int numberOfVariables;
Map<String, Map<String, VariableInfo>> cuVarMap
= new HashMap<String, Map<String,VariableInfo>>();
int numberOfTypes;
IPath blackFlagMainFilePath;
int numberOfSymbols;
int numberOfPubFuncNames;
int numberOfPubFuncEntries;
int numberOfPubVarNames;
int numberOfPubVarEntries;
List<String> pubVars = new ArrayList<String>();
List<String> pubFuncs = new ArrayList<String>();
Map<String, List<ScopeInfo>> scopeInfos
= new LinkedHashMap<String, List<ScopeInfo>>();
IAddress lowAddress;
IAddress highAddress;
Collection<SymbolInfo> symbols;
}
protected static Map<String, TestInfo> testInfos
= new LinkedHashMap<String, TestInfo>();
static {
for (String sym : symFilesToTest) {
TestInfo info = new TestInfo();
info.symFile = getFile(sym);
testInfos.put(sym, info);
}
}
protected static TestInfo lookupInfo(String sym) {
return testInfos.get(sym);
}
protected static void setExe(String sym, String exe) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.exeFile = getFile(exe);
}
// not all the *.exes really exist; used to test mapping from *.exe to *.sym
static {
setExe("BlackFlagMinGW.exe", "BlackFlagMinGW.exe");
setExe("BlackFlag_gcce.sym", "BlackFlag_gcce.exe");
setExe("BlackFlag_linuxgcc.exe", "BlackFlag_linuxgcc.exe");
setExe("BlackFlag_rvct.sym", "BlackFlag_rvct.exe");
setExe("HelloWorld_rvct_2_2.exe.sym", "HelloWorld_rvct_2_2.exe");
setExe("HelloWorld_rvct_4_0.exe.sym", "HelloWorld_rvct_4_0.exe");
setExe("QtConsole_gcce_343.sym", "QtConsole_gcce_343.exe");
}
protected static void setSources(String sym, int i) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.numberOfSources = i;
}
static {
// TODO: this differs in Win and Lin
setSources("BlackFlagMinGW.exe", 121);
setSources("BlackFlag_gcce.sym", 108);
setSources("BlackFlag_linuxgcc.exe", 139);
setSources("BlackFlag_rvct.sym", HostOS.IS_WIN32 ? 207 : 172);
setSources("HelloWorld_rvct_2_2.exe.sym", HostOS.IS_WIN32 ? 323 : 320);
setSources("HelloWorld_rvct_4_0.exe.sym", 315);
setSources("QtConsole_gcce_343.sym", 434);
}
protected static void setModuleScopeChilden(String sym, int i) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.numberOfModuleScopeChildren = i;
}
static {
setModuleScopeChilden("BlackFlagMinGW.exe", 29);
setModuleScopeChilden("BlackFlag_gcce.sym", 27);
setModuleScopeChilden("BlackFlag_linuxgcc.exe", 25);
setModuleScopeChilden("BlackFlag_rvct.sym", 693);
setModuleScopeChilden("HelloWorld_rvct_2_2.exe.sym", 1579);
setModuleScopeChilden("HelloWorld_rvct_4_0.exe.sym", 1014);
setModuleScopeChilden("QtConsole_gcce_343.sym", 3);
}
protected static void setStartEndAddress(String sym, IAddress startAddress, IAddress endAddress) {
TestInfo info = lookupInfo(sym);
assertNotNull(info);
info.lowAddress = startAddress;
info.highAddress = endAddress;
}
static {
setStartEndAddress("BlackFlagMinGW.exe", new Addr32("0x00401000"), new Addr32("0x0046d2c0"));
setStartEndAddress("BlackFlag_gcce.sym", new Addr32("0x00008000"), new Addr32("0x0040a028"));
//start address for linuxgcc indicated only by program header not by sections or symbols
setStartEndAddress("BlackFlag_linuxgcc.exe", new Addr32("0x08048000"), new Addr32("0x0805a01c"));
setStartEndAddress("BlackFlag_rvct.sym", new Addr32("0x00008000"), new Addr32("0x0040a018"));
setStartEndAddress("HelloWorld_rvct_2_2.exe.sym", new Addr32("0x00008000"), new Addr32("0x00400008"));
setStartEndAddress("HelloWorld_rvct_4_0.exe.sym", new Addr32("0x00008000"), new Addr32("0x00400070"));
setStartEndAddress("QtConsole_gcce_343.sym", new Addr32("0x00008000"), new Addr32("0x00400008"));
}
protected static void setVariableCount(String sym, int i) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.numberOfVariables = i;
}
static {
setVariableCount("BlackFlagMinGW.exe", 52);
setVariableCount("BlackFlag_gcce.sym", 105);
setVariableCount("BlackFlag_linuxgcc.exe", 48);
setVariableCount("BlackFlag_rvct.sym", 61);
setVariableCount("HelloWorld_rvct_2_2.exe.sym", 1);
setVariableCount("HelloWorld_rvct_4_0.exe.sym", 1);
setVariableCount("QtConsole_gcce_343.sym", 2);
}
static class VariableInfo {
String name;
String typeName;
public VariableInfo(String name, String typeName) {
this.name = name;
this.typeName = typeName;
}
}
protected static void setCUVariableInfo(String sym, String cu, String var,
String type) {
TestInfo info = lookupInfo(sym);
if (info != null) {
VariableInfo vi = new VariableInfo(var, type);
Map<String, VariableInfo> varMap = info.cuVarMap.get(cu);
if (varMap == null) {
varMap = new HashMap<String, VariableInfo>();
info.cuVarMap.put(cu, varMap);
}
varMap.put(var, vi);
}
}
static {
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KBase",
"const class TLitC8");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KDer1",
"const class TLitC8");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KDer2",
"const class TLitC8");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KDerDer",
"const class TLitC8");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KIFace1",
"const class TLitC8");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/dbg_namespaceRealms.h", "KIFace2",
"const class TLitC8");
setCUVariableInfo(
"BlackFlag_rvct.sym",
"M:/sf/os/kernelhwsrv/kernel/eka/compsupp/symaehabi/callfirstprocessfn.cpp",
"KLitUser", "const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "KTxtEPOC32EX",
"const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "KTxtExampleCode",
"const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "KFormatFailed",
"const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "KTxtOK",
"const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "KTxtPressAnyKey",
"const class TLitC");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/INC/CommonFramework.h", "console",
"class CConsoleBase *");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgchar", "char");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgdouble", "double");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgfloat", "float");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgint", "int");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sglong", "long");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sglongdouble",
"long double");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgschar", "SCHAR");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgshort", "short");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgsint", "SINT");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgslong", "SLONG");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgslonglong",
"SLONGLONG");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgsshort", "SSHORT");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sguchar", "UCHAR");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sguint", "UINT");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgulong", "ULONG");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgulonglong",
"ULONGLONG");
setCUVariableInfo("BlackFlag_rvct.sym",
"/BlackFlag/SRC/dbg_simple_types.cpp", "sgushort", "USHORT");
setCUVariableInfo(
"HelloWorld_rvct_2_2.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/inc/ArmTestApplication.h",
"KUidArmTestApp", "const class TUid");
setCUVariableInfo(
"HelloWorld_rvct_2_2.exe.sym",
"/src/cedar/generic/base/e32/compsupp/symaehabi/callfirstprocessfn.cpp",
"KLitUser", "const class TLitC");
setCUVariableInfo(
"HelloWorld_rvct_2_2.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestAppUi.cpp",
"KFileName", "const class TLitC");
setCUVariableInfo(
"HelloWorld_rvct_2_2.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestAppUi.cpp",
"KText", "const class TLitC");
setCUVariableInfo(
"HelloWorld_rvct_4_0.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestApplication.cpp",
"KUidArmTestApp", "const struct TUid");
setCUVariableInfo(
"HelloWorld_rvct_4_0.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestDocument.cpp",
"mylit", "char[5]");
setCUVariableInfo(
"HelloWorld_rvct_4_0.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestAppUi.cpp",
"KFileName", "const struct TLitC");
setCUVariableInfo(
"HelloWorld_rvct_4_0.exe.sym",
"/home/eswartz/source/runtime-New_configuration/ArmTest/src/ArmTestAppUi.cpp",
"KText", "const struct TLitC");
setCUVariableInfo(
"HelloWorld_rvct_4_0.exe.sym",
"M:/dev2/sf/os/kernelhwsrv/kernel/eka/compsupp/symaehabi/callfirstprocessfn.cpp",
"KLitUser", "const struct TLitC");
setCUVariableInfo("QtConsole_gcce_343.sym",
"/Source/GCCE3/GCCE3/main.cpp", "myGlobalInt", "int");
}
protected static void setTypeCount(String sym, int i) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.numberOfTypes = i;
}
static {
setTypeCount("BlackFlagMinGW.exe", 1378);
setTypeCount("BlackFlag_gcce.sym", 3419);
setTypeCount("BlackFlag_linuxgcc.exe", 1104);
setTypeCount("BlackFlag_rvct.sym", 33708);
setTypeCount("HelloWorld_rvct_2_2.exe.sym", 84689);
setTypeCount("HelloWorld_rvct_4_0.exe.sym", 31565);
setTypeCount("QtConsole_gcce_343.sym", 1434);
}
protected static void setMainBlackFlagFilePath(String sym, String path) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.blackFlagMainFilePath = PathUtils.createPath(path);
}
static {
setMainBlackFlagFilePath("BlackFlagMinGW.exe",
"C:/wascana/workspace/BlackFlagWascana/src/BlackFlagWascana.cpp");
setMainBlackFlagFilePath("BlackFlag_gcce.sym",
"/BlackFlag/SRC/main.cpp");
setMainBlackFlagFilePath("BlackFlag_linuxgcc.exe",
"/mydisk/myprog/BlackFlag/src/BlackFlagWascana.cpp");
setMainBlackFlagFilePath("BlackFlag_rvct.sym",
"\\BlackFlag\\SRC\\main.cpp");
}
private static void setSymbolCount(String sym, int i) {
TestInfo info = lookupInfo(sym);
if (info != null)
info.numberOfSymbols = i;
}
static {
setSymbolCount("BlackFlagMinGW.exe", 2520);
setSymbolCount("BlackFlag_gcce.sym", 2941);
setSymbolCount("BlackFlag_linuxgcc.exe", 469);
setSymbolCount("BlackFlag_rvct.sym", 750);
setSymbolCount("HelloWorld_rvct_2_2.exe.sym", 194);
setSymbolCount("HelloWorld_rvct_4_0.exe.sym", 332);
setSymbolCount("QtConsole_gcce_343.sym", 1008);
}
protected static void setPubCount(String sym, int funcnames,
int funcentries, int varnames, int varentries) {
TestInfo info = lookupInfo(sym);
if (info != null) {
info.numberOfPubFuncNames = funcnames;
info.numberOfPubFuncEntries = funcentries;
info.numberOfPubVarNames = varnames;
info.numberOfPubVarEntries = varentries;
}
}
static {
setPubCount("BlackFlagMinGW.exe", 209, 241, 52, 52);
setPubCount("BlackFlag_gcce.sym", 217, 286, 87, 105);
setPubCount("BlackFlag_linuxgcc.exe", 174, 206, 48, 48);
setPubCount("BlackFlag_rvct.sym", 100, 101, 51, 87);
setPubCount("HelloWorld_rvct_2_2.exe.sym", 11, 14, 2, 4);
setPubCount("HelloWorld_rvct_4_0.exe.sym", 958, 978, 1, 1);
}
protected static void addPubFuncs(String sym, Object... names) {
TestInfo info = lookupInfo(sym);
if (info != null) {
for (Object o : names) {
info.pubFuncs.add(o.toString());
}
}
}
static {
addPubFuncs("BlackFlagMinGW.exe", "main", "dbg_watchpoints",
"Base01::~Base01");
addPubFuncs("BlackFlag_gcce.sym", "E32Main", "dbg_watchpoints",
"Base01::~Base01");
addPubFuncs("BlackFlag_gcce_343.sym", "E32Main", "dbg_watchpoints",
"Base01::~Base01");
addPubFuncs("BlackFlag_linuxgcc.exe", "main", "dbg_watchpoints",
"Base01::~Base01");
addPubFuncs("BlackFlag_rvct.sym", "E32Main", "dbg_watchpoints",
"globalDestructorFunc");
addPubFuncs("HelloWorld_rvct_2_2.exe.sym", "E32Main",
"CallThrdProcEntry", "CleanupClosePushL");
addPubFuncs("HelloWorld_rvct_4_0.exe.sym", "E32Main",
"CallThrdProcEntry", "CleanupClosePushL");
addPubFuncs("QtConsole_gcce_343.sym", "main", "__gxx_personality_v0",
"__gnu_unwind_frame");
}
protected static void addPubVars(String sym, Object... names) {
TestInfo info = lookupInfo(sym);
if (info != null) {
for (Object o : names) {
info.pubVars.add(o.toString());
}
}
}
static {
addPubVars("BlackFlagMinGW.exe", "vgushort", "gulong", "char_wp");
addPubVars("BlackFlag_gcce.sym", "vgushort", "gulong", "g_char");
addPubVars("BlackFlag_gcce_343.sym", "vgushort", "gulong", "g_char");
addPubVars("BlackFlag_linuxgcc.exe", "vgushort", "gulong", "gchar");
addPubVars("BlackFlag_rvct.sym", "vgushort", "gulong", "g_char");
addPubVars("HelloWorld_rvct_2_2.exe.sym", "mylit");
addPubVars("HelloWorld_rvct_4_0.exe.sym", "mylit");
addPubVars("QtConsole_gcce_343.sym", "myGlobalInt");
}
@Before
public void setup() throws Exception {
// each test relies on starting from scratch
Symbols.releaseReaderCache();
}
protected String getTypeName(IType type) {
return TypeUtils.getFullTypeName(type);
}
/**
* Get a low-level DWARF reader for the symbol reader for testing
* @param symbolReader
* @return
*/
protected DwarfDebugInfoProvider getDwarfDebugInfoProvider(
IEDCSymbolReader symbolReader) {
if (!(symbolReader instanceof EDCSymbolReader))
return null;
IDebugInfoProvider debugInfoProvider
= ((EDCSymbolReader) symbolReader).getDebugInfoProvider();
if (!(debugInfoProvider instanceof DwarfDebugInfoProvider))
return null;
DwarfDebugInfoProvider dip
= (DwarfDebugInfoProvider) debugInfoProvider;
// do initial parse (so forward types are detected)
DwarfInfoReader reader = new DwarfInfoReader(dip);
dip.setParsedInitially();
reader.parseInitial();
dip.setParsedForAddresses();
reader.parseForAddresses(true);
return dip;
}
/**
* @param symbolReader
*/
protected void readFully(IEDCSymbolReader symbolReader) {
IModuleScope moduleScope = symbolReader.getModuleScope();
moduleScope.getChildren();
moduleScope.getVariablesByName(null, false);
moduleScope.getVariablesByName(null, true);
moduleScope.getFunctionsByName(null);
moduleScope.getFunctionByName(null);
}
/**
* @param symbolReader
*/
protected void readRandomly(IEDCSymbolReader symbolReader) {
IModuleScope moduleScope = symbolReader.getModuleScope();
IAddress low = moduleScope.getLowAddress();
IAddress high = moduleScope.getHighAddress();
long range = high.getValue().subtract(low.getValue()).longValue();
assertTrue(range > 0);
Random random = new Random(0x120044ff);
for (int cnt = 0; cnt < 1000; cnt++) {
switch (random.nextInt() % 4) {
case 0: {
IAddress addr = low.add(random.nextLong() % range);
moduleScope.getScopeAtAddress(addr);
break;
}
case 1: {
ICompileUnitScope scope
= getRandomCU(symbolReader, random, true);
if (scope != null) {
long curange
= scope.getHighAddress()
.getValue()
.subtract(scope.getLowAddress().getValue())
.longValue();
IAddress addr
= scope.getLowAddress()
.add(random.nextLong() % curange);
scope.getFunctionAtAddress(addr);
}
break;
}
case 2: {
ICompileUnitScope scope
= getRandomCU(symbolReader, random, false);
if (scope != null) {
scope.getVariables();
}
break;
}
case 3: {
ICompileUnitScope scope
= getRandomCU(symbolReader, random, false);
if (scope != null) {
scope.getEnumerators();
}
break;
}
}
}
}
/**
* @param symbolReader
* @return
*/
protected ICompileUnitScope getRandomCU(IEDCSymbolReader symbolReader,
Random random, boolean withCode) {
String[] srcs = symbolReader.getSourceFiles();
int tries = 10;
Collection<ICompileUnitScope> scopes = null;
while (tries-- > 0) {
IPath src
= PathUtils.createPath(srcs[(random.nextInt() & 0xfffff)
% srcs.length]);
scopes = symbolReader.getModuleScope().getCompileUnitsForFile(src);
if (!scopes.isEmpty())
break;
}
if (scopes == null)
return null;
ICompileUnitScope last = null;
for (ICompileUnitScope scope : scopes) {
if (withCode) {
long curange
= scope.getHighAddress()
.getValue()
.subtract(scope.getLowAddress().getValue())
.longValue();
if (curange > 0) {
last = scope;
if (random.nextBoolean()) {
return scope;
}
}
}
else if (random.nextInt(5) == 0) {
return scope;
}
}
return last;
}
/**
* @return
*/
protected String describeScope(IScope scope) {
if (scope == null)
return "";
String myscope
= scope.getClass().getSimpleName() + "["
+ scope.getName() + "]";
return describeScope(scope.getParent()) + ": " + myscope;
}
/**
* @param name
* @return
*/
protected String stripName(String name) {
int idx = name.lastIndexOf(':');
if (idx > 0)
return name.substring(idx+1);
else
return name;
}
static class ScopeInfo {
int address;
String[] names;
public ScopeInfo(int address, String[] names) {
super();
this.address = address;
this.names = names;
}
}
protected static void addScopeVars(String sym, String srcFile,
String function, String className, int address, String... names) {
TestInfo info = lookupInfo(sym);
if (info != null) {
ScopeInfo scope = new ScopeInfo(address, names);
List<ScopeInfo> scopes;
String key = srcFile + "|" + function + "|" + className;
scopes = info.scopeInfos.get(key);
if (scopes == null) {
scopes = new ArrayList<ScopeInfo>();
info.scopeInfos.put(key, scopes);
}
scopes.add(scope);
}
}
static {
/*
* The address information for the unit test is gathered like this:
*
* 1) Find a function of interest, usually with DW_TAG_lexical_block
* entries inside DW_TAG_subroutine.
*
* 2) Add a PC for the entry point (DW_AT_low_pc for that subroutine).
* Usually DW_TAG_formal_parameter entries are live here. Any
* DW_TAG_variable entries with DW_AT_scope==0 (or unspecified) are also
* live.
*
* 3) Find some interesting points where lexical blocks open and add the
* variables from there.
*
* 4) Referencing the original source code is useful too, to avoid
* getting confused.
*
* 5) Finally, ALSO check the DW_AT_location entries for the variables.
* If it references a location list (rather than a static expression),
* then the compiler is indicating that the variable has a narrower
* scope than otherwise indicated. But, that location list may specify
* locations *outside* the advertised lexical block scope. So those
* should not be considered. Note that RVCT may have bogus lexical block
* ranges, but the location lists are useful. GCC-E, on the other hand,
* has better lexical block ranges, but never uses location lists.
*/
// RVCT has totally broken scope info; all lexical scopes go backwards,
// so
// we clamp them to the end of the function
// entry to function
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3e0);
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3e4, "stackArray");
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3ee, "stackArray" /* , "pstackArray" */);
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3f0, "stackArray", "pstackArray");
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3f0 + 2, "stackArray", "pstackArray");
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb3f4, "stackArray", "pstackArray", "i", "value");
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0xb40a, "stackArray", "pstackArray", "pheapArray",
"value");
// GCCE has valid scope info
// entry to function
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x10854);
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x1085a, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj");
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x10876, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj", "i");
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x108ac + 2, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj");
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x108b8 + 4, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj", "j");
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x108f2 + 2, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj", "k");
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x10970 + 2, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj", "m");
// show all variables at end of function, but not variable of last for
// loop scope
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x10a2a, "stackArray", "pstackArray", "value",
"pheapArray", "objArray", "pobj");
// but not past, in case instruction stepping at end of function
addScopeVars("BlackFlag_gcce.sym", "dbg_pointers.cpp", "ptrToArray",
null, 0x10a2a + 2);
// entry to function
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "arrayOfPtrs",
null, 0xb802);
addScopeVars("BlackFlag_rvct.sym", "dbg_pointers.cpp", "arrayOfPtrs",
null, 0xb808, "parray", "pClass2", "i");
// entry to function
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"dlist", 0xa82a, "this", "k");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"dlist", 0xa82e, "this", "k");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"dlist", 0xa830, "this", "found", "k", "search_node");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"dlist", 0xa83c, "this", "found", "k", "search_node",
"__result");
// entry to function
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"list", 0xa652, "this", "k");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"list", 0xa656, "this", "k");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"list", 0xa658, "this", "k", "found", "aux");
addScopeVars("BlackFlag_rvct.sym", "dbg_linked_lists.cpp", "find",
"list", 0xa666, "this", "k", "__result", "found", "aux");
// good lexical scopes here
// entry to function
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa07a, "this", "key");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa080, "this", "key",
"direction", "previous");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa082, "this", "key",
"direction", "previous");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa082, "this", "key",
"direction", "previous");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa092, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa098, "this", "key",
"__result", "direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa0f2, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa0f8, "this", "key",
"direction", "previous", "theNode", "subtree");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa11e, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa138, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa164, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa166, "this", "key",
"direction", "previous", "theNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa16c, "this", "key",
"direction", "previous", "theNode", "pcurrentNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa1ea, "this", "key",
"direction", "previous", "theNode", "next", "pcurrentNode");
addScopeVars("BlackFlag_rvct.sym", "dbg_binary_tree.cpp",
"DeleteFromTree", "binary_tree", 0xa21e, "this", "key",
"direction", "previous", "theNode");
// enty to function
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x8386, "this", "item");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x8394, "this", "item");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x8398, "this", "item", "newmax");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x83a6, "this", "item", "newmax", "copy");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x83a8, "this", "item", "newmax", "copy", "i");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x83b0, "this", "item", "newmax", "copy", "i");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x83bc, "this", "item", "newmax", "copy");
addScopeVars("SimpleCpp_rvct_22.sym", "Templates.h", "add", "List",
0x83cc);
// enty to function
addScopeVars("SimpleCpp_rvct_40.sym", "Templates.cpp", "add", "List",
0x835a, "this", "item", "__result$$1$$_Znaj");
addScopeVars("SimpleCpp_rvct_40.sym", "Templates.cpp", "add", "List",
0x836c, "this", "item", "newmax", "__result$$1$$_Znaj");
addScopeVars("SimpleCpp_rvct_40.sym", "Templates.cpp", "add", "List",
0x837a, "this", "item", "newmax", "copy", "__result$$1$$_Znaj");
addScopeVars("SimpleCpp_rvct_40.sym", "Templates.cpp", "add", "List",
0x837c, "this", "item", "newmax", "copy", "i",
"__result$$1$$_Znaj");
addScopeVars("SimpleCpp_rvct_40.sym", "Templates.cpp", "add", "List",
0x83a0, "this", "item", "__result$$1$$_Znaj");
// entry to function
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x80487a6, "this", "item");
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x80487c0, "this", "item", "newmax", "copy");
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x80487e9, "this", "item", "newmax", "copy", "i");
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x804881e + 1, "this", "item", "newmax", "copy");
// show all locals at end of function
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x8048854, "this", "item", "newmax", "copy");
// but not past
addScopeVars("SimpleCpp_gcc_x86.exe", "Templates.cpp", "add", "List",
0x8048854 + 1, "this", "item");
}
/**
*
*/
protected static class SymbolInfo {
public final String name;
public final String address;
public final long size;
public SymbolInfo(String name, String string, long size){
this.name = name;
this.address = string;
this.size = size;
}
@Override
public String toString(){
return name + ", " + address + ", " + size;
}
}
/**
* @param sym
* @param symbols
*/
protected static void addSymbols(String sym,SymbolInfo... symbols){
TestInfo info = lookupInfo(sym);
assertNotNull(info);
Collection<SymbolInfo> symInfos = info.symbols;
if (symInfos == null){
symInfos = new ArrayList<SymbolInfo>(symbols.length);
info.symbols = symInfos;
}
for (SymbolInfo symInfo : symbols){
symInfos.add(symInfo);
}
}
static {
addSymbols("BlackFlag_linuxgcc.exe",
new SymbolInfo("vgfloat", "08050300", 4),
new SymbolInfo("_Z6arraysv", "0804a09c", 629),
new SymbolInfo("_ZN4list14removeFromBackEv", "0804ac10", 102),
new SymbolInfo("_ZTI6DerDer", "0804dff4", 12),
new SymbolInfo("_GLOBAL__I_gchar", "08048864", 28));
addSymbols("SimpleCpp_gcc_x86.exe",
new SymbolInfo("dtor_idx.6637","0804a024",4),
new SymbolInfo("_Z41__static_initialization_and_destruction_0ii","0804853f",35),
new SymbolInfo("main","080485be",31),
new SymbolInfo("__libc_csu_fini","08048860",5),
new SymbolInfo("_ZN4ListIcE3addEc","08048602",174));
addSymbols("QtConsole_gcce_343.sym",
new SymbolInfo("KErrNone","00009188",4),
new SymbolInfo("KDriveAttRom","0000939c",4),
new SymbolInfo("_Z21base_of_encoded_valuehP15_Unwind_Context","00008290",116),
new SymbolInfo("next_unwind_byte","00008ae8",88),
new SymbolInfo("KLitUser","00009638",16),
//Address 14 rather than 15 due to ARM thumb bit
new SymbolInfo("RunThread","00008014",48));
}
/**
* @param scope
* @return
*/
protected String getClassFor(IFunctionScope scope) {
for (IVariable arg : scope.getParameters()) {
if (arg.getName().equals("this")) {
ICompositeType ct
= (ICompositeType) TypeUtils.getBaseType(arg.getType());
return ct.getName();
}
}
return null;
}
}