Skip to content

Commit

Permalink
Make DecodeMode a first-class enumeration
Browse files Browse the repository at this point in the history
* Right now only has values "Default" and "Thumb", matching the same
integers as before (0 and 1, respectively)
* Did some minor cleanup on the Java CMake files to make it easier to
build and understand when the build does fail
  • Loading branch information
ddehaasgt authored and jdorn-gt committed Aug 26, 2022
1 parent eb41017 commit 904bd18
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 35 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ include(Macros.cmake)
include(AlignOf.cmake)
include(CMakePackageConfigHelpers)

option(GTIRB_JAVADOCS "Create javadocs for GTIRB Java API" ON)
option(ENABLE_CONAN "Use Conan to inject dependencies" OFF)

if(ENABLE_CONAN)
Expand Down
34 changes: 22 additions & 12 deletions include/gtirb/CodeBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <gtirb/CfgNode.hpp>
#include <gtirb/Export.hpp>
#include <gtirb/Node.hpp>
#include <gtirb/proto/CodeBlock.pb.h>
#include <boost/range/iterator_range.hpp>
#include <cstdint>
#include <functional>
Expand All @@ -38,6 +39,14 @@ namespace proto {
class CodeBlock;
} // namespace proto

/// \enum DecodeMode
///
/// \brief Variations on decoding a particular ISA
enum class DecodeMode : uint8_t {
Default = proto::All_Default, ///< Default decode mode for all ISAs
Thumb = proto::ARM_Thumb, ///< Thumb decode mode for ARM32
};

