@global asutil_defined; //Utility functions for address spaces. //contents: // asload: loads an as from a file // assave: writes an address space to a file // asload_str: loads an as from a string // assave_str: writes an address space to a string // ascopy: returns a copy of a given address space. // //NOTE: when saving an AS, any addresses returned by map() //that are not actually mapped will be mapped with a value //of 0 in the loaded version of the AS. if (asutil_defined == nil) { @local svasns; @global asfile_identifier,ascopy,assave_str,asload_str,assave,asload; @global asutils_test; asutil_defined = 1; @include asfile_identifier="AS1"; //the address space to be associated with the names files. @define svasns() { return @names clp64le { typedef long long unsigned int uint64_t; struct adr_range { @0x0 uint64_t beg; @0x8 uint64_t len; @0x10; }; typedef struct adr_range adr_range; struct adr_ranges { @0x0 char identifier[8]; @0x8 unsigned int num_ranges; @["offset" : 0xc, "refine" : @lambda (p) { return [0xc, mkctype_array( subtype(@typeof(p->ranges)), p->num_ranges)]; }] adr_range ranges[]; @0xc; }; }; } /** * for creating a deep copy of an address space. * param: the address space to copy * returns: a copy of the provided address space */ @define ascopy(as) { @local str; str = assave_str(as); return asload_str(str); } /** * for creating an address space out of the string representation of an address * space returned by assave_str. * param: as_str a string representation of an address space returned by * assave_str * returns: an address space */ @define asload_str(as_str) { @local asdom, ranges, offsets, i, q, p, dispatch; asdom = mkdom(svasns(),mksas(as_str)); p = (struct asdom`adr_ranges*){asdom}0; p = refine(p); q = (char*)(p+1); ranges = mkvec(p->num_ranges); offsets = mkvec(p->num_ranges); for(i=0; inum_ranges; ++i) { ranges[i] = mkrange(p->ranges[i].beg,p->ranges[i].len); offsets[i] = (unsigned long)q; q += p->ranges[i].len; } @define dispatch(args ...) { @local ftn; ftn = listref(args,1); if (ftn == "get") { @local r, beg, len, vbeg, vlen; r = listref(args,2); beg = rangebeg(r); len = rangelen(r); if (beg + len < beg) fault(); for (i = 0; i < p->num_ranges; i++) { vbeg = p->ranges[i].beg; vlen = p->ranges[i].len; if (vbeg <= beg && vbeg + vlen >= beg+len) { return asdom.get(mkrange( (beg - vbeg) + offsets[i], len)); } } fault(); } else if (ftn == "map") { return ranges; } else if (ftn == "put") { @local r, beg, len, vbeg, vlen; r = listref(args,2); beg = rangebeg(r); len = rangelen(r); if (beg + len < beg) fault(); for (i = 0; i < p->num_ranges; i++) { vbeg = p->ranges[i].beg; vlen = p->ranges[i].len; if (vbeg <= beg && vbeg + vlen >= beg+len) { return asdom.put(mkrange( (beg - vbeg) + offsets[i], len), listref(args,3) ); } } fault(); } else if (ftn == "ismapped") { return isrinr(args[2], ranges); } else error("call to unimplemented method: %s", ftn); } return mkas(["dispatch":dispatch]); } /** * Translates the given address space to a string. * Relies on as.map() to provide a list of mapped regions. * param: as is the address space to be converted * returns: a binary string representation of as */ @define assave_str(as) { @local range, ranges, i, backing, svas; @local size, svdom, ns, tmpdom, p, q; //general strategy: create a new address space //backed by a string. Then write that string to //disk. //first calculate the necessary size for the as. ranges = as.map(); size = 0; for(i=0; inum_ranges = length(ranges); p = refine(p); backing = mkstr(size+(unsigned int)(p+1)); svdom = mkdom(ns,mksas(backing)); p = (struct svdom`adr_ranges*){svdom}0; putbytes(p->identifier,asfile_identifier); p->num_ranges = length(ranges); p = refine(p); q = (unsigned char*)(p+1); //next free address. for(i=0; iranges[i].beg = rangebeg(ranges[i]); r = {as}(unsigned char*)p->ranges[i].beg; len = rangelen(ranges[i]); p->ranges[i].len = len; if (ismapped(r,len)) { memcpy(q,r,len); } else { for(j=0; j coredom = mkcoreas("core.29360"); assave(coredom,"file.as"); //svstr = assave_str(coredom); loaded = asload("file.as"); //loaded = asload_str(svstr); print(coredom.map()); print(loaded.map()); p = (int*){coredom}0x698050; q = (int*){loaded}0x698050; print(*p); print(*q); p = (int*){coredom}0x7fff8f738088; q = (int*){loaded}0x7fff8f738088; print(*p); print(*q); p = (int*){coredom}140735600918518; q = (int*){loaded}140735600918518; print(*p); print(*q); } //asutils_test(); }