On Thu, 2013-06-27 at 17:09 +0200, Denys Vlasenko wrote:
Signed-off-by: Denys Vlasenko dvlasenk@redhat.com
src/plugins/abrt-gdb-exploitable | 60 ++++++++++++++++++++++++++++++++++++++-- tests/abrt-exploitable/Makefile | 4 +-- 2 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/src/plugins/abrt-gdb-exploitable b/src/plugins/abrt-gdb-exploitable index f33ec45..1f33061 100755 --- a/src/plugins/abrt-gdb-exploitable +++ b/src/plugins/abrt-gdb-exploitable @@ -371,6 +371,62 @@ class SignalAndInsn: self.instruction_is_store = self.x86_instruction_is_store()
- def ppc_get_instruction(self):
try:
# just "disassemble $pc" won't work if $pc doesn't point
# inside a known function
raw_instructions = gdb.execute("disassemble $pc,$pc+32", to_string=True)
except gdb.error:
# For example, if tracee already exited normally.
# Another observed case is if $pc points to unmapped area.
# We get "Python Exception <class 'gdb.error'> No registers"
return
instructions = []
current = None
Is the current variable necessary? It looks like that the current instruction is the last item in the instructions.
for line in raw_instructions.split("\n"):
# line can be:
# "Dump of assembler code from 0xAAAA to 0xBBBB:"
# "[=>] 0x00000000004004dc[ <+0>]: push %rbp"
# (" <+0>" part is present when we run on a live process,
# on coredump it is absent)
# "End of assembler dump."
# "" (empty line)
if line.startswith("=>"):
line = line[2:]
current = len(instructions)
line = line.split(":", 1)
if len(line) < 2: # no ":"?
continue
line = line[1] # drop "foo:"
line = line.strip() # drop leading/trailing whitespace
if line:
instructions.append(line)
if current == None:
[PEP8] if current is None:
# we determined that $pc points to a bad address,
# which is an interesting fact.
return
# There can be a disasm comment: "insn op,op,op # comment";
# strip it, and whitespace on both ends:
t = instructions[current].split("#", 1)[0].strip()
I'm afraid that the current can be length(instructions) and IMHO python indexes from 0.
self.current_instruction = t
# Split it into mnemonic and operands
t = t.split(None, 1)
self.mnemonic = t[0]
if len(t) > 1:
self.operands = t[1]
self.instruction_is_store = self.mnemonic.startswith("st")
self.instruction_is_branch = self.mnemonic.startswith("b")
self.instruction_is_pushing = (self.instruction_is_store and "(r1)" in self.operands)
# Looks like div[o] insns on ppc don't cause exceptions
# (need to check whether, and how, FPE is generated)
#self.instruction_is_division =
# On ppc, return insn is b[cond]lr. TODO: is cond form ever used by gcc?
self.instruction_is_return = (self.mnemonic == "blr")
- def get_instruction(self): self.current_instruction = None self.mnemonic = None
@@ -388,8 +444,8 @@ class SignalAndInsn: # The target architecture is set automatically (currently powerpc:common64) if " i386" in arch: return self.x86_get_instruction()
#if " powerpc" in arch:
# return self.ppc_get_instruction()
if " powerpc" in arch:
return self.ppc_get_instruction() except gdb.error: return
diff --git a/tests/abrt-exploitable/Makefile b/tests/abrt-exploitable/Makefile index 6672fe3..9df463c 100644 --- a/tests/abrt-exploitable/Makefile +++ b/tests/abrt-exploitable/Makefile @@ -34,7 +34,7 @@ all: $(TESTS) clean: rm -f $(TESTS)
-testlive: +testlive: all for t in $(TESTS); do \ echo "====="; \ echo "Test: $$t"; \ @@ -48,7 +48,7 @@ testlive: ./$$t; \ done 2>&1 | tee testlive.log
-testcore: +testcore: all rm ./core* 2>/dev/null; \ ulimit -c unlimited; \ for t in $(TESTS); do \