void runtime·raceread(uintptr addr) { if(!onstack(addr)) { m->racecall = true; runtime∕race·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr)); m->racecall = false; } }
void runtime·racewrite(uintptr addr) { if(!onstack(addr)) { m->racecall = true; runtime∕race·Write(g->goid-1, (void*)addr, runtime·getcallerpc(&addr)); m->racecall = false; } }
static void rangeaccess(void *addr, uintptr size, uintptr step, uintptr callpc, uintptr pc, bool write) { uintptr racectx; if(!onstack((uintptr)addr)) { m->racecall = true; racectx = g->racectx; if(callpc) { if(callpc == (uintptr)runtime·lessstack) runtime·callers(3, &callpc, 1); runtime∕race·FuncEnter(racectx, (void*)callpc); } if(write) runtime∕race·WriteRange(racectx, addr, size, step, (void*)pc); else runtime∕race·ReadRange(racectx, addr, size, step, (void*)pc); if(callpc) runtime∕race·FuncExit(racectx); m->racecall = false; } }
static void memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write) { int64 goid; if(!onstack((uintptr)addr)) { m->racecall = true; goid = g->goid-1; if(callpc) { if(callpc == (uintptr)runtime·lessstack || (callpc >= (uintptr)runtime·mheap.arena_start && callpc < (uintptr)runtime·mheap.arena_used)) runtime·callers(3, &callpc, 1); runtime∕race·FuncEnter(goid, (void*)callpc); } if(write) runtime∕race·Write(goid, addr, (void*)pc); else runtime∕race·Read(goid, addr, (void*)pc); if(callpc) runtime∕race·FuncExit(goid); m->racecall = false; } }
static int get_info(efi_guid_t *guid, uint64_t hw_inst, update_info **info) { efi_guid_t varguid = FWUPDATE_GUID; char *varname = NULL; char *guidstr = NULL; int rc; update_info *local; int error; rc = efi_guid_to_str(guid, &guidstr); if (rc < 0) return -1; guidstr = onstack(guidstr, strlen(guidstr)+1); rc = asprintf(&varname, "fwupdate-%s-%"PRIx64, guidstr, hw_inst); if (rc < 0) return -1; varname = onstack(varname, strlen(varname)+1); uint8_t *data = NULL; size_t data_size = 0; uint32_t attributes; rc = efi_get_variable(varguid, varname, &data, &data_size, &attributes); if (rc < 0) { if (errno != ENOENT) return -1; local = calloc(1, sizeof (*local)); if (!local) return -1; local->update_info_version = UPDATE_INFO_VERSION; local->guid = *guid; local->hw_inst = hw_inst; local->dp_ptr = calloc(1, 1024); if (!local->dp_ptr) { alloc_err: error = errno; free_info(local); errno = error; return -1; } ssize_t sz; sz = efidp_make_end_entire((uint8_t *)local->dp_ptr, 1024); if (sz < 0) { rc = sz; goto alloc_err; } *info = local; return 0; } /* If our size is wrong, or our data is otherwise bad, try to delete * the variable and create a new one. */ if (data_size < sizeof (*local) || !data) { if (data) free(data); get_err: rc = efi_del_variable(varguid, varname); if (rc < 0) return -1; return get_info(guid, hw_inst, info); } local = (update_info *)data; if (local->update_info_version != UPDATE_INFO_VERSION) goto get_err; ssize_t sz = efidp_size((efidp)local->dp); if (sz < 0) { free(data); errno = EINVAL; return -1; } efidp_header *dp = malloc((size_t)sz); if (!dp) { free(data); errno = ENOMEM; return -1; } memcpy(dp, local->dp, (size_t)sz); local->dp_ptr = dp; *info = local; return 0; }