diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java index 4f8e89354e..6a9a947cb4 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java @@ -215,7 +215,7 @@ public class DecompilerUtils { } /** - * Returns the function represented by the given token. This will be either the + * Returns the function represented by the given token. This will be either the * decompiled function or a function referenced within the decompiled function. * * @param program the program @@ -270,8 +270,8 @@ public class DecompilerUtils { /** * Similar to {@link #getTokens(ClangNode, AddressSetView)}, but uses the tokens from - * the given view fields. Sometimes the tokens in the model (represented by the - * {@link ClangNode}) are different than the fields in the view (such as when a list of + * the given view fields. Sometimes the tokens in the model (represented by the + * {@link ClangNode}) are different than the fields in the view (such as when a list of * comment tokens are condensed into a single comment token). * * @param fields the fields to check @@ -354,8 +354,7 @@ public class DecompilerUtils { public static AddressSet findClosestAddressSet(Program program, AddressSpace functionSpace, List tokenList) { AddressSet addressSet = new AddressSet(); - for (int i = 0; i < tokenList.size(); ++i) { - ClangToken tok = tokenList.get(i); + for (ClangToken tok : tokenList) { addTokenAddressRangeToSet(addressSet, tok, functionSpace); } @@ -574,8 +573,8 @@ public class DecompilerUtils { } Stack braceStack = new Stack<>(); - for (int i = 0; i < list.size(); ++i) { - ClangToken token = (ClangToken) list.get(i); + for (ClangNode element : list) { + ClangToken token = (ClangToken) element; if (token instanceof ClangSyntaxToken) { ClangSyntaxToken syntaxToken = (ClangSyntaxToken) token; @@ -637,7 +636,7 @@ public class DecompilerUtils { * sequence of tokens that are part of the comment and group them into a single * ClangCommentToken. This makes post processing on the full comment string easier. * A single comment string can contain white space that manifests as ClangSyntaxTokens - * with white space as text. + * with white space as text. * @param alltoks is the token stream * @param i is the position of the initial comment token * @param first is the initial comment token @@ -750,6 +749,17 @@ public class DecompilerUtils { token = context.getTokenAtCursor(); } + return getDataType(token); + } + + /** + * Returns the data type for the given token + * + * @param token the token + * @return the data type or null + */ + public static DataType getDataType(ClangToken token) { + Varnode varnode = DecompilerUtils.getVarnodeRef(token); if (varnode != null) { HighVariable highVariable = varnode.getHigh(); diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/hover/DataTypeDecompilerHover.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/hover/DataTypeDecompilerHover.java index cebf1d005e..263af2d369 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/hover/DataTypeDecompilerHover.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/hover/DataTypeDecompilerHover.java @@ -20,16 +20,19 @@ import javax.swing.JComponent; import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.support.FieldLocation; import ghidra.GhidraOptions; -import ghidra.app.decompiler.*; +import ghidra.app.decompiler.ClangFieldToken; +import ghidra.app.decompiler.ClangToken; import ghidra.app.decompiler.component.ClangTextField; +import ghidra.app.decompiler.component.DecompilerUtils; +import ghidra.app.plugin.core.datamgr.util.DataTypeUtils; import ghidra.app.plugin.core.hover.AbstractConfigurableHover; import ghidra.app.util.ToolTipUtils; import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.data.DataType; +import ghidra.program.model.data.*; import ghidra.program.model.listing.Program; -import ghidra.program.model.pcode.HighVariable; -import ghidra.program.model.pcode.Varnode; import ghidra.program.util.ProgramLocation; +import ghidra.util.HTMLUtilities; +import ghidra.util.NumericUtilities; public class DataTypeDecompilerHover extends AbstractConfigurableHover implements DecompilerHoverService { @@ -73,44 +76,77 @@ public class DataTypeDecompilerHover extends AbstractConfigurableHover } ClangToken token = ((ClangTextField) field).getToken(fieldLocation); - - DataType dt = getDataType(token); + DataType dt = DecompilerUtils.getDataType(token); if (dt == null) { - dt = getDataType(token.Parent()); + return null; } - if (dt != null) { - String toolTipText = ToolTipUtils.getToolTipText(dt); - return createTooltipComponent(toolTipText); + String toolTipText = null; + if (token instanceof ClangFieldToken) { + toolTipText = createFieldToolTipText((ClangFieldToken) token, dt); + } + else { + toolTipText = ToolTipUtils.getToolTipText(dt); } - return null; + return createTooltipComponent(toolTipText); } - private DataType getDataType(ClangNode node) { + private String createFieldToolTipText(ClangFieldToken token, DataType parentType) { + ClangFieldToken fieldToken = token; + int offset = fieldToken.getOffset(); + DataType fieldType = getFieldDataType(fieldToken); - if (node instanceof ClangVariableDecl) { - return ((ClangVariableDecl) node).getDataType(); + // + // Parent: BarBar + // Offset: 0x8 + // Field Name: fooField + // + + String BR = HTMLUtilities.BR; + StringBuilder newContent = new StringBuilder(); + newContent.append(""); + + //@formatter:off + newContent.append( + row("Parent: ", HTMLUtilities.friendlyEncodeHTML(parentType.getName()))); + newContent.append( + row("Offset: ", NumericUtilities.toHexString(offset))); + newContent.append( + row("Field Name: ", HTMLUtilities.friendlyEncodeHTML(token.getText()))); + //@formatter:on + + newContent.append("
"); + + newContent.append(BR).append("
").append(BR); + + String toolTipText = ToolTipUtils.getToolTipText(fieldType); + StringBuilder buffy = new StringBuilder(toolTipText); + int start = HTMLUtilities.HTML.length(); + buffy.insert(start, newContent); + return buffy.toString(); + } + + private String row(String... cols) { + StringBuilder sb = new StringBuilder(""); + for (String col : cols) { + sb.append("").append(col).append(""); } + sb.append(""); + return sb.toString(); + } - if (node instanceof ClangReturnType) { - return ((ClangReturnType) node).getDataType(); - } - - if (node instanceof ClangTypeToken) { - return ((ClangTypeToken) node).getDataType(); - } - - if (node instanceof ClangVariableToken) { - Varnode vn = ((ClangVariableToken) node).getVarnode(); - if (vn != null) { - HighVariable high = vn.getHigh(); - if (high != null) { - return high.getDataType(); - } + public static DataType getFieldDataType(ClangFieldToken field) { + DataType fieldDt = DataTypeUtils.getBaseDataType(field.getDataType()); + if (fieldDt instanceof Structure) { + Structure parent = (Structure) fieldDt; + int offset = field.getOffset(); + int n = parent.getLength(); + if (offset >= 0 && offset < n) { + DataTypeComponent dtc = parent.getComponentAt(offset); + fieldDt = dtc.getDataType(); } } - - return null; + return fieldDt; } } diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerVariable.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerVariable.java index 95f0f5464d..c5787b490b 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerVariable.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerVariable.java @@ -25,7 +25,7 @@ import ghidra.program.model.listing.Function; import ghidra.program.model.pcode.*; /** - * A base class that represents a variable from the decompiler. This is either a variable + * A base class that represents a variable from the decompiler. This is either a variable * type or a variable with an optional field access. */ public abstract class DecompilerVariable { @@ -51,7 +51,7 @@ public abstract class DecompilerVariable { return ((ClangTypeToken) variable).getDataType(); } -// not sure if we need this; the type returned here is the structure and not the +// not sure if we need this; the type returned here is the structure and not the // field's type // if (variable instanceof ClangFieldToken) { // return ((ClangFieldToken) variable).getDataType(); @@ -79,8 +79,8 @@ public abstract class DecompilerVariable { } } - // Prefer the type of the first input varnode, unless that type is a 'void *'. - // Usually, in that special case, the output varnode has the correct type information. + // Prefer the type of the first input varnode, unless that type is a 'void *'. + // Usually, in that special case, the output varnode has the correct type information. PcodeOp op = variable.getPcodeOp(); dataType = getInputDataType(op); @@ -193,7 +193,7 @@ public abstract class DecompilerVariable { String castString = casts.isEmpty() ? "" : "\tcasts: " + casts + ",\n"; //@formatter:off return "{\n" + - castString + + castString + "\tvariable: " + variable + ",\n" + "}"; //@formatter:on diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java index 9c99fa273a..19fc0eedf1 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java @@ -27,11 +27,10 @@ import ghidra.program.model.data.AlignedStructurePacker.StructurePackResult; import ghidra.program.model.mem.MemBuffer; import ghidra.util.Msg; import ghidra.util.exception.AssertException; +import ghidra.util.task.TaskMonitor; /** - * Structure implementation for the Database. - * - * + * Structure database implementation. */ class StructureDB extends CompositeDB implements StructureInternal { @@ -42,15 +41,6 @@ class StructureDB extends CompositeDB implements StructureInternal { private int numComponents; // If packed, this does not include the undefined components. private List components; - /** - * Constructor - * - * @param dataMgr - * @param cache - * @param compositeAdapter - * @param componentAdapter - * @param record - */ public StructureDB(DataTypeManagerDB dataMgr, DBObjectCache cache, CompositeDBAdapter compositeAdapter, ComponentDBAdapter componentAdapter, DBRecord record) { @@ -95,35 +85,36 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Eliminate use of old trailing flex-array specification which is now specified using - * a zero-element array. Due to the specification of a new array datatype this must handle - * two cases when an old flex-array component is exists: + * Eliminate use of old trailing flex-array specification which is now specified using a + * zero-element array. Due to the specification of a new array datatype this must handle two + * cases when an old flex-array component is exists: *
    - *
  1. read-only case: associated {@link DataTypeManagerDB} is not updateable. This is the normal - * case for an open archive. A non-DB ArrayDataType must be employed with an immutable + *
  2. read-only case: associated {@link DataTypeManagerDB} is not updatable. This is the + * normal case for an open archive. A non-DB ArrayDataType must be employed with an immutable * {@link DataTypeProxyComponentDB} in place of the flex-array component.
  3. *
  4. upgrade (open for update with open transaction): the flex-array record is modified to - * to indicate an appropriate resolved zero-element array. + * indicate an appropriate resolved zero-element array. *
*

- * NOTE: When {@link DataTypeManagerDB} is instantiated for update an upgrade must be forced based upon the - * {@link CompositeDBAdapter#isFlexArrayMigrationRequired()} indicator. The upgrade logic - * (see {@link DataTypeManagerDB#migrateOldFlexArrayComponentsIfRequired(ghidra.util.task.TaskMonitor)}) - * istantiates all structures within the databases with an open transaaction allowing this method - * to perform the neccessary flex-array record migration. + * NOTE: When {@link DataTypeManagerDB} is instantiated for update an upgrade must be forced + * based upon the {@link CompositeDBAdapter#isFlexArrayMigrationRequired()} indicator. The + * upgrade logic(see + * {@link DataTypeManagerDB#migrateOldFlexArrayComponentsIfRequired(TaskMonitor)}) instantiates + * all structures within the databases with an open transaction allowing this method to perform + * the necessary flex-array record migration. *

- * NOTE: The offset of the migrated flex array component and structure length may change during upgrade - * when packing is enabled when the original packed structure length did not properly factor the flex-array - * alignment. Repack does not occur in the read-only case. + * NOTE: The offset of the migrated flex array component and structure length may change during + * upgrade when packing is enabled when the original packed structure length did not properly + * factor the flex-array alignment. Repack does not occur in the read-only case. * - * @param oldFlexArrayRecord record which corresponds to an olf flex-array component + * @param oldFlexArrayRecord record which corresponds to an old flex-array component * @throws IOException if a database error occurs */ private void migrateOldFlexArray(DBRecord oldFlexArrayRecord) throws IOException { long id = oldFlexArrayRecord.getLongValue(ComponentDBAdapter.COMPONENT_DT_ID_COL); DataType dt = dataMgr.getDataType(id); // could be BadDataType if built-in type is missing - // use zero-element array (need positive element length if dt is BadDataType) + // use zero-element array (need positive element length if type is BadDataType) dt = new ArrayDataType(dt, 0, 1, dataMgr); boolean repack = false; @@ -206,13 +197,14 @@ class StructureDB extends CompositeDB implements StructureInternal { DataTypeComponentDB dtc = null; try { if (dataType == DataType.DEFAULT) { - // assume non-packed structure - structre will grow by 1-byte below + // assume non-packed structure - structure will grow by 1-byte below dtc = new DataTypeComponentDB(dataMgr, this, numComponents, structLength); } else { int componentLength = getPreferredComponentLength(dataType, length); - DBRecord rec = componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, - componentLength, numComponents, structLength, name, comment); + DBRecord rec = + componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, + componentLength, numComponents, structLength, name, comment); dtc = new DataTypeComponentDB(dataMgr, componentAdapter, this, rec); dataType.addParent(this); components.add(dtc); @@ -327,8 +319,9 @@ class StructureDB extends CompositeDB implements StructureInternal { length = getPreferredComponentLength(dataType, length); int offset = getComponent(ordinal).getOffset(); - DBRecord rec = componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, length, - ordinal, offset, name, comment); + DBRecord rec = + componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, length, + ordinal, offset, name, comment); DataTypeComponentDB dtc = new DataTypeComponentDB(dataMgr, componentAdapter, this, rec); dataType.addParent(this); shiftOffsets(idx, 1, dtc.getLength()); @@ -553,8 +546,7 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Removes a defined component at the specified index without - * any alteration to other components. + * Removes a defined component at the specified index without any alteration to other components. * @param index defined component index * @return the defined component which was removed. * @throws IOException if an IO error occurs @@ -568,15 +560,15 @@ class StructureDB extends CompositeDB implements StructureInternal { /** * Removes a defined component at the specified index. - * If this corresponds to a zero-length or bit-field component it will - * be cleared without an offset shift to the remaining components. Removal of - * other component types will result in an offset and ordinal shift - * to the remaining components. In the case of a non-packed - * structure, the resulting shift will cause in a timestamp change - * for this structure. + *

+ * If this corresponds to a zero-length or bit-field component it will be cleared without an + * offset shift to the remaining components. Removal of other component types will result in + * an offset and ordinal shift to the remaining components. In the case of a non-packed + * structure, the resulting shift will cause in a timestamp change for this structure. + * * @param index defined component index - * @param disableOffsetShift if false, and component is not a bit-field, an offset shift - * and possible structure length change will be performed for non-packed structure. + * @param disableOffsetShift if false, and component is not a bit-field, an offset shift and + * possible structure length change will be performed for non-packed structure. */ private void doDeleteWithComponentShift(int index, boolean disableOffsetShift) { DataTypeComponentDB dtc = null; @@ -657,8 +649,9 @@ class StructureDB extends CompositeDB implements StructureInternal { } } + // update numComponents only components = newComponents; - updateComposite(numComponents + ordinalAdjustment, -1, -1, true); // update numComponents only + updateComposite(numComponents + ordinalAdjustment, -1, -1, true); if (isPackingEnabled()) { if (!repack(false, true)) { @@ -666,10 +659,11 @@ class StructureDB extends CompositeDB implements StructureInternal { } } else { - updateComposite(-1, structLength + offsetAdjustment, -1, true); // update length only + // update length only + updateComposite(-1, structLength + offsetAdjustment, -1, true); if (bitFieldRemoved) { repack(false, false); - } + } notifySizeChanged(false); } } @@ -781,10 +775,11 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Create copy of structure for target dtm (source archive information is discarded). + * Create copy of structure for target data type manager (source archive information is + * discarded). *

- * WARNING! copying non-packed structures which contain bitfields can produce invalid results when - * switching endianess due to the differences in packing order. + * WARNING! copying non-packed structures which contain bitfields can produce invalid results + * when switching endianness due to the differences in packing order. * * @param dtm target data type manager * @return cloned structure @@ -799,9 +794,10 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Create cloned structure for target dtm preserving source archive information. WARNING! - * cloning non-packed structures which contain bitfields can produce invalid results when - * switching endianess due to the differences in packing order. + * Create cloned structure for target data type manager preserving source archive information. + *

+ * WARNING! cloning non-packed structures which contain bitfields can produce invalid results + * when switching endianness due to the differences in packing order. * * @param dtm target data type manager * @return cloned structure @@ -884,7 +880,7 @@ class StructureDB extends CompositeDB implements StructureInternal { throw new IndexOutOfBoundsException(ordinal); } int idx = Collections.binarySearch(components, Integer.valueOf(ordinal), - OrdinalComparator.INSTANCE); + OrdinalComparator.INSTANCE); if (idx >= 0) { DataTypeComponentDB dtc = components.remove(idx); dtc.getDataType().removeParent(this); @@ -914,9 +910,11 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Backup from specified defined-component index to the first component which contains the specified offset. - * @param index any defined component index which contains offset - * @param offset offset within structure + * Backup from specified defined-component index to the first component which contains the + * specified offset. + * + * @param index any defined component index which contains offset. + * @param offset offset within structure. * @return index of first defined component containing specific offset. */ private int backupToFirstComponentContainingOffset(int index, int offset) { @@ -934,10 +932,12 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Identify defined-component index of the first non-zero-length component which contains the specified offset. - * If only zero-length components exist, the last zero-length component which contains the offset will be returned. - * @param index any defined component index which contains offset - * @param offset offset within structure + * Identify defined-component index of the first non-zero-length component which contains the + * specified offset. If only zero-length components exist, the last zero-length component which + * contains the offset will be returned. + * + * @param index any defined component index which contains offset. + * @param offset offset within structure. * @return index of first defined component containing specific offset. */ private int indexOfFirstNonZeroLenComponentContainingOffset(int index, int offset) { @@ -954,9 +954,11 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Advance from specified defined-component index to the last component which contains the specified offset. - * @param index any defined component index which contains offset - * @param offset offset within structure + * Advance from specified defined-component index to the last component which contains the + * specified offset. + * + * @param index any defined component index which contains offset. + * @param offset offset within structure. * @return index of last defined component containing specific offset. */ private int advanceToLastComponentContainingOffset(int index, int offset) { @@ -993,7 +995,8 @@ class StructureDB extends CompositeDB implements StructureInternal { shiftOffsets(-index - 1, -1, -1); // updates timestamp } else { - // delete all components containing offset working backward from last such component + // delete all components containing the offset working backward from the last such + // component index = advanceToLastComponentContainingOffset(index, offset); DataTypeComponentDB dtc = components.get(index); while (dtc.containsOffset(offset)) { @@ -1011,7 +1014,7 @@ class StructureDB extends CompositeDB implements StructureInternal { lock.release(); } } - + @Override public void clearAtOffset(int offset) { lock.acquire(); @@ -1109,7 +1112,7 @@ class StructureDB extends CompositeDB implements StructureInternal { lock.release(); } } - + @Override public List getComponentsContaining(int offset) { lock.acquire(); @@ -1141,8 +1144,8 @@ class StructureDB extends CompositeDB implements StructureInternal { } if (!hasSizedComponent && offset != structLength && !isPackingEnabled()) { - // generate undefined componentfor padding offset within non-packed structure - // if offset only occupied by zero-length component + // generate undefined component for padding offset within non-packed structure if + // offset only occupied by zero-length component list.add(generateUndefinedComponent(offset, index)); } return list; @@ -1155,8 +1158,9 @@ class StructureDB extends CompositeDB implements StructureInternal { /** * Generate an undefined component following a binary search across the defined components. * @param offset the offset within this structure which was searched for - * @param missingComponentIndex the defined component binary search index result (must be negative) - * @return undefined component + * @param missingComponentIndex the defined component binary search index result (must be + * negative) + * @return undefined component */ private DataTypeComponentDB generateUndefinedComponent(int offset, int missingComponentIndex) { if (missingComponentIndex >= 0) { @@ -1276,8 +1280,9 @@ class StructureDB extends CompositeDB implements StructureInternal { length = getPreferredComponentLength(dataType, length); - DBRecord rec = componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, length, - ordinal, offset, name, comment); + DBRecord rec = + componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key, length, + ordinal, offset, name, comment); dataType.addParent(this); DataTypeComponentDB dtc = new DataTypeComponentDB(dataMgr, componentAdapter, this, rec); shiftOffsets(index, 1 + additionalShift, length + additionalShift); @@ -1335,15 +1340,16 @@ class StructureDB extends CompositeDB implements StructureInternal { // defined component DataTypeComponentDB origDtc = components.get(index); offset = origDtc.getOffset(); - + if (isPackingEnabled() || length == 0) { // case 1: packed structure or zero-length replacement - do 1-for-1 replacement replacedComponents.add(origDtc); } else if (origDtc.getLength() == 0) { - // case 2: replaced component is zero-length (like-for-like replacement handled by case 1 above - throw new IllegalArgumentException( - "Zero-length component may only be replaced with another zero-length component"); + // case 2: replaced component is zero-length (like-for-like replacement handled + // by case 1 above + throw new IllegalArgumentException("Zero-length component may only be " + + "replaced with another zero-length component"); } else if (origDtc.isBitFieldComponent()) { // case 3: replacing bit-field (must replace all bit-fields which overlap) @@ -1371,7 +1377,7 @@ class StructureDB extends CompositeDB implements StructureInternal { } } else { - // case 4: sized component replacemnt - do 1-for-1 replacement + // case 4: sized component replacement - do 1-for-1 replacement replacedComponents.add(origDtc); } } @@ -1424,11 +1430,11 @@ class StructureDB extends CompositeDB implements StructureInternal { if (offset < 0) { throw new IllegalArgumentException("Offset cannot be negative."); } - + lock.acquire(); try { checkDeleted(); - + if (offset >= structLength) { throw new IllegalArgumentException( "Offset " + offset + " is beyond end of structure (" + structLength + ")."); @@ -1452,15 +1458,17 @@ class StructureDB extends CompositeDB implements StructureInternal { // case 1: only defined component(s) at offset are zero-length if (origDtc.getLength() == 0) { if (isPackingEnabled()) { - // if packed: insert after zero-length component + // if packed: insert after zero-length component return insert(index + 1, dataType, length, name, comment); } - // if non-packed: replace undefined component which immediately follows the zero-length component + // if non-packed: replace undefined component which immediately follows the + // zero-length component replacedComponents.add( new DataTypeComponentDB(dataMgr, this, origDtc.getOrdinal() + 1, offset)); } - // case 2: sized component at offset is bit-field (must replace all bit-fields which contain offset) + // case 2: sized component at offset is bit-field (must replace all bit-fields + // which contain offset) else if (origDtc.isBitFieldComponent()) { replacedComponents.add(origDtc); for (int i = index - 1; i >= 0; i--) { @@ -1482,11 +1490,13 @@ class StructureDB extends CompositeDB implements StructureInternal { index = -index - 1; if (isPackingEnabled()) { - // case 4: if replacing padding for packed struction perform insert at correct ordinal + // case 4: if replacing padding for packed structure perform insert at correct + // ordinal return insert(index, dataType, length, name, comment); } - // case 5: replace undefined component at offset - compute undefined component to be replaced + // case 5: replace undefined component at offset - compute undefined component to + // be replaced int ordinal = offset; if (index > 0) { // use previous defined component to determine ordinal for undefined component @@ -1529,10 +1539,10 @@ class StructureDB extends CompositeDB implements StructureInternal { * * @param dataType the structure to get the component information from. * @throws IllegalArgumentException if any of the component data types are not allowed to - * replace a component in this composite data type. For example, suppose dt1 - * contains dt2. Therefore it is not valid to replace a dt2 component with dt1 since - * this would cause a cyclic dependency. - * @see ghidra.program.database.data.DataTypeDB#replaceWith(ghidra.program.model.data.DataType) + * replace a component in this composite data type. For example, suppose dt1 contains dt2. + * Therefore it is not valid to replace a dt2 component with dt1 since this would cause a + * cyclic dependency. + * @see DataTypeDB#replaceWith(DataType) */ @Override public void replaceWith(DataType dataType) { @@ -1647,7 +1657,7 @@ class StructureDB extends CompositeDB implements StructureInternal { DataType dt = resolvedDts[i]; // ancestry check already performed by caller int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength(); if (length < 0 || dtc.isBitFieldComponent()) { - // TODO: bitfield truncation/expansion may be an issues if data organization changes + // TODO: bitfield truncation/expansion may be an issue if data organization changes length = dtc.getLength(); } else { @@ -1967,10 +1977,10 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Check for available undefined bytes within a non-packed structure for a component - * update with the specified ordinal. - * @param lastOrdinalReplacedOrUpdated the ordinal of a component to be updated - * or the last ordinal with in a sequence of components being replaced. + * Check for available undefined bytes within a non-packed structure for a component update + * with the specified ordinal. + * @param lastOrdinalReplacedOrUpdated the ordinal of a component to be updated or the last + * ordinal with in a sequence of components being replaced. * @param bytesNeeded number of additional bytes required to complete operation * @throws IllegalArgumentException if unable to identify/make sufficient space */ @@ -1995,20 +2005,21 @@ class StructureDB extends CompositeDB implements StructureInternal { /** * Replace the specified components with a new component containing the specified data type. - * If {@link DataType#DEFAULT} is specified as the resolvedDataType only a clear operation + * If {@link DataType#DEFAULT} is specified as the resolvedDataType only a clear operation * is performed. * - * @param origComponents the original sequence of data type components in this structure - * to be replaced. These components must be adjacent components in sequential order. - * If an non-packed undefined component is specified no other component may be included. + * @param origComponents the original sequence of data type components in this structure to be + * replaced. These components must be adjacent components in sequential order. If an + * non-packed undefined component is specified no other component may be included. * @param resolvedDataType the data type of the new component - * @param newOffset offset of replacement component which must fall within origComponents bounds + * @param newOffset offset of replacement component which must fall within origComponents + * bounds * @param length the length of the new component * @param name the field name of the new component * @param comment the comment for the new component * @return the new component or null if only a clear operation was performed. * @throws IOException if database IO error occurs - * @throws IllegalArgumentException if unable to identify/make sufficient space + * @throws IllegalArgumentException if unable to identify/make sufficient space */ private DataTypeComponent replaceComponents(LinkedList origComponents, DataType resolvedDataType, int newOffset, int length, String name, String comment) @@ -2151,8 +2162,8 @@ class StructureDB extends CompositeDB implements StructureInternal { checkAncestry(replacementDt); } catch (Exception e) { - // TODO: should we use Undefined1 instead to avoid cases where - // DEFAULT datatype can not be used (bitfield, aligned structure, etc.) + // TODO: should we use Undefined1 instead to avoid cases where DEFAULT datatype can + // not be used (bitfield, aligned structure, etc.) // TODO: failing silently is rather hidden replacementDt = DataType.DEFAULT; } @@ -2293,8 +2304,8 @@ class StructureDB extends CompositeDB implements StructureInternal { } /** - * Perform structure member repack. - * Perform lazy update of stored alignment introduced with v5 adapter. + * Perform structure member repack. Perform lazy update of stored alignment introduced with v5 + * adapter. */ @Override protected boolean repack(boolean isAutoChange, boolean notify) { @@ -2305,9 +2316,9 @@ class StructureDB extends CompositeDB implements StructureInternal { int oldLength = structLength; int oldAlignment = getComputedAlignment(true); // ensure that alignment has been stored - + computedAlignment = -1; // clear cached alignment - + boolean changed; if (!isPackingEnabled()) { changed = adjustNonPackedComponents(!isAutoChange); @@ -2319,7 +2330,7 @@ class StructureDB extends CompositeDB implements StructureInternal { changed |= updateComposite(components.size(), packResult.structureLength, packResult.alignment, !isAutoChange); } - + if (changed && notify) { if (oldLength != structLength) { notifySizeChanged(isAutoChange);