summaryrefslogtreecommitdiff
path: root/src/libmach
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmach')
-rw-r--r--src/libmach/8db.c54
-rw-r--r--src/libmach/darwin.c13
-rw-r--r--src/libmach/linux.c23
3 files changed, 76 insertions, 14 deletions
diff --git a/src/libmach/8db.c b/src/libmach/8db.c
index 5a195baf8..5b3de69a5 100644
--- a/src/libmach/8db.c
+++ b/src/libmach/8db.c
@@ -1017,14 +1017,56 @@ static Optable optabDB[8+64] =
[0x03] = { 0,0, "FMOVLP F0,%e" },
[0x05] = { 0,0, "FMOVX %e,F0" },
[0x07] = { 0,0, "FMOVXP F0,%e" },
-[0x08] = { 0,0, "FCMOVCC %f,F0" },
-[0x09] = { 0,0, "FCMOVNE %f,F0" },
-[0x0a] = { 0,0, "FCMOVHI %f,F0" },
-[0x0b] = { 0,0, "FCMOVNU %f,F0" },
-[0x0d] = { 0,0, "FUCOMI F0,%f" },
-[0x0e] = { 0,0, "FCOMI F0,%f" },
+[0x08] = { 0,0, "FCMOVCC F0,F0" }, /* Mod R/M = 11xx xxxx*/
+[0x09] = { 0,0, "FCMOVCC F1,F0" },
+[0x0a] = { 0,0, "FCMOVCC F2,F0" },
+[0x0b] = { 0,0, "FCMOVCC F3,F0" },
+[0x0c] = { 0,0, "FCMOVCC F4,F0" },
+[0x0d] = { 0,0, "FCMOVCC F5,F0" },
+[0x0e] = { 0,0, "FCMOVCC F6,F0" },
+[0x0f] = { 0,0, "FCMOVCC F7,F0" },
+[0x10] = { 0,0, "FCMOVNE F0,F0" },
+[0x11] = { 0,0, "FCMOVNE F1,F0" },
+[0x12] = { 0,0, "FCMOVNE F2,F0" },
+[0x13] = { 0,0, "FCMOVNE F3,F0" },
+[0x14] = { 0,0, "FCMOVNE F4,F0" },
+[0x15] = { 0,0, "FCMOVNE F5,F0" },
+[0x16] = { 0,0, "FCMOVNE F6,F0" },
+[0x17] = { 0,0, "FCMOVNE F7,F0" },
+[0x18] = { 0,0, "FCMOVHI F0,F0" },
+[0x19] = { 0,0, "FCMOVHI F1,F0" },
+[0x1a] = { 0,0, "FCMOVHI F2,F0" },
+[0x1b] = { 0,0, "FCMOVHI F3,F0" },
+[0x1c] = { 0,0, "FCMOVHI F4,F0" },
+[0x1d] = { 0,0, "FCMOVHI F5,F0" },
+[0x1e] = { 0,0, "FCMOVHI F6,F0" },
+[0x1f] = { 0,0, "FCMOVHI F7,F0" },
+[0x20] = { 0,0, "FCMOVNU F0,F0" },
+[0x21] = { 0,0, "FCMOVNU F1,F0" },
+[0x22] = { 0,0, "FCMOVNU F2,F0" },
+[0x23] = { 0,0, "FCMOVNU F3,F0" },
+[0x24] = { 0,0, "FCMOVNU F4,F0" },
+[0x25] = { 0,0, "FCMOVNU F5,F0" },
+[0x26] = { 0,0, "FCMOVNU F6,F0" },
+[0x27] = { 0,0, "FCMOVNU F7,F0" },
[0x2a] = { 0,0, "FCLEX" },
[0x2b] = { 0,0, "FINIT" },
+[0x30] = { 0,0, "FUCOMI F0,F0" },
+[0x31] = { 0,0, "FUCOMI F1,F0" },
+[0x32] = { 0,0, "FUCOMI F2,F0" },
+[0x33] = { 0,0, "FUCOMI F3,F0" },
+[0x34] = { 0,0, "FUCOMI F4,F0" },
+[0x35] = { 0,0, "FUCOMI F5,F0" },
+[0x36] = { 0,0, "FUCOMI F6,F0" },
+[0x37] = { 0,0, "FUCOMI F7,F0" },
+[0x38] = { 0,0, "FCOMI F0,F0" },
+[0x39] = { 0,0, "FCOMI F1,F0" },
+[0x3a] = { 0,0, "FCOMI F2,F0" },
+[0x3b] = { 0,0, "FCOMI F3,F0" },
+[0x3c] = { 0,0, "FCOMI F4,F0" },
+[0x3d] = { 0,0, "FCOMI F5,F0" },
+[0x3e] = { 0,0, "FCOMI F6,F0" },
+[0x3f] = { 0,0, "FCOMI F7,F0" },
};
static Optable optabDC[8+8] =
diff --git a/src/libmach/darwin.c b/src/libmach/darwin.c
index c443a4fba..63abde313 100644
--- a/src/libmach/darwin.c
+++ b/src/libmach/darwin.c
@@ -222,12 +222,21 @@ addpid(int pid, int force)
// The excthread reads that port and signals
// us if we are waiting on that thread.
pthread_t p;
+ int err;
excport = mach_reply_port();
pthread_mutex_init(&mu, nil);
pthread_cond_init(&cond, nil);
- pthread_create(&p, nil, excthread, nil);
- pthread_create(&p, nil, waitthread, (void*)(uintptr)pid);
+ err = pthread_create(&p, nil, excthread, nil);
+ if (err != 0) {
+ fprint(2, "pthread_create failed: %s\n", strerror(err));
+ abort();
+ }
+ err = pthread_create(&p, nil, waitthread, (void*)(uintptr)pid);
+ if (err != 0) {
+ fprint(2, "pthread_create failed: %s\n", strerror(err));
+ abort();
+ }
first = 0;
}
diff --git a/src/libmach/linux.c b/src/libmach/linux.c
index 30b4da240..6ce18957f 100644
--- a/src/libmach/linux.c
+++ b/src/libmach/linux.c
@@ -238,8 +238,7 @@ fixup:
PTRACE_O_TRACEVFORK |
PTRACE_O_TRACECLONE |
PTRACE_O_TRACEEXEC |
- PTRACE_O_TRACEVFORKDONE |
- PTRACE_O_TRACEEXIT;
+ PTRACE_O_TRACEVFORKDONE;
if(ptrace(PTRACE_SETOPTIONS, tid, 0, (void*)flags) < 0) {
fprint(2, "ptrace PTRACE_SETOPTIONS %d: %r\n", tid);
return nil;
@@ -358,6 +357,12 @@ wait1(int nohang)
break;
case PTRACE_EVENT_EXIT:
+ // We won't see this unless we set PTRACE_O_TRACEEXIT.
+ // The debuggers assume that a read or write on a Map
+ // will fail for a thread that has exited. This event
+ // breaks that assumption. It's not a big deal: we
+ // only lose the ability to see the register state at
+ // the time of exit.
if(trace)
fprint(2, "tid %d: exiting %#x\n", tid, status);
t->state = Exiting;
@@ -755,13 +760,19 @@ static int
ptracerw(int type, int xtype, int isr, int pid, uvlong addr, void *v, uint n)
{
int i;
- uintptr u;
+ uintptr u, a;
uchar buf[sizeof(uintptr)];
for(i=0; i<n; i+=sizeof(uintptr)){
+ // Tread carefully here. On recent versions of glibc,
+ // ptrace is a variadic function which means the third
+ // argument will be pushed onto the stack as a uvlong.
+ // This is fine on amd64 but will not work for 386.
+ // We must convert addr to a uintptr.
+ a = addr+i;
if(isr){
errno = 0;
- u = ptrace(type, pid, addr+i, 0);
+ u = ptrace(type, pid, a, 0);
if(errno)
goto ptraceerr;
if(n-i >= sizeof(uintptr))
@@ -775,14 +786,14 @@ ptracerw(int type, int xtype, int isr, int pid, uvlong addr, void *v, uint n)
u = *(uintptr*)((char*)v+i);
else{
errno = 0;
- u = ptrace(xtype, pid, addr+i, 0);
+ u = ptrace(xtype, pid, a, 0);
if(errno)
return -1;
memmove(buf, &u, sizeof u);
memmove(buf, (char*)v+i, n-i);
memmove(&u, buf, sizeof u);
}
- if(ptrace(type, pid, addr+i, u) < 0)
+ if(ptrace(type, pid, a, u) < 0)
goto ptraceerr;
}
}