diff options
author | Andreas Tobler <andreast@sourceware.org> | 2013-02-01 20:54:18 +0000 |
---|---|---|
committer | Andreas Tobler <andreast@sourceware.org> | 2013-02-01 20:54:18 +0000 |
commit | d78489bf604bd655936b653e8aacaef50885a692 (patch) | |
tree | e70a81185ff07f72f15cca46532b129b26ef003e /gdb/rs6000-tdep.c | |
parent | 8db60374ebbe2b436929e27ce80b2dddb2c4eb13 (diff) | |
download | gdb-d78489bf604bd655936b653e8aacaef50885a692.zip gdb-d78489bf604bd655936b653e8aacaef50885a692.tar.gz gdb-d78489bf604bd655936b653e8aacaef50885a692.tar.bz2 |
2013-02-01 Andreas Tobler <andreast@fgznet.ch>
* Makefile.in (ALL_TARGET_OBS): Add ppc64-tdep.o.
(HFILES_NO_SRCDIR): Add ppc64-tdep.h.
(ALLDEPFILES): Add ppc64-tdep.c.
* configure.tgt (powerpc-*-linux* | powerpc64-*-linux*): Add
ppc64-tdep.o to gdb_target_obs.
* ppc64-tdep.h: New file.
* ppc64-tdep.c: New file.
(insn_d, insn_ds, insn_xfx, ppc64_desc_entry_point): Move from
ppc-linux-tdep.c to here.
(PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN)
(PPC64_STANDARD_LINKAGE2_LEN): Likewise and use ARRAY_SIZE macro.
(ppc64_standard_linkage1_target, ppc64_standard_linkage2_target)
(ppc64_standard_linkage3_target, ppc64_skip_trampoline_code): Move
from ppc-linux-tdep.c to here.
(ppc64_convert_from_func_ptr_addr): Rename from
ppc64_linux_convert_from_func_ptr_addr to
ppc64_convert_from_func_ptr_addr and move from ppc-linux-tdep.c to
here.
* rs6000-tdep.c:
(read_insn): Move from ppc-linux-tdep.c to here.
(insns_match_pattern, insn_d_field, insn_ds_field): Move
from ppc-linux-tdep.c to here and rename them with the ppc_ prefix.
* ppc-linux-tdep.c: Include ppc64-tdep.h.
Removed above functions.
(ppc_linux_init_abi): Adjust.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index a15f757..5bc1105 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -4238,6 +4238,68 @@ show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty, fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value); } +/* Read a PPC instruction from memory. PPC instructions are always + big-endian, no matter what endianness the program is running in, so + we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer. */ + +static unsigned int +read_insn (CORE_ADDR pc) +{ + return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG); +} + +/* Return non-zero if the instructions at PC match the series + described in PATTERN, or zero otherwise. PATTERN is an array of + 'struct ppc_insn_pattern' objects, terminated by an entry whose + mask is zero. + + When the match is successful, fill INSN[i] with what PATTERN[i] + matched. If PATTERN[i] is optional, and the instruction wasn't + present, set INSN[i] to 0 (which is not a valid PPC instruction). + INSN should have as many elements as PATTERN. Note that, if + PATTERN contains optional instructions which aren't present in + memory, then INSN will have holes, so INSN[i] isn't necessarily the + i'th instruction in memory. */ + +int +ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern, + unsigned int *insn) +{ + int i; + + for (i = 0; pattern[i].mask; i++) + { + insn[i] = read_insn (pc); + if ((insn[i] & pattern[i].mask) == pattern[i].data) + pc += 4; + else if (pattern[i].optional) + insn[i] = 0; + else + return 0; + } + + return 1; +} + +/* Return the 'd' field of the d-form instruction INSN, properly + sign-extended. */ + +CORE_ADDR +ppc_insn_d_field (unsigned int insn) +{ + return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000); +} + +/* Return the 'ds' field of the ds-form instruction INSN, with the two + zero bits concatenated at the right, and properly + sign-extended. */ + +CORE_ADDR +ppc_insn_ds_field (unsigned int insn) +{ + return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000); +} + /* Initialization code. */ /* -Wmissing-prototypes */ |