mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-22 22:02:52 +08:00
Merge remote-tracking branch 'origin/GP-899_ghizard_PDB_initial_managed_code_work--SQUASHED'
This commit is contained in:
+5
-6
@@ -255,10 +255,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
PdbProgramAttributes programAttributes = new PdbProgramAttributes(program);
|
||||
if (programAttributes.isPdbLoaded()) {
|
||||
Msg.info(this, "Skipping PDB analysis since it has previouslu run.");
|
||||
Msg.info(this,
|
||||
">> Clear 'PDB Loaded' program property or use Load PDB action if " +
|
||||
"additional PDB processing required.");
|
||||
Msg.info(this, "Skipping PDB analysis since it has previously run.");
|
||||
Msg.info(this, ">> Clear 'PDB Loaded' program property or use Load PDB action if " +
|
||||
"additional PDB processing required.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -361,8 +360,8 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
options.registerOption(OPTION_NAME_FORCELOAD_FILE, OptionType.FILE_TYPE,
|
||||
DEFAULT_FORCE_LOAD_FILE, null, OPTION_DESCRIPTION_FORCELOAD_FILE);
|
||||
}
|
||||
options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE,
|
||||
symbolsRepositoryDir, null, OPTION_DESCRIPTION_SYMBOLPATH);
|
||||
options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE, symbolsRepositoryDir,
|
||||
null, OPTION_DESCRIPTION_SYMBOLPATH);
|
||||
options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null,
|
||||
OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH);
|
||||
|
||||
|
||||
+1
-3
@@ -23,7 +23,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
/**
|
||||
* Metrics captured during the parsing and interpreting of a PDB. This is a Ghidra class
|
||||
* separate from the PDB API that we have crafted to help us quantify and qualify metatdata
|
||||
* about the PDB.
|
||||
* about the PDB.
|
||||
*/
|
||||
public class PdbReaderMetrics {
|
||||
|
||||
@@ -919,8 +919,6 @@ public class PdbReaderMetrics {
|
||||
// Not sure what to do here. What are records in this range?
|
||||
// Worse is when it was originally a TYPE with high bit set. Why would it
|
||||
// just not be given a non-set high bit if primitive.
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
//witnessPrimitive(recordNumber.getNumber());
|
||||
}
|
||||
break;
|
||||
|
||||
+101
-1
@@ -23,7 +23,8 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
* Note: we do not necessarily understand each of these symbol type classes. Refer to the
|
||||
* base class for more information.
|
||||
*/
|
||||
public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol {
|
||||
public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol
|
||||
implements AddressMsSymbol, NameMsSymbol {
|
||||
|
||||
protected long parentPointer;
|
||||
protected long endPointer;
|
||||
@@ -79,4 +80,103 @@ public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol
|
||||
builder.append(String.format(" Return Reg: %s\n", registerContainingReturnValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent pointer.
|
||||
* @return Parent pointer.
|
||||
*/
|
||||
public long getParentPointer() {
|
||||
return parentPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end pointer.
|
||||
* @return End pointer.
|
||||
*/
|
||||
public long getEndPointer() {
|
||||
return endPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next pointer.
|
||||
* @return next pointer.
|
||||
*/
|
||||
public long getNextPointer() {
|
||||
return nextPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the procedure length.
|
||||
* @return Length.
|
||||
*/
|
||||
public long getProcedureLength() {
|
||||
return procedureLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the debug start offset.
|
||||
* @return Debug start offset.
|
||||
*/
|
||||
public long getDebugStartOffset() {
|
||||
return debugStartOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the debug end offset.
|
||||
* @return Debug end offset.
|
||||
*/
|
||||
public long getDebugEndOffset() {
|
||||
return debugEndOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset.
|
||||
* @return Offset.
|
||||
*/
|
||||
@Override
|
||||
public long getOffset() {
|
||||
return symbolOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the segment.
|
||||
* @return Segment.
|
||||
*/
|
||||
@Override
|
||||
public int getSegment() {
|
||||
return symbolSegment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ProcedureFlags}.
|
||||
* @return Procedure flags.
|
||||
*/
|
||||
public ProcedureFlags getFlags() {
|
||||
return procedureFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the procedure name.
|
||||
* @return Name.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token.
|
||||
* @return token.
|
||||
*/
|
||||
public long getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the register containing the return value
|
||||
* @return the register.
|
||||
*/
|
||||
public RegisterName getReturnRegister() {
|
||||
return registerContainingReturnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-1
@@ -58,10 +58,20 @@ public class BlockSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
@Override
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
Address address = applicator.getAddress(symbol);
|
||||
if (applierParam instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||
Address address = applicator.getAddress(symbol);
|
||||
functionSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
||||
}
|
||||
else if (applierParam instanceof SeparatedCodeSymbolApplier) {
|
||||
SeparatedCodeSymbolApplier separatedCodeSymbolApplier =
|
||||
(SeparatedCodeSymbolApplier) applierParam;
|
||||
separatedCodeSymbolApplier.beginBlock(address);
|
||||
}
|
||||
else if (applierParam instanceof ManagedProcedureSymbolApplier) {
|
||||
ManagedProcedureSymbolApplier procedureSymbolApplier =
|
||||
(ManagedProcedureSymbolApplier) applierParam;
|
||||
procedureSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-22
@@ -309,7 +309,7 @@ public class CppCompositeType {
|
||||
* These "insert" methods should be used judiciously. You need to know what/why you are doing
|
||||
* this. Changing the order of "normal" members can mess up the layout algorithms from
|
||||
* {@link DefaultCompositeMember}. The only place we currently think we can use these is
|
||||
* when trying to place vbptr members. Not all of these methods are used too.
|
||||
* when trying to place vbptr members. Not all of these methods are used too.
|
||||
* @param isFlexibleArray TODO
|
||||
*/
|
||||
public void insertMember(String memberName, DataType dataType, boolean isFlexibleArray,
|
||||
@@ -583,8 +583,7 @@ public class CppCompositeType {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public ObjectOrientedClassLayout getLayout(
|
||||
ObjectOrientedClassLayout layoutOptions) {
|
||||
public ObjectOrientedClassLayout getLayout(ObjectOrientedClassLayout layoutOptions) {
|
||||
if (classLayout == null) {
|
||||
classLayout = determineClassLayout(layoutOptions);
|
||||
}
|
||||
@@ -644,8 +643,8 @@ public class CppCompositeType {
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------
|
||||
public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions,
|
||||
VbtManager vbtManager, TaskMonitor monitor) throws PdbException, CancelledException {
|
||||
public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions, VbtManager vbtManager,
|
||||
TaskMonitor monitor) throws PdbException, CancelledException {
|
||||
CategoryPath cn;
|
||||
hasDirect = false;
|
||||
switch (getLayout(layoutOptions)) {
|
||||
@@ -699,8 +698,7 @@ public class CppCompositeType {
|
||||
}
|
||||
directClassLength = getCompositeLength(directDataType);
|
||||
}
|
||||
if (getLayout(
|
||||
layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||
if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||
// Not using the dummy/direct type (only used it to get the
|
||||
// directClassLength), so remove it and add the members to the main
|
||||
// type instead.
|
||||
@@ -836,8 +834,7 @@ public class CppCompositeType {
|
||||
}
|
||||
directClassLength = getCompositeLength(directDataType);
|
||||
}
|
||||
if (getLayout(
|
||||
layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||
if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||
// Not using the dummy/direct type (only used it to get the
|
||||
// directClassLength), so remove it and add the members to the main
|
||||
// type instead.
|
||||
@@ -947,8 +944,6 @@ public class CppCompositeType {
|
||||
throws PdbException {
|
||||
if (placeholderVirtualBaseTables.size() > 1) {
|
||||
// study this.
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
}
|
||||
|
||||
boolean allVbtFound = true;
|
||||
@@ -957,8 +952,6 @@ public class CppCompositeType {
|
||||
PlaceholderVirtualBaseTable table = tableEntry.getValue();
|
||||
if (!table.validateOffset()) {
|
||||
// TODO study this.
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
}
|
||||
DataType vbptr = getVbptrDataType(dtm, vbtManager, table);
|
||||
allVbtFound &=
|
||||
@@ -1153,7 +1146,7 @@ public class CppCompositeType {
|
||||
// // If last base is empty, then its comment and any accumulated to this point
|
||||
// // will not be seen (not applied to a PdbMember). TODO: Consider options,
|
||||
// // though we know we have left it in this state and are OK with it for now.
|
||||
// // We have not considered fall-out from this.
|
||||
// // We have not considered fall-out from this.
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1201,7 +1194,7 @@ public class CppCompositeType {
|
||||
// If last base is empty, then its comment and any accumulated to this point
|
||||
// will not be seen (not applied to a PdbMember). TODO: Consider options,
|
||||
// though we know we have left it in this state and are OK with it for now.
|
||||
// We have not considered fall-out from this.
|
||||
// We have not considered fall-out from this.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1260,7 +1253,7 @@ public class CppCompositeType {
|
||||
// If last base is empty, then its comment and any accumulated to this point
|
||||
// will not be seen (not applied to a PdbMember). TODO: Consider options,
|
||||
// though we know we have left it in this state and are OK with it for now.
|
||||
// We have not considered fall-out from this.
|
||||
// We have not considered fall-out from this.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1314,7 +1307,7 @@ public class CppCompositeType {
|
||||
return new CategoryPath(cn, baseName);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// TODO:
|
||||
// Taken from PdbUtil without change. Would have had to change access on class PdbUtil and
|
||||
// this ensureSize method to public to make it accessible. Can revert to using PdbUtil
|
||||
// once we move this new module from Contrib to Features/PDB.
|
||||
@@ -1352,8 +1345,7 @@ public class CppCompositeType {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
ObjectOrientedClassLayout getLayoutMode(
|
||||
ObjectOrientedClassLayout layoutOptions) {
|
||||
ObjectOrientedClassLayout getLayoutMode(ObjectOrientedClassLayout layoutOptions) {
|
||||
return baseClassType.getLayout(layoutOptions);
|
||||
}
|
||||
|
||||
@@ -1391,7 +1383,7 @@ public class CppCompositeType {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// Syntactic description of base classes.
|
||||
// Syntactic description of base classes.
|
||||
//----------------------------------------------------------------------------------------------
|
||||
private class SyntacticBaseClass extends BaseClass {
|
||||
private SyntacticBaseClass(CppCompositeType baseClassType,
|
||||
@@ -1430,8 +1422,7 @@ public class CppCompositeType {
|
||||
|
||||
Structure getLayout() {
|
||||
if (layout == null) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
// consider what to do here...
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
+5
@@ -69,5 +69,10 @@ public class EndSymbolApplier extends MsSymbolApplier {
|
||||
(SeparatedCodeSymbolApplier) applierParam;
|
||||
separatedCodeSymbolApplier.endBlock();
|
||||
}
|
||||
else if (applierParam instanceof ManagedProcedureSymbolApplier) {
|
||||
ManagedProcedureSymbolApplier procedureSymbolApplier =
|
||||
(ManagedProcedureSymbolApplier) applierParam;
|
||||
procedureSymbolApplier.endBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -129,8 +129,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
||||
|
||||
// MsProperty property = type.getMsProperty();
|
||||
// if (property.isForwardReference()) {
|
||||
// int a = 1;
|
||||
// a = a + 1;
|
||||
// // investigate this
|
||||
// }
|
||||
//// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
||||
//// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
||||
@@ -158,7 +157,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
||||
// //TODO: can we set isSigned in here? ((PrimitiveMsType) underlying)
|
||||
// // TODO: there might be more
|
||||
// // TODO: investigate getSize() on AbstractMsType?
|
||||
// // then: length = underlying.getSize();
|
||||
// // then: length = underlying.getSize();
|
||||
// }
|
||||
// }
|
||||
// // Ghidra does not like size of zero.
|
||||
@@ -227,8 +226,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
||||
// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
||||
// MsProperty property = type.getMsProperty();
|
||||
// if (property.isForwardReference()) {
|
||||
// int a = 1;
|
||||
// a = a + 1;
|
||||
// // investigate this
|
||||
// }
|
||||
// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
||||
//
|
||||
@@ -248,7 +246,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
||||
// length = ((PrimitiveMsType) underlying).getTypeSize();
|
||||
// // TODO: there might be more
|
||||
// // TODO: investigate getSize() on AbstractMsType?
|
||||
// // then: length = underlying.getSize();
|
||||
// // then: length = underlying.getSize();
|
||||
// }
|
||||
// }
|
||||
// // Ghidra does not like size of zero.
|
||||
|
||||
+506
File diff suppressed because it is too large
Load Diff
+28
-8
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
@@ -26,6 +25,7 @@ import ghidra.app.util.bin.format.pdb.PdbParserConstants;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.pdb.PdbCategories;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
@@ -123,6 +123,8 @@ public class PdbApplicator {
|
||||
private PdbAddressManager pdbAddressManager;
|
||||
private List<SymbolGroup> symbolGroups;
|
||||
|
||||
private PdbCliInfoManager pdbCliManagedInfoManager;
|
||||
|
||||
//==============================================================================================
|
||||
// If we have symbols and memory with VBTs in them, then a better VbtManager is created.
|
||||
VbtManager vbtManager;
|
||||
@@ -140,7 +142,7 @@ public class PdbApplicator {
|
||||
* <PRE>
|
||||
* false = simple namespace
|
||||
* true = class namespace
|
||||
* </PRE>
|
||||
* </PRE>
|
||||
*/
|
||||
private Map<SymbolPath, Boolean> isClassByNamespace;
|
||||
|
||||
@@ -309,6 +311,9 @@ public class PdbApplicator {
|
||||
pdbApplicatorMetrics = new PdbApplicatorMetrics();
|
||||
|
||||
pdbAddressManager = new PdbAddressManager(this, imageBase);
|
||||
|
||||
pdbCliManagedInfoManager = new PdbCliInfoManager(this);
|
||||
|
||||
symbolGroups = createSymbolGroups();
|
||||
|
||||
categoryUtils = setPdbCatogoryUtils(pdbFilename);
|
||||
@@ -414,6 +419,14 @@ public class PdbApplicator {
|
||||
log.appendMsg(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MessageLog.
|
||||
* @return the MessageLog
|
||||
*/
|
||||
MessageLog getMessageLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts message to {@link PdbLog} and to Msg.info()
|
||||
* @param originator a Logger instance, "this", or YourClass.class
|
||||
@@ -470,7 +483,7 @@ public class PdbApplicator {
|
||||
// Information for a putative PdbTypeApplicator:
|
||||
|
||||
/**
|
||||
* Returns the {@link DataTypeManager} associated with this analyzer.
|
||||
* Returns the {@link DataTypeManager} associated with this analyzer.
|
||||
* @return DataTypeManager which this analyzer is using.
|
||||
*/
|
||||
DataTypeManager getDataTypeManager() {
|
||||
@@ -502,8 +515,8 @@ public class PdbApplicator {
|
||||
|
||||
/**
|
||||
* Returns the {@link CategoryPath} for a typedef with with the give {@link SymbolPath} and
|
||||
* module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()},
|
||||
* except that modeleNumber of 0 represents publics/globals.
|
||||
* module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()},
|
||||
* except that modeleNumber of 0 represents publics/globals.
|
||||
* @param moduleNumber module number
|
||||
* @param symbolPath SymbolPath of the symbol
|
||||
* @return the CategoryPath
|
||||
@@ -910,6 +923,13 @@ public class PdbApplicator {
|
||||
pdbAddressManager.addMemorySectionRefinement(symbol);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// CLI-Managed infor methods.
|
||||
//==============================================================================================
|
||||
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
|
||||
return pdbCliManagedInfoManager.getCliTableRow(tableNum, rowNum);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// Virtual-Base-Table-related methods.
|
||||
//==============================================================================================
|
||||
@@ -918,7 +938,7 @@ public class PdbApplicator {
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
//
|
||||
//
|
||||
//==============================================================================================
|
||||
Register getRegister(String pdbRegisterName) {
|
||||
return registerNameToRegisterMapper.getRegister(pdbRegisterName);
|
||||
@@ -1140,7 +1160,7 @@ public class PdbApplicator {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
appendLogMsg("Not processing linker symbols because linker module not found");
|
||||
pdbLogAndInfoMessage(this, "Not processing linker symbols because linker module not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import generic.continues.GenericFactory;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.bin.MemoryByteProvider;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pe.*;
|
||||
import ghidra.app.util.bin.format.pe.PortableExecutable.SectionLayout;
|
||||
import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
|
||||
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTable;
|
||||
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow;
|
||||
import ghidra.app.util.importer.MessageLogContinuesFactory;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* Manages CLI-Managed information, the bounds of which we do not yet know.
|
||||
*/
|
||||
public class PdbCliInfoManager {
|
||||
|
||||
private CliStreamMetadata metadataStream;
|
||||
|
||||
/**
|
||||
* Manager of CLI-related tables that we might need access to for PDB processing.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
*/
|
||||
PdbCliInfoManager(PdbApplicator applicator) {
|
||||
Objects.requireNonNull(applicator, "applicator may not be null");
|
||||
metadataStream = getCliStreamMetadata(applicator);
|
||||
}
|
||||
|
||||
public CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
|
||||
if (metadataStream == null) {
|
||||
throw new PdbException("CliStreamMetadata is null");
|
||||
}
|
||||
CliAbstractTable table = metadataStream.getTable(tableNum);
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
return table.getRow(rowNum);
|
||||
}
|
||||
|
||||
private CliStreamMetadata getCliStreamMetadata(PdbApplicator applicator) {
|
||||
Program program = applicator.getProgram();
|
||||
if (program == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteProvider provider = new MemoryByteProvider(program.getMemory(), program.getImageBase());
|
||||
PortableExecutable pe = null;
|
||||
try {
|
||||
GenericFactory factory = MessageLogContinuesFactory.create(applicator.getMessageLog());
|
||||
pe = PortableExecutable.createPortableExecutable(factory, provider,
|
||||
SectionLayout.MEMORY, true, true);
|
||||
NTHeader ntHeader = pe.getNTHeader();
|
||||
OptionalHeader optionalHeader = ntHeader.getOptionalHeader();
|
||||
DataDirectory[] dataDirectory = optionalHeader.getDataDirectories();
|
||||
COMDescriptorDataDirectory comDir =
|
||||
(COMDescriptorDataDirectory) dataDirectory[OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
|
||||
ImageCor20Header header = comDir.getHeader();
|
||||
return header.getMetadata().getMetadataRoot().getMetadataStream();
|
||||
}
|
||||
catch (Exception e) {
|
||||
applicator.pdbLogAndInfoMessage(this, "Unable to retrieve CliStreamMetadata");
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
provider.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
applicator.pdbLogAndInfoMessage(this, "Problem closing ByteProvider");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
-35
@@ -44,10 +44,16 @@ public class PdbResearch {
|
||||
private static Set<Integer> developerDebugOrderIndexNumbers;
|
||||
|
||||
//==============================================================================================
|
||||
// This method exists so we can place breakpoints on call locations to it wherever we
|
||||
// would like to break during debugging.
|
||||
private static void doNothingSetBreakPointHere() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to populate debugIndexNumbers set that gets used by
|
||||
* {@link #checkBreak(int recordNumber)} in which we set a breakpoint on {@code int a = 1;} to
|
||||
* then allow us to debug into other code.
|
||||
* {@link #checkBreak(int recordNumber)} in which we set a breakpoint on
|
||||
* {@code #doNothingSetBreakPointHere();} to then allow us to debug into other code.
|
||||
*/
|
||||
static void initBreakPointRecordNumbers() {
|
||||
debugIndexNumbers = new TreeSet<>();
|
||||
@@ -284,28 +290,28 @@ public class PdbResearch {
|
||||
// debugIndexNumbers.add(6236); // fwdref is 6168
|
||||
//
|
||||
// // member of 6236
|
||||
// debugIndexNumbers.add(6251); // fwdref is 6220
|
||||
// debugIndexNumbers.add(6251); // fwdref is 6220
|
||||
//
|
||||
// // member of 6251
|
||||
// debugIndexNumbers.add(6263); // fwdref is 6237
|
||||
//
|
||||
// // base class / member of 6263
|
||||
// debugIndexNumbers.add(6284); // fwdref is 6252
|
||||
// debugIndexNumbers.add(6284); // fwdref is 6252
|
||||
//
|
||||
// // base class / member of 6284
|
||||
// debugIndexNumbers.add(6328); // fwdref is 6264
|
||||
// debugIndexNumbers.add(6328); // fwdref is 6264
|
||||
//
|
||||
// // member of 6328
|
||||
// debugIndexNumbers.add(6335); // fwdref is 6285
|
||||
// debugIndexNumbers.add(6335); // fwdref is 6285
|
||||
//
|
||||
// // base class of 6335
|
||||
// debugIndexNumbers.add(6341); // fwdref is 6329
|
||||
// debugIndexNumbers.add(6341); // fwdref is 6329
|
||||
}
|
||||
|
||||
/**
|
||||
* Developmental method for breakpoints. TODO: will delete this from production.
|
||||
* Set breakpoint on {@code int a = 1;}
|
||||
* @param recordNumber the record number tha is being processed (set negative to ignore)
|
||||
* Set breakpoint on {@code #doNothingSetBreakPointHere();}
|
||||
* @param recordNumber the record number that is being processed (set negative to ignore)
|
||||
* <p>
|
||||
* This code is useful for developer debugging because the PDB is records-based and we often
|
||||
* need to set breakpoints elsewhere, determine what RecordNumber we are interested in, and
|
||||
@@ -315,8 +321,7 @@ public class PdbResearch {
|
||||
*/
|
||||
static void checkBreak(int recordNumber) {
|
||||
if (debugIndexNumbers.contains(recordNumber)) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,16 +336,13 @@ public class PdbResearch {
|
||||
String nn = applier.getMsType().getName();
|
||||
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>".equals(
|
||||
nn)) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
if ("class std::__1::__iostream_category".equals(nn)) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
if ("std::__1::__do_message".equals(nn)) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
|
||||
//checkBreak(recordNumber);
|
||||
@@ -445,9 +447,10 @@ public class PdbResearch {
|
||||
}
|
||||
else if (applier instanceof ReferenceSymbolApplier) {
|
||||
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
|
||||
SymbolGroup refSymbolGroup = refSymbolApplier.getInitializedReferencedSymbolGroup();
|
||||
AbstractMsSymbolIterator refIter =
|
||||
refSymbolApplier.getInitializedReferencedSymbolGroupIterator();
|
||||
// recursion
|
||||
childWalkSym(applicator, refSymbolGroup.getModuleNumber(), refSymbolGroup.iterator());
|
||||
childWalkSym(applicator, refIter.getModuleNumber(), refIter);
|
||||
}
|
||||
else if (applier instanceof DataSymbolApplier) {
|
||||
DataSymbolApplier dataSymbolApplier = (DataSymbolApplier) applier;
|
||||
@@ -464,19 +467,16 @@ public class PdbResearch {
|
||||
// ConstantSymbolApplier constantSymbolApplier = (ConstantSymbolApplier) applier;
|
||||
// }
|
||||
else {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
static private boolean childWalkType(int moduleNumber, MsTypeApplier applier) {
|
||||
int b = 1;
|
||||
b = b + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
if (applier instanceof AbstractFunctionTypeApplier) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -861,21 +861,18 @@ public class PdbResearch {
|
||||
p = compType.getMsProperty();
|
||||
isForwardReference = p.isForwardReference();
|
||||
if (c == 0 && !isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
// For PDBs that we have looked at, if count is zero
|
||||
// for a forward reference, then the field list record number is zero;
|
||||
// if count is zero for a definition, then, the field list record
|
||||
// number refers to an actual field list.
|
||||
// So... seems we can trust forward reference and ignore count.
|
||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||
int b = 1;
|
||||
b = b + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
}
|
||||
else if (c != 0 && isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
||||
}
|
||||
@@ -916,13 +913,11 @@ public class PdbResearch {
|
||||
// list. So... seems we can trust forward reference and
|
||||
// ignore count.
|
||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
}
|
||||
else if (c != 0 && isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
doNothingSetBreakPointHere();
|
||||
}
|
||||
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
||||
}
|
||||
|
||||
+1
-2
@@ -135,8 +135,7 @@ public class PdbVbtManager extends VbtManager {
|
||||
vbtByAddress.put(address, vbt);
|
||||
}
|
||||
if (!(vbt instanceof PdbVirtualBaseTable)) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
// investigate this
|
||||
}
|
||||
return (PdbVirtualBaseTable) vbt;
|
||||
}
|
||||
|
||||
+3
-3
@@ -52,15 +52,15 @@ public class ReferenceSymbolApplier extends MsSymbolApplier {
|
||||
@Override
|
||||
void apply() throws CancelledException, PdbException {
|
||||
// Potential recursive call via applicator.procSym().
|
||||
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroup().iterator();
|
||||
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator();
|
||||
applicator.procSym(refIter);
|
||||
}
|
||||
|
||||
SymbolGroup getInitializedReferencedSymbolGroup() {
|
||||
AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() {
|
||||
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
|
||||
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
|
||||
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
|
||||
return refSymbolGroup;
|
||||
return refIter;
|
||||
}
|
||||
|
||||
SymbolGroup getReferencedSymbolGroup() {
|
||||
|
||||
+2
-4
@@ -129,17 +129,15 @@ public class SeparatedCodeSymbolApplier extends MsSymbolApplier {
|
||||
return (symbolBlockNestingLevel > 0) && iter.hasNext();
|
||||
}
|
||||
|
||||
int endBlock() {
|
||||
void endBlock() {
|
||||
if (--symbolBlockNestingLevel < 0) {
|
||||
applicator.appendLogMsg("Block Nesting went negative at " + specifiedAddress);
|
||||
}
|
||||
return symbolBlockNestingLevel;
|
||||
}
|
||||
|
||||
private int beginBlock(Address startAddress) {
|
||||
void beginBlock(Address startAddress) {
|
||||
currentBlockAddress = startAddress;
|
||||
++symbolBlockNestingLevel;
|
||||
return symbolBlockNestingLevel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-12
@@ -282,12 +282,12 @@ public class SymbolApplierFactory {
|
||||
// case AnnotationMsSymbol.PDB_ID:
|
||||
// symbol = new AnnotationMsSymbol(pdb, reader);
|
||||
// break;
|
||||
// case GlobalManagedProcedureStMsSymbol.PDB_ID:
|
||||
// symbol = new GlobalManagedProcedureStMsSymbol(pdb, reader);
|
||||
// break;
|
||||
// case LocalManagedProcedureStMsSymbol.PDB_ID:
|
||||
// symbol = new LocalManagedProcedureStMsSymbol(pdb, reader);
|
||||
// break;
|
||||
case GlobalManagedProcedureStMsSymbol.PDB_ID:
|
||||
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||
break;
|
||||
case LocalManagedProcedureStMsSymbol.PDB_ID:
|
||||
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||
break;
|
||||
// case Reserved1MsSymbol.PDB_ID:
|
||||
// symbol = new Reserved1MsSymbol(pdb, reader);
|
||||
// break;
|
||||
@@ -455,12 +455,12 @@ public class SymbolApplierFactory {
|
||||
case TokenReferenceToManagedProcedureMsSymbol.PDB_ID:
|
||||
applier = new ReferenceSymbolApplier(applicator, iter);
|
||||
break;
|
||||
// case GlobalManagedProcedureMsSymbol.PDB_ID:
|
||||
// symbol = new GlobalManagedProcedureMsSymbol(pdb, reader);
|
||||
// break;
|
||||
// case LocalManagedProcedureMsSymbol.PDB_ID:
|
||||
// symbol = new LocalManagedProcedureMsSymbol(pdb, reader);
|
||||
// break;
|
||||
case GlobalManagedProcedureMsSymbol.PDB_ID:
|
||||
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||
break;
|
||||
case LocalManagedProcedureMsSymbol.PDB_ID:
|
||||
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||
break;
|
||||
case TrampolineMsSymbol.PDB_ID:
|
||||
applier = new TrampolineSymbolApplier(applicator, iter);
|
||||
break;
|
||||
|
||||
+10
-10
@@ -150,17 +150,17 @@ public class SymbolGroup {
|
||||
*/
|
||||
class AbstractMsSymbolIterator implements Iterator<AbstractMsSymbol> {
|
||||
|
||||
private int currentIndex;
|
||||
private int nextIndex;
|
||||
private long currentOffset;
|
||||
|
||||
public AbstractMsSymbolIterator() {
|
||||
currentIndex = 0;
|
||||
currentOffset = 0L;
|
||||
nextIndex = 0;
|
||||
currentOffset = -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (currentIndex == offsets.size()) {
|
||||
if (nextIndex == offsets.size()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -175,10 +175,10 @@ public class SymbolGroup {
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
public AbstractMsSymbol peek() throws NoSuchElementException {
|
||||
if (currentIndex == offsets.size()) {
|
||||
if (nextIndex == offsets.size()) {
|
||||
throw new NoSuchElementException("none left");
|
||||
}
|
||||
long temporaryOffset = offsets.get(currentIndex);
|
||||
long temporaryOffset = offsets.get(nextIndex);
|
||||
AbstractMsSymbol symbol = symbolsByOffset.get(temporaryOffset);
|
||||
if (symbol == null) {
|
||||
throw new NoSuchElementException("No symbol");
|
||||
@@ -188,10 +188,10 @@ public class SymbolGroup {
|
||||
|
||||
@Override
|
||||
public AbstractMsSymbol next() {
|
||||
if (currentIndex == offsets.size()) {
|
||||
if (nextIndex == offsets.size()) {
|
||||
throw new NoSuchElementException("none left");
|
||||
}
|
||||
currentOffset = offsets.get(currentIndex++);
|
||||
currentOffset = offsets.get(nextIndex++);
|
||||
return symbolsByOffset.get(currentOffset);
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public class SymbolGroup {
|
||||
* @see #hasNext()
|
||||
*/
|
||||
void initGet() {
|
||||
currentIndex = 0;
|
||||
nextIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,7 +224,7 @@ public class SymbolGroup {
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
currentIndex = index;
|
||||
nextIndex = index;
|
||||
currentOffset = offset;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user