|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: #include "ureg.h" ! 8: ! 9: #include "devtab.h" ! 10: ! 11: enum{ ! 12: Qdir, ! 13: Qctl, ! 14: Qmem, ! 15: Qnote, ! 16: Qnoteid, ! 17: Qnotepg, ! 18: Qproc, ! 19: Qsegment, ! 20: Qstatus, ! 21: Qtext, ! 22: Qwait, ! 23: }; ! 24: ! 25: #define STATSIZE (2*NAMELEN+12+7*12) ! 26: Dirtab procdir[] = ! 27: { ! 28: "ctl", {Qctl}, 0, 0000, ! 29: "mem", {Qmem}, 0, 0000, ! 30: "note", {Qnote}, 0, 0000, ! 31: "noteid", {Qnoteid}, 0, 0666, ! 32: "notepg", {Qnotepg}, 0, 0000, ! 33: "proc", {Qproc}, sizeof(Proc), 0444, ! 34: "segment", {Qsegment}, 0, 0444, ! 35: "status", {Qstatus}, STATSIZE, 0444, ! 36: "text", {Qtext}, 0, 0000, ! 37: "wait", {Qwait}, 0, 0400, ! 38: }; ! 39: ! 40: /* Segment type from portdat.h */ ! 41: char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" }; ! 42: ! 43: /* ! 44: * Qids are, in path: ! 45: * 4 bits of file type (qids above) ! 46: * 23 bits of process slot number + 1 ! 47: * in vers, ! 48: * 32 bits of pid, for consistency checking ! 49: * If notepg, c->pgrpid.path is pgrp slot, .vers is noteid. ! 50: */ ! 51: #define NPROC (sizeof procdir/sizeof(Dirtab)) ! 52: #define QSHIFT 4 /* location in qid of proc slot # */ ! 53: ! 54: #define QID(q) (((q).path&0x0000000F)>>0) ! 55: #define SLOT(q) ((((q).path&0x07FFFFFF0)>>QSHIFT)-1) ! 56: #define PID(q) ((q).vers) ! 57: #define NOTEID(q) ((q).vers) ! 58: ! 59: void procctlreq(Proc*, char*, int); ! 60: int procctlmemio(Proc*, ulong, int, void*, int); ! 61: Chan* proctext(Chan*, Proc*); ! 62: Segment* txt2data(Proc*, Segment*); ! 63: int procstopped(void*); ! 64: ! 65: int ! 66: procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) ! 67: { ! 68: Qid qid; ! 69: Proc *p; ! 70: char buf[NAMELEN]; ! 71: ulong pid, path, perm, len; ! 72: ! 73: USED(ntab); ! 74: if(c->qid.path == CHDIR){ ! 75: if(s >= conf.nproc) ! 76: return -1; ! 77: p = proctab(s); ! 78: pid = p->pid; ! 79: if(pid == 0) ! 80: return 0; ! 81: sprint(buf, "%d", pid); ! 82: qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid}; ! 83: devdir(c, qid, buf, 0, p->user, CHDIR|0555, dp); ! 84: return 1; ! 85: } ! 86: if(s >= NPROC) ! 87: return -1; ! 88: if(tab) ! 89: panic("procgen"); ! 90: ! 91: tab = &procdir[s]; ! 92: path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1)); /* slot component */ ! 93: ! 94: p = proctab(SLOT(c->qid)); ! 95: perm = tab->perm; ! 96: if(perm == 0) ! 97: perm = p->procmode; ! 98: ! 99: len = tab->length; ! 100: if(QID(c->qid) == Qwait) ! 101: len = p->nwait * sizeof(Waitmsg); ! 102: ! 103: qid = (Qid){path|tab->qid.path, c->qid.vers}; ! 104: devdir(c, qid, tab->name, len, p->user, perm, dp); ! 105: return 1; ! 106: } ! 107: ! 108: void ! 109: procinit(void) ! 110: { ! 111: if(conf.nproc >= (1<<(16-QSHIFT))-1) ! 112: print("warning: too many procs for devproc\n"); ! 113: } ! 114: ! 115: void ! 116: procreset(void) ! 117: { ! 118: } ! 119: ! 120: Chan* ! 121: procattach(char *spec) ! 122: { ! 123: return devattach('p', spec); ! 124: } ! 125: ! 126: Chan* ! 127: procclone(Chan *c, Chan *nc) ! 128: { ! 129: return devclone(c, nc); ! 130: } ! 131: ! 132: int ! 133: procwalk(Chan *c, char *name) ! 134: { ! 135: if(strcmp(name, "..") == 0) { ! 136: c->qid.path = Qdir|CHDIR; ! 137: return 1; ! 138: } ! 139: ! 140: return devwalk(c, name, 0, 0, procgen); ! 141: } ! 142: ! 143: void ! 144: procstat(Chan *c, char *db) ! 145: { ! 146: devstat(c, db, 0, 0, procgen); ! 147: } ! 148: ! 149: Chan * ! 150: procopen(Chan *c, int omode) ! 151: { ! 152: Proc *p; ! 153: Pgrp *pg; ! 154: Chan *tc; ! 155: ! 156: if(c->qid.path & CHDIR) ! 157: return devopen(c, omode, 0, 0, procgen); ! 158: ! 159: p = proctab(SLOT(c->qid)); ! 160: pg = p->pgrp; ! 161: if(p->pid != PID(c->qid)) ! 162: error(Eprocdied); ! 163: ! 164: omode = openmode(omode); ! 165: ! 166: switch(QID(c->qid)){ ! 167: case Qtext: ! 168: tc = proctext(c, p); ! 169: tc->offset = 0; ! 170: return tc; ! 171: ! 172: case Qctl: ! 173: case Qnote: ! 174: case Qnoteid: ! 175: case Qmem: ! 176: case Qsegment: ! 177: case Qproc: ! 178: case Qstatus: ! 179: case Qwait: ! 180: break; ! 181: ! 182: case Qnotepg: ! 183: if(omode!=OWRITE || pg->pgrpid == 1) ! 184: error(Eperm); ! 185: c->pgrpid.path = pg->pgrpid+1; ! 186: c->pgrpid.vers = p->noteid; ! 187: break; ! 188: ! 189: default: ! 190: pprint("procopen %lux\n", c->qid); ! 191: error(Egreg); ! 192: } ! 193: ! 194: /* Affix pid to qid */ ! 195: if(p->state != Dead) ! 196: c->qid.vers = p->pid; ! 197: ! 198: return devopen(c, omode, 0, 0, procgen); ! 199: } ! 200: ! 201: void ! 202: proccreate(Chan *c, char *name, int omode, ulong perm) ! 203: { ! 204: USED(c, name, omode, perm); ! 205: error(Eperm); ! 206: } ! 207: ! 208: void ! 209: procremove(Chan *c) ! 210: { ! 211: USED(c); ! 212: error(Eperm); ! 213: } ! 214: ! 215: void ! 216: procwstat(Chan *c, char *db) ! 217: { ! 218: Proc *p; ! 219: Dir d; ! 220: ! 221: if(c->qid.path&CHDIR) ! 222: error(Eperm); ! 223: ! 224: convM2D(db, &d); ! 225: p = proctab(SLOT(c->qid)); ! 226: if(p->pid != PID(c->qid)) ! 227: error(Eprocdied); ! 228: ! 229: if(strcmp(u->p->user, p->user) != 0 && strcmp(u->p->user, eve) != 0) ! 230: error(Eperm); ! 231: ! 232: p->procmode = d.mode&0777; ! 233: } ! 234: ! 235: void ! 236: procclose(Chan * c) ! 237: { ! 238: USED(c); ! 239: } ! 240: ! 241: long ! 242: procread(Chan *c, void *va, long n, ulong offset) ! 243: { ! 244: Proc *p; ! 245: Page *pg; ! 246: KMap *k; ! 247: Segment *s; ! 248: int i, j; ! 249: long l; ! 250: User *up; ! 251: Segment *sg; ! 252: Waitq *wq; ! 253: char statbuf[NSEG*32]; ! 254: char *a = va, *b, *sps; ! 255: ! 256: if(c->qid.path & CHDIR) ! 257: return devdirread(c, a, n, 0, 0, procgen); ! 258: ! 259: p = proctab(SLOT(c->qid)); ! 260: if(p->pid != PID(c->qid)) ! 261: error(Eprocdied); ! 262: ! 263: switch(QID(c->qid)){ ! 264: case Qmem: ! 265: /* ugly math: USERADDR+BY2PG may be == 0 */ ! 266: if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) { ! 267: if(offset+n >= USERADDR+BY2PG-1) ! 268: n = USERADDR+BY2PG - offset; ! 269: pg = p->upage; ! 270: if(pg==0 || p->pid!=PID(c->qid)) ! 271: error(Eprocdied); ! 272: k = kmap(pg); ! 273: b = (char*)VA(k); ! 274: memmove(a, b+(offset-USERADDR), n); ! 275: kunmap(k); ! 276: return n; ! 277: } ! 278: ! 279: if(offset >= KZERO) { ! 280: /* Protect crypt key memory */ ! 281: if(offset < palloc.cmemtop && offset+n > palloc.cmembase) ! 282: error(Eperm); ! 283: ! 284: /* validate physical kernel addresses */ ! 285: if(offset < (ulong)end) { ! 286: if(offset+n > (ulong)end) ! 287: n = (ulong)end - offset; ! 288: memmove(a, (char*)offset, n); ! 289: return n; ! 290: } ! 291: if(offset >= conf.base0 && offset < conf.npage0){ ! 292: if(offset+n > conf.npage0) ! 293: n = conf.npage0 - offset; ! 294: memmove(a, (char*)offset, n); ! 295: return n; ! 296: } ! 297: if(offset >= conf.base1 && offset < conf.npage1){ ! 298: if(offset+n > conf.npage1) ! 299: n = conf.npage1 - offset; ! 300: memmove(a, (char*)offset, n); ! 301: return n; ! 302: } ! 303: } ! 304: ! 305: return procctlmemio(p, offset, n, va, 1); ! 306: ! 307: case Qnote: ! 308: qlock(&p->debug); ! 309: if(waserror()){ ! 310: qunlock(&p->debug); ! 311: nexterror(); ! 312: } ! 313: if(p->pid != PID(c->qid)) ! 314: error(Eprocdied); ! 315: k = kmap(p->upage); ! 316: up = (User*)VA(k); ! 317: if(up->p != p){ ! 318: kunmap(k); ! 319: pprint("note read u/p mismatch"); ! 320: error(Egreg); ! 321: } ! 322: if(n < ERRLEN) ! 323: error(Etoosmall); ! 324: if(up->nnote == 0) ! 325: n = 0; ! 326: else{ ! 327: memmove(va, up->note[0].msg, ERRLEN); ! 328: up->nnote--; ! 329: memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); ! 330: n = ERRLEN; ! 331: } ! 332: if(up->nnote == 0) ! 333: p->notepending = 0; ! 334: kunmap(k); ! 335: poperror(); ! 336: qunlock(&p->debug); ! 337: return n; ! 338: ! 339: case Qproc: ! 340: if(offset >= sizeof(Proc)) ! 341: return 0; ! 342: if(offset+n > sizeof(Proc)) ! 343: n = sizeof(Proc) - offset; ! 344: memmove(a, ((char*)p)+offset, n); ! 345: return n; ! 346: ! 347: case Qstatus: ! 348: if(offset >= STATSIZE) ! 349: return 0; ! 350: if(offset+n > STATSIZE) ! 351: n = STATSIZE - offset; ! 352: ! 353: sps = p->psstate; ! 354: if(sps == 0) ! 355: sps = statename[p->state]; ! 356: memset(statbuf, ' ', sizeof statbuf); ! 357: memmove(statbuf+0*NAMELEN, p->text, strlen(p->text)); ! 358: memmove(statbuf+1*NAMELEN, p->user, strlen(p->user)); ! 359: memmove(statbuf+2*NAMELEN, sps, strlen(sps)); ! 360: j = 2*NAMELEN + 12; ! 361: ! 362: for(i = 0; i < 6; i++) { ! 363: l = p->time[i]; ! 364: if(i == TReal) ! 365: l = MACHP(0)->ticks - l; ! 366: l = TK2MS(l); ! 367: readnum(0, statbuf+j+NUMSIZE*i, NUMSIZE, l, NUMSIZE); ! 368: } ! 369: /* ignore stack, which is mostly non-existent */ ! 370: l = 0; ! 371: for(i=1; i<NSEG; i++){ ! 372: s = p->seg[i]; ! 373: if(s) ! 374: l += s->top - s->base; ! 375: } ! 376: readnum(0, statbuf+j+NUMSIZE*6, NUMSIZE, l>>10, NUMSIZE); ! 377: memmove(a, statbuf+offset, n); ! 378: return n; ! 379: ! 380: case Qsegment: ! 381: j = 0; ! 382: for(i = 0; i < NSEG; i++) ! 383: if(sg = p->seg[i]) ! 384: j += sprint(&statbuf[j], "%-6s %c %.8lux %.8lux %4d\n", ! 385: sname[sg->type&SG_TYPE], sg->type&SG_RONLY ? 'R' : ' ', ! 386: sg->base, sg->top, sg->ref); ! 387: if(offset >= j) ! 388: return 0; ! 389: if(offset+n > j) ! 390: n = j-offset; ! 391: if(n == 0 && offset == 0) ! 392: exhausted("segments"); ! 393: memmove(a, &statbuf[offset], n); ! 394: return n; ! 395: ! 396: case Qwait: ! 397: if(n < sizeof(Waitmsg)) ! 398: error(Etoosmall); ! 399: ! 400: if(!canqlock(&p->qwaitr)) ! 401: error(Einuse); ! 402: ! 403: if(waserror()) { ! 404: qunlock(&p->qwaitr); ! 405: nexterror(); ! 406: } ! 407: ! 408: lock(&p->exl); ! 409: if(u->p == p && p->nchild == 0 && p->waitq == 0) { ! 410: unlock(&p->exl); ! 411: error(Enochild); ! 412: } ! 413: while(p->waitq == 0) { ! 414: unlock(&p->exl); ! 415: sleep(&p->waitr, haswaitq, p); ! 416: lock(&p->exl); ! 417: } ! 418: wq = p->waitq; ! 419: p->waitq = wq->next; ! 420: p->nwait--; ! 421: unlock(&p->exl); ! 422: ! 423: qunlock(&p->qwaitr); ! 424: poperror(); ! 425: memmove(a, &wq->w, sizeof(Waitmsg)); ! 426: free(wq); ! 427: return sizeof(Waitmsg); ! 428: case Qnoteid: ! 429: return readnum(offset, va, n, p->noteid, NUMSIZE); ! 430: } ! 431: error(Egreg); ! 432: return 0; /* not reached */ ! 433: } ! 434: ! 435: ! 436: long ! 437: procwrite(Chan *c, void *va, long n, ulong offset) ! 438: { ! 439: int id; ! 440: User *up; ! 441: KMap *k; ! 442: Ureg *ur; ! 443: User *pxu; ! 444: Page *pg; ! 445: ulong hi; ! 446: char *a, *b; ! 447: char buf[ERRLEN]; ! 448: Proc *p, *t, *et; ! 449: ! 450: if(c->qid.path & CHDIR) ! 451: error(Eisdir); ! 452: ! 453: a = va; ! 454: p = proctab(SLOT(c->qid)); ! 455: ! 456: /* Use the remembered noteid in the channel ! 457: * rather than the process pgrpid ! 458: */ ! 459: if(QID(c->qid) == Qnotepg) { ! 460: pgrpnote(NOTEID(c->pgrpid), va, n, NUser); ! 461: return n; ! 462: } ! 463: ! 464: qlock(&p->debug); ! 465: if(waserror()){ ! 466: qunlock(&p->debug); ! 467: nexterror(); ! 468: } ! 469: if(p->pid != PID(c->qid)) ! 470: error(Eprocdied); ! 471: ! 472: switch(QID(c->qid)){ ! 473: case Qmem: ! 474: if(p->state != Stopped) ! 475: error(Ebadctl); ! 476: ! 477: if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) { ! 478: pg = p->upage; ! 479: if(pg==0 || p->pid!=PID(c->qid)) ! 480: error(Eprocdied); ! 481: k = kmap(pg); ! 482: b = (char*)VA(k); ! 483: pxu = (User*)b; ! 484: hi = offset+n; ! 485: /* Check for floating point registers */ ! 486: if(offset >= (ulong)&u->fpsave && ! 487: hi <= (ulong)&u->fpsave+sizeof(FPsave)){ ! 488: memmove(b+(offset-USERADDR), a, n); ! 489: break; ! 490: } ! 491: /* Check user register set for process at kernel entry */ ! 492: ur = pxu->dbgreg; ! 493: if(offset < (ulong)ur || hi > (ulong)ur+sizeof(Ureg)) { ! 494: kunmap(k); ! 495: error(Ebadarg); ! 496: } ! 497: ur = (Ureg*)(b+((ulong)ur-USERADDR)); ! 498: setregisters(ur, b+(offset-USERADDR), a, n); ! 499: kunmap(k); ! 500: } ! 501: else /* Try user memory segments */ ! 502: n = procctlmemio(p, offset, n, va, 0); ! 503: break; ! 504: ! 505: case Qctl: ! 506: procctlreq(p, va, n); ! 507: break; ! 508: ! 509: case Qnote: ! 510: if(p->kp) ! 511: error(Eperm); ! 512: k = kmap(p->upage); ! 513: up = (User*)VA(k); ! 514: if(up->p != p){ ! 515: kunmap(k); ! 516: pprint("note write u/p mismatch"); ! 517: error(Egreg); ! 518: } ! 519: kunmap(k); ! 520: if(n >= ERRLEN-1) ! 521: error(Etoobig); ! 522: memmove(buf, va, n); ! 523: buf[n] = 0; ! 524: if(!postnote(p, 0, buf, NUser)) ! 525: error("note not posted"); ! 526: break; ! 527: case Qnoteid: ! 528: id = atoi(a); ! 529: if(id == p->pid) { ! 530: p->noteid = id; ! 531: break; ! 532: } ! 533: t = proctab(0); ! 534: for(et = t+conf.nproc; t < et; t++) { ! 535: if(id == t->noteid) { ! 536: if(strcmp(p->user, t->user) != 0) ! 537: error(Eperm); ! 538: p->noteid = id; ! 539: break; ! 540: } ! 541: } ! 542: if(p->noteid != id) ! 543: error(Ebadarg); ! 544: break; ! 545: default: ! 546: pprint("unknown qid in procwrite\n"); ! 547: error(Egreg); ! 548: } ! 549: poperror(); ! 550: qunlock(&p->debug); ! 551: return n; ! 552: } ! 553: ! 554: Chan * ! 555: proctext(Chan *c, Proc *p) ! 556: { ! 557: Chan *tc; ! 558: Image *i; ! 559: Segment *s; ! 560: ! 561: s = p->seg[TSEG]; ! 562: if(s == 0) ! 563: error(Enonexist); ! 564: if(p->state==Dead) ! 565: error(Eprocdied); ! 566: ! 567: lock(s); ! 568: i = s->image; ! 569: if(i == 0) { ! 570: unlock(s); ! 571: error(Eprocdied); ! 572: } ! 573: unlock(s); ! 574: ! 575: lock(i); ! 576: if(waserror()) { ! 577: unlock(i); ! 578: nexterror(); ! 579: } ! 580: ! 581: tc = i->c; ! 582: if(tc == 0) ! 583: error(Eprocdied); ! 584: ! 585: if(incref(tc) == 1 || (tc->flag&COPEN) == 0 || tc->mode!=OREAD) { ! 586: close(tc); ! 587: error(Eprocdied); ! 588: } ! 589: ! 590: if(p->pid != PID(c->qid)) ! 591: error(Eprocdied); ! 592: ! 593: unlock(i); ! 594: poperror(); ! 595: ! 596: return tc; ! 597: } ! 598: ! 599: void ! 600: procstopwait(Proc *p, int ctl) ! 601: { ! 602: int pid; ! 603: ! 604: if(p->pdbg) ! 605: error(Einuse); ! 606: if(procstopped(p)) ! 607: return; ! 608: ! 609: if(ctl != 0) ! 610: p->procctl = ctl; ! 611: p->pdbg = u->p; ! 612: pid = p->pid; ! 613: qunlock(&p->debug); ! 614: u->p->psstate = "Stopwait"; ! 615: if(waserror()) { ! 616: p->pdbg = 0; ! 617: qlock(&p->debug); ! 618: nexterror(); ! 619: } ! 620: sleep(&u->p->sleep, procstopped, p); ! 621: poperror(); ! 622: qlock(&p->debug); ! 623: if(p->pid != pid) ! 624: error(Eprocdied); ! 625: } ! 626: ! 627: void ! 628: procctlreq(Proc *p, char *va, int n) ! 629: { ! 630: int i; ! 631: char buf[NAMELEN+1]; ! 632: ! 633: if(n > NAMELEN) ! 634: n = NAMELEN; ! 635: strncpy(buf, va, n); ! 636: buf[NAMELEN] = '\0'; ! 637: ! 638: if(strncmp(buf, "stop", 4) == 0) ! 639: procstopwait(p, Proc_stopme); ! 640: else if(strncmp(buf, "kill", 4) == 0) { ! 641: switch(p->state) { ! 642: case Broken: ! 643: unbreak(p); ! 644: break; ! 645: case Stopped: ! 646: postnote(p, 0, "sys: killed", NExit); ! 647: p->procctl = Proc_exitme; ! 648: ready(p); ! 649: break; ! 650: default: ! 651: postnote(p, 0, "sys: killed", NExit); ! 652: p->procctl = Proc_exitme; ! 653: } ! 654: } ! 655: else if(strncmp(buf, "hang", 4) == 0) ! 656: p->hang = 1; ! 657: else if(strncmp(buf, "nohang", 6) == 0) ! 658: p->hang = 0; ! 659: else if(strncmp(buf, "waitstop", 8) == 0) ! 660: procstopwait(p, 0); ! 661: else if(strncmp(buf, "startstop", 9) == 0) { ! 662: if(p->state != Stopped) ! 663: error(Ebadctl); ! 664: p->procctl = Proc_traceme; ! 665: ready(p); ! 666: procstopwait(p, Proc_traceme); ! 667: } ! 668: else if(strncmp(buf, "start", 5) == 0) { ! 669: if(p->state != Stopped) ! 670: error(Ebadctl); ! 671: ready(p); ! 672: } ! 673: else if(strncmp(buf, "pri", 3) == 0){ ! 674: if(n < 4) ! 675: error(Ebadctl); ! 676: i = atoi(buf+4); ! 677: if(i < 0) ! 678: i = 0; ! 679: if(i >= Nrq) ! 680: i = Nrq - 1; ! 681: if(i < p->basepri && !iseve()) ! 682: error(Eperm); ! 683: p->basepri = i; ! 684: } ! 685: else ! 686: error(Ebadctl); ! 687: } ! 688: ! 689: int ! 690: procstopped(void *a) ! 691: { ! 692: Proc *p = a; ! 693: return p->state == Stopped; ! 694: } ! 695: ! 696: int ! 697: procctlmemio(Proc *p, ulong offset, int n, void *va, int read) ! 698: { ! 699: KMap *k; ! 700: Pte *pte; ! 701: Page *pg; ! 702: Segment *s; ! 703: ulong soff, l; ! 704: char *a = va, *b; ! 705: ! 706: for(;;) { ! 707: s = seg(p, offset, 1); ! 708: if(s == 0) ! 709: error(Ebadarg); ! 710: ! 711: if(offset+n >= s->top) ! 712: n = s->top-offset; ! 713: ! 714: if(read == 0 && (s->type&SG_TYPE) == SG_TEXT) ! 715: s = txt2data(p, s); ! 716: ! 717: s->steal++; ! 718: soff = offset-s->base; ! 719: if(waserror()) { ! 720: s->steal--; ! 721: nexterror(); ! 722: } ! 723: if(fixfault(s, offset, read, 0) == 0) ! 724: break; ! 725: poperror(); ! 726: s->steal--; ! 727: } ! 728: poperror(); ! 729: pte = s->map[soff/PTEMAPMEM]; ! 730: if(pte == 0) ! 731: panic("procctlmemio"); ! 732: pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG]; ! 733: if(pagedout(pg)) ! 734: panic("procctlmemio1"); ! 735: ! 736: l = BY2PG - (offset&(BY2PG-1)); ! 737: if(n > l) ! 738: n = l; ! 739: ! 740: k = kmap(pg); ! 741: b = (char*)VA(k); ! 742: if(read == 1) ! 743: memmove(a, b+(offset&(BY2PG-1)), n); ! 744: else ! 745: memmove(b+(offset&(BY2PG-1)), a, n); ! 746: ! 747: kunmap(k); ! 748: ! 749: s->steal--; ! 750: qunlock(&s->lk); ! 751: ! 752: if(read == 0) ! 753: p->newtlb = 1; ! 754: ! 755: return n; ! 756: } ! 757: ! 758: Segment* ! 759: txt2data(Proc *p, Segment *s) ! 760: { ! 761: int i; ! 762: Segment *ps; ! 763: ! 764: ps = newseg(SG_DATA, s->base, s->size); ! 765: ps->image = s->image; ! 766: incref(ps->image); ! 767: ps->fstart = s->fstart; ! 768: ps->flen = s->flen; ! 769: ps->flushme = 1; ! 770: ! 771: for(i = 0; i < NSEG; i++) ! 772: if(p->seg[i] == s) ! 773: break; ! 774: if(p->seg[i] != s) ! 775: panic("segment gone"); ! 776: ! 777: qunlock(&s->lk); ! 778: putseg(s); ! 779: qlock(&ps->lk); ! 780: p->seg[i] = ps; ! 781: ! 782: return ps; ! 783: } ! 784: ! 785: Segment* ! 786: data2txt(Segment *s) ! 787: { ! 788: Segment *ps; ! 789: ! 790: ps = newseg(SG_TEXT, s->base, s->size); ! 791: ps->image = s->image; ! 792: incref(ps->image); ! 793: ps->fstart = s->fstart; ! 794: ps->flen = s->flen; ! 795: ps->flushme = 1; ! 796: ! 797: return ps; ! 798: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.