Package ghidra.trace.database.listing

# Class DBTraceCodeManager

java.lang.Object
ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace>
ghidra.trace.database.listing.DBTraceCodeManager

All Implemented Interfaces:
  `ErrorHandler`, `DBTraceManager`, `DBTraceDelegatingManager<DBTraceCodeSpace>`, `TraceCodeManager`, `TraceCodeOperations`

public class DBTraceCodeManager extends AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace> implements TraceCodeManager, DBTraceDelegatingManager<DBTraceCodeSpace>
The implementation of `TraceCodeManager` for `DBTrace`

The "fluent" interfaces actually create quite a burden to implement here; however, we have some opportunity to extract common code among the various views. There are a few concepts and nuances to consider in order to handle all the fluent cases. The manager implements `TraceCodeOperations` directly, which means it must provide a version of each `TraceCodeUnitsView` that composes all memory address spaces. These are named with the suffix `MemoryView` and extend `AbstractBaseDBTraceCodeUnitsMemoryView`.

In addition, in order to support `getCodeSpace(AddressSpace, boolean)`, it must provide a version of each that can be bound to a single memory address space. Same for `getCodeRegisterSpace(TraceThread, int, boolean)`. These are named with the suffix `View` and extend `AbstractBaseDBTraceCodeUnitsView`.

Furthermore, there are three types of views:

1. Those defined by a table, i.e., defined data and instructions. These extend `AbstractBaseDBTraceDefinedUnitsView`.
2. Those defined implicitly, but may have a support table, i.e., undefined units. This is implemented by `DBTraceUndefinedDataView`.
3. Those defined as the composition of others, i.e., data and defined units. These extend `AbstractComposedDBTraceCodeUnitsView`.

The first two types represent a view of a single code unit type, so they both extend `AbstractSingleDBTraceCodeUnitsView`.

The abstract classes do not nominally implement the trace manager's `TraceBaseCodeUnitsView` nor `TraceBaseDefinedUnitsView` interfaces, because Java prevents the (nominal) implementation of the same interface with different type parameters by the same class. E.g., `DBTraceDataView` would inherit `TraceBaseCodeUnitsView<DBTraceData>` via `AbstractBaseDBTraceCodeUnitsView`, but also `TraceBaseCodeUnitsView<TraceDataUnit>` via `TraceDataView`. Instead, the abstract classes structurally implement those interfaces, meaning they implement the methods required by the interface, but without naming the interface in their `implements` clause. The realizations, e.g., `DBTraceDataView`, nominally implement their corresponding interfaces, meaning they do name the interface. Each realization will inherit the structural implementation from the abstract classes, satisfying the requirements imposed by nominally implementing the interface.

Note, as a result, navigating from declarations in the interfaces to implementations in abstract classes using your IDE may not work as expected :/ . The best way is probably to display the type hierarchy of the interface declaring the desired method. Open one of the classes implementing it, then display all its methods, including those inherited, and search for desired method.

Here is the type hierarchy presented with notes regarding structural interface implementations:

- `AbstractBaseDBTraceCodeUnitsView` structurally implements `TraceBaseCodeUnitsView`
  - `AbstractComposedDBTraceCodeUnitsView`
    - `DBTraceCodeUnitsView` nominally implements `TraceCodeUnitsView`
    - `DBTraceDataView` nominally implements `TraceDataView`
    - `DBTraceDefinedUnitsView` nominally implements `TraceDefinedUnitsView`
  - `AbstractSingleDBTraceCodeUnitsView`
    - `AbstractBaseDBTraceDefinedUnitsView` structurally implements `TraceBaseDefinedUnitsView`
      - `DBTraceDefinedDataView` nominally implements `TraceDefinedDataView`
      - `DBTraceInstructionsView` nominally implements `TraceInstructionsView`
    - `DBTraceUndefinedDataView` nominally implements `TraceUndefinedDataView`

The view composition is not hierarchical, as each may represent a different combination, and one type may appear in several compositions. The single-type views are named first, then the composed views:

- Instructions - single-type view
- Defined Data - single-type view
- Undefined Data - single-type view

Note that while the API presents separate views for defined data and undefined units, both are represented by the type `TraceData`. Meaning, a client with a data unit in hand cannot determine whether it is defined or undefined from its type alone. It must invoke `Data.isDefined()` instead. While the implementation provides a separate type, which we see mirrors the hierarchy of the views' implementation, the client interfaces do not.

