public inbox for frysk-cvs@sourceware.org help / color / mirror / Atom feed
From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Implement frysk.sys.ptrace in jni. Date: Wed, 14 May 2008 17:10:00 -0000 [thread overview] Message-ID: <20080514171053.26157.qmail@sourceware.org> (raw) The branch, master has been updated via 9e07b5e5c951f582ed2e466295376bafc6c46df3 (commit) from 9da8189a51b382e4d3e46fbf770808d8592e357e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 9e07b5e5c951f582ed2e466295376bafc6c46df3 Author: Andrew Cagney <cagney@redhat.com> Date: Wed May 14 13:09:40 2008 -0400 Implement frysk.sys.ptrace in jni. frysk-sys/ChangeLog 2008-05-14 Andrew Cagney <cagney@redhat.com> * Makefile.am (JNIXX_CLASSES): Add java.lang.ArrayIndexOutOfBoundsException. frysk-sys/frysk/jnixx/ChangeLog 2008-05-14 Andrew Cagney <cagney@redhat.com> * chars.hxx (class ByteArrayElements): New. * bounds.hxx: New. * JniBindings.java: Generate GetArrayLength, and Throw. frysk-sys/frysk/sys/ptrace/ChangeLog 2008-05-14 Andrew Cagney <cagney@redhat.com> * jni/Ptrace.cxx: Convert to JNI. * jni/AddressSpace.cxx: Convert to JNI. * jni/RegisterSet.cxx: Covert to JNI. * jni/Utrace.cxx: Delete. ----------------------------------------------------------------------- Summary of changes: frysk-sys/ChangeLog | 5 + frysk-sys/Makefile.am | 1 + frysk-sys/frysk/jnixx/ChangeLog | 6 + frysk-sys/frysk/jnixx/JniBindings.java | 22 +++- .../jni/AddressSpace.cxx => jnixx/bounds.hxx} | 29 ++++- frysk-sys/frysk/jnixx/chars.hxx | 26 ++++ frysk-sys/frysk/sys/ptrace/ChangeLog | 7 + frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx | 155 +++++++++++++++++++- frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx | 117 +++++++++++++++- .../ptrace/jni/{AddressSpace.cxx => Ptrace.hxx} | 2 +- frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx | 55 +++++++- 11 files changed, 419 insertions(+), 6 deletions(-) copy frysk-sys/frysk/{sys/ptrace/jni/AddressSpace.cxx => jnixx/bounds.hxx} (69%) copy frysk-sys/frysk/sys/ptrace/jni/{AddressSpace.cxx => Ptrace.hxx} (97%) First 500 lines of diff: diff --git a/frysk-sys/ChangeLog b/frysk-sys/ChangeLog index 22e6cec..7fdfce7 100644 --- a/frysk-sys/ChangeLog +++ b/frysk-sys/ChangeLog @@ -1,3 +1,8 @@ +2008-05-14 Andrew Cagney <cagney@redhat.com> + + * Makefile.am (JNIXX_CLASSES): Add + java.lang.ArrayIndexOutOfBoundsException. + 2008-05-13 Andrew Cagney <cagney@redhat.com> * Makefile.am (JNIXX_CLASSES): Add diff --git a/frysk-sys/Makefile.am b/frysk-sys/Makefile.am index bb39422..cd10704 100644 --- a/frysk-sys/Makefile.am +++ b/frysk-sys/Makefile.am @@ -73,6 +73,7 @@ lib/unwind/Unwind%.java: lib/unwind/Unwind.java # jnixx's auto-detect algorithm misses hidden class references, # explicitly add them here. JNIXX_CLASSES += frysk.sys.ProcessIdentifierFactory +JNIXX_CLASSES += java.lang.ArrayIndexOutOfBoundsException \f # Quick hack to get a test JNI program up-and-running; as a package is diff --git a/frysk-sys/frysk/jnixx/ChangeLog b/frysk-sys/frysk/jnixx/ChangeLog index 61f470a..84ffdc5 100644 --- a/frysk-sys/frysk/jnixx/ChangeLog +++ b/frysk-sys/frysk/jnixx/ChangeLog @@ -1,3 +1,9 @@ +2008-05-14 Andrew Cagney <cagney@redhat.com> + + * chars.hxx (class ByteArrayElements): New. + * bounds.hxx: New. + * JniBindings.java: Generate GetArrayLength, and Throw. + 2008-05-13 Andrew Cagney <cagney@redhat.com> * PrintDeclarations.java: Do not generate non-ENV wrappers. diff --git a/frysk-sys/frysk/jnixx/JniBindings.java b/frysk-sys/frysk/jnixx/JniBindings.java index 7464cb7..40026dc 100644 --- a/frysk-sys/frysk/jnixx/JniBindings.java +++ b/frysk-sys/frysk/jnixx/JniBindings.java @@ -207,6 +207,18 @@ class JniBindings { }) /** + * java.lang.Throwable + */ + .put(Throwable.class, false, + null, "Throw", + new String[] { + "::jnixx::env", "env", + }, + new Object[] { + "env.Throw((jthrowable) _object);" + }) + + /** * java.lang.String */ // NewString @@ -302,7 +314,7 @@ class JniBindings { "return " + type + "Array(env, env.New" + Type + "Array(length));", }) .put(types[i], false, - "const j" + type + "*", "GetElements", + "j" + type + "*", "GetElements", new String[] { "::jnixx::env", "env", "jboolean*", "isCopy", @@ -311,6 +323,14 @@ class JniBindings { "return env.Get" + Type + "ArrayElements((j" + type + "Array) _object, isCopy);" }) .put(types[i], false, + "jsize", "GetArrayLength", + new String[] { + "::jnixx::env", "env", + }, + new Object[] { + "return env.GetArrayLength((j" + type + "Array) _object);" + }) + .put(types[i], false, null, "ReleaseElements", new String[] { "::jnixx::env", "env", diff --git a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx b/frysk-sys/frysk/jnixx/bounds.hxx similarity index 69% copy from frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx copy to frysk-sys/frysk/jnixx/bounds.hxx index b358932..9f84d5e 100644 --- a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx +++ b/frysk-sys/frysk/jnixx/bounds.hxx @@ -37,4 +37,31 @@ // version and license this file solely under the GPL without // exception. -#include "jni.hxx" +/** + * Given an array, verify an attempt to access elements. If the + * access is out-of-bounds throw an exception. + */ + +inline void verifyBounds(::jnixx::env env, ::jnixx::byteArray data, + jint stop) { + if (stop < 0) { + ::java::lang::ArrayIndexOutOfBoundsException::New(env, stop).Throw(env); + } + if (stop > data.GetArrayLength(env)) { + ::java::lang::ArrayIndexOutOfBoundsException::New(env, stop).Throw(env); + } +} + +inline void verifyBounds(::jnixx::env env, ::jnixx::byteArray data, + jint start, jint length) { + if (start < 0) { + ::java::lang::ArrayIndexOutOfBoundsException::New(env, start).Throw(env); + } + if (start >= data.GetArrayLength(env)) { + ::java::lang::ArrayIndexOutOfBoundsException::New(env, start).Throw(env); + } + if (length < 0) { + ::java::lang::ArrayIndexOutOfBoundsException::New(env, length).Throw(env); + } + verifyBounds(env, data, start + length); +} diff --git a/frysk-sys/frysk/jnixx/chars.hxx b/frysk-sys/frysk/jnixx/chars.hxx index 5c44b81..f00cf2c 100644 --- a/frysk-sys/frysk/jnixx/chars.hxx +++ b/frysk-sys/frysk/jnixx/chars.hxx @@ -88,3 +88,29 @@ public: free(); } }; + +class ByteArrayElements { +private: + ::jnixx::byteArray bytes; + ::jnixx::env env; +public: + jbyte* p; + ByteArrayElements(::jnixx::env env, ::jnixx::byteArray bytes) { + this->bytes = bytes; + this->env = env; + if (bytes != NULL) { + this->p = bytes.GetElements(env, NULL); + } else { + this->p = NULL; + } + } + void release() { + if (p != NULL) { + bytes.ReleaseElements(env, p, 0); + p = NULL; + } + } + ~ByteArrayElements() { + release(); + } +}; diff --git a/frysk-sys/frysk/sys/ptrace/ChangeLog b/frysk-sys/frysk/sys/ptrace/ChangeLog index 4e9675f..3fa5f68 100644 --- a/frysk-sys/frysk/sys/ptrace/ChangeLog +++ b/frysk-sys/frysk/sys/ptrace/ChangeLog @@ -1,3 +1,10 @@ +2008-05-14 Andrew Cagney <cagney@redhat.com> + + * jni/Ptrace.cxx: Convert to JNI. + * jni/AddressSpace.cxx: Convert to JNI. + * jni/RegisterSet.cxx: Covert to JNI. + * jni/Utrace.cxx: Delete. + 2008-05-07 Andrew Cagney <cagney@redhat.com> * jni/AddressSpace.cxx: Include jni.hxx. diff --git a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx b/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx index b358932..4177164 100644 --- a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx +++ b/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2006, 2007, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,157 @@ // version and license this file solely under the GPL without // exception. +#include <stdint.h> +#include <sys/types.h> +#include <sys/ptrace.h> +#include "linux.ptrace.h" +#include <string.h> + #include "jni.hxx" +#include "frysk/jnixx/bounds.hxx" +#include "frysk/jnixx/chars.hxx" + +#include "frysk/sys/ptrace/jni/Ptrace.hxx" + +using namespace java::lang; + +union word { + long l; + uint8_t b[sizeof (long)]; +}; + +jint +frysk::sys::ptrace::AddressSpace::peek(::jnixx::env env, jint pid, jlong addr) { + union word w; + long paddr = addr & -sizeof(long); +#if DEBUG + fprintf(stderr, "peek 0x%lx paddr 0x%lx", (long)addr, paddr); +#endif + w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0); +#if DEBUG + fprintf(stderr, " word 0x%lx", w.l); +#endif + int index = addr & (sizeof(long) - 1); +#if DEBUG + fprintf(stderr, " index %d", index); +#endif + uint8_t byte = w.b[index]; +#if DEBUG + fprintf(stderr, " byte %d/0x%x\n", byte, byte); +#endif + return byte; +} + +void +frysk::sys::ptrace::AddressSpace::poke(::jnixx::env env, jint pid, jlong addr, jint data) { + // Implement read-modify-write + union word w; +#if DEBUG + fprintf(stderr, "poke 0x%x", (int)(data & 0xff)); +#endif + long paddr = addr & -sizeof(long); +#if DEBUG + fprintf(stderr, " addr 0x%lx paddr 0x%lx", (long)addr, paddr); +#endif + w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0); +#if DEBUG + fprintf(stderr, " word 0x%lx", w.l); +#endif + int index = addr & (sizeof(long) - 1); +#if DEBUG + fprintf (stderr, " index %d", index); +#endif + w.b[index] = data; +#if DEBUG + fprintf(stderr, " word 0x%lx\n", w.l); +#endif + ptraceOp(env, GetPtPoke(env), pid, (void*)(addr & -sizeof(long)), w.l); +} + +void +frysk::sys::ptrace::AddressSpace::transfer(::jnixx::env env, + jint op, jint pid, jlong addr, + ::jnixx::byteArray bytes, + jint offset, jint length) { + const int ptPeek = GetPtPeek(env); + const int ptPoke = GetPtPoke(env); + verifyBounds(env, bytes, offset, length); + // Somewhat more clueful implementation + for (jlong i = 0; i < length;) { +#if DEBUG + fprintf(stderr, + "transfer pid %d addr 0x%lx length %d offset %d op %d (%s)", + (int)pid, (long)addr, (int)length, (int)offset, + (int)op, op_as_string(op)); +#endif + + union word w; + unsigned long waddr = addr & -sizeof(long); + unsigned long woff = (addr - waddr); + unsigned long remaining = length - i; + unsigned long wend; + if (remaining > sizeof(long) - woff) + wend = sizeof(long); + else + wend = woff + remaining; + long wlen = wend - woff; + +#if DEBUG + fprintf(stderr, + " i %ld waddr 0x%lx woff %lu wend %lu remaining %lu wlen %lu", + (long)i, waddr, woff, wend, remaining, wlen); +#endif + + // Either a peek; or a partial write requiring read/modify/write. + if (op == ptPeek || woff != 0 || wend != sizeof(long)) { + w.l = ptraceOp(env, ptPeek, pid, (void*)waddr, 0); +#if DEBUG + fprintf(stderr, " peek 0x%lx", w.l); +#endif + } + + // extract or modify + ByteArrayElements elements = ByteArrayElements(env, bytes); + if (op == ptPeek) + memcpy(offset + i + elements.p, &w.b[woff], wlen); + else { + memcpy(&w.b[woff], offset + i + elements.p, wlen); +#if DEBUG + fprintf(stderr, " poke 0x%lx", w.l); +#endif + w.l = ptraceOp(env, ptPoke, pid, (void*)waddr, w.l); + } + elements.release(); + + i += wlen; + addr += wlen; + +#if DEBUG + fprintf(stderr, "\n"); +#endif + } +} + +frysk::sys::ptrace::AddressSpace +frysk::sys::ptrace::AddressSpace::text(::jnixx::env env) { + return frysk::sys::ptrace::AddressSpace::New(env, -1UL, + String::NewStringUTF(env, "TEXT"), + PTRACE_PEEKTEXT, + PTRACE_POKETEXT); +} + +frysk::sys::ptrace::AddressSpace +frysk::sys::ptrace::AddressSpace::data(::jnixx::env env) { + return frysk::sys::ptrace::AddressSpace::New(env, -1UL, + String::NewStringUTF(env, "DATA"), + PTRACE_PEEKDATA, + PTRACE_POKEDATA); +} + +frysk::sys::ptrace::AddressSpace +frysk::sys::ptrace::AddressSpace::usr(::jnixx::env env) { + return frysk::sys::ptrace::AddressSpace::New(env, -1UL, + String::NewStringUTF(env, "USR"), + PTRACE_PEEKUSR, + PTRACE_POKEUSR); +} diff --git a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx index b358932..d6726ed 100644 --- a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx +++ b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2006, 2007, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,119 @@ // version and license this file solely under the GPL without // exception. +#include <errno.h> +#include <sys/ptrace.h> +#include "linux.ptrace.h" + #include "jni.hxx" + +#include "frysk/sys/ptrace/jni/Ptrace.hxx" + +#include "frysk/jnixx/exceptions.hxx" + +static const char* +op_as_string(int op) { + switch(op) { +#define OP(NAME) case NAME: return #NAME + OP(PTRACE_ATTACH); + OP(PTRACE_DETACH); + OP(PTRACE_SINGLESTEP); + OP(PTRACE_CONT); + OP(PTRACE_SYSCALL); +#if defined(__i386__) || defined(__x86_64__) + OP(PTRACE_GETREGS); + OP(PTRACE_SETREGS); + OP(PTRACE_GETFPREGS); + OP(PTRACE_SETFPREGS); +#endif +#if defined(__i386__) + OP(PTRACE_GETFPXREGS); + OP(PTRACE_SETFPXREGS); +#endif + OP(PTRACE_GETEVENTMSG); + OP(PTRACE_SETOPTIONS); + OP(PTRACE_PEEKDATA); + OP(PTRACE_POKEDATA); + OP(PTRACE_PEEKTEXT); + OP(PTRACE_POKETEXT); + OP(PTRACE_PEEKUSR); + OP(PTRACE_POKEUSR); + default: return "<unknown>"; +#undef OP + } +} + +long +ptraceOp(::jnixx::env env, int op, int pid, void* addr, long data) { + errno = 0; + long result = ::ptrace ((enum __ptrace_request) op, pid, addr, data); + if (errno != 0) + errnoException(env, errno, "ptrace", + "op 0x%x (%s), pid %d, addr 0x%lx, data 0x%lx", + op, op_as_string(op), pid, (long)addr, data); + return result; +} + +void +frysk::sys::ptrace::Ptrace::attach(::jnixx::env env, jint pid) { + ptraceOp(env, PTRACE_ATTACH, pid, NULL, 0); +} + +void +frysk::sys::ptrace::Ptrace::detach(::jnixx::env env, jint pid, jint sig) { + ptraceOp(env, PTRACE_DETACH, pid, NULL, sig); +} + +void +frysk::sys::ptrace::Ptrace::singleStep(::jnixx::env env, jint pid, jint sig) { + ptraceOp(env, PTRACE_SINGLESTEP, pid, NULL, sig); +} + +void +frysk::sys::ptrace::Ptrace::cont(::jnixx::env env, jint pid, jint sig) { + ptraceOp(env, PTRACE_CONT, pid, NULL, sig); +} + +void +frysk::sys::ptrace::Ptrace::sysCall(::jnixx::env env, jint pid, jint sig) { + ptraceOp(env, PTRACE_SYSCALL, pid, NULL, sig); +} + +jlong +frysk::sys::ptrace::Ptrace::getEventMsg(::jnixx::env env, jint pid) { + /* Note: PTRACE_GETEVENTMSG ends up calling the function + kernel/ptrace.c: ptrace_ptraceOp(env, ) and that uses put_user to store + child->ptrace_message write sizeof(ptrace_message) bytes into the + MESSAGE parameter. include/linux/sched.h declares ptrace_message + as a long. */ + long msg; + ptraceOp(env, PTRACE_GETEVENTMSG, pid, NULL, (long) &msg); + return msg; +} +\f +void +frysk::sys::ptrace::Ptrace::setOptions(::jnixx::env env, + jint pid, jlong options) { + ptraceOp(env, PTRACE_SETOPTIONS, pid, 0, options); +} + +jlong +frysk::sys::ptrace::Ptrace::optionTraceClone(::jnixx::env env) { + return PTRACE_O_TRACECLONE; +} +jlong +frysk::sys::ptrace::Ptrace::optionTraceFork(::jnixx::env env) { + return PTRACE_O_TRACEFORK; +} +jlong +frysk::sys::ptrace::Ptrace::optionTraceExit(::jnixx::env env) { + return PTRACE_O_TRACEEXIT; +} +jlong +frysk::sys::ptrace::Ptrace::optionTraceSysgood(::jnixx::env env) { + return PTRACE_O_TRACESYSGOOD; +} +jlong +frysk::sys::ptrace::Ptrace::optionTraceExec(::jnixx::env env) { + return PTRACE_O_TRACEEXEC; +} diff --git a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx similarity index 97% copy from frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx copy to frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx index b358932..be134ef 100644 --- a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx +++ b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx @@ -37,4 +37,4 @@ // version and license this file solely under the GPL without // exception. -#include "jni.hxx" +extern long ptraceOp(::jnixx::env, int, int, void*, long); diff --git a/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx b/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx index b358932..d44b1df 100644 --- a/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx +++ b/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2006, 2007, 2008, Red Hat Inc. // hooks/post-receive -- frysk system monitor/debugger
reply other threads:[~2008-05-14 17:10 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080514171053.26157.qmail@sourceware.org \ --to=cagney@sourceware.org \ --cc=frysk-cvs@sourceware.org \ --cc=frysk@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).