static void CreateMem(IMODE *im) { ALIASNAME *p; if (im->offset->type != en_pc && im->offset->type != en_sub) { if (im->mode == i_immed) { p = LookupMem(im->offset->v.sp->imvalue); } else { ALIASADDRESS *aa; p = LookupMem(im); p = LookupAliasName(p, 0); } if (im->size == ISZ_ADDR || im->offset->type == en_label || im->offset->type == en_global) { ALIASADDRESS *aa; aa = LookupAddress(p, 0); if (!aa->pointsto) { ALIASNAME *an = LookupAliasName(p, 0); aa->pointsto = aAlloc(sizeof(ALIASLIST)); aa->pointsto->address = LookupAddress(an, 0); } } } }
void AliasUses(BITINT *bits, IMODE *im, BOOLEAN rhs) { if (im) { if (rhs) { if (im->offset->type == en_tempref) { ormap(bits, tempInfo[im->offset->v.sp->value.i]->modifiedBy); if (im->mode == i_direct) { im = LookupLoadTemp(im, im); } setbit(bits, termMap[im->offset->v.sp->value.i]); } else if (im->mode == i_direct) { ALIASNAME *an = LookupMem(im); ALIASADDRESS *aa ; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); while (aa->merge) aa = aa->merge; if (aa->modifiedBy) ormap(bits, aa->modifiedBy); im = GetLoadTemp(im); if (im) { setbit(bits, termMap[im->offset->v.sp->value.i]); } } else if (im->mode == i_immed && !isintconst(im->offset) && !iscomplexconst(im->offset) && !isfloatconst(im->offset) && im->offset->type != en_labcon) { ALIASNAME *an = LookupMem(im); ALIASADDRESS *aa ; aa = LookupAddress(an, 0); while (aa->merge) aa = aa->merge; if (aa->modifiedBy) ormap(bits, aa->modifiedBy); im = im->offset->v.sp->imvalue; if (im) { im = GetLoadTemp(im); if (im) { setbit(bits, termMap[im->offset->v.sp->value.i]); } } } } else { setbit(bits, termMap[im->offset->v.sp->value.i]); } } }
static void HandleAssnBlock(QUAD *head) { ALIASLIST *src=NULL, *dest=NULL; int i, n = head->ans->offset->v.i; if ((head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { dest = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; } else if (head->dc.left->mode == i_immed) { ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); dest = aa->pointsto; } else { diag("HandleAssnBlock: invalid dest type"); } if (head->dc.right->mode == i_direct && ((head->temps & TEMP_RIGHT) || head->dc.right->retval)) { src = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; } else if (head->dc.right->mode == i_immed) { ALIASNAME *an = LookupMem(head->dc.right); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); src = aa->pointsto; } else { diag("HandleAssnBlock: invalid src type"); } for (i=0; i < n; i++) { ALIASLIST *lsrc = src; while (lsrc) { ALIASADDRESS *aasrc = GetAddress(lsrc->address->name, i); if (aasrc) { ALIASLIST *ldest = dest; while (ldest) { ALIASADDRESS *aadest = LookupAddress(ldest->address->name, i); AliasUnion(&aadest->pointsto, aasrc->pointsto); ldest = ldest->next; } } lsrc = lsrc->next; } } }
KernReturn<void> Module::RelocateGOT() { for(elf_rel_t *rel = _rel; rel < _relLimit; rel ++) { elf32_address_t *address = reinterpret_cast<elf32_address_t *>(_relocationBase + rel->r_offset); elf32_address_t target; uint32_t symnum = ELF32_R_SYM(rel->r_info); uint32_t type = ELF32_R_TYPE(rel->r_info); elf_sym_t *lookup = _symTable + symnum; const char *name = _strTable + lookup->st_name; switch(type) { case R_386_NONE: break; case R_386_32: case R_386_GLOB_DAT: { Module *container; void *symbol = LookupAddress(name, container); if(!symbol) return Error(KERN_RESOURCES_MISSING, "Couldn't find symbol '%s'!\n", name); target = reinterpret_cast<elf32_address_t>(symbol); *address += target; break; } case R_386_PC32: { Module *container; void *symbol = LookupAddress(name, container); if(!symbol) return Error(KERN_RESOURCES_MISSING, "Couldn't find symbol '%s'!\n", name); target = reinterpret_cast<elf32_address_t>(symbol); *address += target - reinterpret_cast<elf32_address_t>(address); break; } case R_386_RELATIVE: *address += _relocationBase; break; default: return Error(KERN_INVALID_ARGUMENT, "Unknown relocation type %d", type); } } return ErrorNone; }
void AliasStruct(BITINT *bits, IMODE *ans, IMODE *left, IMODE *right) { ALIASLIST *src; int i, n = ans->offset->v.i; if (left->offset->type == en_tempref && left->mode == i_direct) { src = tempInfo[left->offset->v.sp->value.i]->pointsto; while (src) { ALIASADDRESS *aa = src->address; while (aa->merge) aa = aa->merge; for (i=0; i < n; i++) { ALIASNAME *an = GetAliasName(aa->name, i); if (an) { ALIASADDRESS *aa2 = LookupAddress(an, 0); while (aa2->merge) aa2 = aa2->merge; if (aa2 && aa2->modifiedBy) { ormap(bits, aa2->modifiedBy); } } } src = src->next; } setbit(bits, termMap[left->offset->v.sp->value.i]); return; } else if (left->mode == i_immed) { ALIASNAME *an = LookupMem(left); ALIASADDRESS *aa; for (i=0; i < n; i++) { ALIASNAME *an2 = GetAliasName(an, i); if (an2) { aa = LookupAddress(an2, 0); while (aa->merge) aa = aa->merge; if (aa && aa->modifiedBy) { ormap(bits, aa->modifiedBy); } ResetProcessed(); scanDepends(bits, aa->pointsto); } } return; } else { diag("AliasStruct: invalid src type"); } }
static void HandleParm(QUAD *head) { if (head->dc.left->size == ISZ_ADDR) { // temp, mem ALIASLIST *result = NULL, **base = NULL, *addr; if (head->temps & TEMP_LEFT) { base = &tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; } else if (!isintconst(head->dc.left->offset)) { ALIASNAME *an; ALIASADDRESS *aa; switch (head->dc.left->offset->type) { case en_labcon: case en_global: case en_label: case en_pc: case en_threadlocal: return; default: break; } an = LookupMem(head->dc.left->offset->v.sp->imvalue); if (head->dc.left->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); base = &aa->pointsto; } if (base) { addr = *base; AliasUnionParm(&parmList, (*base)); while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, 0); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } addr = addr->next; } } } }
static void HandleAssnBlock(QUAD *head) { ALIASNAME *dest = NULL; if ((head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { // we don't support writing to arbitrary memory, e.g. a pointer returned from a function call return; } else if (head->dc.left->mode == i_immed) { dest = LookupMem(head->dc.left); dest = LookupAliasName(dest, 0); } else { diag("HandleAssnBlock: invalid dest type"); } if (head->dc.right->mode == i_direct && ((head->temps & TEMP_RIGHT) || head->dc.right->retval)) { ALIASLIST *src = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; while (src) { ALIASNAME *srcn = src->address->name; LIST *addr = srcn->addresses; while (addr) { ALIASADDRESS *aa= (ALIASADDRESS *)addr ->data; ALIASADDRESS *aadest = LookupAddress(dest, aa->offset); AliasUnion(&aadest->pointsto, aa->pointsto); addr = addr->next; } src = src->next; } } else if (head->dc.right->mode == i_immed) { ALIASNAME *src = LookupMem(head->dc.right); LIST *addr; addr = src->addresses; while (addr) { ALIASADDRESS *aa= (ALIASADDRESS *)addr->data; ALIASADDRESS *aadest = LookupAddress(dest, aa->offset); AliasUnion(&aadest->pointsto, aa->pointsto); addr = addr->next; } } else { diag("HandleAssnBlock: invalid src type"); } }
static void SetStride(ALIASADDRESS *addr, int stride) { int i; for (i=0; i < DAGSIZE; i++) { ALIASADDRESS *scan = addresses[i]; while (scan) { if (addr != scan && addr->name == scan->name) { if (addr->offset < scan->offset) { int o2 = addr->offset + (scan->offset - addr->offset) % stride; if (addr->offset == o2) { AliasUnion(&addr->pointsto, scan->pointsto); scan->merge = addr; } else { ALIASADDRESS *sc2 = LookupAddress(addr->name, o2); if (sc2 && sc2 != scan) { AliasUnion(&sc2->pointsto, scan->pointsto); scan->merge = sc2; } } } } scan = scan->next; } } }
error ConnectTCP(const std::string& host, uint16_t port, int64_t timeoutMilliseconds, std::shared_ptr<TCPSocket>* clientSock) { if (clientSock == nullptr) { assert(0 && "clientSock must not be nullptr"); return error::illegal_argument; } internal::init(); std::string remoteAddr; error addrErr = LookupAddress(host, &remoteAddr); if (addrErr != error::nil) { return addrErr; } SOCKET fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == INVALID_SOCKET) { return error::wrap(etype::os, WSAGetLastError()); } struct sockaddr_in serverAddr = {0}; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); serverAddr.sin_addr.S_un.S_addr = inet_addr(remoteAddr.c_str()); if (timeoutMilliseconds <= 0) { // connect in blocking mode if (connect(fd, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { int connErr = WSAGetLastError(); closesocket(fd); return error::wrap(etype::os, connErr); } } else { // connect in non blocking mode ioctlsocket(fd, FIONBIO, &kNonBlockingMode); if (connect(fd, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { int connErr = WSAGetLastError(); if (connErr != WSAEWOULDBLOCK) { closesocket(fd); return error::wrap(etype::os, connErr); } } fd_set writefds, exceptfds; error err = waitUntilReady(fd, nullptr, &writefds, &exceptfds, timeoutMilliseconds); if (err != error::nil) { closesocket(fd); return err; } ioctlsocket(fd, FIONBIO, &kBlockingMode); } *clientSock = std::make_shared<TCPSocket>(fd, std::move(remoteAddr), port); return error::nil; }
static void CreateMem(IMODE *im) { ALIASNAME *p; if (im->offset->type != en_pc && im->offset->type != en_sub) { if (im->mode == i_immed) { if (!im->offset->v.sp->imvalue) { // make one in the case of global addresses that aren't used // directly IMODE *ap2 = (IMODE *)Alloc(sizeof(IMODE)); ap2->offset = im->offset; ap2->mode = i_direct; ap2->size = ISZ_ADDR; im->offset->v.sp->imvalue = ap2; } p = LookupMem(im->offset->v.sp->imvalue); } else { ALIASADDRESS *aa; p = LookupMem(im); p = LookupAliasName(p, 0); } if (im->size == ISZ_ADDR || im->offset->type == en_label || im->offset->type == en_global) { ALIASADDRESS *aa; aa = LookupAddress(p, 0); if (!aa->pointsto) { ALIASNAME *an = LookupAliasName(p, 0); aa->pointsto = aAlloc(sizeof(ALIASLIST)); aa->pointsto->address = LookupAddress(an, 0); } } } }
static void Infer(IMODE *ans, IMODE *reg, ALIASLIST *pointsto) { if (pointsto) { ALIASLIST *result = NULL; int c = InferOffset(reg); int l = InferStride(reg); BOOL xchanged = changed; while (pointsto) { ALIASADDRESS *addr = LookupAddress(pointsto->address->name, pointsto->address->offset + c); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); SetStride(pointsto->address, l); pointsto = pointsto->next; } changed = xchanged; AliasUnion(&tempInfo[ans->offset->v.sp->value.i]->pointsto, result); } }
KernReturn<void> Module::RelocatePLT() { for(elf_rel_t *rel = _pltRel; rel < _pltRelLimit; rel ++) { elf32_address_t *address = reinterpret_cast<elf32_address_t *>(_relocationBase + rel->r_offset); uint32_t symnum = ELF32_R_SYM(rel->r_info); uint32_t type = ELF32_R_TYPE(rel->r_info); assert(type == R_386_JMP_SLOT); elf_sym_t *lookup = _symTable + symnum; const char *name = _strTable + lookup->st_name; Module *container; void *symbol = LookupAddress(name, container); if(!symbol) return Error(KERN_RESOURCES_MISSING, "Couldn't find symbol '%s'!\n", name); *address = (elf32_address_t)(symbol); } return ErrorNone; }
static void HandleAdd(QUAD *head) { if ((head->ans->size == ISZ_ADDR) && (head->temps & TEMP_ANS)) { if (head->dc.opcode == i_add && head->dc.left->mode == i_immed) { if (head->temps & TEMP_RIGHT) { if (isintconst(head->dc.left->offset)) { // C + R ALIASLIST *scan = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // p + R if (head->dc.left->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.right, al); } } } else if (head->dc.right->mode == i_immed) { if (!isintconst(head->dc.left->offset) && head->dc.left->offset->type != en_labcon) { // p + C ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.right->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto,al); } else if (!isintconst(head->dc.right->offset) && head->dc.right->offset->type != en_labcon) { // C + p ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); } } } else if (head->dc.right->mode == i_immed) { if (head->temps & TEMP_LEFT) { if (isintconst(head->dc.right->offset)) { // R+C int c = head->dc.opcode == i_add ? head->dc.right->offset->v.i : -head->dc.right->offset->v.i; ALIASLIST *scan = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + c); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // R + p if (head->dc.right->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.left, al); } } } } else if ((head ->temps & (TEMP_LEFT | TEMP_RIGHT)) == (TEMP_LEFT | TEMP_RIGHT)) { // R+R ALIASLIST *src; IMODE *one = head->dc.left; IMODE *two = head->dc.right; if (two->size == ISZ_ADDR) { IMODE *three = one; one = two; two = three; } if (one->size == ISZ_ADDR) { // now one has the pointer, two has something else src = tempInfo[one->offset->v.sp->value.i]->pointsto; Infer(head->ans, two, src); } } } }
static void HandleAssn(QUAD *head) { if (head->ans == head->dc.left) return; if (head->ans->mode == i_ind) { if (head->temps & TEMP_LEFT) { // ind, temp ALIASLIST *addr; ALIASLIST *src = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, src); addr = addr->next; } } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // ind, immed ALIASLIST *addr; ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, aa->pointsto); addr = addr->next; } } } else if (head->dc.left->mode == i_ind && (head->temps & TEMP_ANS)) { // temp, ind ALIASLIST *result = NULL; ALIASLIST *addr = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; BOOLEAN xchanged = changed; while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, addr->address->offset); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } AliasUnion(&result, addr->address->pointsto); addr = addr->next; } changed = xchanged; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = result; } else if (head->ans->size == ISZ_ADDR) { if (!(head->temps & TEMP_ANS) && !head->ans->retval) { if (head->temps & TEMP_LEFT) { // mem, temp ALIASLIST *al; ALIASNAME *an = LookupMem(head->ans); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // mem, immed ALIASNAME *an2 = LookupMem(head->dc.left); ALIASADDRESS *aa2 = LookupAddress(an2, 0); ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa2; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, al); } } else if (head->temps & TEMP_ANS) { if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon&& !isintconst(head->dc.left->offset) ) { // temp, immed BOOLEAN xchanged = changed; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = (ALIASLIST *)aAlloc(sizeof(ALIASLIST)); al->address = aa; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = NULL; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); changed = xchanged; } else if (head->dc.left->retval) { AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, parmList); } else if (!(head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { // temp, mem ALIASLIST *result = NULL; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa; ALIASLIST *addr; BOOLEAN xchanged = changed; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, aa->pointsto); changed = xchanged; } else if (head->temps & TEMP_LEFT) { // temp, temp AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } } } }