GT-2823 Partial changes from first review.

This commit is contained in:
ghizard 2019-04-23 12:35:05 -04:00
parent 0e4b725c37
commit 56bcc2beb9
19 changed files with 241 additions and 104 deletions

View file

@ -152,11 +152,12 @@ public abstract class AbstractChangeExecutionModelMsSymbol extends AbstractMsSym
/**
* Parses some specific values for this version of symbol.
* <P>
* Implementing class must, in the appropriate order pertinent to itself, parse
* {@link #subtype} and {@link #flag} if
* {@link #model}=={@link #AbstractChangeExecutionModelMsSymbol.Model.COBOL} or
* {@link #offsetToPcodeFunctionTable} and {@link #offsetToSegmentPcodeInformation} if
* {@link #model}=={@link #AbstractChangeExecutionModelMsSymbol.Model.PCODE}.
* Implementing class must, in the appropriate order pertinent to itself, do the following:
* <PRE>
* if {@link #model}=={@link #AbstractChangeExecutionModelMsSymbol.Model.COBOL}, then parse
* {@link #subtype} and {@link #flag}
* else if {@link #model}=={@link #AbstractChangeExecutionModelMsSymbol.Model.PCODE}, then parse
* {@link #offsetToPcodeFunctionTable} and {@link #offsetToSegmentPcodeInformation}. </PRE>
* @param reader {@link PdbByteReader} from which to parse the information.
* @throws PdbException Upon not enough data left to parse.
*/

View file