- Code Units - Instructions, Defined Data, Undefined Data
- Data - Defined Data, Undefined Data
- Defined Units - Instructions, Defined Data

The `MemoryView` classes compose the memory address spaces into a single view. These need not mirror the same implementation hierarchy as the views they compose. Other than special handling for compositions including undefined units, each memory view need not know anything about the views it composes. There are two abstract classes: `AbstractBaseDBTraceCodeUnitsMemoryView`, which is suitable for composing views without undefined units, and `AbstractWithUndefinedDBTraceCodeUnitsMemoryView`, which extends the base making it suitable for composing views with undefined units. The realizations each extend from the appropriate abstract class. Again, the abstract classes do not nominally implement `TraceBaseCodeUnitsView`. They structurally implement it, partly satisfying the requirements on the realizations, which nominally implement their appropriate interfaces.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `DBTraceCodeManager.DBTraceCodePrototypeEntry`
  A prototype entry

  ## Nested classes/interfaces inherited from class ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager

  `AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry`

  ## Nested classes/interfaces inherited from interface ghidra.trace.database.space.DBTraceDelegatingManager

  `DBTraceDelegatingManager.ExcConsumer<T,E extends Throwable>, DBTraceDelegatingManager.ExcFunction<T,R,E extends Throwable>, DBTraceDelegatingManager.ExcPredicate<T,E extends Throwable>, DBTraceDelegatingManager.ExcSupplier<T,E extends Throwable>`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final DBTraceCodeUnitsMemoryView`
  `codeUnits`
  `protected final DBTraceDataMemoryView`
  `data`
  `protected final DBTraceDataTypeManager`
  `dataTypeManager`
  `protected final DBTraceDefinedDataMemoryView`
  `definedData`
  `protected final DBTraceDefinedUnitsMemoryView`
  `definedUnits`
  `protected final Map<InstructionPrototype,DBTraceCodeManager.DBTraceCodePrototypeEntry>`
  `entriesByProto`
  `protected final DBTraceInstructionsMemoryView`
  `instructions`
  `static final String`
  `NAME`
  `protected final DBTraceOverlaySpaceAdapter`
  `overlayAdapter`
  `protected final DBTracePlatformManager`
  `platformManager`
  `protected final DBCachedObjectStore<DBTraceCodeManager.DBTraceCodePrototypeEntry>`
  `protoStore`
  `protected final DBTraceReferenceManager`
  `referenceManager`
  `protected final Map<AddressSnap,UndefinedDBTraceData>`
  `undefinedCache`
  `protected final DBTraceUndefinedDataMemoryView`
  `undefinedData`

  ### Fields inherited from class ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager

  `baseLanguage, dbh, lock, name, NO_ADDRESS_SPACE, regSpacesByContainer, spaces, spaceStore, spacesView, threadManager, trace`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DBTraceCodeManager(DBHandle dbh, OpenMode openMode, ReadWriteLock lock, TaskMonitor monitor, Language baseLanguage, DBTrace trace, DBTraceThreadManager threadManager, DBTracePlatformManager platformManager, DBTraceDataTypeManager dataTypeManager, DBTraceOverlaySpaceAdapter overlayAdapter, DBTraceReferenceManager referenceManager)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `clearData(Set<Long> deletedDataTypeIds, TaskMonitor monitor)`
  `void`
  `clearPlatform(Lifespan span, AddressRange range, DBTraceGuestPlatform guest, TaskMonitor monitor)`
  `DBTraceCodeUnitsMemoryView`
  `codeUnits()`
  Get a view of all the code units in the listing
  `protected DBTraceCodeSpace`
  `createSpace(AddressSpace space, AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry ent)`
  `DBTraceDataMemoryView`
  `data()`
  Get a view of only the data units (defined and undefined) in the listing
  `DBTraceDefinedDataMemoryView`
  `definedData()`
  Get a view of only the defined data units in the listing
  `DBTraceDefinedUnitsMemoryView`
  `definedUnits()`
  Get a view of only the defined units (data and instructions) in the listing
  `void`
  `deleteLangauge(DBTraceGuestPlatform.DBTraceGuestLanguage guest, TaskMonitor monitor)`
  `void`
  `deletePlatform(DBTraceGuestPlatform guest, TaskMonitor monitor)`
  `UndefinedDBTraceData`
  `doCreateUndefinedUnit(long snap, Address address, TraceThread thread, int frameLevel)`
  `protected DBTraceCodeManager.DBTraceCodePrototypeEntry`
  `doRecordPrototype(InstructionPrototype prototype, DBTraceGuestPlatform.DBTraceGuestLanguage guest, MemBuffer memBuffer, ProcessorContextView context)`
  `protected DBTraceCodeManager.DBTraceCodePrototypeEntry`
  `findOrRecordPrototype(InstructionPrototype prototype, DBTraceGuestPlatform.DBTraceGuestLanguage guest, MemBuffer memBuffer, ProcessorContextView context)`
  `AddressSetView`
  `getCodeAdded(long from, long to)`
  Query for the address set where code units have been added between the two given snaps
  `DBTraceCodeSpace`
  `getCodeRegisterSpace(TraceStackFrame frame, boolean createIfAbsent)`
  Get the code space for registers of the given stack frame
  `DBTraceCodeSpace`
  `getCodeRegisterSpace(TraceThread thread, boolean createIfAbsent)`
  Get the code space for registers of the given thread's innermost frame
  `DBTraceCodeSpace`
  `getCodeRegisterSpace(TraceThread thread, int frameLevel, boolean createIfAbsent)`
  Get the code space for registers of the given thread and frame
  `AddressSetView`
  `getCodeRemoved(long from, long to)`
  Query for the address set where code units have been removed between the two given snaps
  `DBTraceCodeSpace`
  `getCodeSpace(AddressSpace space, boolean createIfAbsent)`
  Get the code space for the memory of the given address space
  `DBTraceCodeSpace`
  `getForSpace(AddressSpace space, boolean createIfAbsent)`
  `protected InstructionPrototype`
  `getPrototypeByKey(int key)`
  `protected static Address`
  `instructionMax(Instruction instruction, boolean includeDelays)`
  `DBTraceInstructionsMemoryView`
  `instructions()`
  Get a view of only the instructions in the listing
  `void`
  `invalidateCache(boolean all)`
  Invalidate this manager's caches
  `protected void`
  `loadPrototypes()`
  `Lock`
  `readLock()`
  `void`
  `replaceDataTypes(Map<Long,Long> dataTypeReplacementMap)`
  `DBTraceUndefinedDataMemoryView`
  `undefinedData()`
  Get a view of only the undefined data units in the listing
  `protected byte[]`
  `valueBytes(RegisterValue rv)`
  `Lock`
  `writeLock()`

  ### Methods inherited from class ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager

  `dbError, get, getActiveSpaces, getBaseLanguage, getForRegisterSpace, getForRegisterSpace, getForRegisterSpace, getLock, getSpaceByName, getTabledSpaces, getTrace, loadSpaces, tableName`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

  ### Methods inherited from interface ghidra.trace.database.space.DBTraceDelegatingManager

  `checkIsInMemory, delegateAddressSet, delegateAny, delegateCollection, delegateDeleteB, delegateDeleteV, delegateFirst, delegateHashSet, delegateRead, delegateRead, delegateReadB, delegateReadI, delegateReadI, delegateReadOr, delegateWrite, delegateWriteAll, delegateWriteI, delegateWriteV`

- ## Field Details

  - ### NAME

    public static final String NAME
    See Also:
      - Constant Field Values

  - ### platformManager

    protected final DBTracePlatformManager platformManager

  - ### dataTypeManager

    protected final DBTraceDataTypeManager dataTypeManager

  - ### overlayAdapter

    protected final DBTraceOverlaySpaceAdapter overlayAdapter

  - ### referenceManager

    protected final DBTraceReferenceManager referenceManager

  - ### protoStore

    protected final DBCachedObjectStore<DBTraceCodeManager.DBTraceCodePrototypeEntry> protoStore

  - ### entriesByProto

    protected final Map<InstructionPrototype,DBTraceCodeManager.DBTraceCodePrototypeEntry> entriesByProto

  - ### codeUnits

    protected final DBTraceCodeUnitsMemoryView codeUnits

  - ### instructions

    protected final DBTraceInstructionsMemoryView instructions

  - ### data

    protected final DBTraceDataMemoryView data

  - ### definedData

    protected final DBTraceDefinedDataMemoryView definedData

  - ### undefinedData

    protected final DBTraceUndefinedDataMemoryView undefinedData

  - ### definedUnits

    protected final DBTraceDefinedUnitsMemoryView definedUnits

  - ### undefinedCache

    protected final Map<AddressSnap,UndefinedDBTraceData> undefinedCache

- ## Constructor Details

  - ### DBTraceCodeManager

    public DBTraceCodeManager(DBHandle dbh, OpenMode openMode, ReadWriteLock lock, TaskMonitor monitor, Language baseLanguage, DBTrace trace, DBTraceThreadManager threadManager, DBTracePlatformManager platformManager, DBTraceDataTypeManager dataTypeManager, DBTraceOverlaySpaceAdapter overlayAdapter, DBTraceReferenceManager referenceManager) throws IOException, VersionException
    Throws:
      `IOException`
      `VersionException`

- ## Method Details

  - ### instructionMax

    protected static Address instructionMax(Instruction instruction, boolean includeDelays) throws AddressOverflowException
    Throws:
      `AddressOverflowException`

  - ### doCreateUndefinedUnit

    public UndefinedDBTraceData doCreateUndefinedUnit(long snap, Address address, TraceThread thread, int frameLevel)

  - ### loadPrototypes

    protected void loadPrototypes()

  - ### valueBytes

    protected byte[] valueBytes(RegisterValue rv)

  - ### doRecordPrototype

    protected DBTraceCodeManager.DBTraceCodePrototypeEntry doRecordPrototype(InstructionPrototype prototype, DBTraceGuestPlatform.DBTraceGuestLanguage guest, MemBuffer memBuffer, ProcessorContextView context)

  - ### findOrRecordPrototype

    protected DBTraceCodeManager.DBTraceCodePrototypeEntry findOrRecordPrototype(InstructionPrototype prototype, DBTraceGuestPlatform.DBTraceGuestLanguage guest, MemBuffer memBuffer, ProcessorContextView context)

  - ### getPrototypeByKey

    protected InstructionPrototype getPrototypeByKey(int key)

  - ### createSpace

    protected DBTraceCodeSpace createSpace(AddressSpace space, AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry ent) throws VersionException, IOException
    Specified by:
      `createSpace` in class `AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace>`
    Throws:
      `VersionException`
      `IOException`

  - ### getForSpace

    public DBTraceCodeSpace getForSpace(AddressSpace space, boolean createIfAbsent)
    Specified by:
      `getForSpace` in interface `DBTraceDelegatingManager<DBTraceCodeSpace>`
    Overrides:
      `getForSpace` in class `AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace>`

  - ### readLock

    public Lock readLock()
    Specified by:
      `readLock` in interface `DBTraceDelegatingManager<DBTraceCodeSpace>`

  - ### writeLock

    public Lock writeLock()
    Specified by:
      `writeLock` in interface `DBTraceDelegatingManager<DBTraceCodeSpace>`

  - ### getCodeSpace

    public DBTraceCodeSpace getCodeSpace(AddressSpace space, boolean createIfAbsent)
    Description copied from interface: `TraceCodeManager`
    Get the code space for the memory of the given address space
    Specified by:
      `getCodeSpace` in interface `TraceCodeManager`
    Parameters:
      `space` - the address space
      `createIfAbsent` - true to create the space if it's not already present
    Returns:
      the space, of `null` if absent and not created

  - ### getCodeRegisterSpace

    public DBTraceCodeSpace getCodeRegisterSpace(TraceThread thread, boolean createIfAbsent)
    Description copied from interface: `TraceCodeManager`
    Get the code space for registers of the given thread's innermost frame
    Specified by:
      `getCodeRegisterSpace` in interface `TraceCodeManager`
    Parameters:
      `thread` - the thread
      `createIfAbsent` - true to create the space if it's not already present
    Returns:
      the space, of `null` if absent and not created

  - ### getCodeRegisterSpace

    public DBTraceCodeSpace getCodeRegisterSpace(TraceThread thread, int frameLevel, boolean createIfAbsent)
    Description copied from interface: `TraceCodeManager`
    Get the code space for registers of the given thread and frame
    Specified by:
      `getCodeRegisterSpace` in interface `TraceCodeManager`
    Parameters:
      `thread` - the thread
      `frameLevel` - the frame (0 for innermost)
      `createIfAbsent` - true to create the space if it's not already present
    Returns:
      the space, of `null` if absent and not created

  - ### getCodeRegisterSpace

    public DBTraceCodeSpace getCodeRegisterSpace(TraceStackFrame frame, boolean createIfAbsent)
    Description copied from interface: `TraceCodeManager`
    Get the code space for registers of the given stack frame

    Note this is simply a shortcut for `TraceCodeManager.getCodeRegisterSpace(TraceThread, int, boolean)`, and does not in any way bind the space to the lifetime of the given frame. Nor, if the frame is moved, will this space move with it.

    Specified by:
      `getCodeRegisterSpace` in interface `TraceCodeManager`
    Parameters:
      `frame` - the frame whose space to get
      `createIfAbsent` - true to create the space if it's not already present
    Returns:
      the space, or `null` if absent and not created

  - ### replaceDataTypes

    public void replaceDataTypes(Map<Long,Long> dataTypeReplacementMap)

  - ### clearData

    public void clearData(Set<Long> deletedDataTypeIds, TaskMonitor monitor)

  - ### clearPlatform

    public void clearPlatform(Lifespan span, AddressRange range, DBTraceGuestPlatform guest, TaskMonitor monitor) throws CancelledException
    Throws:
      `CancelledException`

  - ### deletePlatform

    public void deletePlatform(DBTraceGuestPlatform guest, TaskMonitor monitor) throws CancelledException
    Throws:
      `CancelledException`

  - ### deleteLangauge

    public void deleteLangauge(DBTraceGuestPlatform.DBTraceGuestLanguage guest, TaskMonitor monitor) throws CancelledException
    Throws:
      `CancelledException`

  - ### invalidateCache

    public void invalidateCache(boolean all)
    Description copied from interface: `DBTraceManager`
    Invalidate this manager's caches
    Specified by:
      `invalidateCache` in interface `DBTraceManager`
    Overrides:
      `invalidateCache` in class `AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace>`
    Parameters:
      `all` - probably nothing. Check out implementations of `ManagerDB.invalidateCache(boolean)`.

  - ### codeUnits

    public DBTraceCodeUnitsMemoryView codeUnits()
    Description copied from interface: `TraceCodeOperations`
    Get a view of all the code units in the listing
    Specified by:
      `codeUnits` in interface `TraceCodeOperations`
    Returns:
      the code-units view

  - ### instructions

    public DBTraceInstructionsMemoryView instructions()
    Description copied from interface: `TraceCodeOperations`
    Get a view of only the instructions in the listing

    This view supports the creation of new instruction units. This view also supports clearing.

    Specified by:
      `instructions` in interface `TraceCodeOperations`
    Returns:
      the instruction-units view

  - ### data

    public DBTraceDataMemoryView data()
    Description copied from interface: `TraceCodeOperations`
    Get a view of only the data units (defined and undefined) in the listing
    Specified by:
      `data` in interface `TraceCodeOperations`
    Returns:
      the data-units view

  - ### definedData

    public DBTraceDefinedDataMemoryView definedData()
    Description copied from interface: `TraceCodeOperations`
    Get a view of only the defined data units in the listing

    This view supports the creation of new data units. This view also supports clearing.

    Specified by:
      `definedData` in interface `TraceCodeOperations`
    Returns:
      the defined-data-units view

  - ### undefinedData

    public DBTraceUndefinedDataMemoryView undefinedData()
    Description copied from interface: `TraceCodeOperations`
    Get a view of only the undefined data units in the listing
    Specified by:
      `undefinedData` in interface `TraceCodeOperations`
    Returns:
      return the undefined-data-units view

  - ### definedUnits

    public DBTraceDefinedUnitsMemoryView definedUnits()
    Description copied from interface: `TraceCodeOperations`
    Get a view of only the defined units (data and instructions) in the listing

    This view support clearing.

    Specified by:
      `definedUnits` in interface `TraceCodeOperations`
    Returns:
      the defined-units-view

  - ### getCodeAdded

    public AddressSetView getCodeAdded(long from, long to)
    Description copied from interface: `TraceCodeManager`
    Query for the address set where code units have been added between the two given snaps
    Specified by:
      `getCodeAdded` in interface `TraceCodeManager`
    Parameters:
      `from` - the beginning snap
      `to` - the ending snap
    Returns:
      the view of addresses where units have been added

  - ### getCodeRemoved

    public AddressSetView getCodeRemoved(long from, long to)
    Description copied from interface: `TraceCodeManager`
    Query for the address set where code units have been removed between the two given snaps
    Specified by:
      `getCodeRemoved` in interface `TraceCodeManager`
    Parameters:
      `from` - the beginning snap
      `to` - the ending snap
    Returns:
      the view of addresses where units have been removed