mirror of
https://github.com/RKX1209/nsemu.git
synced 2024-06-22 06:02:21 -04:00
Add Unconditional branch op support to Disassembler
This commit is contained in:
parent
cf23eabba3
commit
b00aea1a31
|
@ -47,7 +47,8 @@ static void DisasPCRelAddr(uint32_t insn, DisasCallback *cb) {
|
|||
offset = sextract64 (insn, 5, 19);
|
||||
offset = offset << 2 | sextract64 (insn, 29, 2);
|
||||
rd = extract32 (insn, 0, 5);
|
||||
base = PC - 4;
|
||||
//base = PC - 4;
|
||||
base = PC;
|
||||
|
||||
if (page) {
|
||||
base &= ~0xfff;
|
||||
|
@ -258,6 +259,49 @@ static void DisasDataProcImm(uint32_t insn, DisasCallback *cb) {
|
|||
}
|
||||
}
|
||||
|
||||
static void DisasUncondBrImm(uint32_t insn, DisasCallback *cb) {
|
||||
uint64_t addr = PC + sextract32(insn, 0, 26) * 4 - 4;
|
||||
|
||||
if (insn & (1U << 31)) {
|
||||
/* BL Branch with link */
|
||||
cb->MoviI64(GPR_LR, addr, false, true);
|
||||
}
|
||||
|
||||
/* B Branch / BL Branch with link */
|
||||
cb->GotoI64(addr);
|
||||
}
|
||||
|
||||
static void DisasBranchExcSys(uint32_t insn, DisasCallback *cb) {
|
||||
switch (extract32(insn, 25, 7)) {
|
||||
case 0x0a: case 0x0b:
|
||||
case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
|
||||
DisasUncondBrImm(insn, cb);
|
||||
break;
|
||||
case 0x1a: case 0x5a: /* Compare & branch (immediate) */
|
||||
|
||||
break;
|
||||
case 0x1b: case 0x5b: /* Test & branch (immediate) */
|
||||
|
||||
break;
|
||||
case 0x2a: /* Conditional branch (immediate) */
|
||||
|
||||
break;
|
||||
case 0x6a: /* Exception generation / System */
|
||||
if (insn & (1 << 24)) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x6b: /* Unconditional branch (register) */
|
||||
|
||||
break;
|
||||
default:
|
||||
UnallocatedOp (insn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisasA64(uint32_t insn, DisasCallback *cb) {
|
||||
switch (extract32 (insn, 25, 4)) {
|
||||
case 0x0: case 0x1: case 0x2: case 0x3: // Unallocated
|
||||
|
@ -267,6 +311,7 @@ void DisasA64(uint32_t insn, DisasCallback *cb) {
|
|||
DisasDataProcImm (insn, cb);
|
||||
break;
|
||||
case 0xa: case 0xb: /* Branch, exception generation and system insns */
|
||||
DisasBranchExcSys (insn, cb);
|
||||
break;
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
|
|
|
@ -5,18 +5,21 @@ Interpreter *Interpreter::inst = nullptr;
|
|||
IntprCallback *Interpreter::disas_cb = nullptr;
|
||||
|
||||
int Interpreter::SingleStep() {
|
||||
uint32_t inst = ARMv8::ReadInst (PC);
|
||||
debug_print ("Run Code: 0x%08lx\n", inst);
|
||||
PC += sizeof(uint32_t);
|
||||
uint32_t inst = byte_swap(ARMv8::ReadInst (PC));
|
||||
debug_print ("Run Code: 0x%lx: 0x%08lx\n", PC, inst);
|
||||
Disassembler::DisasA64 (inst, disas_cb);
|
||||
PC += sizeof(uint32_t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Interpreter::Run() {
|
||||
debug_print ("Running with Interpreter\n");
|
||||
while (Cpu::GetState () == Cpu::State::Running) {
|
||||
/*while (Cpu::GetState () == Cpu::State::Running) {
|
||||
SingleStep ();
|
||||
}
|
||||
}*/
|
||||
int test_max = 3;
|
||||
for (int i = 0; i < test_max; i++)
|
||||
SingleStep();
|
||||
}
|
||||
|
||||
void IntprCallback::MoviI64(unsigned int reg_idx, uint64_t imm, bool unchanged, bool bit64) {
|
||||
|
@ -38,3 +41,7 @@ void IntprCallback::OrrI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wm
|
|||
void IntprCallback::EorI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bool bit64) {}
|
||||
void IntprCallback::SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) {}
|
||||
void IntprCallback::UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) {}
|
||||
void IntprCallback::GotoI64(uint64_t imm) {
|
||||
debug_print ("Goto: 0x%016lx\n", imm + 4);
|
||||
PC = imm;
|
||||
}
|
||||
|
|
2
Main.cpp
2
Main.cpp
|
@ -110,6 +110,6 @@ printUsage:
|
|||
#endif
|
||||
}
|
||||
nsemu->BootUp (parse.nonOption (0));
|
||||
Nsemu ::destroy ();
|
||||
Nsemu::destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,13 @@ struct ARMv8State {
|
|||
|
||||
extern ARMv8State arm_state;
|
||||
|
||||
#define LR ARMv8 ::arm_state.gpr[30]
|
||||
#define SP ARMv8 ::arm_state.gpr[31]
|
||||
#define ZERO ARMv8 ::arm_state.gpr[31]
|
||||
#define GPR_LR 30
|
||||
#define GPR_SP 31
|
||||
#define GPR_ZERO 31
|
||||
|
||||
#define LR ARMv8 ::arm_state.gpr[GPR_LR]
|
||||
#define SP ARMv8 ::arm_state.gpr[GPR_SP]
|
||||
#define ZERO ARMv8 ::arm_state.gpr[GPR_ZERO]
|
||||
#define PC ARMv8 ::arm_state.pc
|
||||
|
||||
#define GPR(x) ARMv8 ::arm_state.gpr[x]
|
||||
|
|
|
@ -14,6 +14,8 @@ virtual void EorI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bo
|
|||
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
||||
virtual void SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) = 0;
|
||||
virtual void UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) = 0;
|
||||
/* Go to Immediate address */
|
||||
virtual void GotoI64(uint64_t imm) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ void EorI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bool bit64
|
|||
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
||||
void SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
||||
void UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
||||
|
||||
/* Go to Immediate address */
|
||||
void GotoI64(uint64_t imm);
|
||||
};
|
||||
|
||||
/* Global Interpreter singleton class .*/
|
||||
|
|
|
@ -47,6 +47,10 @@ inline void bindump(uint8_t *ptr, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
inline uint32_t byte_swap(uint32_t b) {
|
||||
return ((b >> 24) & 0xff) | ((b << 8) & 0xff0000) | ((b >> 8) & 0xff00) | ((b << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
inline int32_t host_order32(const char *b) {
|
||||
return ((b[3]) << 24) | ((b[2]) << 16) | ((b[1]) << 8) | (b[0]);
|
||||
}
|
||||
|
@ -56,6 +60,11 @@ static inline uint32_t extract32(uint32_t bitfield, int from, int len) {
|
|||
return (bitfield >> from) & (~0U >> (32 - len));
|
||||
}
|
||||
|
||||
static inline int32_t sextract32(uint64_t bitfield, int from, int len) {
|
||||
assert (from >= 0 && len > 0 && from + len <= 32);
|
||||
return ((int32_t) (bitfield << (32 - from - len))) >> (32 - len);
|
||||
}
|
||||
|
||||
static inline int64_t sextract64(uint64_t bitfield, int from, int len) {
|
||||
assert (from >= 0 && len > 0 && from + len <= 64);
|
||||
return ((int64_t) (bitfield << (64 - from - len))) >> (64 - len);
|
||||
|
|
|
@ -8,7 +8,7 @@ PYTHON2 := python2
|
|||
MEPHISTO := ctu
|
||||
RUBY := ruby
|
||||
|
||||
libtransistor_TESTS := malloc bsd_ai_packing bsd sfdnsres
|
||||
NSEMU_TESTS := simple_disas malloc bsd_ai_packing bsd sfdnsres
|
||||
|
||||
libtransistor_OBJECTS := build/lib/svc.o build/lib/ipc.o build/lib/tls.o build/lib/util.o build/lib/ipc/sm.o build/lib/ipc/bsd.o
|
||||
|
||||
|
@ -21,7 +21,7 @@ export CC_FOR_TARGET = clang -g -fPIC -ffreestanding -fexceptions -target aarch6
|
|||
|
||||
.SUFFIXES: # disable built-in rules
|
||||
|
||||
all: build/lib/libtransistor.nro.a build/lib/libtransistor.nso.a $(addprefix build/test/test_,$(addsuffix .nro,$(libtransistor_TESTS))) $(addprefix build/test/test_,$(addsuffix .nso,$(libtransistor_TESTS))) $(addprefix build/test/test_,$(addsuffix .nro.so,$(libtransistor_TESTS))) $(addprefix build/test/test_,$(addsuffix .nso.so,$(libtransistor_TESTS)))
|
||||
all: build/lib/libtransistor.nro.a build/lib/libtransistor.nso.a $(addprefix build/test/test_,$(addsuffix .nro,$(NSEMU_TESTS))) $(addprefix build/test/test_,$(addsuffix .nso,$(NSEMU_TESTS))) $(addprefix build/test/test_,$(addsuffix .nro.so,$(NSEMU_TESTS))) $(addprefix build/test/test_,$(addsuffix .nso.so,$(NSEMU_TESTS)))
|
||||
|
||||
run_tests: run_malloc_test run_bsd_ai_packing_test run_bsd_test run_sfdnsres_test
|
||||
|
||||
|
@ -38,6 +38,10 @@ build/test/%.o: test/%.c
|
|||
mkdir -p $(@D)
|
||||
$(CC) $(CC_FLAGS) -c -o $@ $<
|
||||
|
||||
build/test/%.o: test/%.S
|
||||
mkdir -p $(@D)
|
||||
$(AS) $(AS_FLAGS) $< -filetype=obj -o $@
|
||||
|
||||
build/lib/%.o: lib/%.c
|
||||
mkdir -p $(@D)
|
||||
$(CC) $(CC_FLAGS) -c -o $@ $<
|
||||
|
@ -54,11 +58,11 @@ build/test/%.nso: build/test/%.nso.so
|
|||
mkdir -p $(@D)
|
||||
$(PYTHON2) ./tools/elf2nxo.py $< $@ nso
|
||||
|
||||
build/test/%.nro.so: build/test/%.o build/lib/libtransistor.nro.a newlib/aarch64-none-switch/newlib/libc.a
|
||||
build/test/%.nro.so: build/test/%.o build/lib/libtransistor.nro.a newlib/aarch64-none-switch/newlib/libc.a
|
||||
mkdir -p $(@D)
|
||||
$(LD) $(LD_FLAGS) -o $@ $< --whole-archive build/lib/libtransistor.nro.a --no-whole-archive newlib/aarch64-none-switch/newlib/libc.a
|
||||
|
||||
build/test/%.nso.so: build/test/%.o build/lib/libtransistor.nso.a newlib/aarch64-none-switch/newlib/libc.a
|
||||
build/test/%.nso.so: build/test/%.o build/lib/libtransistor.nso.a newlib/aarch64-none-switch/newlib/libc.a
|
||||
mkdir -p $(@D)
|
||||
$(LD) $(LD_FLAGS) -o $@ $< --whole-archive build/lib/libtransistor.nso.a --no-whole-archive newlib/aarch64-none-switch/newlib/libc.a
|
||||
|
||||
|
|
4
test/test/test_simple_disas.S
Normal file
4
test/test/test_simple_disas.S
Normal file
|
@ -0,0 +1,4 @@
|
|||
.section .text, "e"
|
||||
.global main
|
||||
main:
|
||||
adr x5, 0x1000
|
Loading…
Reference in a new issue