Consume ghidra-native 0.7.2 and refresh subprojects in place

Use the upstream Meson dependency, shared source manifest, and Sleigh compilation helper instead of maintaining local copies. Check pinned subprojects before Make and XPS builds, cache fetched revisions for offline reuse, and save local ghidra-native changes in a named stash before updating.
This commit is contained in:
pancake authored and pancake committed 2026-10-15 21:32:18 +02:00
1 parent aeede61eea
commit 911d82d214
15 files changed
+74 -422

No files matched your search

+7 -6
View File
@@ -1,13 +1,14 @@
include config.mk
DESTDIR?=
GHIDRA_NATIVE_COMMIT=0.7.0
all: ghidra-processors.txt
all: subprojects ghidra-processors.txt
$(MAKE) -C src
$(MAKE) -C ghidra
c:
subprojects:
$(MAKE) -C subprojects
c: subprojects
make -C src -j4
purge: clean
@@ -17,7 +18,7 @@ purge: clean
ghidra-processors.txt: ghidra-processors.txt.default
cp -f ghidra-processors.txt.default ghidra-processors.txt
asan: ghidra-processors.txt
asan: subprojects ghidra-processors.txt
CFLAGS=-g CXXFLAGS=-g $(MAKE) -C src asan
asan-run:
@@ -65,4 +66,4 @@ bindist: ghidra-processors.txt
cd $(BINDIST_DIR) && zip -r $(CURDIR)/$(BINDIST_ZIP) plugins bin
rm -rf $(BINDIST_DIR)
.PHONY: mrproper clean install uninstall all dist bindist
.PHONY: mrproper clean install uninstall all dist bindist subprojects
+9 -1
View File
@@ -28,7 +28,7 @@ To build and install r2ghidra you need the following software installed in your
* pkg-config - that's how build system find libraries and include files to compile stuff
* acr/make or meson/ninja - pick the build system you like! all of them are maintained and working
* msvc/g++/clang++ - basically a C++ compiler (and a C compiler)
* git/patch - needed to clone ghidra-native and build stuff
* git/python3 - needed to clone and prepare ghidra-native
If the build fails, please carefully read the error message and act accordingly, r2pm should
handle the `PKG_CONFIG_PATH` automatically for you in any case.
@@ -149,6 +149,11 @@ $ ./configure --prefix=$(r2 -H R2_PREFIX)
$ make
$ make install # or make user-install
```
`make` checks the pinned subproject revisions automatically. Existing
ghidra-native checkouts are updated in place; before switching versions,
patched sources and local changes are saved in a named Git stash inside
`subprojects/ghidra-native`. A matching checkout can be reused offline.
At the moment there is no way to select which processors to support, so it builds them all and takes a lot of time to compile the sleighfiles.
### Meson/Ninja
@@ -161,6 +166,9 @@ meson compile -C b
meson install -C b
```
To update an existing ghidra-native checkout after the dependency pin changes,
run `make -C subprojects ghidra-native` before reconfiguring Meson.
### Windows
To compile r2ghidra on windows you need Visual Studio and git installed:
+3 -61
View File
@@ -17,53 +17,8 @@ ZLIB_CFLAGS=-I../subprojects/zlib
GHIDRA_HOME=../subprojects/ghidra-native
GHIDRA_DECOMPILER=$(GHIDRA_HOME)/src/decompiler
G_DECOMPILER=marshal.cc space.cc float.cc address.cc pcoderaw.cc
G_DECOMPILER+=translate.cc opcodes.cc globalcontext.cc
G_DECOMPILER+=capability.cc architecture.cc options.cc graph.cc
G_DECOMPILER+=cover.cc block.cc cast.cc typeop.cc database.cc
G_DECOMPILER+=cpool.cc comment.cc stringmanage.cc modelrules.cc fspec.cc action.cc loadimage.cc
G_DECOMPILER+=varnode.cc op.cc type.cc variable.cc varmap.cc
G_DECOMPILER+=jumptable.cc emulate.cc emulateutil.cc flow.cc userop.cc expression.cc
G_DECOMPILER+=multiprecision.cc funcdata.cc funcdata_block.cc funcdata_varnode.cc
G_DECOMPILER+=funcdata_op.cc unionresolve.cc pcodeinject.cc heritage.cc prefersplit.cc
G_DECOMPILER+=rangeutil.cc ruleaction.cc subflow.cc blockaction.cc
G_DECOMPILER+=merge.cc double.cc coreaction.cc condexe.cc override.cc
G_DECOMPILER+=dynamic.cc crc32.cc prettyprint.cc printlanguage.cc
G_DECOMPILER+=printc.cc printjava.cc memstate.cc opbehavior.cc
G_DECOMPILER+=paramid.cc transform.cc string_ghidra.cc constseq.cc
G_DECOMPILER+=signature.cc bitfield.cc
G_DECOMPILER+=ghidra_arch.cc inject_ghidra.cc ghidra_translate.cc
G_DECOMPILER+=loadimage_ghidra.cc typegrp_ghidra.cc database_ghidra.cc
G_DECOMPILER+=ghidra_context.cc cpool_ghidra.cc comment_ghidra.cc
# signature_ghidra.cc needs GhidraCommand from ghidra_process.cc, whose main() clashes with sleighc
# G_DECOMPILER+=signature_ghidra.cc
# G_DECOMPILER+=ghidra_process.cc
G_DECOMPILER+= $(GHIDRA_LIBDECOMP_SRCS)
G_DECOMPILER+=sleigh_arch.cc
G_DECOMPILER+=sleigh.cc
G_DECOMPILER+=inject_sleigh.cc
G_DECOMPILER+=pcodecompile.cc
G_DECOMPILER+=sleighbase.cc
G_DECOMPILER+=slghsymbol.cc
G_DECOMPILER+=slghpatexpress.cc
G_DECOMPILER+=slghpattern.cc
G_DECOMPILER+=semantics.cc
G_DECOMPILER+=context.cc
G_DECOMPILER+=slaformat.cc
G_DECOMPILER+=compression.cc
G_DECOMPILER+=filemanage.cc
# set(DECOMPILER_SOURCE_CONSOLE_CXX
## G_DECOMPILER+=consolemain.cc
## G_DECOMPILER+=interface.cc
## G_DECOMPILER+=ifacedecomp.cc
## G_DECOMPILER+=ifaceterm.cc
## G_DECOMPILER+=callgraph.cc
## G_DECOMPILER+=raw_arch.cc
-include $(GHIDRA_HOME)/sources.mk
G_DECOMPILER=$(GHIDRA_EMBEDDED_SRCS)
ifeq ($(USE_BISON),1)
$(GHIDRA_DECOMPILER)/grammar.cc: $(GHIDRA_DECOMPILER)/grammar.y
@@ -92,28 +47,15 @@ $(GHIDRA_DECOMPILER)/slghparse.cc: $(GHIDRA_DECOMPILER)/slghparse.y
$(GHIDRA_DECOMPILER)/slghscan.cc: $(GHIDRA_DECOMPILER)/slghscan.l $(GHIDRA_DECOMPILER)/slghparse.cc
$(FLEX) --header-file=$(GHIDRA_DECOMPILER)/slghscan.tab.hh -o $(GHIDRA_DECOMPILER)/slghscan.cc $(GHIDRA_DECOMPILER)/slghscan.l
else
G_DECOMPILER+= grammar.cc
# no .cc? G_DECOMPILER+= ruleparser.cc
G_DECOMPILER+= xml.cc
G_DECOMPILER+= pcodeparse.cc
# G_DECOMPILER+= slghparse.cc ## bison
# G_DECOMPILER+= pcodeparse.cc ## bison
endif
GHIDRA_SRCS=$(addprefix $(GHIDRA_DECOMPILER)/,$(G_DECOMPILER))
GHIDRA_OBJS+=$(subst .cc,.o,$(GHIDRA_SRCS))
GHIDRA_LIBDECOMP_SRCS=libdecomp.cc
GHIDRA_LIBDECOMP_OBJS+=$(subst .cc,.o,$(GHIDRA_LIBDECOMP_SRCS))
GHIDRA_SLEIGH_COMPILER_SRCS=slgh_compile.cc
GHIDRA_SLEIGH_COMPILER_OBJS=$(subst .cc,.o,$(GHIDRA_SLEIGH_COMPILER_SRCS))
sleigh: sleighc
$(SLEIGHC) $(SPECFILE) $(SLAFILE)
SLEIGHTC_OBJS=$(GHIDRA_DECOMPILER)/slgh_compile.o $(GHIDRA_DECOMPILER)/slghscan.o $(GHIDRA_DECOMPILER)/slghparse.o
SLEIGHTC_OBJS=$(addprefix $(GHIDRA_DECOMPILER)/,$(GHIDRA_SLEIGH_COMPILER_SRCS:.cc=.o))
sleighc: $(SLEIGHTC_OBJS) $(GHIDRA_OBJS)
$(CXX) $(CXXFLAGS) -o sleighc $(SLEIGHTC_OBJS) $(GHIDRA_OBJS) $(ZLIB_LDFLAGS) $(LDFLAGS)
+3 -4
View File
@@ -1,12 +1,11 @@
# Sleigh compilation for processor definitions
proc_file = meson.current_source_dir() / '..' / 'ghidra-processors.txt.default'
proc_res = run_command('cat', proc_file, check: true)
proc_list = proc_res.stdout().strip().split('\n')
proc_list = import('fs').read(proc_file).strip().split('\n')
proc_dir = meson.current_source_dir() / '..' / 'subprojects' / 'ghidra-native' / 'src' / 'Processors'
proc_dir = ghidra.get_variable('processor_dir')
sleigh_dir = r2_plugdir / 'r2ghidra_sleigh'
sleigh_compile = meson.current_source_dir() / 'sleigh_compile.py'
sleigh_compile = ghidra.get_variable('sleigh_compile')
python = find_program('python3', 'python', required: true)
-22
View File
@@ -1,22 +0,0 @@
#!/usr/bin/env python3
import pathlib
import subprocess
import sys
def main() -> int:
if len(sys.argv) != 4:
print("usage: sleigh_compile.py <sleighc> <processor-dir> <stamp>", file=sys.stderr)
return 2
sleighc, proc_dir, stamp_path = sys.argv[1:4]
result = subprocess.run([sleighc, "-a", proc_dir], check=False)
if result.returncode != 0:
return result.returncode
pathlib.Path(stamp_path).write_text("ok\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+4 -25
View File
@@ -2,7 +2,7 @@ project(
'r2ghidra',
['c', 'cpp'],
license : 'LGPL3',
meson_version : '>=0.50.1',
meson_version : '>=0.60.0',
version : '6.2.4',
default_options : ['c_std=c11', 'cpp_std=c++20', 'b_vscrt=md']
)
@@ -87,46 +87,25 @@ add_global_arguments('-DNDEBUG', language: ['c', 'cpp'])
r2ghidra_incdirs = include_directories(incdirs)
zlib = dependency('zlib', version : '>=1.2.8', required: false)
if not zlib.found()
zlib_proj = subproject('zlib', default_options: ['default_library=static', 'werror=false'])
zlib = zlib_proj.get_variable('zlib_dep')
meson.override_dependency('zlib', zlib)
endif
ghidra = subproject('ghidra-native', version: '>=0.7.2', default_options: ['default_library=static', 'werror=false'])
ghidra = subproject('ghidra-native', default_options: ['default_library=static', 'werror=false'])
# ghidra_decompiler_sources = ghidra.get_variable('sources')
# ghidra_slgh_sources = ghidra.get_variable('slgh_sources')
ghidra_incs = ghidra.get_variable('incs')
libdecomp_static = ghidra.get_variable('libdecomp_static')
slgh_static = ghidra.get_variable('slgh_static')
r2ghidra_deps = [r_core, zlib]
r2ghidra_deps = [r_core, ghidra.get_variable('ghidra_dep')]
r2ghidra_cpp_args = []
r2ghidra_core_sources = [
r2ghidra_sources,
# ghidra_decompiler_sources,
'src/anal_ghidra_plugin.c',
'src/anal_ghidra.cpp',
'src/core_ghidra_plugin.c',
'src/core_ghidra.cpp',
]
sleighc_sources = [
r2ghidra_sources,
# ghidra_slgh_sources,
# ghidra_decompiler_sources,
]
r2ghidra_core_plugin = shared_library('core_r2ghidra',
r2ghidra_core_sources,
link_with: libdecomp_static,
dependencies: r2ghidra_deps,
cpp_args: r2ghidra_cpp_args,
override_options : ['c_std=c11', 'cpp_std=c++20'],
include_directories: [ghidra_incs, r2ghidra_incdirs],
include_directories: r2ghidra_incdirs,
install: true,
install_dir: r2_plugdir
)
+1 -2
View File
@@ -3,8 +3,7 @@
all: prepare
prepare: ../config.h
@test -d ../subprojects/ghidra-native || $(MAKE) -C ../subprojects ghidra-native
@test -f ../subprojects/zlib/zlib.h || $(MAKE) -C ../subprojects zlib
$(MAKE) -C ../subprojects
R2GHIDRA_VERSION=$(shell sed -n 's/^VERSION //p' ../configure.acr)
+3
View File
@@ -22,6 +22,9 @@ make -C libr/xps/p/r2ghidra/r2plugin prepare
The `prepare` step fetches the ghidra-native and zlib subprojects (network
access on first run) and generates `config.h` if missing.
It also checks dependency revisions and updates ghidra-native in place, saving
local changes in its Git stash before switching versions. Both XPS build systems
read the native source manifest shipped by ghidra-native.
Then build radare2 as usual. With make:
+2 -23
View File
@@ -39,29 +39,8 @@ R2GHIDRA_XPS_C_SRCS=\
anal_ghidra_plugin.c \
core_ghidra_plugin.c
# Keep in sync with ghidra/deps.mk (G_DECOMPILER with USE_BISON=0)
R2GHIDRA_XPS_DEC_SRCS=\
marshal.cc space.cc float.cc address.cc pcoderaw.cc \
translate.cc opcodes.cc globalcontext.cc \
capability.cc architecture.cc options.cc graph.cc \
cover.cc block.cc cast.cc typeop.cc database.cc \
cpool.cc comment.cc stringmanage.cc modelrules.cc fspec.cc action.cc loadimage.cc \
varnode.cc op.cc type.cc variable.cc varmap.cc \
jumptable.cc emulate.cc emulateutil.cc flow.cc userop.cc expression.cc \
multiprecision.cc funcdata.cc funcdata_block.cc funcdata_varnode.cc \
funcdata_op.cc unionresolve.cc pcodeinject.cc heritage.cc prefersplit.cc \
rangeutil.cc ruleaction.cc subflow.cc blockaction.cc \
merge.cc double.cc coreaction.cc condexe.cc override.cc \
dynamic.cc crc32.cc prettyprint.cc printlanguage.cc \
printc.cc printjava.cc memstate.cc opbehavior.cc \
paramid.cc transform.cc string_ghidra.cc constseq.cc \
ghidra_arch.cc inject_ghidra.cc ghidra_translate.cc \
loadimage_ghidra.cc typegrp_ghidra.cc database_ghidra.cc \
ghidra_context.cc cpool_ghidra.cc comment_ghidra.cc \
grammar.cc xml.cc pcodeparse.cc libdecomp.cc \
sleigh_arch.cc sleigh.cc inject_sleigh.cc pcodecompile.cc \
sleighbase.cc slghsymbol.cc slghpatexpress.cc slghpattern.cc \
semantics.cc context.cc slaformat.cc compression.cc filemanage.cc
-include $(R2GHIDRA_XPS_WD)/subprojects/ghidra-native/sources.mk
R2GHIDRA_XPS_DEC_SRCS=$(GHIDRA_EMBEDDED_SRCS)
R2GHIDRA_XPS_ZLIB_SRCS=\
adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c \
+7 -35
View File
@@ -8,13 +8,9 @@ core_plugins += ['r2ghidra']
add_languages('cpp', native: false)
r2g_fs = import('fs')
if not r2g_fs.is_file('../config.h') or not r2g_fs.is_file('../subprojects/ghidra-native/src/decompiler/marshal.cc') or not r2g_fs.is_file('../subprojects/zlib/zlib.h')
r2g_prep = run_command('make', '-C', meson.current_source_dir(), 'prepare', check: false)
if r2g_prep.returncode() != 0
error('r2ghidra: prepare failed, run `make -C ' + meson.current_source_dir() + ' prepare` manually:\n' + r2g_prep.stderr())
endif
r2g_prep = run_command('make', '-C', meson.current_source_dir(), 'prepare', check: false)
if r2g_prep.returncode() != 0
error('r2ghidra: prepare failed, run `make -C ' + meson.current_source_dir() + ' prepare` manually:\n' + r2g_prep.stderr())
endif
r2g_src_names = [
@@ -38,34 +34,10 @@ r2g_src_names = [
'core_ghidra_plugin.c',
]
# Keep in sync with ghidra/deps.mk (G_DECOMPILER with USE_BISON=0)
r2g_dec_names = [
'marshal.cc', 'space.cc', 'float.cc', 'address.cc', 'pcoderaw.cc',
'translate.cc', 'opcodes.cc', 'globalcontext.cc',
'capability.cc', 'architecture.cc', 'options.cc', 'graph.cc',
'cover.cc', 'block.cc', 'cast.cc', 'typeop.cc', 'database.cc',
'cpool.cc', 'comment.cc', 'stringmanage.cc', 'modelrules.cc',
'fspec.cc', 'action.cc', 'loadimage.cc',
'varnode.cc', 'op.cc', 'type.cc', 'variable.cc', 'varmap.cc',
'jumptable.cc', 'emulate.cc', 'emulateutil.cc', 'flow.cc',
'userop.cc', 'expression.cc',
'multiprecision.cc', 'funcdata.cc', 'funcdata_block.cc',
'funcdata_varnode.cc', 'funcdata_op.cc', 'unionresolve.cc',
'pcodeinject.cc', 'heritage.cc', 'prefersplit.cc',
'rangeutil.cc', 'ruleaction.cc', 'subflow.cc', 'blockaction.cc',
'merge.cc', 'double.cc', 'coreaction.cc', 'condexe.cc', 'override.cc',
'dynamic.cc', 'crc32.cc', 'prettyprint.cc', 'printlanguage.cc',
'printc.cc', 'printjava.cc', 'memstate.cc', 'opbehavior.cc',
'paramid.cc', 'transform.cc', 'string_ghidra.cc', 'constseq.cc',
'ghidra_arch.cc', 'inject_ghidra.cc', 'ghidra_translate.cc',
'loadimage_ghidra.cc', 'typegrp_ghidra.cc', 'database_ghidra.cc',
'ghidra_context.cc', 'cpool_ghidra.cc', 'comment_ghidra.cc',
'grammar.cc', 'xml.cc', 'pcodeparse.cc', 'libdecomp.cc',
'sleigh_arch.cc', 'sleigh.cc', 'inject_sleigh.cc', 'pcodecompile.cc',
'sleighbase.cc', 'slghsymbol.cc', 'slghpatexpress.cc', 'slghpattern.cc',
'semantics.cc', 'context.cc', 'slaformat.cc', 'compression.cc',
'filemanage.cc',
]
r2g_python = find_program('python3', 'python', required: true)
r2g_source_reader = files('../subprojects/ghidra-native/scripts/sources.py')
import('fs').read('../subprojects/ghidra-native/sources.mk')
r2g_dec_names = run_command(r2g_python, r2g_source_reader, 'GHIDRA_EMBEDDED_SRCS', check: true).stdout().strip().split()
r2g_zlib_names = [
'adler32.c', 'compress.c', 'crc32.c', 'deflate.c', 'gzclose.c',
+2
View File
@@ -4,6 +4,8 @@
DEPS=ghidra-native zlib
ALL=$(basename $(wildcard *.mk))
.PHONY: $(ALL)
default: $(DEPS)
all: $(ALL)
+2
View File
@@ -2,6 +2,8 @@
ACR_WRAP=acr-wrap
for i in *.wrap ; do
# ghidra-native.mk handles version updates and upstream's patch target.
[ "$i" = ghidra-native.wrap ] && continue
o=`echo $i | sed -e 's,.wrap,.mk,'`
echo "[ACR] Wrapping $i"
${ACR_WRAP} $i > $o
+30 -14
View File
@@ -1,22 +1,38 @@
# This file is autogenerated by acr-wrap
# Maintained separately from acr-wrap: use upstream's patch target and preserve
# local changes when switching versions. The wrap owns the URL and version pin.
WRAP_wrap_git_url:=https://github.com/radareorg/ghidra-native
WRAP_wrap_git_revision:=0.7.0
WRAP_wrap_git_directory:=ghidra-native
WRAP_wrap_git_patch_directory:=ghidra-native
WRAP_wrap_git_depth:=1
GHIDRA_NATIVE_URL=$(shell sed -n 's/^url *= *//p' ghidra-native.wrap)
GHIDRA_NATIVE_REVISION=$(shell sed -n 's/^revision *= *//p' ghidra-native.wrap)
.PHONY: ghidra-native_clean ghidra-native_all
.PHONY: ghidra-native ghidra-native_clean ghidra-native_all
ghidra-native:
if [ ! -d "ghidra-native" ] || ! (cd "ghidra-native" 2>/dev/null && test "$$(git rev-parse HEAD 2>/dev/null)" = "$$(git rev-parse '0.7.0^{commit}' 2>/dev/null)"); then rm -rf "ghidra-native"; ${MAKE} ghidra-native_all; fi
@set -e; \
if [ ! -d ghidra-native ]; then \
git clone --depth=1 "$(GHIDRA_NATIVE_URL)" ghidra-native; \
elif [ ! -e ghidra-native/.git ]; then \
echo "ghidra-native exists but is not a git checkout" >&2; exit 1; \
fi; \
revision=$$(git -C ghidra-native rev-parse --verify '$(GHIDRA_NATIVE_REVISION)^{commit}' 2>/dev/null || git -C ghidra-native rev-parse --verify 'refs/r2ghidra/$(GHIDRA_NATIVE_REVISION)^{commit}' 2>/dev/null || true); \
prepare=0; \
if [ "$$(git -C ghidra-native rev-parse --verify HEAD)" != "$$revision" ]; then \
if [ -z "$$revision" ]; then \
git -C ghidra-native fetch --depth=1 "$(GHIDRA_NATIVE_URL)" "$(GHIDRA_NATIVE_REVISION)"; \
revision=$$(git -C ghidra-native rev-parse --verify FETCH_HEAD); \
git -C ghidra-native update-ref 'refs/r2ghidra/$(GHIDRA_NATIVE_REVISION)' "$$revision"; \
fi; \
prepare=1; \
elif [ ! -f ghidra-native/patch.done ] && ! git -C ghidra-native diff --quiet; then \
prepare=1; \
fi; \
if [ "$$prepare" = 1 ]; then \
git -C ghidra-native stash push --include-untracked -m "r2ghidra: before updating ghidra-native to $(GHIDRA_NATIVE_REVISION)"; \
git -C ghidra-native checkout --detach "$$revision"; \
rm -f ghidra-native/patch.done; \
fi
$(MAKE) -C ghidra-native patch
ghidra-native_all:
git clone --no-checkout --depth=1 https://github.com/radareorg/ghidra-native ghidra-native
cd ghidra-native && git fetch --depth=1 origin 0.7.0
cd ghidra-native && git checkout FETCH_HEAD
cp -rf packagefiles/ghidra-native/* ghidra-native
cd ghidra-native && $(MAKE) patch
ghidra-native_all: ghidra-native
ghidra-native_clean:
rm -rf ghidra-native
+1 -2
View File
@@ -1,6 +1,5 @@
[wrap-git]
url = https://github.com/radareorg/ghidra-native
revision = 0.7.0
revision = 0.7.2
directory = ghidra-native
patch_directory = ghidra-native
depth = 1
@@ -1,227 +0,0 @@
project('ghidra-native', 'cpp', meson_version : '>=0.60.0', version : '0.7.0')
fs = import('fs')
# Wrap-git checkouts arrive pristine: apply upstream's own patch stack exactly
# once at configure time. `make dist` archives are shipped pre-patched (they
# carry patch.done and no .git), so this stays a no-op for them. git is
# guaranteed to exist for wrap-git builds and keeps Windows dev machines free of
# a GNU patch dependency.
gn_src = meson.current_source_dir()
if fs.is_dir(gn_src / 'patches')
git = find_program('git', required: false)
if not git.found()
error('Applying the ghidra-native patch stack requires git')
endif
# Meson keeps an existing checkout as-is (it only warns when the wrap file
# changed), so fail loudly instead of silently building a stale revision.
head = run_command(git, '-C', gn_src, 'rev-parse', 'HEAD', check: false)
if head.returncode() == 0
revision = run_command(git, '-C', gn_src, 'rev-parse', meson.project_version() + '^{commit}', check: true)
if head.stdout().strip() != revision.stdout().strip()
error('ghidra-native: checkout is at @0@ but the wrap pins @1@; remove subprojects/ghidra-native and reconfigure'.format(
head.stdout().strip(), meson.project_version()))
endif
endif
if not fs.is_file(gn_src / 'patch.done')
# `git diff --quiet` only looks at tracked files: the packagefiles overlay
# (meson.build) is untracked and must not count as "dirty".
status = run_command(git, '-C', gn_src, 'diff', '--quiet', check: false)
if status.returncode() == 0
# Top-level patches only, like upstream's `ls patches/*.patch | sort -n`:
# git lists them sorted by name and the zero-padded numeric prefixes make
# that the same order, with ghidra-native.patch last.
listing = run_command(git, '-C', gn_src, 'ls-files', 'patches', check: true)
patch_files = []
foreach p : listing.stdout().strip().split('\n')
p = p.strip()
if p.startswith('patches/') and p.endswith('.patch') and p.split('/').length() == 2
patch_files += p
endif
endforeach
if patch_files.length() == 0
error('ghidra-native: patches/ holds no patches to apply')
endif
foreach p : patch_files
applied = run_command(git, '-C', gn_src, 'apply', '--whitespace=nowarn', p, check: false)
if applied.returncode() != 0
error('ghidra-native: failed to apply @0@:\n@1@'.format(p, applied.stderr()))
endif
endforeach
message('ghidra-native: applied @0@ upstream patches'.format(patch_files.length()))
elif status.returncode() == 1
# Already patched (or locally modified): never apply the stack twice.
message('ghidra-native: sources already modified, assuming the patch stack is applied')
else
error('ghidra-native: cannot check the git working tree:\n' + status.stderr())
endif
endif
endif
base_sources = [
'src/decompiler/marshal.cc',
'src/decompiler/space.cc',
'src/decompiler/float.cc',
'src/decompiler/address.cc',
'src/decompiler/pcoderaw.cc',
'src/decompiler/translate.cc',
'src/decompiler/opcodes.cc',
'src/decompiler/globalcontext.cc',
'src/decompiler/xml.cc',
]
decompiler_sources = [
'src/decompiler/capability.cc',
'src/decompiler/architecture.cc',
'src/decompiler/options.cc',
'src/decompiler/graph.cc',
'src/decompiler/cover.cc',
'src/decompiler/block.cc',
'src/decompiler/cast.cc',
'src/decompiler/typeop.cc',
'src/decompiler/database.cc',
'src/decompiler/cpool.cc',
'src/decompiler/comment.cc',
'src/decompiler/stringmanage.cc',
'src/decompiler/modelrules.cc',
'src/decompiler/fspec.cc',
'src/decompiler/action.cc',
'src/decompiler/loadimage.cc',
'src/decompiler/varnode.cc',
'src/decompiler/op.cc',
'src/decompiler/type.cc',
'src/decompiler/variable.cc',
'src/decompiler/varmap.cc',
'src/decompiler/jumptable.cc',
'src/decompiler/emulate.cc',
'src/decompiler/emulateutil.cc',
'src/decompiler/flow.cc',
'src/decompiler/userop.cc',
'src/decompiler/expression.cc',
'src/decompiler/multiprecision.cc',
'src/decompiler/funcdata.cc',
'src/decompiler/funcdata_block.cc',
'src/decompiler/funcdata_varnode.cc',
'src/decompiler/unionresolve.cc',
'src/decompiler/funcdata_op.cc',
'src/decompiler/pcodeinject.cc',
'src/decompiler/heritage.cc',
'src/decompiler/prefersplit.cc',
'src/decompiler/rangeutil.cc',
'src/decompiler/ruleaction.cc',
'src/decompiler/subflow.cc',
'src/decompiler/transform.cc',
'src/decompiler/blockaction.cc',
'src/decompiler/merge.cc',
'src/decompiler/double.cc',
'src/decompiler/coreaction.cc',
'src/decompiler/condexe.cc',
'src/decompiler/override.cc',
'src/decompiler/dynamic.cc',
'src/decompiler/crc32.cc',
'src/decompiler/prettyprint.cc',
'src/decompiler/printlanguage.cc',
'src/decompiler/printc.cc',
'src/decompiler/printjava.cc',
'src/decompiler/memstate.cc',
'src/decompiler/opbehavior.cc',
'src/decompiler/paramid.cc',
'src/decompiler/signature.cc',
'src/decompiler/string_ghidra.cc',
'src/decompiler/constseq.cc',
'src/decompiler/bitfield.cc',
]
libdecomp_sources = [
'src/decompiler/libdecomp.cc',
]
ghidra_sources = [
'src/decompiler/ghidra_process.cc',
'src/decompiler/ghidra_arch.cc',
'src/decompiler/loadimage_ghidra.cc',
'src/decompiler/typegrp_ghidra.cc',
'src/decompiler/database_ghidra.cc',
'src/decompiler/ghidra_context.cc',
'src/decompiler/cpool_ghidra.cc',
'src/decompiler/comment_ghidra.cc',
'src/decompiler/signature_ghidra.cc',
'src/decompiler/inject_ghidra.cc',
'src/decompiler/ghidra_translate.cc',
]
slgh_sources = [
'src/decompiler/sleigh.cc',
'src/decompiler/sleigh_arch.cc',
'src/decompiler/inject_sleigh.cc',
'src/decompiler/pcodecompile.cc',
'src/decompiler/sleighbase.cc',
'src/decompiler/slghsymbol.cc',
'src/decompiler/slghpatexpress.cc',
'src/decompiler/slghpattern.cc',
'src/decompiler/semantics.cc',
'src/decompiler/context.cc',
'src/decompiler/slaformat.cc',
'src/decompiler/compression.cc',
'src/decompiler/filemanage.cc',
'src/decompiler/pcodeparse.cc',
'src/decompiler/grammar.cc',
]
sleigh_compiler_sources = [
'src/decompiler/slgh_compile.cc',
'src/decompiler/slgh_compile.hh',
'src/decompiler/slghparse.hh',
'src/decompiler/slghparse.cc',
'src/decompiler/slghscan.cc',
]
zlib = dependency('zlib', version : '>=1.2.8', required: false)
if not zlib.found()
zlib_proj = subproject('zlib', default_options: ['default_library=static', 'werror=false'])
zlib = zlib_proj.get_variable('zlib_dep')
meson.override_dependency('zlib', zlib)
endif
incs = include_directories('src/decompiler')
ghidra_base_static = static_library('base',
base_sources,
include_directories: incs,
implicit_include_directories: false
)
ghidra_decompiler_static = static_library('ghidra',
decompiler_sources,
dependencies: zlib,
link_with: ghidra_base_static,
include_directories: incs,
implicit_include_directories: false
)
slgh_static = static_library('slgh',
slgh_sources, # + sleigh_compiler_sources,
dependencies: zlib,
link_with: ghidra_base_static,
include_directories: incs,
implicit_include_directories: false
)
libdecomp_static = static_library('libdecomp',
libdecomp_sources,
dependencies: zlib,
link_with: [ghidra_decompiler_static, slgh_static],
include_directories: incs,
implicit_include_directories: false
)
sleighc_exe = executable('sleighc',
sleigh_compiler_sources,
dependencies: zlib,
link_with: slgh_static,
include_directories: incs,
implicit_include_directories: false,
override_options : ['c_std=c11', 'cpp_std=c++14'],
install: true
)