void JITLinker::ReferenceHelper :: writeReference(MemoryWriter& writer, ref_t reference, size_t disp, _Module* module) { ref_t mask = reference & mskAnyRef; ref_t refID = reference & ~mskAnyRef; //// check if it is a constant, resolve it immediately //if (mask == mskLinkerConstant) { // writer.writeDWord(getLinkerConstant(refID)); // return; //} if (!module) module = _module; ref_t position = writer.Position(); writer.writeDWord(disp); // vmt entry offset should be resolved later if (mask == mskVMTEntryOffset) { _references->add(position, RefInfo(reference, module)); return; } // try to resolve immediately void* vaddress = _owner->_loader->resolveReference( _owner->_loader->retrieveReference(module, refID, mask), mask); if (vaddress != LOADER_NOTLOADED) { resolveReference(writer.Memory(), position, (ref_t)vaddress, mask, _owner->_virtualMode); } // or resolve later else _references->add(position, RefInfo(reference, module)); }
size_t JITLinker :: loadMethod(ReferenceHelper& refHelper, MemoryReader& reader, MemoryWriter& writer) { size_t position = writer.Position(); // method just in time compilation _compiler->compileProcedure(refHelper, reader, writer); return _virtualMode ? position : (size_t)writer.Memory()->get(position); }
void ECodesAssembler :: fixJump(const wchar16_t* label, MemoryWriter& writer, LabelInfo& info) { _Memory* code = writer.Memory(); Map<const wchar16_t*, int>::Iterator it = info.fwdJumps.start(); while (!it.Eof()) { if (StringHelper::compare(it.key(), label)) { (*code)[*it] = writer.Position(); } it++; } }
void ECodesAssembler :: fixJump(ident_t label, MemoryWriter& writer, LabelInfo& info) { _Memory* code = writer.Memory(); Map<ident_t, int>::Iterator it = info.fwdJumps.start(); while (!it.Eof()) { if (label.compare(it.key())) { (*code)[*it] = writer.Position() - *it - 4; } it++; } }
void JITCompiler32 :: fixVMT(MemoryWriter& vmtWriter, void* classClassVAddress, void* packageVAddress, int count, bool virtualMode) { _Memory* image = vmtWriter.Memory(); // update class package reference if available if (packageVAddress != NULL) { int position = vmtWriter.Position(); vmtWriter.seek(position - 0x10); if (virtualMode) { vmtWriter.writeRef((ref_t)packageVAddress, 0); } else vmtWriter.writeDWord((int)packageVAddress); vmtWriter.seek(position); } // update class vmt reference if available if (classClassVAddress != NULL) { vmtWriter.seek(vmtWriter.Position() - 4); if (virtualMode) { vmtWriter.writeRef((ref_t)classClassVAddress, 0); } else vmtWriter.writeDWord((int)classClassVAddress); } // if in virtual mode mark method addresses as reference if (virtualMode) { ref_t entryPosition = vmtWriter.Position(); for (int i = 0 ; i < count ; i++) { image->addReference(mskCodeRef, entryPosition + 4); entryPosition += 8; } } }