Skip to content

Commit

Permalink
Xtensa Support (#2380)
Browse files Browse the repository at this point in the history
* Fix leaks

* Remove unnecessary new lines

* Add checks for actual buffer length before attempting reading it.

* Xtensa: add xtensa support

* Xtensa fixes

- fix MCExpr
- fix Xtensa_add_cs_detail
- add `add_cs_detail`
- add `MCExpr *MCOperand_getExpr(const MCOperand *MC)` `void printExpr(const MCExpr *E, SStream *O)`

autosync fix

- fix StreamOperation.py
- replace `report_fatal_error` with `CS_ASSERT`
- fix patch StreamOperation.py
- replace `assert` with `CS_ASSERT`
- fix AddCSDetail.py
- fix QualifiedIdentifier

* Xtensa fix

* Xtensa fix .py

* add Xtensa to the fuzzer

* Xtensa `LITBASE`: add a basic implementation

* Xtensa `LITBASE`: add a integration test

* Xtensa: fix cs_v6_release_guide.md

* Xtensa: fix `XTENSA_OP_GROUP_MEMOPERAND`

* Xtensa: fix

* Xtensa: fix Targets.py

* Use isUint and isInt all over Xtensa

* Add documentation about LITBASE functionality

* Fix typo

* Replace hard with Capstone assert

* Xtensa: fix arch_config.json

* Xtensa: fix

---------

Co-authored-by: Rot127 <unisono@quyllur.org>
  • Loading branch information
imbillow and Rot127 authored Sep 30, 2024
1 parent 29d8773 commit 21f7bc8
Show file tree
Hide file tree
Showing 88 changed files with 9,468 additions and 131 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/auto-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ jobs:
./src/autosync/ASUpdater.py -d -a LoongArch -s IncGen
./src/autosync/ASUpdater.py -d -a Mips -s IncGen
./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen
./src/autosync/ASUpdater.py -d -a Xtensa -s IncGen
- name: CppTranslator - Patch tests
run: |
Expand All @@ -96,3 +97,4 @@ jobs:
./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate
./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate
./src/autosync/ASUpdater.py --ci -d -a SystemZ -s Translate
./src/autosync/ASUpdater.py --ci -d -a Xtensa -s Translate
27 changes: 25 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()

set(BUILD_RPATH_USE_ORIGIN true)

# Detect whether capstone is compiled as top-level or a subdirectory
set(PROJECT_IS_TOP_LEVEL OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
Expand Down Expand Up @@ -85,8 +87,8 @@ if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
endif()

set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSTEMZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH)
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch)
set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSTEMZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH XTENSA)
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch Xtensa)

# If building for OSX it's best to allow CMake to handle building both architectures
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
Expand Down Expand Up @@ -211,6 +213,7 @@ set(HEADERS_COMMON
include/capstone/alpha.h
include/capstone/hppa.h
include/capstone/loongarch.h
include/capstone/xtensa.h
)

## architecture support
Expand Down Expand Up @@ -680,6 +683,22 @@ if (CAPSTONE_LOONGARCH_SUPPORT)
)
endif ()

if(CAPSTONE_XTENSA_SUPPORT)
add_definitions(-DCAPSTONE_HAS_XTENSA)
set(SOURCES_XTENSA
arch/Xtensa/XtensaDisassembler.c
arch/Xtensa/XtensaInstPrinter.c
arch/Xtensa/XtensaMapping.c
arch/Xtensa/XtensaModule.c
)
set(HEADERS_XTENSA
arch/Xtensa/XtensaDisassembler.h
arch/Xtensa/XtensaInstPrinter.h
arch/Xtensa/XtensaMapping.h
arch/Xtensa/XtensaModule.h
)
endif()

if (CAPSTONE_OSXKERNEL_SUPPORT)
add_definitions(-DCAPSTONE_HAS_OSXKERNEL)
endif()
Expand Down Expand Up @@ -707,6 +726,7 @@ set(ALL_SOURCES
${SOURCES_ALPHA}
${SOURCES_HPPA}
${SOURCES_LOONGARCH}
${SOURCES_XTENSA}
)

