From 0ed83875fcb25b57ce16d2fb8a23f307c950140e Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Tue, 23 Feb 2021 12:33:16 -0500 Subject: [PATCH] GP-696 Raised ProgramDB version to 23 (upgrade not required). Implement BigRefList for from-refs --- .../ghidra/program/database/ProgramDB.java | 4 +++- .../database/references/BigRefListV0.java | 21 ++++++++++++------- .../database/references/FromAdapterV0.java | 3 +++ .../references/ReferenceDBManager.java | 1 + 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java index 331393df72..237f44302d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java @@ -96,8 +96,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM * 19-Jun-2020 - version 22 - Corrected fixed length indexing implementation causing * change in index table low-level storage for newly * created tables. + * 18-Feb-2021 - version 23 Added support for Big Reflist for tracking FROM references. + * Primarily used for large numbers of Entry Point references. */ - static final int DB_VERSION = 22; + static final int DB_VERSION = 23; /** * UPGRADE_REQUIRED_BFORE_VERSION should be changed to DB_VERSION anytime the diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java index e4b5b67c75..4f8e5f2dda 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java @@ -62,17 +62,17 @@ class BigRefListV0 extends RefList { * @param address address associated with this list * @param adapter entry record storage adapter * @param addrMap address map for encoding/decoding addresses - * @param program + * @param program associated Program * @param cache RefList object cache * @param isFrom true for from-adapter use, false for to-adapter use - * @throws IOException + * @throws IOException if database IO error occurs */ BigRefListV0(Address address, RecordAdapter adapter, AddressMap addrMap, ProgramDB program, DBObjectCache cache, boolean isFrom) throws IOException { super(addrMap.getKey(address, true), address, adapter, addrMap, program, cache, isFrom); record = ToAdapter.TO_REFS_SCHEMA.createRecord(key); - table = program.getDBHandle().createTable(BASE_TABLE_NAME + Long.toHexString(key), - BIG_REFS_SCHEMA, new int[] { ADDRESS_COL }); + table = program.getDBHandle() + .createTable(getTableName(), BIG_REFS_SCHEMA, new int[] { ADDRESS_COL }); } /** @@ -80,9 +80,10 @@ class BigRefListV0 extends RefList { * @param rec existing refList record * @param adapter entry record storage adapter * @param addrMap address map for encoding/decoding addresses - * @param program + * @param program associated Program * @param cache RefList object cache * @param isFrom true for from-adapter use, false for to-adapter use + * @throws IOException if database IO error occurs */ BigRefListV0(DBRecord rec, RecordAdapter adapter, AddressMap addrMap, ProgramDB program, DBObjectCache cache, boolean isFrom) throws IOException { @@ -91,11 +92,10 @@ class BigRefListV0 extends RefList { if (rec.getBinaryData(ToAdapter.REF_DATA_COL) != null) { throw new IllegalArgumentException("Invalid reference record"); } - String tableName = BASE_TABLE_NAME + Long.toHexString(rec.getKey()); - table = program.getDBHandle().getTable(tableName); + table = program.getDBHandle().getTable(getTableName()); if (table == null) { throw new IOException( - "BigRefList table not found for " + address + " (" + tableName + ")"); + "BigRefList table not found for " + address + " (" + getTableName() + ")"); } if (!isFrom) { refLevel = rec.getByteValue(ToAdapter.REF_LEVEL_COL); @@ -103,6 +103,11 @@ class BigRefListV0 extends RefList { record = rec; } + private String getTableName() { + String prefix = isFrom ? "From" : ""; + return prefix + BASE_TABLE_NAME + Long.toHexString(key); + } + @Override public RefList checkRefListSize(DBObjectCache cache, int newSpaceRequired) { return this; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java index f1597d3dbc..e05b0cf90f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java @@ -60,6 +60,9 @@ class FromAdapterV0 extends FromAdapter { long fromAddr) throws IOException { DBRecord rec = table.getRecord(fromAddr); if (rec != null) { + if (rec.getBinaryData(REF_DATA_COL) == null) { + return new BigRefListV0(rec, this, addrMap, program, cache, true); + } return new RefListV0(rec, this, addrMap, program, cache, true); } return null; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java index 867e454da0..f3f47f5be9 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java @@ -382,6 +382,7 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan if (fromRefs == null) { fromRefs = fromAdapter.createRefList(program, fromCache, fromAddr); } + fromRefs = fromRefs.checkRefListSize(fromCache, 1); fromRefs.addRef(fromAddr, toAddr, type, opIndex, -1, isPrimary, sourceType, isOffset, isShifted, offsetOrShift);