/* | |
* Copyright (c) 2010 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.Collection; | |
import java.util.HashMap; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols; | |
import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; | |
import org.eclipse.cdt.debug.edc.symbols.ISymbol; | |
import org.eclipse.cdt.utils.Addr32; | |
import org.eclipse.core.runtime.IPath; | |
import org.junit.Test; | |
/** | |
* Note: several tests are implied by TestDwarfReader | |
*/ | |
public class TestExecutableReader 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", | |
"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 { | |
IPath symFile; | |
IPath exeFile; | |
Map<String, SymLookupInfo> symToFuncAddrMap = new HashMap<String,SymLookupInfo>(); | |
} | |
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); | |
} | |
static class SymLookupInfo { | |
boolean isMangled; | |
int addr; | |
@Override | |
public String toString() { | |
return "mangled="+isMangled+"; addr="+Integer.toHexString(addr); | |
} | |
} | |
private static void addSymbolAddr(String sym, String symbol, boolean isMangled, int addr) { | |
TestInfo info = lookupInfo(sym); | |
if (info != null) { | |
SymLookupInfo si = new SymLookupInfo(); | |
si.isMangled = isMangled; | |
si.addr = addr; | |
info.symToFuncAddrMap.put(symbol, si); | |
} | |
} | |
static { | |
addSymbolAddr("BlackFlagMinGW.exe", "_mainCRTStartup", true, 0x401130); | |
addSymbolAddr("BlackFlagMinGW.exe", "mainCRTStartup", false, 0x401130); | |
addSymbolAddr("BlackFlagMinGW.exe", "_main", true, 0x40663d); | |
addSymbolAddr("BlackFlagMinGW.exe", "_main", false, 0x40663d); | |
addSymbolAddr("BlackFlagMinGW.exe", "main", false, 0x40663d); | |
addSymbolAddr("BlackFlag_gcce.sym", "_Z7E32Mainv", true, 0x80a0); | |
addSymbolAddr("BlackFlag_gcce.sym", "E32Main", false, 0x80a0); | |
addSymbolAddr("BlackFlag_gcce.sym", "::E32Main", false, 0x80a0); | |
addSymbolAddr("BlackFlag_gcce.sym", "E32Main()", false, 0x80a0); | |
addSymbolAddr("BlackFlag_linuxgcc.exe", "main", false, 0x8048880); | |
addSymbolAddr("BlackFlag_rvct.sym", "_Z7E32Mainv", true, 0x849c); | |
addSymbolAddr("BlackFlag_rvct.sym", "E32Main", false, 0x849c); | |
addSymbolAddr("BlackFlag_rvct.sym", "E32Main()", false, 0x849c); | |
addSymbolAddr("BlackFlag_rvct.sym", "::E32Main()", false, 0x849c); | |
addSymbolAddr("BlackFlag_rvct.sym", "::E32Main", false, 0x849c); | |
addSymbolAddr("HelloWorld_rvct_2_2.exe.sym", "_E32Startup", true, 0x8000); | |
addSymbolAddr("HelloWorld_rvct_2_2.exe.sym", "_E32Startup", false, 0x8000); | |
addSymbolAddr("HelloWorld_rvct_2_2.exe.sym", "::_E32Startup", false, 0x8000); | |
addSymbolAddr("HelloWorld_rvct_4_0.exe.sym", "_Z7E32Mainv", true, 0x82ea); | |
addSymbolAddr("HelloWorld_rvct_4_0.exe.sym", "E32Main", false, 0x82ea); | |
addSymbolAddr("HelloWorld_rvct_4_0.exe.sym", "::E32Main()", false, 0x82ea); | |
} | |
@Test | |
public void testLookupOfSymbol() throws Exception { | |
for (TestInfo info : testInfos.values()) { | |
if (info.symToFuncAddrMap == null) continue; | |
IEDCSymbolReader reader = Symbols.getSymbolReader(info.symFile); | |
assertNotNull("Symbol reader null for: " + info.symFile, reader); | |
for (Map.Entry<String, SymLookupInfo> entry : info.symToFuncAddrMap.entrySet()) { | |
SymLookupInfo si = entry.getValue(); | |
String label = info.symFile.lastSegment() + ":" + entry.getKey() + ":" + si; | |
doLookupSymbol(reader, entry, si, label); | |
} | |
} | |
} | |
/** | |
* @param reader | |
* @param entry | |
* @param si | |
* @param label | |
*/ | |
private void doLookupSymbol(IEDCSymbolReader reader, | |
Map.Entry<String, SymLookupInfo> entry, SymLookupInfo si, | |
String label) { | |
Collection<ISymbol> symbols; | |
if (!si.isMangled) { | |
// should find after unmangling | |
symbols = reader.findUnmangledSymbols(entry.getKey()); | |
assertEquals(label, 1, symbols.size()); | |
} else { | |
// should match mangled symbol | |
symbols = reader.findSymbols(entry.getKey()); | |
assertEquals(label, 1, symbols.size()); | |
} | |
assertEquals(label, new Addr32(si.addr), | |
symbols.iterator().next().getAddress()); | |
} | |
} |