@ -75,7 +75,7 @@ public abstract class AbstractCompile2MsSymbol extends AbstractMsSymbol {
while (reader.hasMore()) {
AbstractString string = new StringUtf8Nt();
string.parse(reader);
if (string.get().length() == 0) {
if (string.get().isEmpty()) {
break;
}
stringList.add(string);
@ -298,7 +298,7 @@ public abstract class AbstractCompile2MsSymbol extends AbstractMsSymbol {
* @param flagsIn {@code long} containing unsigned int value.
*/
protected void processFlags(long flagsIn) {
language = new LanguageName((int) (flagsIn & 0xff));
language = LanguageName.fromValue((int) (flagsIn & 0xff));
flagsIn >>= 8;
compiledForEditAndContinue = ((flagsIn & 0x0001) == 0x0001);

View file

@ -53,10 +53,10 @@ public abstract class AbstractDataHighLevelShaderLanguageMsSymbol extends Abstra
}
/**
* Returns the register type.
* @return Register type.
* Returns the {@link HLSLRegisterType}.
* @return The {@link HLSLRegisterType}.
*/
public String getRegisterType() {
public HLSLRegisterType getRegisterType() {
return internals.getRegisterType();
}

View file

@ -15,6 +15,7 @@
*/
package ghidra.pdb.pdbreader.symbol;
import ghidra.pdb.PdbByteReader;
import ghidra.pdb.pdbreader.*;
/**
@ -28,22 +29,14 @@ import ghidra.pdb.pdbreader.*;
public abstract class AbstractDataHighLevelShaderLanguageSymbolInternals
extends AbstractSymbolInternals {
protected static final String regTypeHLSL[] = { "TEMP", "INPUT", "OUTPUT", "INDEXABLE_TEMP",
"IMMEDIATE32", "IMMEDIATE64", "SAMPLER", "RESOURCE", "CONSTANT_BUFFER",
"IMMEDIATE_CONSTANT_BUFFER", "LABEL", "INPUT_PRIMITIVEID", "OUTPUT_DEPTH", "NULL",
"RASTERIZER", "OUTPUT_COVERAGE_MASK", "STREAM", "FUNCTION_BODY", "FUNCTION_TABLE",
"INTERFACE", "FUNCTION_INPUT", "FUNCTION_OUTPUT", "OUTPUT_CONTROL_POINT_ID",
"INPUT_FORK_INSTANCE_ID", "INPUT_JOIN_INSTANCE_ID", "INPUT_CONTROL_POINT",
"OUTPUT_CONTROL_POINT", "INPUT_PATCH_CONSTANT", "INPUT_DOMAIN_POINT", "THIS_POINTER",
"UNORDERED_ACCESS_VIEW", "THREAD_GROUP_SHARED_MEMORY", "INPUT_THREAD_ID",
"INPUT_THREAD_GROUP_ID", "INPUT_THREAD_ID_IN_GROUP", "INPUT_COVERAGE_MASK",
"INPUT_THREAD_ID_IN_GROUP_FLATTENED", "INPUT_GS_INSTANCE_ID", "OUTPUT_DEPTH_GREATER_EQUAL",
"OUTPUT_DEPTH_LESS_EQUAL", "CYCLE_COUNTER" };
//==============================================================================================
/**
* Implementing class is required to parse these four fields in the
* {@link #parse(PdbByteReader)} method.
*/
protected int typeIndex;
protected long dataOffset;
protected int registerType;
protected HLSLRegisterType registerType;
protected AbstractString name;
//==============================================================================================
@ -59,11 +52,8 @@ public abstract class AbstractDataHighLevelShaderLanguageSymbolInternals
return dataOffset;
}
public String getRegisterType() {
if (registerType >= 0 && registerType < regTypeHLSL.length) {
return regTypeHLSL[registerType];
}
return "INVALID_REG";
public HLSLRegisterType getRegisterType() {
return registerType;
}
public int getTypeIndex() {

View file

@ -112,7 +112,7 @@ public abstract class AbstractDefinedSingleAddressRangeMsSymbol extends Abstract
protected void emitRangeAndGaps(StringBuilder builder) {
builder.append(addressRange);
builder.append(String.format(", %d Gaps", addressGapList.size()));
if (addressGapList.size() == 0) {
if (addressGapList.isEmpty()) {
return;
}
builder.append(" (startOffset, length):");

View file

@ -18,7 +18,9 @@ package ghidra.pdb.pdbreader.symbol;
import ghidra.pdb.*;
/**
* Address Gap property used by a number of specific PDB symbol types.
* Address Gap property used by a number of specific PDB symbol types. This seems to specify
* one of potentially many address gaps in an address range.
* @see AbstractDefinedSingleAddressRangeMsSymbol
*/
public class AddressGap extends AbstractParsableItem {

View file

@ -329,7 +329,7 @@ public class Compile3MsSymbol extends AbstractMsSymbol {
* @param flagsIn {@code long} containing unsigned int value.
*/
protected void processFlags(long flagsIn) {
language = new LanguageName((int) (flagsIn & 0xff));
language = LanguageName.fromValue((int) (flagsIn & 0xff));
flagsIn >>= 8;
compiledForEditAndContinue = ((flagsIn & 0x0001) == 0x0001);

View file

@ -93,7 +93,7 @@ public class CompileFlagsMsSymbol extends AbstractMsSymbol {
*/
protected void processFlags(byte[] flagsIn) {
int flagsByte = flagsIn[0];
language = new LanguageName(flagsByte);
language = LanguageName.fromValue(flagsByte);
flagsByte = flagsIn[1];
pcodePresent = ((flagsByte & 0x0001) == 0x0001);

View file

@ -46,8 +46,8 @@ public class DataHighLevelShaderLanguageSymbolInternals
@Override
public void emit(StringBuilder builder) {
builder.append(
String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex), getRegisterType()));
builder.append(String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex),
getRegisterType().toString()));
builder.append(String.format(
" base data: slot = %d offset = %d, texture slot = %d, sampler slot = %d, UAV slot = %d\n",
dataSlot, dataOffset, textureSlotStart, samplerSlotStart, uavSlotStart));
@ -59,7 +59,8 @@ public class DataHighLevelShaderLanguageSymbolInternals
typeIndex = reader.parseInt();
pdb.pushDependencyStack(new CategoryIndex(CategoryIndex.Category.DATA, typeIndex));
pdb.popDependencyStack();
registerType = reader.parseUnsignedShortVal();
registerType = HLSLRegisterType.fromValue(
reader.parseUnsignedShortVal());
dataSlot = reader.parseUnsignedShortVal();
dataOffset = reader.parseUnsignedShortVal();
textureSlotStart = reader.parseUnsignedShortVal();

View file

@ -46,8 +46,8 @@ public class DataHighLevelShaderLanguageSymbolInternals32
@Override
public void emit(StringBuilder builder) {
builder.append(
String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex), getRegisterType()));
builder.append(String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex),
getRegisterType().toString()));
builder.append(String.format(
" base data: slot = %d offset = %d, texture slot = %d, sampler slot = %d, UAV slot = %d\n",
dataSlot, dataOffset, textureSlotStart, samplerSlotStart, uavSlotStart));
@ -63,7 +63,8 @@ public class DataHighLevelShaderLanguageSymbolInternals32
textureSlotStart = reader.parseUnsignedIntVal();
samplerSlotStart = reader.parseUnsignedIntVal();
uavSlotStart = reader.parseUnsignedIntVal();
registerType = reader.parseUnsignedShortVal();
registerType = HLSLRegisterType.fromValue(
reader.parseUnsignedShortVal());
name.parse(reader);
}

View file

@ -45,8 +45,8 @@ public class DataHighLevelShaderLanguageSymbolInternals32Extended
@Override
public void emit(StringBuilder builder) {
builder.append(
String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex), getRegisterType()));
builder.append(String.format(": Type: %s. %s\n", pdb.getTypeRecord(typeIndex),
getRegisterType().toString()));
builder.append(String.format(
" register index = %d, base data offset start = %d, bind space = %d, bind slot = %d\n",
registerIndex, dataOffset, bindSpace, bindSlot));
@ -62,7 +62,8 @@ public class DataHighLevelShaderLanguageSymbolInternals32Extended
dataOffset = reader.parseUnsignedIntVal();
bindSpace = reader.parseUnsignedIntVal();
bindSlot = reader.parseUnsignedIntVal();
registerType = reader.parseUnsignedShortVal();
registerType = HLSLRegisterType.fromValue(
reader.parseUnsignedShortVal());
name.parse(reader);
}

View file

@ -35,6 +35,13 @@ public class EnvironmentBlockMsSymbol extends AbstractMsSymbol {
private int flags;
// TODO: MSFT API struct shows rev; usage shows fEC somewhere (not in struct)
private boolean rev;
/**
* These appear to be pairs of strings that we then output as
* <P>
* string1 = string2
* <P>
* string3 = string4...
*/
private List<AbstractString> stringList = new ArrayList<>();
/**
@ -49,7 +56,7 @@ public class EnvironmentBlockMsSymbol extends AbstractMsSymbol {
while (reader.hasMore()) {
AbstractString string = new StringUtf8Nt();
string.parse(reader);
if (string.get().length() == 0) {
if (string.get().isEmpty()) {
break;
}
stringList.add(string);

View file

@ -15,6 +15,9 @@
*/
package ghidra.pdb.pdbreader.symbol;
import java.util.HashMap;
import java.util.Map;
import ghidra.pdb.PdbByteReader;
import ghidra.pdb.PdbException;
import ghidra.pdb.pdbreader.AbstractPdb;
@ -29,12 +32,43 @@ public class FrameSecurityCookieMsSymbol extends AbstractMsSymbol {
public static final int PDB_ID = 0x113a;
private String[] cookieTypeString = { "COPY", "XOR_SP", "XOR_BP", "XOR_R13" };
public enum CookieType {
INVALID("invalid", -1),
COPY("COPY", 0),
XOR_SP("XOR_SP", 1),
XOR_BP("XOR_BP", 2),
XOR_R13("XOR_R13", 3);
private static final Map<Integer, CookieType> BY_VALUE = new HashMap<>();
static {
for (CookieType val : values()) {
BY_VALUE.put(val.value, val);
}
}
public final String label;
public final int value;
@Override
public String toString() {
return label;
}
public static CookieType fromValue(int val) {
return BY_VALUE.getOrDefault(val, INVALID);
}
private CookieType(String label, int value) {
this.label = label;
this.value = value;
}
}
protected long offset;
protected int registerIndex;
protected RegisterName registerName;
protected int cookieTypeIndex; // cookie type (valid values seem to be 0, 1, 2, 3)
protected CookieType cookieType;
protected int flags;
/**
@ -49,10 +83,7 @@ public class FrameSecurityCookieMsSymbol extends AbstractMsSymbol {
registerIndex = reader.parseUnsignedShortVal();
registerName = new RegisterName(pdb, registerIndex);
// One example seems to show only room for a byte here, leaving the last byte for flags.
cookieTypeIndex = reader.parseUnsignedByteVal();
if (cookieTypeIndex >= cookieTypeString.length) {
cookieTypeIndex = 0;
}
cookieType = CookieType.fromValue(reader.parseUnsignedByteVal());
flags = reader.parseUnsignedByteVal();
}
@ -86,19 +117,11 @@ public class FrameSecurityCookieMsSymbol extends AbstractMsSymbol {
}
/**
* Returns the cookie type index.
* Returns the {@link CookieType}.
* @return Cookie type index.
*/
public int getCookieTypeIndex() {
return cookieTypeIndex;
}
/**
* Returns the cookie string.
* @return Cookie string.
*/
public String getCookie() {
return cookieTypeString[cookieTypeIndex];
public CookieType getCookieType() {
return cookieType;
}
/**
@ -112,7 +135,7 @@ public class FrameSecurityCookieMsSymbol extends AbstractMsSymbol {
@Override
public void emit(StringBuilder builder) {
builder.append(String.format("%s: %s+%08X, Type: %s, %02X", getSymbolTypeName(),
registerName.toString(), offset, cookieTypeString[cookieTypeIndex], flags));
registerName.toString(), offset, cookieType.toString(), flags));
}
@Override

View file

@ -0,0 +1,94 @@
/* ###
* 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.pdb.pdbreader.symbol;
import java.util.HashMap;
import java.util.Map;
/**
* Enumerates the High Level Shader Language Register Type.
* @see AbstractDataHighLevelShaderLanguageSymbolInternals
*/
public enum HLSLRegisterType {
INVALID("INVALID_REG", -1),
TEMP("TEMP", 0),
INPUT("INPUT", 1),
OUTPUT("OUTPUT", 2),
INDEXABLE_TEMP("INDEXABLE_TEMP", 3),
IMMEDIATE32("IMMEDIATE32", 4),
IMMEDIATE64("IMMEDIATE64", 5),
SAMPLER("SAMPLER", 6),
RESOURCE("RESOURCE", 7),
CONSTANT_BUFFER("CONSTANT_BUFFER", 8),
IMMEDIATE_CONSTANT_BUFFER("IMMEDIATE_CONSTANT_BUFFER", 9),
LABEL("LABEL", 10),
INPUT_PRIMITIVEID("INPUT_PRIMITIVEID", 11),
OUTPUT_DEPTH("OUTPUT_DEPTH", 12),
NULL("NULL", 13),
RASTERIZER("RASTERIZER", 14),
OUTPUT_COVERAGE_MASK("OUTPUT_COVERAGE_MASK", 15),
STREAM("STREAM", 16),
FUNCTION_BODY("FUNCTION_BODY", 17),
FUNCTION_TABLE("FUNCTION_TABLE", 18),
INTERFACE("INTERFACE", 19),
FUNCTION_INPUT("FUNCTION_INPUT", 20),
FUNCTION_OUTPUT("FUNCTION_OUTPUT", 21),
OUTPUT_CONTROL_POINT_ID("OUTPUT_CONTROL_POINT_ID", 22),
INPUT_FORK_INSTANCE_ID("INPUT_FORK_INSTANCE_ID", 23),
INPUT_JOIN_INSTANCE_ID("INPUT_JOIN_INSTANCE_ID", 24),
INPUT_CONTROL_POINT("INPUT_CONTROL_POINT", 25),
OUTPUT_CONTROL_POINT("OUTPUT_CONTROL_POINT", 26),
INPUT_PATCH_CONSTANT("INPUT_PATCH_CONSTANT", 27),
INPUT_DOMAIN_POINT("INPUT_DOMAIN_POINT", 28),
THIS_POINTER("THIS_POINTER", 29),
UNORDERED_ACCESS_VIEW("UNORDERED_ACCESS_VIEW", 30),
THREAD_GROUP_SHARED_MEMORY("THREAD_GROUP_SHARED_MEMORY", 31),
INPUT_THREAD_ID("INPUT_THREAD_ID", 32),
INPUT_THREAD_GROUP_ID("INPUT_THREAD_GROUP_ID", 33),
INPUT_THREAD_ID_IN_GROUP("INPUT_THREAD_ID_IN_GROUP", 34),
INPUT_COVERAGE_MASK("INPUT_COVERAGE_MASK", 35),
INPUT_THREAD_ID_IN_GROUP_FLATTENED("INPUT_THREAD_ID_IN_GROUP_FLATTENED", 36),
INPUT_GS_INSTANCE_ID("INPUT_GS_INSTANCE_ID", 37),
OUTPUT_DEPTH_GREATER_EQUA("OUTPUT_DEPTH_GREATER_EQUA", 38),
OUTPUT_DEPTH_LESS_EQUAL("OUTPUT_DEPTH_LESS_EQUAL", 39),
CYCLE_COUNTER("CYCLE_COUNTER", 40);
private static final Map<Integer, HLSLRegisterType> BY_VALUE = new HashMap<>();
static {
for (HLSLRegisterType val : values()) {
BY_VALUE.put(val.value, val);
}
}
public final String label;
public final int value;
@Override
public String toString() {
return label;
}
public static HLSLRegisterType fromValue(int val) {
return BY_VALUE.getOrDefault(val, INVALID);
}
private HLSLRegisterType(String label, int value) {
this.label = label;
this.value = value;
}
}

View file

@ -15,7 +15,8 @@
*/
package ghidra.pdb.pdbreader.symbol;
import ghidra.pdb.AbstractParsableItem;
import java.util.HashMap;
import java.util.Map;
/**
* Language name used by certain PDB symbols.
@ -23,29 +24,49 @@ import ghidra.pdb.AbstractParsableItem;
* @see Compile3MsSymbol
* @see CompileFlagsMsSymbol
*/
public class LanguageName extends AbstractParsableItem {
public enum LanguageName {
private static final String idString[] =
{ "C", "C++", "FORTRAN", "MASM", "Pascal", "Basic", "COBOL", "LINK", "CVTRES", "CVTPGD",
"C#", "VisualBasic", "ILASM", "Java", "JScript", "MSIL", "HLSL", "???" };
INVALID("???", -1),
C("C", 0),
CPP("C++", 1),
FORTRAN("FORTRAN", 2),
MASM("MASM", 3),
PASCAL("Pascal", 4),
BASIC("Basic", 5),
COBOL("COBOL", 6),
LINK("LINK", 7),
CVTRES("CVTRES", 8),
CVTPGD("CVTPGD", 9),
CSHARP("C#", 10),
VISUALBASIC("VisualBasic", 11),
ILASM("ILASM", 12),
JAVA("Java", 13),
JSCRIPT("JScript", 14),
MSIL("MSIL", 15),
HLSL("HLSL", 16);
//==============================================================================================
private int languageIndex;
//==============================================================================================
/**
* Constructor for this symbol component. Takes an int language index argument.
* @param languageIndexIn Language index.
*/
public LanguageName(int languageIndexIn) {
this.languageIndex =
(languageIndexIn >= 0 && languageIndex < idString.length) ? languageIndexIn
: idString.length - 1;
private static final Map<Integer, LanguageName> BY_VALUE = new HashMap<>();
static {
for (LanguageName val : values()) {
BY_VALUE.put(val.value, val);
}
}
public final String label;
public final int value;
@Override
public void emit(StringBuilder builder) {
builder.append(idString[languageIndex]);
public String toString() {
return label;
}
public static LanguageName fromValue(int val) {
return BY_VALUE.getOrDefault(val, INVALID);
}
private LanguageName(String label, int value) {
this.label = label;
this.value = value;
}
}

View file

@ -133,11 +133,7 @@ public class ProcessorName extends AbstractParsableItem {
}
private String getProcessorName() {
String val = processorStringMap.get(processorIndex);
if (val != null) {
return val;
}
return badProcessor;
return processorStringMap.getOrDefault(processorIndex, badProcessor);
}
}

View file

@ -20,9 +20,6 @@ import java.util.Map;
/**
* VTShape Descriptor Property used on VtShapeMsType PDB data type.
* <P>
* Note: we do not necessarily understand each of these data type classes. Refer to the
* base class for more information.
*/
public enum VtShapeDescriptorMsProperty {

View file

@ -15,7 +15,7 @@
*/
package ghidra.pdb.pdbreader.symbol;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
@ -35,12 +35,13 @@ public class SymbolsTest extends AbstractGenericTest {
// ensure consistency across the tests. We are setting it int the pdb here (in the static
// assignment block), but we do not know the order that any tests are run, so having the
// same value will ensure consistent results.
private static final int processorIndex = 0x0000;
//private static TypeProgramInterface tpi;
private static SymbolParser symbolParser;
static {
private int processorIndex;
private SymbolParser symbolParser;
public SymbolsTest() {
try (DummyPdb700 dummyPdb700 = new DummyPdb700(4096, 4096, 4096, 4096)) {
pdb = dummyPdb700;
processorIndex = 0x0000;
pdb.setTargetProcessorIndexNumber(processorIndex);
symbolParser = pdb.getSymbolParser();
@ -60,7 +61,7 @@ public class SymbolsTest extends AbstractGenericTest {
dummyPdb700.setItemRecord(4096, item);
}
catch (Exception e) {
Msg.error(null, "Error in static initialization of test", e);
Msg.error(null, "Error in initialization of test", e);
assert false;
}
}

View file

@ -15,7 +15,7 @@
*/
package ghidra.pdb.pdbreader.type;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
@ -36,18 +36,20 @@ public class TypesTest extends AbstractGenericTest {
// ensure consistency across the tests. We are setting it int the pdb here (in the static
// assignment block), but we do not know the order that any tests are run, so having the
// same value will ensure consistent results.
private static final int processorIndex = 0x0000;
private static int stringIdMsType1;
private static int stringIdMsType2;
private static int substringListMsType1;
private static int referencedSymbolMsType1;
private static int methodList16MsType1;
private static int methodListMsType1;
private static int vtShapeMsType1;
private static TypeParser typeParser;
static {
private int processorIndex;
private int stringIdMsType1;
private int stringIdMsType2;
private int substringListMsType1;
private int referencedSymbolMsType1;
private int methodList16MsType1;
private int methodListMsType1;
private int vtShapeMsType1;
private TypeParser typeParser;
public TypesTest() {
try (DummyPdb700 dummyPdb700 = new DummyPdb700(4096, 4096, 4096, 4096)) {
pdb = dummyPdb700;
processorIndex = 0x0000;
pdb.setTargetProcessorIndexNumber(processorIndex);
typeParser = pdb.getTypeParser();