/// \class CodeBlock
///
/// \brief A basic block.
Expand All @@ -53,11 +62,12 @@ class GTIRB_EXPORT_API CodeBlock : public CfgNode {
///
/// \param C The Context in which this block will be held.
/// \param Size The size of the block in bytes.
/// \param DecodeMode The decode mode of the block.
/// \param DMode The decode mode of the block.
///
/// \return The newly created CodeBlock.
static CodeBlock* Create(Context& C, uint64_t Size, uint64_t DecodeMode = 0) {
return C.Create<CodeBlock>(C, Size, DecodeMode);
static CodeBlock* Create(Context& C, uint64_t Size,
gtirb::DecodeMode DMode = DecodeMode::Default) {
return C.Create<CodeBlock>(C, Size, DMode);
}

/// \brief Get the \ref ByteInterval this block belongs to.
Expand All @@ -79,7 +89,7 @@ class GTIRB_EXPORT_API CodeBlock : public CfgNode {
/// differentiate between sub-ISAs; ARM and Thumb, for example.
///
/// \return The decode mode.
uint64_t getDecodeMode() const { return DecodeMode; }
gtirb::DecodeMode getDecodeMode() const { return this->DecodeMode; }

/// \brief Get the offset from the beginning of the \ref ByteInterval this
/// block belongs to.
Expand Down Expand Up @@ -111,7 +121,7 @@ class GTIRB_EXPORT_API CodeBlock : public CfgNode {
///
/// This field is used in some ISAs where it is used to
/// differentiate between sub-ISAs; ARM and Thumb, for example.
void setDecodeMode(uint64_t DM) { DecodeMode = DM; }
void setDecodeMode(gtirb::DecodeMode DM) { this->DecodeMode = DM; }

/// \brief Iterator over bytes in this block.
///
Expand Down Expand Up @@ -365,19 +375,19 @@ class GTIRB_EXPORT_API CodeBlock : public CfgNode {

private:
CodeBlock(Context& C) : CfgNode(C, Kind::CodeBlock) {}
CodeBlock(Context& C, uint64_t S, uint64_t Decode)
: CfgNode(C, Kind::CodeBlock), Size(S), DecodeMode(Decode) {}
CodeBlock(Context& C, uint64_t S, uint64_t Decode, const UUID& U)
: CfgNode(C, Kind::CodeBlock, U), Size(S), DecodeMode(Decode) {}
CodeBlock(Context& C, uint64_t S, gtirb::DecodeMode DMode)
: CfgNode(C, Kind::CodeBlock), Size(S), DecodeMode(DMode) {}
CodeBlock(Context& C, uint64_t S, gtirb::DecodeMode DMode, const UUID& U)
: CfgNode(C, Kind::CodeBlock, U), Size(S), DecodeMode(DMode) {}

void setParent(ByteInterval* BI, CodeBlockObserver* O) {
Parent = BI;
Observer = O;
}

static CodeBlock* Create(Context& C, uint64_t Size, uint64_t DecodeMode,
static CodeBlock* Create(Context& C, uint64_t Size, gtirb::DecodeMode DMode,
const UUID& U) {
return C.Create<CodeBlock>(C, Size, DecodeMode, U);
return C.Create<CodeBlock>(C, Size, DMode, U);
}

/// \brief The protobuf message type used for serializing CodeBlock.
Expand Down Expand Up @@ -408,7 +418,7 @@ class GTIRB_EXPORT_API CodeBlock : public CfgNode {
ByteInterval* Parent{nullptr};
CodeBlockObserver* Observer{nullptr};
uint64_t Size{0};
uint64_t DecodeMode{0};
gtirb::DecodeMode DecodeMode{DecodeMode::Default};

friend class Context; // Enables Context::Create
friend class ByteInterval; // Enables to/fromProtobuf, setByteInterval
Expand Down
10 changes: 10 additions & 0 deletions java/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ set(GTIRB_JAVA_API_JARS
"${TARGET_DIR}/gtirb_api-${GTIRB_JAVA_API_VERSION}-javadoc.jar"
)

find_program(
MAVEN mvn
HINTS $ENV{PATH}
DOC "mvn (maven) must be in your PATH to build the GTIRB Java API."
)

if(NOT GTIRB_JAVADOCS)
set(MAVEN_ARGS "-Dmaven.javadoc.skip=true")
endif()

add_custom_command(
OUTPUT ${GTIRB_JAVA_API_JARS} ${GTIRB_JAVA_APIDOCS_DIR}/index.html
COMMAND ${MVN} package
Expand Down
23 changes: 17 additions & 6 deletions java/com/grammatech/gtirb/CodeBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@
* CodeBlock represents a basic block in the binary.
*/
public class CodeBlock extends ByteBlock {
private long decodeMode;
/**
* Variations on decoding a particular ISA
*/
public enum DecodeMode {
Default,
Thumb,
}

private DecodeMode decodeMode;

/**
* Class constructor for a {@link CodeBlock} from a protobuf CodeBlock.
Expand All @@ -32,13 +40,14 @@ private CodeBlock(ByteString protoUuid,
ByteIntervalOuterClass.Block protoBlock, long size,
ByteInterval byteInterval) {
super(protoUuid, protoBlock, size, byteInterval);
this.decodeMode = protoBlock.getCode().getDecodeMode();
this.decodeMode =
DecodeMode.values()[protoCodeBlock.getDecodeModeValue()];
}

/**
* Class constructor for a {@link CodeBlock}.
*/
public CodeBlock(long size, long offset, long decodeMode,
public CodeBlock(long size, long offset, DecodeMode decodeMode,
ByteInterval byteInterval) {
super(size, offset, byteInterval);
this.decodeMode = decodeMode;
Expand All @@ -49,14 +58,16 @@ public CodeBlock(long size, long offset, long decodeMode,
*
* @return The decode mode.
*/
public long getDecodeMode() { return decodeMode; }
public DecodeMode getDecodeMode() { return decodeMode; }

/**
* Set the decode mode of this {@link CodeBlock}.
*
* @param decodeMode The decode mode.
*/
public void setDecodeMode(long decodeMode) { this.decodeMode = decodeMode; }
public void setDecodeMode(DecodeMode decodeMode) {
this.decodeMode = decodeMode;
}

/**
* De-serialize a {@link CodeBlock} from a protobuf Block.
Expand Down Expand Up @@ -92,7 +103,7 @@ ByteIntervalOuterClass.Block.Builder toProtobuf() {

CodeBlockOuterClass.CodeBlock.Builder protoCodeBlock =
CodeBlockOuterClass.CodeBlock.newBuilder();
protoCodeBlock.setDecodeMode(this.getDecodeMode());
protoCodeBlock.setDecodeModeValue(this.decodeMode.ordinal());
protoCodeBlock.setUuid(Util.uuidToByteString(this.getUuid()));
protoCodeBlock.setSize(this.getSize());
protoBlock.setOffset(this.getOffset());
Expand Down
7 changes: 6 additions & 1 deletion proto/CodeBlock.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ syntax = "proto3";
package gtirb.proto;
option java_package = "com.grammatech.gtirb.proto";

enum DecodeMode {
All_Default = 0;
ARM_Thumb = 1;
};

message CodeBlock {
reserved "address";
reserved 2;

bytes uuid = 1;
uint64 size = 3;
uint64 decode_mode = 4;
DecodeMode decode_mode = 4;
}
21 changes: 16 additions & 5 deletions python/gtirb/block.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import typing
from enum import Enum
from uuid import UUID

from .node import Node, _NodeMessage
Expand Down Expand Up @@ -243,10 +244,20 @@ class CodeBlock(ByteBlock, CfgNode):
(e.g. differentiating blocks written in ARM and Thumb).
"""

class DecodeMode(Enum):
""" Variations on decoding a particular ISA
"""

Default = CodeBlock_pb2.DecodeMode.Value("All_Default")
"""Default decode mode for all ISAs"""

Thumb = CodeBlock_pb2.DecodeMode.Value("ARM_Thumb")
"""Thumb decode mode for ARM32"""

def __init__(
self,
*,
decode_mode: int = 0,
decode_mode: DecodeMode = DecodeMode.Default,
size: int = 0,
offset: int = 0,
uuid: typing.Optional[UUID] = None,
Expand All @@ -257,7 +268,7 @@ def __init__(
:param decode_mode: The decode mode of the block,
used in some ISAs to differentiate between sub-ISAs
(e.g. differentiating blocks written in ARM and Thumb).
Defaults to 0.
Defaults to DecodeMode.Default.
:param offset: The offset from the beginning of the byte interval to
which this block belongs.
:param uuid: The UUID of this ``CodeBlock``,
Expand All @@ -269,7 +280,7 @@ def __init__(
super().__init__(
size=size, offset=offset, uuid=uuid, byte_interval=byte_interval
)
self.decode_mode = decode_mode
self.decode_mode = decode_mode # type: CodeBlock.DecodeMode

@classmethod
def _decode_protobuf(
Expand All @@ -281,7 +292,7 @@ def _decode_protobuf(
assert ir
assert isinstance(proto_block, CodeBlock_pb2.CodeBlock)
b = cls(
decode_mode=proto_block.decode_mode,
decode_mode=CodeBlock.DecodeMode(proto_block.decode_mode),
size=proto_block.size,
uuid=uuid,
)
Expand All @@ -292,7 +303,7 @@ def _to_protobuf(self) -> CodeBlock_pb2.CodeBlock:
proto_block = CodeBlock_pb2.CodeBlock()
proto_block.uuid = self.uuid.bytes
proto_block.size = self.size
proto_block.decode_mode = self.decode_mode
proto_block.decode_mode = self.decode_mode.value
return proto_block

def deep_eq(self, other: object) -> bool:
Expand Down
6 changes: 4 additions & 2 deletions src/CodeBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ using namespace gtirb;
void CodeBlock::toProtobuf(MessageType* Message) const {
nodeUUIDToBytes(this, *Message->mutable_uuid());
Message->set_size(this->Size);
Message->set_decode_mode(this->DecodeMode);
Message->set_decode_mode(static_cast<proto::DecodeMode>(this->DecodeMode));
}

ErrorOr<CodeBlock*> CodeBlock::fromProtobuf(Context& C,
Expand All @@ -34,7 +34,9 @@ ErrorOr<CodeBlock*> CodeBlock::fromProtobuf(Context& C,
if (!uuidFromBytes(Message.uuid(), Id))
return {IR::load_error::BadUUID, "Cannot load code block"};

return CodeBlock::Create(C, Message.size(), Message.decode_mode(), Id);
return CodeBlock::Create(
C, Message.size(), static_cast<gtirb::DecodeMode>(Message.decode_mode()),
Id);
}

uint64_t CodeBlock::getOffset() const {
Expand Down
2 changes: 1 addition & 1 deletion src/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inline auto dataBlockKey(const DataBlock* B) {
// Include a dummy "decode mode" to match the key type for CodeBlocks for
// blockKey().
return std::make_tuple(B->getAddress(), B->getSize(), B->getKind(),
(uint64_t)0, B->getUUID());
DecodeMode::Default, B->getUUID());
}

inline auto blockKey(const Node& N) {
Expand Down
8 changes: 4 additions & 4 deletions src/test/CFG.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,8 @@ TEST(Unit_CFG, protobufRoundTrip) {
CFG Result;
std::stringstream ss;

auto B1 = CodeBlock::Create(Ctx, 1, 2);
auto B2 = CodeBlock::Create(Ctx, 3, 4);
auto B1 = CodeBlock::Create(Ctx, 1, DecodeMode::Default);
auto B2 = CodeBlock::Create(Ctx, 3, DecodeMode::Thumb);
auto P1 = ProxyBlock::Create(Ctx);
{
CFG Original;
Expand All @@ -510,11 +510,11 @@ TEST(Unit_CFG, protobufRoundTrip) {
auto It = Range.begin();
EXPECT_EQ(It->getUUID(), B1->getUUID());
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getSize(), 1);
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getDecodeMode(), 2);
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getDecodeMode(), DecodeMode::Default);
++It;
EXPECT_EQ(It->getUUID(), B2->getUUID());
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getSize(), 3);
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getDecodeMode(), 4);
EXPECT_EQ(dyn_cast<CodeBlock>(&*It)->getDecodeMode(), DecodeMode::Thumb);
++It;
EXPECT_EQ(It->getUUID(), P1->getUUID());

Expand Down
8 changes: 4 additions & 4 deletions src/test/CodeBlock.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ TEST(Unit_CodeBlock, ctor) { EXPECT_NE(CodeBlock::Create(Ctx, 0), nullptr); }

TEST(Unit_CodeBlock, getters) {
auto* BI = ByteInterval::Create(Ctx, Addr(0), 2);
auto* B = BI->addBlock<CodeBlock>(Ctx, 0, 1, 2);
auto* B = BI->addBlock<CodeBlock>(Ctx, 0, 1, DecodeMode::Thumb);

EXPECT_EQ(Addr{0}, B->getAddress());
EXPECT_EQ(uint64_t{1}, B->getSize());
EXPECT_EQ(uint64_t{2}, B->getDecodeMode());
EXPECT_EQ(DecodeMode::Thumb, B->getDecodeMode());
EXPECT_EQ(BI, B->getByteInterval());
}

Expand Down Expand Up @@ -83,12 +83,12 @@ TEST(Unit_CodeBlock, protobufRoundTrip) {
std::stringstream ss;
{
Context InnerCtx;
CodeBlock* Original = CodeBlock::Create(InnerCtx, 1234, 98);
CodeBlock* Original = CodeBlock::Create(InnerCtx, 1234, DecodeMode::Thumb);
STH::save(*Original, ss);
}
CodeBlock* Result = STH::load<CodeBlock>(Ctx, ss);

EXPECT_EQ(Result->getSize(), 1234);
EXPECT_EQ(Result->getDecodeMode(), 98);
EXPECT_EQ(Result->getDecodeMode(), DecodeMode::Thumb);
EXPECT_EQ(Result->getByteInterval(), nullptr);
}

0 comments on commit 904bd18

Please sign in to comment.