V10/cmd/adb/v7/trcrun.c
/*
* machine-specific functions for running the debugged process
* v7-style (ptrace)
*/
#include "defs.h"
#include "regs.h"
#include "ptrace.h"
#include <sys/param.h>
#include <signal.h>
extern char lastc, peekc;
extern ADDR txtsize;
/*
* kill process
*/
killpcs()
{
ptrace(P_KILL, pid, 0, 0);
}
/*
* grab the process already opened (but not traced);
* stop it so we can look at it
*/
grab()
{
error("antique system, can't grab");
}
/*
* turn off tracing & let it go
*/
ungrab()
{
error("antique system, can't ungrab");
}
/*
* get the program to be debugged ready to run
* program is left stopped at the beginning (so we can poke in breakpoints)
*/
extern int (*sigint)(), (*sigqit)();
startpcs()
{
if ((pid = fork()) == 0) {
close(fsym);
close(fcor);
signal(SIGINT, sigint);
signal(SIGQUIT, sigqit);
doexec();
exit(0);
}
if (pid == -1)
error("cannot fork");
bpwait();
if (adrflg)
rput(PC, wtoa(adrval));
while (rdc() != EOR)
;
reread();
}
/*
* set process running, single-stepped
*/
runstep(keepsig)
int keepsig;
{
delbp();
ptrace(P_STEP, pid, CONTNEXT, keepsig ? signo : 0);
}
/*
* set process running
*/
runrun(keepsig)
int keepsig;
{
ptrace(P_CONT, pid, CONTNEXT, keepsig ? signo : 0);
}
/*
* exec the program to be debugged
* opening standard input and output as requested
*/
extern char **environ;
doexec()
{
char *argl[MAXARG];
char args[LINSIZ];
register char *p;
register char **ap;
register char *thisarg;
ap = argl;
p = args;
*ap++ = symfil;
for (rdc(); lastc != EOR;) {
thisarg = p;
if (lastc == '<' || lastc == '>') {
*p++ = lastc;
rdc();
}
while (lastc != EOR && lastc != SPC && lastc != TB) {
*p++ = lastc;
readchar();
}
if (lastc == SPC || lastc == TB)
rdc();
*p++ = 0;
if (*thisarg == '<') {
close(0);
if (open(&thisarg[1], 0) < 0) {
printf("%s: cannot open\n", &thisarg[1]);
_exit(0);
}
}
else if (*thisarg == '>') {
close(1);
if (creat(&thisarg[1], 0666) < 0) {
printf("%s: cannot create\n", &thisarg[1]);
_exit(0);
}
}
else
*ap++ = thisarg;
}
*ap = NULL;
ptrace(P_INIT, 0, (int *)0, 0);
execve(symfil, argl, environ);
perror(symfil);
}
/*
* wait for the process to stop;
* pick up status and registers when it does
*/
#define WSLEEP 10
extern int errno;
bpwait()
{
register int w;
int stat;
int (*isig)();
int nulsig();
isig = signal(SIGINT, SIG_IGN);
while ((w = wait(&stat)) != -1 && w != pid)
;
signal(SIGINT, isig);
if (w == -1)
errflg = "wait failed";
else if ((stat & 0177) == 0177) { /* trace status */
signo = (stat >> 8) & 0177;
mapimage();
if (signo == SIGTRAP)
signo = 0;
else {
sigprint();
newline();
}
return;
}
else {
errflg = "process terminated";
sigcode = 0;
if ((signo = stat & 0177) != 0)
sigprint();
if (stat & 0200) {
prints(" - core dumped");
corfil = "core";
}
pid = 0;
setcor();
}
}
/*
* is the right-hand file a process image?
*/
trcimage()
{
return (pid != 0);
}
/*
* grab some data from the user block,
* before maps are set up (ugh)
*/
int
trcunab(off)
int off;
{
int data;
errno = 0;
data = ptrace(P_RDU, pid, off, 0);
if (errno) {
errflg = "can't read user block";
return (0);
}
return (data);
}