set(ALL_HEADERS
Expand All @@ -733,6 +753,7 @@ set(ALL_HEADERS
${HEADERS_ALPHA}
${HEADERS_HPPA}
${HEADERS_LOONGARCH}
${HEADERS_XTENSA}
)

## properties
Expand Down Expand Up @@ -785,6 +806,7 @@ source_group("Source\\TriCore" FILES ${SOURCES_TRICORE})
source_group("Source\\Alpha" FILES ${SOURCES_ALPHA})
source_group("Source\\HPPA" FILES ${SOURCES_HPPA})
source_group("Source\\LoongArch" FILES ${SOURCES_LOONGARCH})
source_group("Source\\Xtensa" FILES ${SOURCES_XTENSA})

source_group("Include\\Common" FILES ${HEADERS_COMMON})
source_group("Include\\Engine" FILES ${HEADERS_ENGINE})
Expand All @@ -809,6 +831,7 @@ source_group("Include\\TriCore" FILES ${HEADERS_TRICORE})
source_group("Include\\Alpha" FILES ${HEADERS_ALPHA})
source_group("Include\\HPPA" FILES ${HEADERS_HPPA})
source_group("Include\\LoongArch" FILES ${HEADERS_LOONGARCH})
source_group("Include\\Xtensa" FILES ${HEADERS_XTENSA})

## installation
if(CAPSTONE_INSTALL)
Expand Down
5 changes: 3 additions & 2 deletions CREDITS.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ david942j: BPF (both classic and extended) architecture.
fanfuqiang & citypw & porto703 : RISCV architecture.
Josh "blacktop" Maine: Arm64 architecture improvements.
Finn Wilkinson: AArch64 update to Armv9.2-a (SME + SVE2 support)
Billow & Sidneyp : TriCore architecture.
Billow & Sidneyp: TriCore architecture.
Dmitry Sibirtsev: Alpha & HPPA architecture.
Jiajie Chen & Yanglin Xun: LoongArch architecture.
Jiajie Chen & Yanglin Xun: LoongArch architecture.
Billow: Xtensa architecture.
2 changes: 1 addition & 1 deletion MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
typedef struct MCInst MCInst;
typedef struct cs_struct cs_struct;
typedef struct MCOperand MCOperand;
typedef unsigned MCRegister;
typedef void MCExpr;

/// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
Expand Down
2 changes: 2 additions & 0 deletions MCRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
#define CS_LLVM_MC_MCREGISTERINFO_H

#include "capstone/platform.h"
#include "SStream.h"

/// An unsigned integer type large enough to represent all physical registers,
/// but not necessarily virtual registers.
typedef int16_t MCPhysReg;
typedef const MCPhysReg* iterator;
typedef uint16_t MCRegister;

typedef struct MCRegisterClass2 {
iterator RegsBegin;
Expand Down
13 changes: 12 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,21 @@ ifneq (,$(findstring loongarch,$(CAPSTONE_ARCHS)))
LIBOBJ_LOONGARCH += $(LIBSRC_LOONGARCH:%.c=$(OBJDIR)/%.o)
endif

DEP_XTENSA =
DEP_XTENSA += $(wildcard arch/Xtensa/Xtensa*.inc)

LIBOBJ_XTENSA =
ifneq (,$(findstring xtensa,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_XTENSA
LIBSRC_XTENSA += $(wildcard arch/Xtensa/Xtensa*.c)
LIBOBJ_XTENSA += $(LIBSRC_XTENSA:%.c=$(OBJDIR)/%.o)
endif

LIBOBJ =
LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o $(OBJDIR)/MCInst.o $(OBJDIR)/MCInstPrinter.o $(OBJDIR)/Mapping.o
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_AARCH64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_SH)
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF)
LIBOBJ += $(LIBOBJ_TRICORE) $(LIBOBJ_ALPHA) $(LIBOBJ_HPPA) $(LIBOBJ_LOONGARCH)
LIBOBJ += $(LIBOBJ_TRICORE) $(LIBOBJ_ALPHA) $(LIBOBJ_HPPA) $(LIBOBJ_LOONGARCH) $(LIBOBJ_XTENSA)


ifeq ($(PKG_EXTRA),)
Expand Down Expand Up @@ -492,6 +502,7 @@ $(LIBOBJ_TRICORE): $(DEP_TRICORE)
$(LIBOBJ_ALPHA): $(DEP_ALPHA)
$(LIBOBJ_HPPA): $(DEP_HPPA)
$(LIBOBJ_LOONGARCH): $(DEP_LOONGARCH)
$(LIBOBJ_XTENSA): $(DEP_XTENSA)

ifeq ($(CAPSTONE_STATIC),yes)
$(ARCHIVE): $(LIBOBJ)
Expand Down
1 change: 1 addition & 0 deletions Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ DEFINE_get_detail_op(loongarch, LoongArch);
DEFINE_get_detail_op(mips, Mips);
DEFINE_get_detail_op(riscv, RISCV);
DEFINE_get_detail_op(systemz, SystemZ);
DEFINE_get_detail_op(xtensa, Xtensa);

/// Returns true if for this architecture the
/// alias operands should be filled.
Expand Down
4 changes: 4 additions & 0 deletions Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ DECL_get_detail_op(loongarch, LoongArch);
DECL_get_detail_op(mips, Mips);
DECL_get_detail_op(riscv, RISCV);
DECL_get_detail_op(systemz, SystemZ);
DECL_get_detail_op(xtensa, Xtensa);

/// Increments the detail->arch.op_count by one.
#define DEFINE_inc_detail_op_count(arch, ARCH) \
Expand Down Expand Up @@ -177,6 +178,8 @@ DEFINE_inc_detail_op_count(riscv, RISCV);
DEFINE_dec_detail_op_count(riscv, RISCV);
DEFINE_inc_detail_op_count(systemz, SystemZ);
DEFINE_dec_detail_op_count(systemz, SystemZ);
DEFINE_inc_detail_op_count(xtensa, Xtensa);
DEFINE_dec_detail_op_count(xtensa, Xtensa);

/// Returns true if a memory operand is currently edited.
static inline bool doing_mem(const MCInst *MI)
Expand Down Expand Up @@ -208,6 +211,7 @@ DEFINE_get_arch_detail(loongarch, LoongArch);
DEFINE_get_arch_detail(mips, Mips);
DEFINE_get_arch_detail(riscv, RISCV);
DEFINE_get_arch_detail(systemz, SystemZ);
DEFINE_get_arch_detail(xtensa, Xtensa);

#define DEFINE_check_safe_inc(Arch, ARCH) \
static inline void Arch##_check_safe_inc(const MCInst *MI) { \
Expand Down
6 changes: 3 additions & 3 deletions MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ static inline bool isUIntN(unsigned N, uint64_t x) {

/// isIntN - Checks if an signed integer fits into the given (dynamic)
/// bit width.
//static inline bool isIntN(unsigned N, int64_t x) {
// return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
//}
static inline bool isIntN(unsigned N, int64_t x) {
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
}

/// isMask_32 - This function returns true if the argument is a sequence of ones
/// starting at the least significant bit with the remainder zero (32 bit
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Capstone Engine
[![oss-fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/capstone.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:capstone)

> [!TIP]
> Welcome to join our community group! &ensp; [<img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat-squeare&logo=telegram&logoColor=white" height="22" />](https://t.me/CapstoneEngine)
> Welcome to join our community group!
> &ensp; [<img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat-squeare&logo=telegram&logoColor=white" height="22" />](https://t.me/CapstoneEngine)
Capstone is a disassembly framework with the target of becoming the ultimate
disasm engine for binary analysis and reversing in the security community.
Expand All @@ -17,7 +18,7 @@ Capstone offers some unparalleled features:

- Support multiple hardware architectures: ARM, AArch64, Alpha, BPF, Ethereum VM,
LoongArch, HP PA-RISC (HPPA), M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH,
Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86 (16, 32, 64).
Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86 (16, 32, 64), Xtensa.

- Having clean/simple/lightweight/intuitive architecture-neutral API.

Expand Down
6 changes: 6 additions & 0 deletions arch/SystemZ/SystemZDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,16 @@ static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *By
Table = DecoderTable16;
Inst = readBytes16(MI, Bytes);
} else if (Bytes[0] < 0xc0) {
if (BytesLen < 4) {
return MCDisassembler_Fail;
}
*Size = 4;
Table = DecoderTable32;
Inst = readBytes32(MI, Bytes);
} else {
if (BytesLen < 6) {
return MCDisassembler_Fail;
}
*Size = 6;
Table = DecoderTable48;
Inst = readBytes48(MI, Bytes);
Expand Down
Loading

0 comments on commit 21f7bc8

Please sign in to comment.