mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-5274_ghizard_DefaultCompositeMember_improve_align_add_nopack_option--SQUASHED'
This commit is contained in:
commit
7a37920a21
10 changed files with 584 additions and 489 deletions
|
@ -121,9 +121,9 @@ public class ApplyDataTypes {
|
||||||
Composite composite = (Composite) cachedDataType;
|
Composite composite = (Composite) cachedDataType;
|
||||||
PdbUtil.clearComponents(composite);
|
PdbUtil.clearComponents(composite);
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, compositeDefinition.isClass,
|
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false,
|
||||||
compositeDefinition.length, getNormalMembersOnly(compositeDefinition),
|
compositeDefinition.isClass, compositeDefinition.length,
|
||||||
msg -> Msg.warn(this, msg), monitor)) {
|
getNormalMembersOnly(compositeDefinition), msg -> Msg.warn(this, msg), monitor)) {
|
||||||
PdbUtil.clearComponents(composite);
|
PdbUtil.clearComponents(composite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class BitFieldGroupCompositeMember extends CompositeMember {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void finalizeDataType(int preferredSize) {
|
void finalizeDataType(int preferredSize, boolean packingDisabled) {
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,10 @@ abstract class CompositeMember {
|
||||||
* This method will appropriately rename and categorize associated anonymous structures and
|
* This method will appropriately rename and categorize associated anonymous structures and
|
||||||
* unions to reflect the final organization and check if internal alignment should be enabled.
|
* unions to reflect the final organization and check if internal alignment should be enabled.
|
||||||
* @param preferredSize preferred size of composite if known, else <= 0 if unknown
|
* @param preferredSize preferred size of composite if known, else <= 0 if unknown
|
||||||
|
* @param packingDisabled {@code true} to disable any attempted use of packing on this
|
||||||
|
* composite or any of its generated composite dependencies
|
||||||
*/
|
*/
|
||||||
abstract void finalizeDataType(int preferredSize);
|
abstract void finalizeDataType(int preferredSize, boolean packingDisabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this member is a container
|
* Determine if this member is a container
|
||||||
|
@ -98,14 +100,15 @@ abstract class CompositeMember {
|
||||||
/**
|
/**
|
||||||
* Add specified member to this member. If this member is not a composite
|
* Add specified member to this member. If this member is not a composite
|
||||||
* it will trigger the creation
|
* it will trigger the creation
|
||||||
* @param member
|
* @param member the member to be added
|
||||||
* @return
|
* @return {@code true} if the specified member was successfully added to this member
|
||||||
*/
|
*/
|
||||||
abstract boolean addMember(DefaultCompositeMember member);
|
abstract boolean addMember(DefaultCompositeMember member);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instructs this member to add itself to the specified structure
|
* Instructs this member to add itself to the specified structure
|
||||||
* @param structure composite structure
|
* @param structure composite structure
|
||||||
|
* @return {@code true} if this member was successfully added to the specified structure
|
||||||
*/
|
*/
|
||||||
abstract boolean addToStructure(DefaultCompositeMember structure);
|
abstract boolean addToStructure(DefaultCompositeMember structure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
private TreeMap<Integer, CompositeMember> structureMemberOffsetMap;
|
private TreeMap<Integer, CompositeMember> structureMemberOffsetMap;
|
||||||
private RangeMap structureMemberRangeMap;
|
private RangeMap structureMemberRangeMap;
|
||||||
private int largestPrimitiveSize;
|
private int largestPrimitiveSize;
|
||||||
private boolean hasPadding = false;
|
private boolean hasStructurePadding = false;
|
||||||
|
|
||||||
// Union container data
|
// Union container data
|
||||||
private List<CompositeMember> unionMemberList;
|
private List<CompositeMember> unionMemberList;
|
||||||
|
@ -250,7 +250,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void finalizeDataType(int preferredSize) {
|
void finalizeDataType(int preferredSize, boolean packingDisabled) {
|
||||||
if (!isContainer()) {
|
if (!isContainer()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
updateContainerNameAndCategoryPath("s");
|
updateContainerNameAndCategoryPath("s");
|
||||||
CompositeMember lastMember = null;
|
CompositeMember lastMember = null;
|
||||||
for (CompositeMember member : structureMemberOffsetMap.values()) {
|
for (CompositeMember member : structureMemberOffsetMap.values()) {
|
||||||
member.finalizeDataType(0);
|
member.finalizeDataType(0, packingDisabled);
|
||||||
lastMember = member;
|
lastMember = member;
|
||||||
}
|
}
|
||||||
transformLastMemberIntoFlexArray(lastMember);
|
transformLastMemberIntoFlexArray(lastMember);
|
||||||
|
@ -269,10 +269,10 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
else if (isUnionContainer()) {
|
else if (isUnionContainer()) {
|
||||||
updateContainerNameAndCategoryPath("u");
|
updateContainerNameAndCategoryPath("u");
|
||||||
for (CompositeMember member : unionMemberList) {
|
for (CompositeMember member : unionMemberList) {
|
||||||
member.finalizeDataType(0);
|
member.finalizeDataType(0, packingDisabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alignComposite(preferredSize);
|
alignComposite(preferredSize, packingDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -318,8 +318,10 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
/**
|
/**
|
||||||
* Align container composite data type if possible.
|
* Align container composite data type if possible.
|
||||||
* @param preferredSize preferred size of composite if known, else <= 0 if unknown
|
* @param preferredSize preferred size of composite if known, else <= 0 if unknown
|
||||||
|
* @param packingDisabled {@code true} to disable any attempted use of packing on this
|
||||||
|
* composite or any of its generated composite dependencies
|
||||||
*/
|
*/
|
||||||
private void alignComposite(int preferredSize) {
|
private void alignComposite(int preferredSize, boolean packingDisabled) {
|
||||||
|
|
||||||
Composite composite = (Composite) memberDataType;
|
Composite composite = (Composite) memberDataType;
|
||||||
|
|
||||||
|
@ -333,6 +335,20 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to get unions to get to the preferred size by adding a padding member
|
||||||
|
if (composite instanceof Union && preferredSize > composite.getAlignedLength()) {
|
||||||
|
ArrayDataType padding = new ArrayDataType(CharDataType.dataType, preferredSize);
|
||||||
|
composite.add(padding, PADDING_COMPONENT_NAME, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packingDisabled) {
|
||||||
|
if (composite instanceof Structure) {
|
||||||
|
removeAllPadding(composite); // includes bit-field padding
|
||||||
|
}
|
||||||
|
setComputedAlignment(composite);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Composite copy = (Composite) composite.copy(dataTypeManager);
|
Composite copy = (Composite) composite.copy(dataTypeManager);
|
||||||
|
|
||||||
int pack = 0;
|
int pack = 0;
|
||||||
|
@ -341,18 +357,18 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
boolean alignOK = isGoodAlignment(copy, preferredSize);
|
boolean alignOK = isGoodAlignment(copy, preferredSize);
|
||||||
if (alignOK) {
|
if (alignOK) {
|
||||||
composite.setToDefaultPacking();
|
composite.setToDefaultPacking();
|
||||||
if (hasPadding) {
|
if (hasStructurePadding) {
|
||||||
removeUnnecessaryPadding(composite);
|
removeUnnecessaryPadding(composite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (composite instanceof Structure) {
|
||||||
if (preferredSize > 0 && copy.getLength() != preferredSize) {
|
if (preferredSize > 0 && copy.getLength() != preferredSize) {
|
||||||
copy.setToMachineAligned(); // will only impact structure length
|
copy.setToMachineAligned(); // will only impact structure length
|
||||||
alignOK = isGoodAlignment(copy, preferredSize);
|
alignOK = isGoodAlignment(copy, preferredSize);
|
||||||
if (alignOK) {
|
if (alignOK) {
|
||||||
composite.setToDefaultPacking();
|
composite.setToDefaultPacking();
|
||||||
composite.setToMachineAligned();
|
composite.setToMachineAligned();
|
||||||
if (hasPadding) {
|
if (hasStructurePadding) {
|
||||||
removeUnnecessaryPadding(composite);
|
removeUnnecessaryPadding(composite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +378,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
}
|
}
|
||||||
if (!alignOK) {
|
if (!alignOK) {
|
||||||
removeAllPadding(composite); // includes bit-field padding
|
removeAllPadding(composite); // includes bit-field padding
|
||||||
if (!hasPadding) {
|
if (!hasStructurePadding) {
|
||||||
pack = 1;
|
pack = 1;
|
||||||
copy.setExplicitPackingValue(pack);
|
copy.setExplicitPackingValue(pack);
|
||||||
alignOK = isGoodAlignment(copy, preferredSize);
|
alignOK = isGoodAlignment(copy, preferredSize);
|
||||||
|
@ -372,13 +388,46 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!alignOK && errorConsumer != null && !isClass) { // don't complain about Class structs which always fail
|
// Unions fall through to here
|
||||||
|
if (!alignOK) {
|
||||||
|
setComputedAlignment(composite);
|
||||||
|
}
|
||||||
|
// Don't complain about Class structs which always fail... this might always be true
|
||||||
|
// for the MSDIA analyzer, but we hope classes will align better with PDB Universal in
|
||||||
|
// the future
|
||||||
|
if (!alignOK && errorConsumer != null && !isClass) {
|
||||||
String anonymousStr = parent != null ? " anonymous " : "";
|
String anonymousStr = parent != null ? " anonymous " : "";
|
||||||
errorConsumer.accept("PDB " + anonymousStr + memberType +
|
errorConsumer.accept("PDB " + anonymousStr + memberType +
|
||||||
" reconstruction failed to align " + composite.getPathName());
|
" reconstruction failed to align " + composite.getPathName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes and sets the alignment of the composite. Will not set an alignment if the
|
||||||
|
* calculation does not make sense
|
||||||
|
* @param composite the composite to affect
|
||||||
|
*/
|
||||||
|
private void setComputedAlignment(Composite composite) {
|
||||||
|
// Only need to compute alignment from immediate child components, as those components
|
||||||
|
// would have already seen this method in their calculations.
|
||||||
|
// If any component of the composite is not at an offset that is a multiple of that
|
||||||
|
// comonent's alignment, then abort setting the composite alignment
|
||||||
|
int compositeAlignment = 1;
|
||||||
|
for (DataTypeComponent dtc : composite.getDefinedComponents()) {
|
||||||
|
DataType dt = dtc.getDataType();
|
||||||
|
int offset = dtc.getOffset();
|
||||||
|
int alignment = dt.getAlignment();
|
||||||
|
if (offset % alignment != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
compositeAlignment = Integer.max(compositeAlignment, alignment);
|
||||||
|
}
|
||||||
|
if (composite.getLength() % compositeAlignment != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
composite.align(compositeAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
private void removeUnnecessaryPadding(Composite packedComposite) {
|
private void removeUnnecessaryPadding(Composite packedComposite) {
|
||||||
if (!packedComposite.isPackingEnabled()) {
|
if (!packedComposite.isPackingEnabled()) {
|
||||||
throw new IllegalArgumentException("composite must have packing enabled");
|
throw new IllegalArgumentException("composite must have packing enabled");
|
||||||
|
@ -507,7 +556,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
structureMemberRangeMap = new RangeMap(-1);
|
structureMemberRangeMap = new RangeMap(-1);
|
||||||
// allow padding size to use pointer-size and smaller by default
|
// allow padding size to use pointer-size and smaller by default
|
||||||
largestPrimitiveSize = memberDataType.getDataOrganization().getPointerSize();
|
largestPrimitiveSize = memberDataType.getDataOrganization().getPointerSize();
|
||||||
hasPadding = false;
|
hasStructurePadding = false;
|
||||||
unionMemberList = null;
|
unionMemberList = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -786,7 +835,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
int paddingOffset =
|
int paddingOffset =
|
||||||
DataOrganizationImpl.getAlignedOffset(paddingDt.getAlignment(), structLen);
|
DataOrganizationImpl.getAlignedOffset(paddingDt.getAlignment(), structLen);
|
||||||
struct.insertAtOffset(paddingOffset, paddingDt, -1, PADDING_COMPONENT_NAME, null);
|
struct.insertAtOffset(paddingOffset, paddingDt, -1, PADDING_COMPONENT_NAME, null);
|
||||||
hasPadding = true;
|
hasStructurePadding = true;
|
||||||
|
|
||||||
structLen = struct.getLength();
|
structLen = struct.getLength();
|
||||||
fillSpace = nextComponentOffset - structLen;
|
fillSpace = nextComponentOffset - structLen;
|
||||||
|
@ -1296,6 +1345,8 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
* Buildup an empty composite by applying datatype composite members.
|
* Buildup an empty composite by applying datatype composite members.
|
||||||
* Only those children with a kind of "Member" will be processed.
|
* Only those children with a kind of "Member" will be processed.
|
||||||
* @param composite empty composite to which members will be added
|
* @param composite empty composite to which members will be added
|
||||||
|
* @param packingDisabled {@code true} to disable any attempted use of packing on this
|
||||||
|
* composite or any of its generated composite dependencies
|
||||||
* @param isClass true if composite corresponds to a Class structure, else false
|
* @param isClass true if composite corresponds to a Class structure, else false
|
||||||
* @param preferredCompositeSize preferred size of composite, <= 0 indicates unknown
|
* @param preferredCompositeSize preferred size of composite, <= 0 indicates unknown
|
||||||
* @param members list of composite members
|
* @param members list of composite members
|
||||||
|
@ -1304,9 +1355,10 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
* @return true if members successfully added to composite
|
* @return true if members successfully added to composite
|
||||||
* @throws CancelledException if monitor is cancelled
|
* @throws CancelledException if monitor is cancelled
|
||||||
*/
|
*/
|
||||||
public static boolean applyDataTypeMembers(Composite composite, boolean isClass,
|
public static boolean applyDataTypeMembers(Composite composite, boolean packingDisabled,
|
||||||
int preferredCompositeSize, List<? extends PdbMember> members,
|
boolean isClass, int preferredCompositeSize,
|
||||||
Consumer<String> errorConsumer, TaskMonitor monitor) throws CancelledException {
|
List<? extends PdbMember> members, Consumer<String> errorConsumer, TaskMonitor monitor)
|
||||||
|
throws CancelledException {
|
||||||
|
|
||||||
Composite editComposite = composite;
|
Composite editComposite = composite;
|
||||||
|
|
||||||
|
@ -1332,7 +1384,7 @@ public class DefaultCompositeMember extends CompositeMember {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootMember.finalizeDataType(preferredCompositeSize);
|
rootMember.finalizeDataType(preferredCompositeSize, packingDisabled);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
addVftPtrs(composite, classType, lists.vftPtrs(), type, myMembers);
|
addVftPtrs(composite, classType, lists.vftPtrs(), type, myMembers);
|
||||||
addMembers(composite, classType, lists.nonstaticMembers(), type, myMembers);
|
addMembers(composite, classType, lists.nonstaticMembers(), type, myMembers);
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, isClass, size, myMembers,
|
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, isClass, size, myMembers,
|
||||||
msg -> reconstructionWarn(msg, hasHiddenComponents(lists)),
|
msg -> reconstructionWarn(msg, hasHiddenComponents(lists)),
|
||||||
applicator.getCancelOnlyWrappingMonitor())) {
|
applicator.getCancelOnlyWrappingMonitor())) {
|
||||||
clearComponents(composite);
|
clearComponents(composite);
|
||||||
|
|
|
@ -686,7 +686,7 @@ public class CppCompositeType {
|
||||||
addLayoutPdbMembers(directClassPdbMembers, layoutMembers);
|
addLayoutPdbMembers(directClassPdbMembers, layoutMembers);
|
||||||
insertVirtualFunctionTablePointers(directClassPdbMembers);
|
insertVirtualFunctionTablePointers(directClassPdbMembers);
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false, 0,
|
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false, false, 0,
|
||||||
directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
||||||
clearComponents(directDataType);
|
clearComponents(directDataType);
|
||||||
}
|
}
|
||||||
|
@ -706,7 +706,8 @@ public class CppCompositeType {
|
||||||
directDataType = new StructureDataType(cn.getParent(), cn.getName(), 0,
|
directDataType = new StructureDataType(cn.getParent(), cn.getName(), 0,
|
||||||
composite.getDataTypeManager());
|
composite.getDataTypeManager());
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false,
|
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false,
|
||||||
size, directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
false, size, directClassPdbMembers, msg -> Msg.warn(this, msg),
|
||||||
|
monitor)) {
|
||||||
clearComponents(directDataType);
|
clearComponents(directDataType);
|
||||||
}
|
}
|
||||||
directClassLength = getCompositeLength(directDataType);
|
directClassLength = getCompositeLength(directDataType);
|
||||||
|
@ -735,7 +736,7 @@ public class CppCompositeType {
|
||||||
throw new PdbException("Unhandled layout mode");
|
throw new PdbException("Unhandled layout mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, memberData,
|
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, false, size, memberData,
|
||||||
msg -> Msg.warn(this, msg), monitor)) {
|
msg -> Msg.warn(this, msg), monitor)) {
|
||||||
clearComponents(composite);
|
clearComponents(composite);
|
||||||
}
|
}
|
||||||
|
@ -826,7 +827,7 @@ public class CppCompositeType {
|
||||||
addLayoutPdbMembers(directClassPdbMembers, layoutMembers);
|
addLayoutPdbMembers(directClassPdbMembers, layoutMembers);
|
||||||
insertVirtualFunctionTablePointers(directClassPdbMembers);
|
insertVirtualFunctionTablePointers(directClassPdbMembers);
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false, 0,
|
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false, false, 0,
|
||||||
directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
||||||
clearComponents(directDataType);
|
clearComponents(directDataType);
|
||||||
}
|
}
|
||||||
|
@ -846,7 +847,8 @@ public class CppCompositeType {
|
||||||
directDataType = new StructureDataType(cn.getParent(), cn.getName(), 0,
|
directDataType = new StructureDataType(cn.getParent(), cn.getName(), 0,
|
||||||
composite.getDataTypeManager());
|
composite.getDataTypeManager());
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false,
|
if (!DefaultCompositeMember.applyDataTypeMembers(directDataType, false,
|
||||||
size, directClassPdbMembers, msg -> Msg.warn(this, msg), monitor)) {
|
false, size, directClassPdbMembers, msg -> Msg.warn(this, msg),
|
||||||
|
monitor)) {
|
||||||
clearComponents(directDataType);
|
clearComponents(directDataType);
|
||||||
}
|
}
|
||||||
directClassLength = getCompositeLength(directDataType);
|
directClassLength = getCompositeLength(directDataType);
|
||||||
|
@ -875,7 +877,7 @@ public class CppCompositeType {
|
||||||
throw new PdbException("Unhandled layout mode");
|
throw new PdbException("Unhandled layout mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, memberData,
|
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, false, size, memberData,
|
||||||
msg -> Msg.warn(this, msg), monitor)) {
|
msg -> Msg.warn(this, msg), monitor)) {
|
||||||
clearComponents(composite);
|
clearComponents(composite);
|
||||||
}
|
}
|
||||||
|
|
|
@ -545,7 +545,7 @@ public class PdbResearch {
|
||||||
members.add(member);
|
members.add(member);
|
||||||
size += extra.getLength();
|
size += extra.getLength();
|
||||||
}
|
}
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, members,
|
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, false, size, members,
|
||||||
msg -> reconstructionWarn(msg), monitor)) {
|
msg -> reconstructionWarn(msg), monitor)) {
|
||||||
((Structure) composite).deleteAll();
|
((Structure) composite).deleteAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class VtShapeTypeApplier extends MsDataTypeApplier {
|
||||||
members.add(member);
|
members.add(member);
|
||||||
}
|
}
|
||||||
// offset has the total size at this point
|
// offset has the total size at this point
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(shape, false, offset, members,
|
if (!DefaultCompositeMember.applyDataTypeMembers(shape, false, false, offset, members,
|
||||||
msg -> Msg.warn(this, msg), applicator.getCancelOnlyWrappingMonitor())) {
|
msg -> Msg.warn(this, msg), applicator.getCancelOnlyWrappingMonitor())) {
|
||||||
CompositeTypeApplier.clearComponents(shape);
|
CompositeTypeApplier.clearComponents(shape);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,8 +135,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
);
|
);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(union, false, 8, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(union, false, false, 8, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -174,8 +174,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "ushort", 8));
|
new MyPdbMember("f", "ushort", 8));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 12, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 12, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -209,8 +209,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "ushort", 7));
|
new MyPdbMember("f", "ushort", 7));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 9, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 9, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -242,8 +242,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "ushort", 7));
|
new MyPdbMember("f", "ushort", 7));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 9, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 9, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -275,8 +275,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "ushort", 8));
|
new MyPdbMember("f", "ushort", 8));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 12, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 12, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -297,6 +297,42 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleStructureWithFillerBitFieldsPackingDisabled() throws Exception {
|
||||||
|
|
||||||
|
StructureDataType struct = new StructureDataType("struct", 0, dataMgr);
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
List<MyPdbMember> members =
|
||||||
|
CollectionUtils.asList(new MyPdbMember("a", "uchar", 0),
|
||||||
|
new MyPdbMember("b:0x2:0x2", "uchar", 1),
|
||||||
|
new MyPdbMember("c1:0x1:0x4", "uchar", 1),
|
||||||
|
new MyPdbMember("c2:0x1:0x6", "uchar", 1),
|
||||||
|
new MyPdbMember("d:0x7:0x0", "uchar", 2),
|
||||||
|
new MyPdbMember("e:0x4:0x0", "uint", 4),
|
||||||
|
new MyPdbMember("f", "ushort", 8));
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, true, false, 12, members,
|
||||||
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
"/struct\n" +
|
||||||
|
"aligned(4) pack(disabled)\n" +
|
||||||
|
"Structure struct {\n" +
|
||||||
|
" 0 uchar 1 a \"\"\n" +
|
||||||
|
" 1 uchar:2(2) 1 b \"\"\n" +
|
||||||
|
" 1 uchar:1(4) 1 c1 \"\"\n" +
|
||||||
|
" 1 uchar:1(6) 1 c2 \"\"\n" +
|
||||||
|
" 2 uchar:7(0) 1 d \"\"\n" +
|
||||||
|
" 4 uint:4(0) 1 e \"\"\n" +
|
||||||
|
" 8 ushort 2 f \"\"\n" +
|
||||||
|
"}\n" +
|
||||||
|
"Length: 12 Alignment: 4", struct, true);
|
||||||
|
//@formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnionedStructuresWithFillerBitFields() throws Exception {
|
public void testUnionedStructuresWithFillerBitFields() throws Exception {
|
||||||
|
|
||||||
|
@ -338,8 +374,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("a5:0x1:0x5", "char", 0));
|
new MyPdbMember("a5:0x1:0x5", "char", 0));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 1, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 1, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -398,8 +434,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "ushort", 0));
|
new MyPdbMember("f", "ushort", 0));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(union, false, 2, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(union, false, false, 2, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
// NOTE: handling of bit-fields within union is rather ambiguous within
|
// NOTE: handling of bit-fields within union is rather ambiguous within
|
||||||
// PDB data
|
// PDB data
|
||||||
|
@ -444,8 +480,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("e", "char[0]", 1));
|
new MyPdbMember("e", "char[0]", 1));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 1, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 1, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -475,8 +511,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "char[0]", 8));
|
new MyPdbMember("f", "char[0]", 8));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 16, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 16, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -485,6 +521,7 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
"Union union {\n" +
|
"Union union {\n" +
|
||||||
" 0 union_s_0 12 _s_0 \"\"\n" +
|
" 0 union_s_0 12 _s_0 \"\"\n" +
|
||||||
" 0 union_s_1 8 _s_1 \"\"\n" +
|
" 0 union_s_1 8 _s_1 \"\"\n" +
|
||||||
|
" 0 char[16] 16 _padding_ \"\"\n" +
|
||||||
"}\n" +
|
"}\n" +
|
||||||
"Length: 16 Alignment: 8\n" +
|
"Length: 16 Alignment: 8\n" +
|
||||||
"/union/union_s_0\n" +
|
"/union/union_s_0\n" +
|
||||||
|
@ -521,8 +558,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("f", "char[0]", 0));
|
new MyPdbMember("f", "char[0]", 0));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 12, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 12, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -565,13 +602,13 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("c", "char", 1));
|
new MyPdbMember("c", "char", 1));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 1, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 2, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
"/union\n" +
|
"/union\n" +
|
||||||
"pack(disabled)\n" +
|
"pack()\n" +
|
||||||
"Union union {\n" +
|
"Union union {\n" +
|
||||||
" 0 union_s_0 1 _s_0 \"\"\n" +
|
" 0 union_s_0 1 _s_0 \"\"\n" +
|
||||||
" 0 union_s_1 2 _s_1 \"\"\n" +
|
" 0 union_s_1 2 _s_1 \"\"\n" +
|
||||||
|
@ -622,8 +659,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("b", "longlong", 8));
|
new MyPdbMember("b", "longlong", 8));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 16, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 16, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -706,8 +743,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
|
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 12, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 12, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
@ -717,8 +754,9 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
" 0 ulong 4 a \"\"\n" +
|
" 0 ulong 4 a \"\"\n" +
|
||||||
" 0 longlong 8 b \"\"\n" +
|
" 0 longlong 8 b \"\"\n" +
|
||||||
" 0 union_s_2 2 _s_2 \"\"\n" +
|
" 0 union_s_2 2 _s_2 \"\"\n" +
|
||||||
|
" 0 char[12] 12 _padding_ \"\"\n" +
|
||||||
"}\n" +
|
"}\n" +
|
||||||
"Length: 8 Alignment: 1\n" +
|
"Length: 12 Alignment: 1\n" +
|
||||||
"/union/union_s_2\n" +
|
"/union/union_s_2\n" +
|
||||||
"pack()\n" +
|
"pack()\n" +
|
||||||
"Structure union_s_2 {\n" +
|
"Structure union_s_2 {\n" +
|
||||||
|
@ -816,8 +854,8 @@ public class CompositeMemberTest extends AbstractGhidraHeadlessIntegrationTest
|
||||||
new MyPdbMember("buf", "char[0]", 0x2c));
|
new MyPdbMember("buf", "char[0]", 0x2c));
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, 0x38, members, this,
|
assertTrue(DefaultCompositeMember.applyDataTypeMembers(struct, false, false, 0x38, members,
|
||||||
TaskMonitor.DUMMY));
|
this, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
CompositeTestUtils.assertExpectedComposite(this,
|
CompositeTestUtils.assertExpectedComposite(this,
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class ConflictHandler2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
size += extra.getLength();
|
size += extra.getLength();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, members,
|
if (DefaultCompositeMember.applyDataTypeMembers(composite, false, false, size, members,
|
||||||
msg -> Msg.warn(ConflictHandler2Test.class, msg), monitor)) {
|
msg -> Msg.warn(ConflictHandler2Test.class, msg), monitor)) {
|
||||||
((Structure) composite).deleteAll();
|
((Structure) composite).deleteAll();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue