mirror of
https://github.com/radareorg/r2ghidra.git
synced 2026-11-07 06:25:57 -10:00
Remove the pugixml dependency in favor of r2's rxml API
This commit is contained in:
1 parent
27da2f8b6b
commit
826ffb55ba
16 files changed
+46
-323
No files matched your search
@@ -20,7 +20,6 @@ ghidra/sleighc
|
||||
|
||||
subprojects/.wraplock
|
||||
subprojects/ghidra-native
|
||||
subprojects/pugixml
|
||||
subprojects/zlib
|
||||
/Makefile
|
||||
config.h
|
||||
|
||||
+1
-3
@@ -22,10 +22,8 @@ projects, each distributed under its own license:
|
||||
- **ghidra-native** (statically linked) — Apache License 2.0. See
|
||||
`subprojects/ghidra-native/LICENSE` once fetched, or the upstream
|
||||
repository at <https://github.com/radareorg/ghidra-native>.
|
||||
- **pugixml** (vendored under `subprojects/pugixml`) — MIT License.
|
||||
See `subprojects/pugixml/LICENSE.md`.
|
||||
- **zlib** (vendored under `subprojects/zlib`) — zlib license. See
|
||||
`subprojects/zlib/LICENSE`.
|
||||
|
||||
The Apache-2.0, MIT and zlib licenses are all compatible with
|
||||
The Apache-2.0 and zlib licenses are both compatible with
|
||||
distribution under the LGPLv3 of the combined work.
|
||||
@@ -45,7 +45,6 @@ install uninstall user-install user-uninstall:
|
||||
|
||||
mrproper: clean
|
||||
rm -rf subprojects/ghidra-native
|
||||
rm -rf subprojects/pugixml
|
||||
rm -rf subprojects/zlib
|
||||
|
||||
r2ghidra_sleigh.zip dist: ghidra-processors.txt
|
||||
|
||||
@@ -154,7 +154,5 @@ under its own license:
|
||||
* [ghidra-native](https://github.com/radareorg/ghidra-native) — Apache
|
||||
License 2.0 (statically linked; this is the native portion of the
|
||||
Ghidra decompiler that r2ghidra is built around).
|
||||
* [pugixml](https://pugixml.org/) — MIT License (vendored under
|
||||
`subprojects/pugixml`).
|
||||
* [zlib](https://zlib.net/) — zlib License (vendored under
|
||||
`subprojects/zlib`).
|
||||
@@ -2,6 +2,5 @@
|
||||
#define R2GHIDRA_CONFIG_H 1
|
||||
|
||||
#define R2GHIDRA_VERSION "@R2GHIDRA_VERSION@"
|
||||
#define R2GHIDRA_USE_RXML @USE_RXML@
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,5 @@ R2_CFLAGS=@R2_CFLAGS@
|
||||
R2_LDFLAGS=@R2_LDFLAGS@
|
||||
VERSION=@VERSION@
|
||||
|
||||
R2GHIDRA_USE_RXML=@USE_RXML@
|
||||
|
||||
R2_USER_PLUGINS=@R2_USER_PLUGINS@
|
||||
R2_LIBR_PLUGINS=@R2_LIBR_PLUGINS@
|
||||
@@ -18,7 +18,6 @@ control_c() {
|
||||
exit 1
|
||||
}
|
||||
trap control_c 2
|
||||
USE_RXML=0
|
||||
split_host() {
|
||||
S="$"
|
||||
while : ; do
|
||||
@@ -174,10 +173,6 @@ System types:
|
||||
--target=TARGET configure for building compilers for TARGET [HOST]
|
||||
EOF2
|
||||
|
||||
printf "
|
||||
Optional Features:
|
||||
--with-rxml use r2 apis instead of pugixml
|
||||
"
|
||||
printf "
|
||||
Some influential environment variables:
|
||||
CXX C++ compiler command
|
||||
@@ -245,7 +240,7 @@ echo "AUTHOR: pancake"
|
||||
echo "EMAIL: [email protected]"
|
||||
echo "LANGS: c++"
|
||||
echo "PKGCONFIG: r_core r_asm r_anal"
|
||||
echo "FLAGS: --with-rxml"
|
||||
echo "FLAGS: "
|
||||
exit 0
|
||||
;;
|
||||
--cache-file)
|
||||
@@ -297,7 +292,6 @@ echo "FLAGS: --with-rxml"
|
||||
--mandir)
|
||||
MANDIR="$value"; ;;
|
||||
|
||||
"--with-rxml") USE_RXML="1"; ;;
|
||||
*) if [ "$value" ]; then eval "`echo $flag2=$value`" ;
|
||||
else echo ; echo "WARNING: Unknown flag '$flag'." >&2 ; echo ; fi ;;
|
||||
esac
|
||||
@@ -315,7 +309,7 @@ parse_options "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CXX CXXFLAGS LDFLAGS HAVE_LANG_CXX CPP HAVE_GIT GIT PKGCONFIG R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE R2ASM_CFLAGS R2ASM_LDFLAGS HAVE_PKGCFG_R_ASM R2ANAL_CFLAGS R2ANAL_LDFLAGS HAVE_PKGCFG_R_ANAL HAVE_R2 R2 USE_RXML R2_PREFIX R2_USER_PLUGINS R2_LIBR_PLUGINS R2GHIDRA_VERSION"
|
||||
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CXX CXXFLAGS LDFLAGS HAVE_LANG_CXX CPP HAVE_GIT GIT PKGCONFIG R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE R2ASM_CFLAGS R2ASM_LDFLAGS HAVE_PKGCFG_R_ASM R2ANAL_CFLAGS R2ANAL_LDFLAGS HAVE_PKGCFG_R_ANAL HAVE_R2 R2 R2_PREFIX R2_USER_PLUGINS R2_LIBR_PLUGINS R2GHIDRA_VERSION"
|
||||
|
||||
create_environ
|
||||
|
||||
@@ -430,6 +424,14 @@ tmp=`${PKGCONFIG} --libs r_core 2>/dev/null`
|
||||
if [ $? = 0 ]; then
|
||||
echo yes; HAVE_PKGCFG_R_CORE=1;
|
||||
R2_LDFLAGS=$tmp; fi; fi
|
||||
printf 'checking radare2 >= 6.1.4 for the rxml API... '
|
||||
if ${PKGCONFIG} --atleast-version=6.1.4 r_core 2>/dev/null; then
|
||||
echo yes
|
||||
else
|
||||
echo no
|
||||
echo 'ERROR: r2ghidra requires radare2 >= 6.1.4' >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
|
||||
printf 'checking pkg-config flags for r_asm... '
|
||||
tmp=`${PKGCONFIG} --cflags r_asm 2>/dev/null`
|
||||
@@ -566,7 +568,7 @@ do_remove
|
||||
if [ "$QUIET" = 0 ]; then
|
||||
echo
|
||||
echo "Final report:"
|
||||
for A in USE_RXML VERSION R2_PREFIX PREFIX PKGCONFIG ; do
|
||||
for A in VERSION R2_PREFIX PREFIX PKGCONFIG ; do
|
||||
eval VAL="\$${A}"
|
||||
[ -z "${VAL}" ] && VAL="\"\""
|
||||
echo " - ${A} = ${VAL}"
|
||||
|
||||
+1
-3
@@ -15,8 +15,6 @@ CHKPRG BISON bison
|
||||
CHKPRG FLEX flex
|
||||
))
|
||||
|
||||
ARG_WITH USE_RXML rxml use r2 apis instead of pugixml ;
|
||||
|
||||
EXEC! R2_PREFIX r2 -H R2_PREFIX ;
|
||||
EXEC! R2_USER_PLUGINS r2 -H R2_USER_PLUGINS ;
|
||||
EXEC! R2_LIBR_PLUGINS r2 -H R2_LIBR_PLUGINS ;
|
||||
@@ -25,4 +23,4 @@ R2GHIDRA_VERSION = $VERSION ;
|
||||
|
||||
SUBDIRS config.mk config.h Makefile ;
|
||||
|
||||
REPORT USE_RXML VERSION R2_PREFIX PREFIX PKGCONFIG ;
|
||||
REPORT VERSION R2_PREFIX PREFIX PKGCONFIG ;
|
||||
+1
-8
@@ -71,7 +71,7 @@ if cpp.get_id() == 'msvc'
|
||||
cpp.find_library('r_config', dirs: r2libdir),
|
||||
]
|
||||
else
|
||||
r_core = dependency('r_core')
|
||||
r_core = dependency('r_core', version : '>=6.1.4')
|
||||
endif
|
||||
|
||||
r2ghidra_version = meson.project_version()
|
||||
@@ -104,13 +104,6 @@ slgh_static = ghidra.get_variable('slgh_static')
|
||||
|
||||
r2ghidra_deps = [r_core, zlib]
|
||||
r2ghidra_cpp_args = []
|
||||
if get_option('rxml')
|
||||
r2ghidra_cpp_args += ['-DR2GHIDRA_USE_RXML=1']
|
||||
else
|
||||
pugixml = subproject('pugixml').get_variable('pugixml_dep')
|
||||
r2ghidra_deps += pugixml
|
||||
r2ghidra_cpp_args += ['-DR2GHIDRA_USE_RXML=0']
|
||||
endif
|
||||
|
||||
r2ghidra_core_sources = [
|
||||
r2ghidra_sources,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
option('rxml', type: 'boolean', value: true, description: 'Use radare2 rxml APIs instead of pugixml')
|
||||
+27
-231
@@ -7,18 +7,12 @@
|
||||
#undef LoadImage
|
||||
#endif
|
||||
|
||||
#define TEST_UNKNOWN_NODES 0
|
||||
|
||||
#ifndef R2GHIDRA_USE_RXML
|
||||
#define R2GHIDRA_USE_RXML 1
|
||||
#endif
|
||||
|
||||
#include <funcdata.hh>
|
||||
#include <r_util.h>
|
||||
#if R2GHIDRA_USE_RXML
|
||||
#include "r_util/r_xml.h"
|
||||
#else
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#if R2_VERSION_NUMBER < 60104
|
||||
#error r2ghidra requires radare2 >= 6.1.4 for the rxml API
|
||||
#endif
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@@ -30,7 +24,7 @@ struct ParseCodeXMLContext {
|
||||
std::map<uintm, PcodeOp *> ops;
|
||||
std::map<ut64, Varnode *> varnodes;
|
||||
std::map<ut64, Symbol *> symbols;
|
||||
|
||||
|
||||
explicit ParseCodeXMLContext(ghidra::Funcdata *func) : func (func) {
|
||||
for (auto it=func->beginOpAll (); it != func->endOpAll (); it++) {
|
||||
ops[it->first.getTime ()] = it->second;
|
||||
@@ -50,11 +44,9 @@ struct ParseCodeXMLContext {
|
||||
}
|
||||
};
|
||||
|
||||
#if R2GHIDRA_USE_RXML
|
||||
#define ANNOTATOR_RXML_PARAMS RXmlNode *node, ParseCodeXMLContext *ctx, std::vector<RCodeMetaItem> *out
|
||||
#define ANNOTATOR_RXML [](ANNOTATOR_RXML_PARAMS) -> void
|
||||
#define ANNOTATOR_PARAMS RXmlNode *node, ParseCodeXMLContext *ctx, std::vector<RCodeMetaItem> *out
|
||||
|
||||
void AnnotateOprefRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
void AnnotateOpref(ANNOTATOR_PARAMS) {
|
||||
const char *opref_str = rxml_dom_get_attribute(node, "opref");
|
||||
if (!opref_str) {
|
||||
return;
|
||||
@@ -76,7 +68,7 @@ void AnnotateOprefRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
annotation.offset.offset = op->getAddr().getOffset();
|
||||
}
|
||||
|
||||
void AnnotateFunctionNameRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
void AnnotateFunctionName(ANNOTATOR_PARAMS) {
|
||||
const char *func_name = rxml_dom_child_value(node);
|
||||
if (!func_name) {
|
||||
return;
|
||||
@@ -114,7 +106,7 @@ void AnnotateFunctionNameRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
}
|
||||
}
|
||||
|
||||
void AnnotateCommentOffsetRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
void AnnotateCommentOffset(ANNOTATOR_PARAMS) {
|
||||
const char *off_str = rxml_dom_get_attribute(node, "off");
|
||||
if (!off_str) {
|
||||
return;
|
||||
@@ -130,157 +122,12 @@ void AnnotateCommentOffsetRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
annotation.offset.offset = off;
|
||||
}
|
||||
|
||||
void AnnotateColorRxml(ANNOTATOR_RXML_PARAMS);
|
||||
void AnnotateVariableRxml(ANNOTATOR_RXML_PARAMS);
|
||||
|
||||
static const std::map<std::string, std::vector<void (*)(ANNOTATOR_RXML_PARAMS)>> annotators_rxml = {
|
||||
{ "statement", { AnnotateOprefRxml } },
|
||||
{ "op", { AnnotateOprefRxml, AnnotateColorRxml } },
|
||||
{ "comment", { AnnotateCommentOffsetRxml, AnnotateColorRxml } },
|
||||
{ "variable", { AnnotateVariableRxml, AnnotateColorRxml } },
|
||||
{ "funcname", { AnnotateFunctionNameRxml, AnnotateColorRxml } },
|
||||
{ "type", { AnnotateColorRxml } },
|
||||
{ "syntax", { AnnotateColorRxml } }
|
||||
};
|
||||
|
||||
static void ParseNodeRxml(RXmlNode *node, ParseCodeXMLContext *ctx, std::ostream &stream, RCodeMeta *code) {
|
||||
if (rxml_dom_is_text(node)) {
|
||||
char* cleaned = strdup(node->text ? node->text : "");
|
||||
if (strlen(cleaned) > 1) {
|
||||
r_str_trim(cleaned);
|
||||
}
|
||||
stream << cleaned;
|
||||
R_FREE(cleaned);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<RCodeMetaItem> annotations;
|
||||
|
||||
const char *name = rxml_dom_name(node);
|
||||
if (name && !strcmp(name, "break")) {
|
||||
stream << "\n";
|
||||
int indent = rxml_dom_attr_int(node, "indent", 0);
|
||||
stream << std::string(indent, ' ');
|
||||
} else if (name) {
|
||||
auto it = annotators_rxml.find(name);
|
||||
if (it != annotators_rxml.end()) {
|
||||
auto &callbacks = it->second;
|
||||
for (auto &callback : callbacks) {
|
||||
callback(node, ctx, &annotations);
|
||||
}
|
||||
for (auto &annotation : annotations) {
|
||||
annotation.start = stream.tellp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (RXmlNode *child = rxml_dom_first_child(node); child; child = rxml_dom_next_sibling(child)) {
|
||||
ParseNodeRxml(child, ctx, stream, code);
|
||||
}
|
||||
|
||||
for (auto &annotation : annotations) {
|
||||
annotation.end = stream.tellp();
|
||||
RCodeMetaItem *item = r_codemeta_item_clone(&annotation);
|
||||
r_codemeta_add_item(code, item);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define ANNOTATOR_PARAMS pugi::xml_node node, ParseCodeXMLContext *ctx, std::vector<RCodeMetaItem> *out
|
||||
#define ANNOTATOR [](ANNOTATOR_PARAMS) -> void
|
||||
|
||||
void AnnotateOpref(ANNOTATOR_PARAMS) {
|
||||
pugi::xml_attribute attr = node.attribute ("opref");
|
||||
if (attr.empty ()) {
|
||||
return;
|
||||
}
|
||||
ut64 opref = attr.as_ullong (UT64_MAX);
|
||||
if (opref == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
auto opit = ctx->ops.find ((uintm)opref);
|
||||
if (opit == ctx->ops.end ()) {
|
||||
return;
|
||||
}
|
||||
auto op = opit->second;
|
||||
|
||||
out->emplace_back ();
|
||||
auto &annotation = out->back ();
|
||||
annotation = {};
|
||||
annotation.type = R_CODEMETA_TYPE_OFFSET;
|
||||
annotation.offset.offset = op->getAddr ().getOffset ();
|
||||
}
|
||||
|
||||
void AnnotateFunctionName(ANNOTATOR_PARAMS) {
|
||||
const char *func_name = node.child_value ();
|
||||
if (!func_name) {
|
||||
return;
|
||||
}
|
||||
RCodeMetaItem annotation = {};
|
||||
annotation.type = R_CODEMETA_TYPE_FUNCTION_NAME;
|
||||
pugi::xml_attribute attr = node.attribute ("opref");
|
||||
if (attr.empty ()) {
|
||||
if (ctx->func->getName() == func_name) {
|
||||
annotation.reference.name = strdup(ctx->func->getName().c_str());
|
||||
annotation.reference.offset = ctx->func->getAddress().getOffset();
|
||||
out->push_back(annotation);
|
||||
// Code below makes an offset annotation for the function name(for the currently decompiled function)
|
||||
RCodeMetaItem offsetAnnotation = {};
|
||||
offsetAnnotation.type = R_CODEMETA_TYPE_OFFSET;
|
||||
offsetAnnotation.offset.offset = annotation.reference.offset;
|
||||
out->push_back (offsetAnnotation);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ut64 opref = attr.as_ullong (UT64_MAX);
|
||||
if (opref == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
auto opit = ctx->ops.find ((uintm)opref);
|
||||
if (opit == ctx->ops.end ()) {
|
||||
return;
|
||||
}
|
||||
PcodeOp *op = opit->second;
|
||||
FuncCallSpecs *call_func_spec = ctx->func->getCallSpecs (op);
|
||||
if (call_func_spec) {
|
||||
annotation.reference.name = strdup (call_func_spec->getName ().c_str ());
|
||||
annotation.reference.offset = call_func_spec->getEntryAddress ().getOffset ();
|
||||
out->push_back (annotation);
|
||||
}
|
||||
}
|
||||
|
||||
void AnnotateCommentOffset(ANNOTATOR_PARAMS) {
|
||||
pugi::xml_attribute attr = node.attribute("off");
|
||||
if (attr.empty()) {
|
||||
return;
|
||||
}
|
||||
ut64 off = attr.as_ullong(UT64_MAX);
|
||||
if (off == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
out->emplace_back();
|
||||
auto &annotation = out->back();
|
||||
annotation = {};
|
||||
annotation.type = R_CODEMETA_TYPE_OFFSET;
|
||||
annotation.offset.offset = off;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Translate Ghidra's color annotations, which are essentially
|
||||
* loose token classes of the high level decompiled source code.
|
||||
**/
|
||||
#if R2GHIDRA_USE_RXML
|
||||
void AnnotateColorRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
int color = rxml_dom_attr_int(node, "color", -1);
|
||||
#else
|
||||
void AnnotateColor(ANNOTATOR_PARAMS) {
|
||||
pugi::xml_attribute attr = node.attribute("color");
|
||||
if (attr.empty ()) {
|
||||
return;
|
||||
}
|
||||
int color = attr.as_int(-1);
|
||||
#endif
|
||||
int color = rxml_dom_attr_int(node, "color", -1);
|
||||
if (color < 0) {
|
||||
return;
|
||||
}
|
||||
@@ -351,8 +198,7 @@ void AnnotateLocalVariable(Symbol *symbol, std::vector<RCodeMetaItem> *out) {
|
||||
out->push_back (annotation);
|
||||
}
|
||||
|
||||
#if R2GHIDRA_USE_RXML
|
||||
void AnnotateVariableRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
void AnnotateVariable(ANNOTATOR_PARAMS) {
|
||||
const char* varref_str = rxml_dom_get_attribute(node, "varref");
|
||||
if (!varref_str) {
|
||||
RXmlNode* parent = rxml_dom_parent(node);
|
||||
@@ -368,21 +214,6 @@ void AnnotateVariableRxml(ANNOTATOR_RXML_PARAMS) {
|
||||
return;
|
||||
}
|
||||
ut64 varref = r_num_get(NULL, varref_str);
|
||||
#else
|
||||
void AnnotateVariable(ANNOTATOR_PARAMS) {
|
||||
pugi::xml_attribute attr = node.attribute ("varref");
|
||||
if (attr.empty ()) {
|
||||
auto node_parent = node.parent ();
|
||||
if (std::string("vardecl") == node_parent.name ()) {
|
||||
pugi::xml_attribute attributeSymbolId = node_parent.attribute ("symref");
|
||||
ut64 symref = attributeSymbolId.as_ullong(UT64_MAX);
|
||||
Symbol *symbol = ctx->symbols[symref];
|
||||
AnnotateLocalVariable (symbol, out);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ut64 varref = attr.as_ullong(UT64_MAX);
|
||||
#endif
|
||||
if (varref == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
@@ -406,8 +237,7 @@ void AnnotateVariable(ANNOTATOR_PARAMS) {
|
||||
}
|
||||
}
|
||||
|
||||
#if !R2GHIDRA_USE_RXML
|
||||
static const std::map<std::string, std::vector <void (*)(ANNOTATOR_PARAMS)> > annotators = {
|
||||
static const std::map<std::string, std::vector<void (*)(ANNOTATOR_PARAMS)>> annotators = {
|
||||
{ "statement", { AnnotateOpref } },
|
||||
{ "op", { AnnotateOpref, AnnotateColor } },
|
||||
{ "comment", { AnnotateCommentOffset, AnnotateColor } },
|
||||
@@ -417,7 +247,6 @@ static const std::map<std::string, std::vector <void (*)(ANNOTATOR_PARAMS)> > an
|
||||
{ "syntax", { AnnotateColor } }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Ghidra returns an annotated AST of the decompiled high-level language code.
|
||||
* The AST is saved in XML format.
|
||||
@@ -427,30 +256,26 @@ static const std::map<std::string, std::vector <void (*)(ANNOTATOR_PARAMS)> > an
|
||||
* and translates them into a suitable format
|
||||
* that can be natively saved in the RCodeMeta structure.
|
||||
**/
|
||||
static void ParseNode(pugi::xml_node node, ParseCodeXMLContext *ctx, std::ostream &stream, RCodeMeta *code) {
|
||||
// A leaf is an XML node which contains parts of the high level decompilation language
|
||||
if (node.type () == pugi::xml_node_type::node_pcdata) {
|
||||
// XXX: optimise it?
|
||||
char* cleaned = strdup (node.value());
|
||||
if (strlen (cleaned) > 1) {
|
||||
r_str_trim (cleaned);
|
||||
static void ParseNode(RXmlNode *node, ParseCodeXMLContext *ctx, std::ostream &stream, RCodeMeta *code) {
|
||||
if (rxml_dom_is_text(node)) {
|
||||
char* cleaned = strdup(node->text ? node->text : "");
|
||||
if (strlen(cleaned) > 1) {
|
||||
r_str_trim(cleaned);
|
||||
}
|
||||
stream << cleaned;
|
||||
R_FREE (cleaned);
|
||||
R_FREE(cleaned);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<RCodeMetaItem> annotations;
|
||||
#if TEST_UNKNOWN_NODES
|
||||
bool close_test = false;
|
||||
static const std::set<std::string> boring_tags = { "syntax" };
|
||||
#endif
|
||||
|
||||
if (std::string("break") == node.name()) {
|
||||
const char *name = rxml_dom_name(node);
|
||||
if (name && !strcmp(name, "break")) {
|
||||
stream << "\n";
|
||||
stream << std::string(node.attribute("indent").as_uint(0), ' ');
|
||||
} else {
|
||||
auto it = annotators.find(node.name());
|
||||
int indent = rxml_dom_attr_int(node, "indent", 0);
|
||||
stream << std::string(indent, ' ');
|
||||
} else if (name) {
|
||||
auto it = annotators.find(name);
|
||||
if (it != annotators.end()) {
|
||||
auto &callbacks = it->second;
|
||||
for (auto &callback : callbacks) {
|
||||
@@ -460,63 +285,34 @@ static void ParseNode(pugi::xml_node node, ParseCodeXMLContext *ctx, std::ostrea
|
||||
annotation.start = stream.tellp();
|
||||
}
|
||||
}
|
||||
#if TEST_UNKNOWN_NODES
|
||||
else if (boring_tags.find(node.name()) == boring_tags.end()) {
|
||||
close_test = true;
|
||||
stream << "<" << node.name();
|
||||
for (pugi::xml_attribute attr : node.attributes()) {
|
||||
stream << " " << attr.name() << "=\"" << attr.value() << "\""; // unescaped, but who cares
|
||||
}
|
||||
stream << ">";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (pugi::xml_node child : node) {
|
||||
for (RXmlNode *child = rxml_dom_first_child(node); child; child = rxml_dom_next_sibling(child)) {
|
||||
ParseNode(child, ctx, stream, code);
|
||||
}
|
||||
|
||||
// an annotation applies for a node an all its children
|
||||
for (auto &annotation : annotations) {
|
||||
annotation.end = stream.tellp();
|
||||
RCodeMetaItem *item = r_codemeta_item_clone (&annotation);
|
||||
r_codemeta_add_item (code, item);
|
||||
RCodeMetaItem *item = r_codemeta_item_clone(&annotation);
|
||||
r_codemeta_add_item(code, item);
|
||||
}
|
||||
#if TEST_UNKNOWN_NODES
|
||||
if (close_test) {
|
||||
stream << "</" << node.name() << ">";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API RCodeMeta *ParseCodeXML(ghidra::Funcdata *func, const char *xml) {
|
||||
#if R2GHIDRA_USE_RXML
|
||||
RXmlNode *doc = rxml_dom_parse(xml);
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
pugi::xml_document doc;
|
||||
if(!doc.load_string (xml, pugi::parse_default | pugi::parse_ws_pcdata)) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
std::stringstream ss;
|
||||
RCodeMeta *code = r_codemeta_new("");
|
||||
if (!code) {
|
||||
#if R2GHIDRA_USE_RXML
|
||||
rxml_dom_free(doc);
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
ParseCodeXMLContext ctx (func);
|
||||
#if R2GHIDRA_USE_RXML
|
||||
ParseNodeRxml (rxml_dom_first_child(doc), &ctx, ss, code);
|
||||
ParseNode (rxml_dom_first_child(doc), &ctx, ss, code);
|
||||
rxml_dom_free(doc);
|
||||
#else
|
||||
ParseNode (doc.child ("function"), &ctx, ss, code);
|
||||
#endif
|
||||
std::string str = ss.str ();
|
||||
code->code = strdup (str.c_str ());
|
||||
return code;
|
||||
|
||||
+4
-19
@@ -26,21 +26,6 @@ R2GHIDRA_SRCS+=SleighInstruction.cpp
|
||||
R2G_PLUG_SRCS= anal_ghidra.cpp core_ghidra.cpp
|
||||
R2G_PLUG_SRCS+= anal_ghidra_plugin.o core_ghidra_plugin.o
|
||||
|
||||
#R2GHIDRA_USE_RXML?=1
|
||||
CXXFLAGS+=-DR2GHIDRA_USE_RXML=$(R2GHIDRA_USE_RXML)
|
||||
|
||||
ifeq ($(R2GHIDRA_USE_RXML),0)
|
||||
PUGIXML_HOME=../subprojects/pugixml/src/
|
||||
PUGIXML_CFLAGS=-I$(PUGIXML_HOME)
|
||||
PUGIXML_SRCS= $(PUGIXML_HOME)/pugixml.cpp
|
||||
PUGIXML_OBJS= $(PUGIXML_HOME)/pugixml.o
|
||||
#PUGIXML_OBJS= pugixml.o
|
||||
|
||||
$(PUGIXML_OBJS): $(PUGIXML_SRCS)
|
||||
$(CXX) -c $(R2_LDFLAGS) $(CXXFLAGS) -o $@ $<
|
||||
|
||||
CXXFLAGS+=$(PUGIXML_CFLAGS)
|
||||
endif
|
||||
# CXXFLAGS+=-DR2GHIDRA_SLEIGHHOME_DEFAULT=\"$(GHIDRA_HOME)\"
|
||||
|
||||
R2GHIDRA_OBJS=$(subst .cpp,.o,$(R2GHIDRA_SRCS))
|
||||
@@ -82,7 +67,7 @@ subprojects-zlib: ../subprojects/zlib/libz.a
|
||||
|
||||
clean:
|
||||
$(MAKE) -C fidb clean
|
||||
rm -f *.o $(PUGIXML_OBJS)
|
||||
rm -f *.o
|
||||
rm -f *.o $(GHIDRA_DECOMPILER)/*.o
|
||||
rm -f $(R2G_CORE_PLUGIN) $(R2G_ASM_PLUGIN) $(R2G_ANAL_PLUGIN) sleighc fidb/r2fidb
|
||||
|
||||
@@ -90,7 +75,7 @@ plugins: $(R2G_CORE_PLUGIN) sleighc
|
||||
$(MAKE) sign
|
||||
$(MAKE) -C fidb
|
||||
|
||||
deps=$(R2GHIDRA_OBJS) $(GHIDRA_OBJS) $(R2G_PLUGIN_OBJS) $(PUGIXML_OBJS)
|
||||
deps=$(R2GHIDRA_OBJS) $(GHIDRA_OBJS) $(R2G_PLUGIN_OBJS)
|
||||
|
||||
# zlib's configure rewrites zconf.h, racing any object that includes zlib.h under -j
|
||||
$(R2GHIDRA_OBJS) $(GHIDRA_OBJS) $(R2G_PLUGIN_OBJS): | ../subprojects/zlib/libz.a
|
||||
@@ -100,11 +85,11 @@ asan:
|
||||
$(MAKE) user-install
|
||||
|
||||
$(R2G_CORE_PLUGIN): $(deps)
|
||||
$(CXX) -shared -o $@ $(R2GHIDRA_OBJS) $(GHIDRA_OBJS) $(PUGIXML_OBJS) core_ghidra.o \
|
||||
$(CXX) -shared -o $@ $(R2GHIDRA_OBJS) $(GHIDRA_OBJS) core_ghidra.o \
|
||||
anal_ghidra.o core_ghidra_plugin.o anal_ghidra_plugin.o $(R2_LDFLAGS) $(ZLIB_LDFLAGS) $(LDFLAGS) $(CXXFLAGS)
|
||||
|
||||
$(R2G_ANAL_PLUGIN): $(deps)
|
||||
$(CXX) -shared $(GHIDRA_OBJS) $(PUGIXML_OBJS) anal_ghidra.o anal_ghidra_plugin.o \
|
||||
$(CXX) -shared $(GHIDRA_OBJS) anal_ghidra.o anal_ghidra_plugin.o \
|
||||
$(R2GHIDRA_OBJS) $(R2_LDFLAGS) $(ZLIB_LDFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@
|
||||
|
||||
ifneq (,$(wildcard /usr/bin/codesign))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Development Makefile: Remember that distribution tarballs use Makefile.dist instead
|
||||
.PHONY: default all clean
|
||||
|
||||
DEPS=ghidra-native pugixml zlib
|
||||
DEPS=ghidra-native zlib
|
||||
ALL=$(basename $(wildcard *.mk))
|
||||
|
||||
default: $(DEPS)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
project('pugixml', 'cpp', meson_version : '>=0.60.0', version : '1.15')
|
||||
|
||||
pugixml_sources = [
|
||||
'src/pugixml.cpp',
|
||||
]
|
||||
|
||||
incdirs = [
|
||||
'src',
|
||||
]
|
||||
|
||||
pugixml_dep = declare_dependency(
|
||||
sources: pugixml_sources,
|
||||
include_directories: include_directories(incdirs),
|
||||
)
|
||||
@@ -1,21 +0,0 @@
|
||||
# This file is autogenerated by acr-wrap
|
||||
|
||||
WRAP_wrap_git_url:=https://github.com/zeux/pugixml.git
|
||||
WRAP_wrap_git_revision:=v1.15
|
||||
WRAP_wrap_git_directory:=pugixml
|
||||
WRAP_wrap_git_patch_directory:=pugixml
|
||||
WRAP_wrap_git_depth:=1
|
||||
|
||||
.PHONY: pugixml_clean pugixml_all
|
||||
|
||||
pugixml:
|
||||
if [ ! -d "pugixml" -o "v1.15" != "$(shell cd pugixml 2>/dev/null && git rev-parse HEAD)" ]; then rm -rf "pugixml"; ${MAKE} pugixml_all; fi
|
||||
|
||||
pugixml_all:
|
||||
git clone --no-checkout --depth=1 https://github.com/zeux/pugixml.git pugixml
|
||||
cd pugixml && git fetch --depth=1 origin v1.15
|
||||
cd pugixml && git checkout FETCH_HEAD
|
||||
cp -rf packagefiles/pugixml/* pugixml
|
||||
|
||||
pugixml_clean:
|
||||
rm -rf pugixml
|
||||
@@ -1,6 +0,0 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/zeux/pugixml.git
|
||||
revision = v1.15
|
||||
directory = pugixml
|
||||
patch_directory = pugixml
|
||||
depth = 1
|
||||
Reference in new issue
Block a user