Skip to content

Commit

Permalink
GP-4285 Compressed SLEIGH
Browse files Browse the repository at this point in the history
  • Loading branch information
caheckman committed Feb 28, 2024
1 parent b380fd5 commit 8fbd171
Show file tree
Hide file tree
Showing 207 changed files with 15,220 additions and 6,042 deletions.
1 change: 1 addition & 0 deletions Ghidra/Features/Decompiler/Module.manifest
@@ -0,0 +1 @@
MODULE FILE LICENSE: src/decompile/zlib zlib License
33 changes: 31 additions & 2 deletions Ghidra/Features/Decompiler/buildNatives.gradle
Expand Up @@ -26,7 +26,6 @@ if (findProject(':Generic') == null) {
* Define the "native build model" for building the decompiler executables.
*/
model {

// Define the source files that are compiled and linked to become the decompiler.
// The decompiler source is a bit weird in that all the cpp and headers all live in
// the same directory with other files that are not used by the decompiler.
Expand Down Expand Up @@ -174,6 +173,8 @@ model {
include "slghpattern.cc"
include "semantics.cc"
include "context.cc"
include "slaformat.cc"
include "compression.cc"
include "filemanage.cc"
include "slgh_compile.cc"

Expand All @@ -188,7 +189,27 @@ model {
srcDir "src/decompile/cpp"
}
} // end cpp

if (isCurrentWindows()) {
c {
source {
srcDir "src/decompile/zlib"
include "*.c"
}
}
}
} // end sources (sleigh)

binaries {
all{ b ->
if (b.toolChain in Gcc || b.toolChain in Clang) {
b.linker.args "-lz"
}
else {
b.cppCompiler.define "LOCAL_ZLIB"
}
}
} // end binaries.all (sleigh)
} // end sleigh

} // end components
Expand Down Expand Up @@ -223,7 +244,15 @@ model {
b.cppCompiler.define "WIN64"
b.cppCompiler.define "_WIN64"
}
}
}
b.cCompiler.args "/W3"
b.cCompiler.args "/O2"
b.cCompiler.args "/Oy" // Omit frame pointer
b.cCompiler.define "_CRT_SECURE_NO_DEPRECATE"
b.cCompiler.define "_CRT_NONSTDC_NO_DEPRECATE"
b.cCompiler.define "WIN64"
b.cCompiler.define "ZLIB_WINAPI"
b.cCompiler.define "NO_GZIP"
}
else if (b.toolChain in Clang) {
b.cppCompiler.args "-std=c++11"
Expand Down
2 changes: 2 additions & 0 deletions Ghidra/Features/Decompiler/certification.manifest
Expand Up @@ -4,6 +4,7 @@
##MODULE IP: Modified Nuvola Icons - LGPL 2.1
##MODULE IP: Oxygen Icons - LGPL 3.0
##MODULE IP: Tango Icons - Public Domain
##MODULE IP: zlib License
Module.manifest||GHIDRA||||END|
data/decompiler.theme.properties||GHIDRA||||END|
src/decompile/.cproject||GHIDRA||||END|
Expand Down Expand Up @@ -67,6 +68,7 @@ src/decompile/datatests/twodim.xml||GHIDRA||||END|
src/decompile/datatests/union_datatype.xml||GHIDRA||||END|
src/decompile/datatests/varcross.xml||GHIDRA||||END|
src/decompile/datatests/wayoffarray.xml||GHIDRA||||END|
src/decompile/zlib/README.txt||GHIDRA||||END|
src/main/doc/commonprofile.xsl||GHIDRA||||END|
src/main/doc/cspec.xml||GHIDRA||||END|
src/main/doc/cspec_html.xsl||GHIDRA||||END|
Expand Down
10 changes: 5 additions & 5 deletions Ghidra/Features/Decompiler/src/decompile/cpp/Makefile
Expand Up @@ -50,9 +50,9 @@ YACC=bison
# libraries
#INCLUDES=-I$(BFDHOME)/include
INCLUDES=
BFDLIB=-lbfd -lz
BFDLIB=-lbfd

LNK=
LNK=-lz

# Source files
ALL_SOURCE= $(wildcard *.cc)
Expand Down Expand Up @@ -87,7 +87,7 @@ DECCORE=capability architecture options graph cover block cast typeop database c
printlanguage printc printjava memstate opbehavior paramid signature $(COREEXT_NAMES)
# Files used for any project that use the sleigh decoder
SLEIGH= sleigh pcodeparse pcodecompile sleighbase slghsymbol \
slghpatexpress slghpattern semantics context filemanage
slghpatexpress slghpattern semantics context slaformat compression filemanage
# Additional files for the GHIDRA specific build
GHIDRA= ghidra_arch inject_ghidra ghidra_translate loadimage_ghidra \
typegrp_ghidra database_ghidra ghidra_context cpool_ghidra \
Expand Down Expand Up @@ -260,10 +260,10 @@ test: ghidra_test_dbg
./ghidra_test_dbg

ghidra_dbg: $(GHIDRA_DBG_OBJS)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_dbg $(GHIDRA_DBG_OBJS) $(LNK)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_dbg $(GHIDRA_DBG_OBJS)

ghidra_opt: $(GHIDRA_OPT_OBJS)
$(CXX) $(OPT_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_opt $(GHIDRA_OPT_OBJS) $(LNK)
$(CXX) $(OPT_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_opt $(GHIDRA_OPT_OBJS)

sleigh_dbg: $(SLEIGH_DBG_OBJS)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o sleigh_dbg $(SLEIGH_DBG_OBJS) $(LNK)
Expand Down
6 changes: 3 additions & 3 deletions Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
Expand Up @@ -98,10 +98,10 @@ public:
void encode(Encoder &encoder) const; ///< Encode \b this to a stream
void encode(Encoder &encoder,int4 size) const; ///< Encode \b this and a size to a stream

/// Restore an address from parsed XML
/// Decode an address from a stream
static Address decode(Decoder &decoder);

/// Restore an address and size from parsed XML
/// Decode an address and size from a stream
static Address decode(Decoder &decoder,int4 &size);
};

Expand Down Expand Up @@ -221,7 +221,7 @@ class RangeProperties {
bool seenLast; ///< End of the range is actively specified
public:
RangeProperties(void) { first = 0; last = 0; isRegister = false; seenLast = false; }
void decode(Decoder &decoder); ///< Restore \b this from an XML stream
void decode(Decoder &decoder); ///< Decode \b this from a stream
};

/// \brief A disjoint set of Ranges, possibly across multiple address spaces
Expand Down
Expand Up @@ -236,7 +236,7 @@ public:
void setPrototype(const PrototypePieces &pieces); ///< Set the prototype for a particular function
void setPrintLanguage(const string &nm); ///< Establish a particular output language
void globalify(void); ///< Mark \e all spaces as global
void decodeFlowOverride(Decoder &decoder); ///< Set flow overrides from XML
void decodeFlowOverride(Decoder &decoder); ///< Decode flow overrides from a stream
virtual ~Architecture(void); ///< Destructor

/// \brief Get a string describing \b this architecture
Expand Down
2 changes: 1 addition & 1 deletion Ghidra/Features/Decompiler/src/decompile/cpp/block.hh
Expand Up @@ -132,7 +132,7 @@ private:
// the result of the condition being false
static void replaceEdgeMap(vector<BlockEdge> &vec); ///< Update block references in edges with copy map
void addInEdge(FlowBlock *b,uint4 lab); ///< Add an edge coming into \b this
void decodeNextInEdge(Decoder &decoder,BlockMap &resolver); ///< Restore the next input edge from XML
void decodeNextInEdge(Decoder &decoder,BlockMap &resolver); ///< Decode the next input edge from stream
void halfDeleteInEdge(int4 slot); ///< Delete the \e in half of an edge, correcting indices
void halfDeleteOutEdge(int4 slot); ///< Delete the \e out half of an edge, correcting indices
void removeInEdge(int4 slot); ///< Remove an incoming edge
Expand Down
4 changes: 2 additions & 2 deletions Ghidra/Features/Decompiler/src/decompile/cpp/comment.hh
Expand Up @@ -68,7 +68,7 @@ public:
int4 getUniq(void) const { return uniq; } ///< Get the sub-sorting index
const string &getText(void) const { return text; } ///< Get the body of the comment
void encode(Encoder &encoder) const; ///< Encode the comment to a stream
void decode(Decoder &decoder); ///< Restore the comment from XML
void decode(Decoder &decoder); ///< Decode the comment from a stream
static uint4 encodeCommentType(const string &name); ///< Convert name string to comment property
static string decodeCommentType(uint4 val); ///< Convert comment property to string
};
Expand Down Expand Up @@ -146,7 +146,7 @@ public:
/// \param encoder is the stream encoder
virtual void encode(Encoder &encoder) const=0;

/// \brief Restore all comments from a \<commentdb> element
/// \brief Decode all comments from a \<commentdb> element
///
/// \param decoder is the stream decoder
virtual void decode(Decoder &decoder)=0;
Expand Down
165 changes: 165 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/compression.cc
@@ -0,0 +1,165 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "compression.hh"

namespace ghidra {

/// The compression \b level ranges from 1-9 from faster/least compression to slower/most compression.
/// Use a \b level of 0 for no compression and -1 for the \e default compression level.
/// \param level is the compression level
Compress::Compress(int4 level)

{
compStream.zalloc = Z_NULL;
compStream.zfree = Z_NULL;
compStream.opaque = Z_NULL;
int4 ret = deflateInit(&compStream, level);
if (ret != Z_OK)
throw LowlevelError("Could not initialize deflate stream state");
}

Compress::~Compress(void)

{
deflateEnd(&compStream);
}

/// Return the number of bytes of output space still available. Output may be limited by the amount
/// of space in the output buffer or the amount of data available in the current input buffer.
/// \param buffer is where compressed bytes are stored
/// \param sz is the size, in bytes, of the buffer
/// \param finish is set to \b true if this is the final buffer to add to the stream
/// \return the number of output bytes still available
int4 Compress::deflate(uint1 *buffer,int4 sz,bool finish)

{
int flush = finish ? Z_FINISH : Z_NO_FLUSH;
compStream.avail_out = sz;
compStream.next_out = buffer;

int ret = ::deflate(&compStream, flush);
if (ret == Z_STREAM_ERROR)
throw LowlevelError("Error compressing stream");
return compStream.avail_out;
}

Decompress::Decompress(void)

{
streamFinished = false;
compStream.zalloc = Z_NULL;
compStream.zfree = Z_NULL;
compStream.opaque = Z_NULL;
compStream.avail_in = 0;
compStream.next_in = Z_NULL;
int ret = inflateInit(&compStream);
if (ret != Z_OK)
throw LowlevelError("Could not initialize inflate stream state");
}

/// Return the number of bytes of output space still available. Output may be limited by the amount
/// of space in the output buffer or the amount of data available in the current input buffer.
/// \param buffer is where uncompressed bytes are stored
/// \param sz is the size, in bytes, of the buffer
/// \return the number of output bytes still available
int4 Decompress::inflate(uint1 *buffer,int4 sz)

{
compStream.avail_out = sz;
compStream.next_out = buffer;

int ret = ::inflate(&compStream, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
case Z_STREAM_ERROR:
throw LowlevelError("Error decompressing stream");
case Z_STREAM_END:
streamFinished = true;
break;
default:
break;
}

return compStream.avail_out;
}

Decompress::~Decompress(void)

{
inflateEnd(&compStream);
}

const int4 CompressBuffer::IN_BUFFER_SIZE = 4096;
const int4 CompressBuffer::OUT_BUFFER_SIZE = 4096;

/// \param s is the backing output stream
/// \param level is the level of compression
CompressBuffer::CompressBuffer(ostream &s,int4 level)
: outStream(s), compressor(level)
{
inBuffer = new uint1[IN_BUFFER_SIZE];
outBuffer = new uint1[OUT_BUFFER_SIZE];
setp((char *)inBuffer,(char *)inBuffer + IN_BUFFER_SIZE-1);
}

CompressBuffer::~CompressBuffer(void)

{
delete [] inBuffer;
delete [] outBuffer;
}

/// The compressor is called repeatedly and its output is written to the backing stream
/// until the compressor can no longer fill the \e output buffer.
/// \param lastBuffer is \b true if this is the final set of bytes to add to the compressed stream
void CompressBuffer::flushInput(bool lastBuffer)

{
int len = pptr() - pbase();
compressor.input((uint1 *)pbase(),len);
int4 outAvail;
do {
outAvail = OUT_BUFFER_SIZE;
outAvail = compressor.deflate(outBuffer,outAvail,lastBuffer);
outStream.write((char *)outBuffer,OUT_BUFFER_SIZE-outAvail);
} while(outAvail == 0);
pbump(-len);
}

/// \param c is the final character filling the buffer
/// \return the written character
int CompressBuffer::overflow(int c)

{
if (c != EOF) {
*pptr() = c;
pbump(1);
}
flushInput(false);
return c;
}

/// \return 0 for success
int CompressBuffer::sync(void)

{
flushInput(true);
return 0;
}

}

0 comments on commit 8fbd171

Please sign in to comment.