diff options
author | cognet <cognet@FreeBSD.org> | 2008-08-03 01:53:14 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2008-08-03 01:53:14 +0000 |
commit | 9468ed046dd7dfc62d5fe28db1b7770e2415faed (patch) | |
tree | 254ea102fd1c2449a3c9b292a1e7529bebabc143 /sys | |
parent | 17ddb2b74506b2f3bba3fb7c4a88355af62a3040 (diff) | |
download | FreeBSD-src-9468ed046dd7dfc62d5fe28db1b7770e2415faed.zip FreeBSD-src-9468ed046dd7dfc62d5fe28db1b7770e2415faed.tar.gz |
Handle ldr pc, [reg] in branch_taken().
Obtained from: NetBSD
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arm/arm/db_interface.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/arm/arm/db_interface.c b/sys/arm/arm/db_interface.c index 7bc2772..8076ed3 100644 --- a/sys/arm/arm/db_interface.c +++ b/sys/arm/arm/db_interface.c @@ -294,7 +294,7 @@ db_fetch_reg(int reg) u_int branch_taken(u_int insn, db_addr_t pc) { - u_int addr, nregs; + u_int addr, nregs, offset = 0; switch ((insn >> 24) & 0xf) { case 0xa: /* b ... */ @@ -311,6 +311,17 @@ branch_taken(u_int insn, db_addr_t pc) case 0x1: /* mov pc, reg */ addr = db_fetch_reg(insn & 0xf); return (addr); + case 0x5: /* ldr pc, [reg] */ + addr = db_fetch_reg((insn >> 16) & 0xf); + /* ldr pc, [reg, #offset] */ + if (insn & (1 << 24)) + offset = insn & 0xfff; + if (insn & 0x00800000) + addr += offset; + else + addr -= offset; + db_read_bytes(addr, 4, (char *)&addr); + return (addr); case 0x8: /* ldmxx reg, {..., pc} */ case 0x9: addr = db_fetch_reg((insn >> 16) & 0xf); |