Skip to content

Commit afbe571

Browse files
committed
Merge remote-tracking branch 'origin/GP-4340_ghidra1_DataTypeConflictNames--SQUASHED'
2 parents 7f58541 + 5dc7347 commit afbe571

File tree

22 files changed

+488
-366
lines changed

22 files changed

+488
-366
lines changed

Ghidra/Debug/Debugger-isf/src/main/java/ghidra/program/model/data/ISF/IsfDataTypeWriter.java

+65-35
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.google.gson.JsonObject;
3030
import com.google.gson.stream.JsonWriter;
3131

32+
import ghidra.program.database.data.DataTypeUtilities;
3233
import ghidra.program.database.data.ProgramDataTypeManager;
3334
import ghidra.program.model.address.Address;
3435
import ghidra.program.model.address.AddressFormatException;
@@ -96,7 +97,8 @@ public class IsfDataTypeWriter extends AbstractIsfWriter {
9697
* @param baseWriter the writer to use when writing data types
9798
* @throws IOException if there is an exception writing the output
9899
*/
99-
public IsfDataTypeWriter(DataTypeManager dtm, List<DataType> target, Writer baseWriter) throws IOException {
100+
public IsfDataTypeWriter(DataTypeManager dtm, List<DataType> target, Writer baseWriter)
101+
throws IOException {
100102
super(baseWriter);
101103
this.baseWriter = baseWriter;
102104
this.dtm = dtm;
@@ -117,11 +119,12 @@ public IsfDataTypeWriter(DataTypeManager dtm, List<DataType> target, Writer base
117119
STRICT = true;
118120
}
119121

122+
@Override
120123
public JsonObject getRootObject(TaskMonitor monitor) throws CancelledException, IOException {
121124
genRoot(monitor);
122125
return data;
123126
}
124-
127+
125128
@Override
126129
protected void genRoot(TaskMonitor monitor) throws CancelledException, IOException {
127130
genMetadata();
@@ -160,7 +163,8 @@ private void genMetadata() {
160163
oskey = metaData.get("Compiler ID");
161164
if (metaData.containsKey("PDB Loaded")) {
162165
os = gson.toJsonTree(new IsfWinOS(metaData));
163-
} else if (metaData.containsKey("Executable Format")) {
166+
}
167+
else if (metaData.containsKey("Executable Format")) {
164168
if (metaData.get("Executable Format").contains("ELF")) {
165169
oskey = "linux";
166170
os = gson.toJsonTree(new IsfLinuxOS(gson, metaData));
@@ -201,15 +205,18 @@ private void genSymbols(TaskMonitor monitor) {
201205
Symbol symbol = iterator.next();
202206
symbolToJson(imageBase, symbolTable, linkages, map, symbol);
203207
}
204-
} else {
208+
}
209+
else {
205210
for (Address addr : requestedAddresses) {
206-
Symbol[] symsFromAddr = symbolTable.getSymbols(addr.add(imageBase.getOffset()));
211+
Symbol[] symsFromAddr =
212+
symbolTable.getSymbols(addr.add(imageBase.getOffset()));
207213
for (Symbol symbol : symsFromAddr) {
208214
symbolToJson(imageBase, symbolTable, linkages, map, symbol);
209215
}
210216
}
211217
}
212-
} else {
218+
}
219+
else {
213220
for (String key : requestedSymbols) {
214221
SymbolIterator iter = symbolTable.getSymbols(key);
215222
while (iter.hasNext()) {
@@ -263,7 +270,7 @@ private void processMap(Map<String, DataType> map, List<String> keylist, TaskMon
263270
monitor.setMaximum(keylist.size());
264271
for (String key : keylist) {
265272
DataType dataType = map.get(key);
266-
if (key.contains(".conflict")) {
273+
if (DataTypeUtilities.isConflictDataType(dataType)) {
267274
continue;
268275
}
269276
obj = getObjectForDataType(dataType, monitor);
@@ -273,28 +280,34 @@ private void processMap(Map<String, DataType> map, List<String> keylist, TaskMon
273280
if (dataType instanceof FunctionDefinition) {
274281
// Would be nice to support this in the future, but Volatility does not
275282
add(functions, dataType.getPathName(), obj);
276-
} else if (IsfUtilities.isBaseDataType(dataType)) {
283+
}
284+
else if (IsfUtilities.isBaseDataType(dataType)) {
277285
add(baseTypes, dataType.getPathName(), obj);
278-
} else if (dataType instanceof TypeDef) {
286+
}
287+
else if (dataType instanceof TypeDef) {
279288
DataType baseDataType = ((TypeDef) dataType).getBaseDataType();
280289
if (IsfUtilities.isBaseDataType(baseDataType)) {
281290
add(baseTypes, dataType.getPathName(), obj);
282-
} else if (baseDataType instanceof Enum) {
291+
}
292+
else if (baseDataType instanceof Enum) {
283293
add(enums, dataType.getPathName(), obj);
284-
} else {
294+
}
295+
else {
285296
add(userTypes, dataType.getPathName(), obj);
286297
}
287-
} else if (dataType instanceof Enum) {
298+
}
299+
else if (dataType instanceof Enum) {
288300
add(enums, dataType.getPathName(), obj);
289-
} else if (dataType instanceof Composite) {
301+
}
302+
else if (dataType instanceof Composite) {
290303
add(userTypes, dataType.getPathName(), obj);
291304
}
292305
monitor.increment();
293306
}
294307
}
295308

296-
private void symbolToJson(Address imageBase, SymbolTable symbolTable, Map<String, Symbol> linkages,
297-
Map<String, JsonObject> map, Symbol symbol) {
309+
private void symbolToJson(Address imageBase, SymbolTable symbolTable,
310+
Map<String, Symbol> linkages, Map<String, JsonObject> map, Symbol symbol) {
298311
String key = symbol.getName();
299312
Address address = symbol.getAddress();
300313
JsonObject sym = map.containsKey(key) ? map.get(key) : new JsonObject();
@@ -305,10 +318,12 @@ private void symbolToJson(Address imageBase, SymbolTable symbolTable, Map<String
305318
sym.addProperty("linkage_name", linkage.getName());
306319
sym.addProperty("address", linkage.getAddress().getOffset());
307320
}
308-
} else {
321+
}
322+
else {
309323
if (address.getAddressSpace().equals(imageBase.getAddressSpace())) {
310324
sym.addProperty("address", address.subtract(imageBase));
311-
} else {
325+
}
326+
else {
312327
sym.addProperty("address", address.getOffset());
313328
}
314329
}
@@ -323,6 +338,7 @@ private void symbolToJson(Address imageBase, SymbolTable symbolTable, Map<String
323338
}
324339
}
325340

341+
@Override
326342
public void write(JsonObject obj) {
327343
gson.toJson(obj, writer);
328344
}
@@ -332,7 +348,8 @@ protected void addSingletons() {
332348
add(baseTypes, "undefined", getTree(newTypedefPointer(null)));
333349
}
334350

335-
protected JsonObject getObjectForDataType(DataType dt, TaskMonitor monitor) throws IOException, CancelledException {
351+
protected JsonObject getObjectForDataType(DataType dt, TaskMonitor monitor)
352+
throws IOException, CancelledException {
336353
IsfObject isf = getIsfObject(dt, monitor);
337354
if (isf != null) {
338355
JsonObject jobj = (JsonObject) getTree(isf);
@@ -351,7 +368,8 @@ protected JsonObject getObjectForDataType(DataType dt, TaskMonitor monitor) thro
351368
* @param monitor the task monitor
352369
* @throws IOException if there is an exception writing the output
353370
*/
354-
protected IsfObject getIsfObject(DataType dt, TaskMonitor monitor) throws IOException, CancelledException {
371+
protected IsfObject getIsfObject(DataType dt, TaskMonitor monitor)
372+
throws IOException, CancelledException {
355373
if (dt == null) {
356374
throw new IOException("Null datatype passed to getIsfObject");
357375
}
@@ -377,21 +395,29 @@ protected IsfObject getIsfObject(DataType dt, TaskMonitor monitor) throws IOExce
377395
if (dt instanceof Dynamic dynamic) {
378396
DataType rep = dynamic.getReplacementBaseType();
379397
return rep == null ? null : getIsfObject(rep, monitor);
380-
} else if (dt instanceof TypeDef typedef) {
398+
}
399+
else if (dt instanceof TypeDef typedef) {
381400
return getObjectTypeDef(typedef, monitor);
382-
} else if (dt instanceof Composite composite) {
401+
}
402+
else if (dt instanceof Composite composite) {
383403
return new IsfComposite(composite, this, monitor);
384-
} else if (dt instanceof Enum enumm) {
404+
}
405+
else if (dt instanceof Enum enumm) {
385406
return new IsfEnum(enumm);
386-
} else if (dt instanceof BuiltInDataType builtin) {
407+
}
408+
else if (dt instanceof BuiltInDataType builtin) {
387409
return new IsfBuiltIn(builtin);
388-
} else if (dt instanceof BitFieldDataType) {
410+
}
411+
else if (dt instanceof BitFieldDataType) {
389412
// skip - not hit
390-
} else if (dt instanceof FunctionDefinition) { /// FAIL
413+
}
414+
else if (dt instanceof FunctionDefinition) { /// FAIL
391415
// skip - not hit
392-
} else if (dt.equals(DataType.DEFAULT)) {
416+
}
417+
else if (dt.equals(DataType.DEFAULT)) {
393418
// skip - not hit
394-
} else {
419+
}
420+
else {
395421
Msg.warn(this, "Unable to write datatype. Type unrecognized: " + dt.getClass());
396422
}
397423

@@ -417,8 +443,8 @@ public IsfObject resolve(DataType dt) {
417443
}
418444
}
419445
}
420-
Msg.warn(this,
421-
"WARNING! conflicting data type names: " + dt.getPathName() + " - " + resolvedType.getPathName());
446+
Msg.warn(this, "WARNING! conflicting data type names: " + dt.getPathName() + " - " +
447+
resolvedType.getPathName());
422448
return resolved.get(dt);
423449
}
424450

@@ -465,8 +491,9 @@ public IsfObject getObjectTypeDeclaration(DataTypeComponent component) {
465491
return newIsfDynamicComponent(dynamic, type, elementCnt);
466492

467493
}
468-
Msg.error(this, dynamic.getClass().getSimpleName() + " returned bad replacementBaseType: "
469-
+ replacementBaseType.getClass().getSimpleName());
494+
Msg.error(this,
495+
dynamic.getClass().getSimpleName() + " returned bad replacementBaseType: " +
496+
replacementBaseType.getClass().getSimpleName());
470497
}
471498
}
472499
return null;
@@ -500,7 +527,7 @@ public IsfObject getObjectDataType(DataType dataType, int componentOffset) {
500527
IsfObject baseObject = getObjectDataType(IsfUtilities.getBaseDataType(dataType));
501528
return new IsfDataTypeTypeDef(dataType, baseObject);
502529
}
503-
if (dataType.getPathName().contains(".conflict")) {
530+
if (DataTypeUtilities.isConflictDataType(dataType)) {
504531
if (!deferredKeys.contains(dataType.getPathName())) {
505532
deferredKeys.add(dataType.getPathName());
506533
}
@@ -513,7 +540,8 @@ public IsfObject getObjectDataType(DataType dataType, int componentOffset) {
513540
*
514541
* @throws CancelledException if the action is cancelled by the user
515542
*/
516-
protected IsfObject getObjectTypeDef(TypeDef typeDef, TaskMonitor monitor) throws CancelledException {
543+
protected IsfObject getObjectTypeDef(TypeDef typeDef, TaskMonitor monitor)
544+
throws CancelledException {
517545
DataType dataType = typeDef.getDataType();
518546
String typedefName = typeDef.getPathName();
519547

@@ -527,7 +555,8 @@ protected IsfObject getObjectTypeDef(TypeDef typeDef, TaskMonitor monitor) throw
527555
return newTypedefUser(typeDef, isfObject);
528556
}
529557
return newTypedefPointer(typeDef);
530-
} catch (Exception e) {
558+
}
559+
catch (Exception e) {
531560
Msg.error(this, "TypeDef error: " + e);
532561
}
533562
clearResolve(typedefName, baseType);
@@ -544,7 +573,8 @@ public void requestAddress(String key) throws IOException {
544573
return;
545574
}
546575
requestedAddresses.add(address);
547-
} catch (AddressFormatException e) {
576+
}
577+
catch (AddressFormatException e) {
548578
throw new IOException("Bad address format: " + key);
549579
}
550580
}

Ghidra/Features/Base/ghidra_scripts/FindDataTypeConflictCauseScript.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
1617
// Search for the root cause of a datatype conflict based upon a selected datatype.
1718
//@category Data Types
1819
import java.util.*;
@@ -55,8 +56,8 @@ protected void run() throws Exception {
5556
}
5657

5758
DataType selectedDt = DataTypeUtilities.getBaseDataType(selectedDatatypes.get(0));
58-
if (selectedDt instanceof Pointer || selectedDt instanceof Array) {
59-
popup("Selected datatype must not be a Pointer or Array");
59+
if (selectedDt == null) {
60+
popup("Selected datatype must not be a default Pointer");
6061
return;
6162
}
6263

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSyncInfo.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,13 @@ public boolean hasChange() {
190190
if (sourceDt == null) {
191191
return true;
192192
}
193-
if (!DataTypeSynchronizer.namesAreEquivalent(sourceDt, refDt)) {
194-
return true;
195-
}
196-
if (!StringUtils.equals(refDt.getDescription(), sourceDt.getDescription())) {
197-
return true;
193+
if (!DataTypeSynchronizer.isPointerOrArray(refDt)) {
194+
if (!DataTypeSynchronizer.namesAreEquivalent(sourceDt, refDt)) {
195+
return true;
196+
}
197+
if (!StringUtils.equals(refDt.getDescription(), sourceDt.getDescription())) {
198+
return true;
199+
}
198200
}
199201
DataType dt = sourceDt.clone(refDt.getDataTypeManager());
200202
return !dt.isEquivalent(refDt);

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSynchronizer.java

+23-32
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
import ghidra.app.util.ToolTipUtils;
2929
import ghidra.app.util.html.HTMLDataTypeRepresentation;
3030
import ghidra.app.util.html.MissingArchiveDataTypeHTMLRepresentation;
31-
import ghidra.program.database.data.DataTypeManagerDB;
32-
import ghidra.program.database.data.ProgramDataTypeManager;
31+
import ghidra.program.database.data.*;
3332
import ghidra.program.model.data.*;
3433
import ghidra.util.*;
3534
import ghidra.util.exception.AssertException;
@@ -127,11 +126,13 @@ public static void commitAssumingTransactionsOpen(DataTypeManager sourceDTM, Dat
127126
// not handled by resolve.
128127
long lastChangeTime = refDT.getLastChangeTime();
129128
DataType sourceDT = sourceDTM.resolve(refDT, DataTypeConflictHandler.REPLACE_HANDLER);
130-
if (!namesAreEquivalent(refDT, sourceDT)) {
131-
renameDataType(sourceDTM, sourceDT, refDT);
132-
}
133-
if (!StringUtils.equals(refDT.getDescription(), sourceDT.getDescription())) {
134-
sourceDT.setDescription(refDT.getDescription());
129+
if (!isPointerOrArray(refDT)) {
130+
if (!namesAreEquivalent(refDT, sourceDT)) {
131+
renameDataType(sourceDTM, sourceDT, refDT);
132+
}
133+
if (!StringUtils.equals(refDT.getDescription(), sourceDT.getDescription())) {
134+
sourceDT.setDescription(refDT.getDescription());
135+
}
135136
}
136137
sourceDT.setLastChangeTime(lastChangeTime);
137138
refDT.setLastChangeTimeInSourceArchive(lastChangeTime);
@@ -140,11 +141,13 @@ public static void commitAssumingTransactionsOpen(DataTypeManager sourceDTM, Dat
140141
public static void updateAssumingTransactionsOpen(DataTypeManager refDTM, DataType sourceDT) {
141142
long lastChangeTime = sourceDT.getLastChangeTime();
142143
DataType refDT = refDTM.resolve(sourceDT, DataTypeConflictHandler.REPLACE_HANDLER);
143-
if (!namesAreEquivalent(refDT, sourceDT)) {
144-
renameDataType(refDTM, refDT, sourceDT);
145-
}
146-
if (!StringUtils.equals(sourceDT.getDescription(), refDT.getDescription())) {
147-
refDT.setDescription(sourceDT.getDescription());
144+
if (!isPointerOrArray(sourceDT)) {
145+
if (!namesAreEquivalent(refDT, sourceDT)) {
146+
renameDataType(refDTM, refDT, sourceDT);
147+
}
148+
if (!StringUtils.equals(sourceDT.getDescription(), refDT.getDescription())) {
149+
refDT.setDescription(sourceDT.getDescription());
150+
}
148151
}
149152
refDT.setLastChangeTimeInSourceArchive(lastChangeTime);
150153
refDT.setLastChangeTime(lastChangeTime);
@@ -252,14 +255,10 @@ private static void renameDataType(DataTypeManager sourceDTM, DataType sourceDT,
252255
}
253256
}
254257
String name = dtToCopy.getName();
255-
int index = name.indexOf(DataType.CONFLICT_SUFFIX);
256-
if (index > 0) {
257-
name = name.substring(0, index);
258-
}
259258
CategoryPath path = sourceDT.getCategoryPath();
260259
if (sourceDTM.getDataType(path, name) != null) {
261260
name = ((DataTypeManagerDB) sourceDTM).getUnusedConflictName(sourceDT.getCategoryPath(),
262-
name);
261+
dtToCopy);
263262
}
264263
try {
265264
sourceDT.setName(name);
@@ -282,27 +281,19 @@ private static boolean isAutoNamedTypedef(DataType dt) {
282281
return false;
283282
}
284283

285-
public static boolean namesAreEquivalent(DataType dt1, DataType dt2) {
284+
static boolean isPointerOrArray(DataType dt) {
285+
return (dt instanceof Pointer) || (dt instanceof Array);
286+
}
287+
288+
static boolean namesAreEquivalent(DataType dt1, DataType dt2) {
286289
if (isAutoNamedTypedef(dt1)) {
287290
return isAutoNamedTypedef(dt2);
288291
}
289292
else if (isAutoNamedTypedef(dt2)) {
290293
return false;
291294
}
292-
String name1 = dt1.getName();
293-
String name2 = dt2.getName();
294-
if (name1.equals(name2)) {
295-
return true;
296-
}
297-
int index = name1.indexOf(DataType.CONFLICT_SUFFIX);
298-
if (index > 0) {
299-
name1 = name1.substring(0, index);
300-
}
301-
index = name2.indexOf(DataType.CONFLICT_SUFFIX);
302-
if (index > 0) {
303-
name2 = name2.substring(0, index);
304-
}
305-
return name1.equals(name2);
295+
return DataTypeUtilities.getNameWithoutConflict(dt1)
296+
.equals(DataTypeUtilities.getNameWithoutConflict(dt2));
306297

307298
}
308299

0 commit comments

Comments
 (0)