Commit c8dee277 authored by Russ Cox's avatar Russ Cox

acid. works only on Linux for now

R=r
DELTA=7031  (6906 added, 113 deleted, 12 changed)
OCL=13847
CL=13852
parent 2f4352a2
......@@ -127,8 +127,8 @@ i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
Symbol s, f;
USED(link);
i = 0;
osp = 0;
i = 0;
while(findsym(pc, CTEXT, &s)) {
if (osp == sp)
break;
......@@ -142,7 +142,6 @@ i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
break;
sp += f.value-mach->szaddr;
}
if (geta(map, sp, &pc) < 0)
break;
......
......@@ -43,6 +43,7 @@ OFILES=\
8.$O\
8db.$O\
6obj.$O\
$(GOOS).$O\
# v.$O\
# k.$O\
# u.$O\
......
......@@ -37,7 +37,7 @@
static int mget(Map*, uvlong, void*, int);
static int mput(Map*, uvlong, void*, int);
static struct segment* reloc(Map*, uvlong, vlong*);
static Seg* reloc(Map*, uvlong, vlong*);
/*
* routines to get/put various types
......@@ -189,101 +189,42 @@ put1(Map *map, uvlong addr, uchar *v, int size)
return mput(map, addr, v, size);
}
static int
spread(struct segment *s, void *buf, int n, uvlong off)
{
uvlong base;
static struct {
struct segment *s;
char a[8192];
uvlong off;
} cache;
if(s->cache){
base = off&~(sizeof cache.a-1);
if(cache.s != s || cache.off != base){
cache.off = ~0;
if(seek(s->fd, base, 0) >= 0
&& readn(s->fd, cache.a, sizeof cache.a) == sizeof cache.a){
cache.s = s;
cache.off = base;
}
}
if(cache.s == s && cache.off == base){
off &= sizeof cache.a-1;
if(off+n > sizeof cache.a)
n = sizeof cache.a - off;
memmove(buf, cache.a+off, n);
return n;
}
}
return pread(s->fd, buf, n, off);
}
static int
mget(Map *map, uvlong addr, void *buf, int size)
{
uvlong off;
int i, j, k;
struct segment *s;
Seg *s;
s = reloc(map, addr, (vlong*)&off);
if (!s)
return -1;
if (s->fd < 0) {
if (s->rw == nil) {
werrstr("unreadable map");
return -1;
}
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
k = spread(s, buf, size-j, off+j);
if (k < 0) {
werrstr("can't read address %llux: %r", addr);
return -1;
}
j += k;
if (j == size)
return j;
}
werrstr("partial read at address %llux (size %d j %d)", addr, size, j);
return -1;
return s->rw(map, s, off, buf, size, 1);
}
static int
mput(Map *map, uvlong addr, void *buf, int size)
{
vlong off;
int i, j, k;
struct segment *s;
Seg *s;
s = reloc(map, addr, &off);
if (!s)
return -1;
if (s->fd < 0) {
if (s->rw == nil) {
werrstr("unwritable map");
return -1;
}
seek(s->fd, off, 0);
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
k = write(s->fd, buf, size-j);
if (k < 0) {
werrstr("can't write address %llux: %r", addr);
return -1;
}
j += k;
if (j == size)
return j;
}
werrstr("partial write at address %llux", addr);
return -1;
return s->rw(map, s, off, buf, size, 0);
}
/*
* convert address to file offset; returns nonzero if ok
*/
static struct segment*
static Seg*
reloc(Map *map, uvlong addr, vlong *offp)
{
int i;
......
// Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach_amd64.h>
Map*
attachproc(int pid, Fhdr *fp)
{
sysfatal("attachproc not implemented");
return nil;
}
int
ctlproc(int pid, char *msg)
{
sysfatal("ctlproc not implemented");
return -1;
}
void
detachproc(Map *m)
{
sysfatal("detachproc not implemented");
}
int
procnotes(int pid, char ***pnotes)
{
sysfatal("procnotes not implemented");
return -1;
}
char*
proctextfile(int pid)
{
sysfatal("proctextfile not implemented");
return nil;
}
int
procthreadpids(int pid, int **thread)
{
sysfatal("procthreadpids not implemented");
return -1;
}
This diff is collapsed.
......@@ -44,7 +44,7 @@ newmap(Map *map, int n)
{
int size;
size = sizeof(Map)+(n-1)*sizeof(struct segment);
size = sizeof(Map)+(n-1)*sizeof(Seg);
if (map == 0)
map = malloc(size);
else
......@@ -59,7 +59,7 @@ newmap(Map *map, int n)
}
int
setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name, Maprw *rw)
{
int i;
......@@ -76,6 +76,7 @@ setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
map->seg[i].inuse = 1;
map->seg[i].name = name;
map->seg[i].fd = fd;
map->seg[i].rw = rw;
return 1;
}
......@@ -110,58 +111,6 @@ stacktop(int pid)
return strtoull(cp, 0, 16);
}
Map*
attachproc(int pid, int kflag, int corefd, Fhdr *fp)
{
char buf[64], *regs;
int fd;
Map *map;
uvlong n;
int mode;
map = newmap(0, 4);
if (!map)
return 0;
if(kflag) {
regs = "kregs";
mode = OREAD;
} else {
regs = "regs";
mode = ORDWR;
}
if (mach->regsize) {
sprint(buf, "/proc/%d/%s", pid, regs);
fd = open(buf, mode);
if(fd < 0) {
free(map);
return 0;
}
setmap(map, fd, 0, mach->regsize, 0, "regs");
}
if (mach->fpregsize) {
sprint(buf, "/proc/%d/fpregs", pid);
fd = open(buf, mode);
if(fd < 0) {
close(map->seg[0].fd);
free(map);
return 0;
}
setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
}
setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
if(kflag || fp->dataddr >= mach->utop) {
setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
return map;
}
n = stacktop(pid);
if (n == 0) {
setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
return map;
}
setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
return map;
}
int
findseg(Map *map, char *name)
{
......@@ -182,6 +131,29 @@ unusemap(Map *map, int i)
map->seg[i].inuse = 0;
}
int
fdrw(Map *map, Seg *s, uvlong addr, void *v, uint n, int isread)
{
int tot, m;
for(tot=0; tot<n; tot+=m){
if(isread)
m = pread(s->fd, (uchar*)v+tot, n-tot, addr+tot);
else
m = pwrite(s->fd, (uchar*)v+tot, n-tot, addr+tot);
if(m == 0){
werrstr("short %s", isread ? "read" : "write");
return -1;
}
if(m < 0){
werrstr("%s %d at %#llux (+%#llux): %r", isread ? "read" : "write", n, addr, s->f);
return -1;
}
}
return 0;
}
Map*
loadmap(Map *map, int fd, Fhdr *fp)
{
......@@ -195,11 +167,13 @@ loadmap(Map *map, int fd, Fhdr *fp)
map->seg[0].fd = fd;
map->seg[0].inuse = 1;
map->seg[0].name = "text";
map->seg[0].rw = fdrw;
map->seg[1].b = fp->dataddr;
map->seg[1].e = fp->dataddr+fp->datsz;
map->seg[1].f = fp->datoff;
map->seg[1].fd = fd;
map->seg[1].inuse = 1;
map->seg[1].name = "data";
map->seg[0].rw = fdrw;
return map;
}
......@@ -30,9 +30,10 @@ OFILES=$(RT0OFILES) $(LIBOFILES)
OS_H=$(GOARCH)_$(GOOS).h
HFILES=runtime.h $(OS_H_)
install: rt0 $(LIB)
install: rt0 $(LIB) runtime.acid
cp $(RT0OFILES) $(GOROOT)/lib
cp $(LIB) $(GOROOT)/lib
cp runtime.acid $(GOROOT)/acid/runtime.acid
rt0: $(RT0OFILES)
......@@ -45,7 +46,7 @@ nuke:
rm -f *.$(O) *.a $(GOROOT)/lib/$(LIB)
clean:
rm -f *.$(O) *.a
rm -f *.$(O) *.a runtime.acid
%.$O: %.c
$(CC) $<
......@@ -55,3 +56,6 @@ sys_file.$O: sys_file.c sys_types.h $(OS_H)
%.$O: %.s
$(AS) $<
runtime.acid: runtime.h
$(CC) -a runtime.h >runtime.acid
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment