163 uint8_t vtimeBlob[] = {
164 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,
169 vtimeBlob,
sizeof(vtimeBlob));
171 uint8_t vgettimeofdayBlob[] = {
172 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00,
178 vgettimeofdayBlob,
sizeof(vgettimeofdayBlob));
193 uint8_t numGDTEntries = 0;
194 uint64_t nullDescriptor = 0;
195 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
199 SegDescriptor initDesc = 0;
200 initDesc.type.codeOrData = 0;
209 initDesc.limit = 0xFFFFFFFF;
213 SegDescriptor csLowPLDesc = initDesc;
214 csLowPLDesc.type.codeOrData = 1;
216 uint64_t csLowPLDescVal = csLowPLDesc;
217 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
222 SegSelector csLowPL = 0;
223 csLowPL.si = numGDTEntries - 1;
227 SegDescriptor dsLowPLDesc = initDesc;
228 dsLowPLDesc.type.codeOrData = 0;
230 uint64_t dsLowPLDescVal = dsLowPLDesc;
231 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
236 SegSelector dsLowPL = 0;
237 dsLowPL.si = numGDTEntries - 1;
241 SegDescriptor dsDesc = initDesc;
242 dsDesc.type.codeOrData = 0;
244 uint64_t dsDescVal = dsDesc;
245 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
251 ds.si = numGDTEntries - 1;
255 SegDescriptor csDesc = initDesc;
256 csDesc.type.codeOrData = 1;
258 uint64_t csDescVal = csDesc;
259 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
265 cs.si = numGDTEntries - 1;
268 SegSelector scall = 0;
269 scall.si = csLowPL.si;
272 SegSelector sret = 0;
273 sret.si = dsLowPL.si;
277 TSSlow TSSDescLow = 0;
278 TSSDescLow.type = 0xB;
281 TSSDescLow.limit = 0xFFFFFFFF;
284 TSShigh TSSDescHigh = 0;
291 } tssDescVal = {TSSDescLow, TSSDescHigh};
293 physProxy.
writeBlob(gdtPhysAddr + numGDTEntries * 8,
294 &tssDescVal,
sizeof(tssDescVal));
298 SegSelector tssSel = 0;
299 tssSel.si = numGDTEntries - 1;
301 uint64_t tss_base_addr = (TSSDescHigh.base << 32) | TSSDescLow.base;
302 uint64_t tss_limit = TSSDescLow.limit;
304 SegAttr tss_attr = 0;
306 tss_attr.type = TSSDescLow.type;
307 tss_attr.dpl = TSSDescLow.dpl;
308 tss_attr.present = TSSDescLow.p;
309 tss_attr.granularity = TSSDescLow.g;
310 tss_attr.unusable = 0;
325 tslAttr.unusable = 1;
416 RegVal sfmask = (1 << 8) | (1 << 10);
455 tss.IST1_low = IST_start;
456 tss.IST1_high = IST_start >> 32;
457 tss.RSP0_low = tss.IST1_low;
458 tss.RSP0_high = tss.IST1_high;
459 tss.RSP1_low = tss.IST1_low;
460 tss.RSP1_high = tss.IST1_high;
461 tss.RSP2_low = tss.IST1_low;
462 tss.RSP2_high = tss.IST1_high;
463 physProxy.
writeBlob(tssPhysAddr, &tss,
sizeof(tss));
466 GateDescriptorLow PFGateLow = 0;
469 PFGateLow.selector = csLowPL;
472 PFGateLow.type = 0xe;
475 GateDescriptorHigh PFGateHigh = 0;
482 } PFGate = {PFGateLow, PFGateHigh};
484 physProxy.
writeBlob(idtPhysAddr + 0xE0, &PFGate,
sizeof(PFGate));
496 uint8_t syscallBlob[] = {
498 0x48, 0xa3, 0x00, 0x70, 0x00,
499 0x00, 0x00, 0xc9, 0xff, 0xff,
501 0x48, 0xa3, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x48, 0xa1, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00,
513 assert(syscallDataBuf >= syscallCodePhysAddr +
sizeof syscallBlob);
514 std::memcpy(&syscallBlob[12], &syscallDataBuf,
sizeof syscallDataBuf);
515 std::memcpy(&syscallBlob[28], &syscallDataBuf,
sizeof syscallDataBuf);
518 syscallBlob,
sizeof(syscallBlob));
521 uint8_t faultBlob[] = {
523 0x48, 0xa3, 0x00, 0x70, 0x00,
524 0x00, 0x00, 0xc9, 0xff, 0xff,
526 0x48, 0x83, 0xc4, 0x08,
531 physProxy.
writeBlob(pfHandlerPhysAddr, faultBlob,
sizeof(faultBlob));
547 auto m5op_range =
system->m5opRange();
548 if (m5op_range.size()) {
550 m5op_range.size(),
false);
556 SegAttr dataAttr = 0;
558 dataAttr.unusable = 0;
559 dataAttr.defaultSize = 1;
560 dataAttr.longMode = 1;
562 dataAttr.granularity = 1;
563 dataAttr.present = 1;
565 dataAttr.writable = 1;
566 dataAttr.readable = 1;
567 dataAttr.expandDown = 0;
580 csAttr.defaultSize = 0;
583 csAttr.granularity = 1;
588 csAttr.expandDown = 0;
766 int intSize =
sizeof(IntType);
770 std::string filename;
781 X86_OnboardFPU = 1 << 0,
782 X86_VirtualModeExtensions = 1 << 1,
783 X86_DebuggingExtensions = 1 << 2,
784 X86_PageSizeExtensions = 1 << 3,
786 X86_TimeStampCounter = 1 << 4,
787 X86_ModelSpecificRegisters = 1 << 5,
788 X86_PhysicalAddressExtensions = 1 << 6,
789 X86_MachineCheckExtensions = 1 << 7,
791 X86_CMPXCHG8Instruction = 1 << 8,
792 X86_OnboardAPIC = 1 << 9,
793 X86_SYSENTER_SYSEXIT = 1 << 11,
795 X86_MemoryTypeRangeRegisters = 1 << 12,
796 X86_PageGlobalEnable = 1 << 13,
797 X86_MachineCheckArchitecture = 1 << 14,
798 X86_CMOVInstruction = 1 << 15,
800 X86_PageAttributeTable = 1 << 16,
801 X86_36BitPSEs = 1 << 17,
802 X86_ProcessorSerialNumber = 1 << 18,
803 X86_CLFLUSHInstruction = 1 << 19,
805 X86_DebugTraceStore = 1 << 21,
806 X86_ACPIViaMSR = 1 << 22,
807 X86_MultimediaExtensions = 1 << 23,
809 X86_FXSAVE_FXRSTOR = 1 << 24,
810 X86_StreamingSIMDExtensions = 1 << 25,
811 X86_StreamingSIMDExtensions2 = 1 << 26,
812 X86_CPUSelfSnoop = 1 << 27,
814 X86_HyperThreading = 1 << 28,
815 X86_AutomaticClockControl = 1 << 29,
816 X86_IA64Processor = 1 << 30
827 X86_VirtualModeExtensions |
828 X86_DebuggingExtensions |
829 X86_PageSizeExtensions |
830 X86_TimeStampCounter |
831 X86_ModelSpecificRegisters |
832 X86_PhysicalAddressExtensions |
833 X86_MachineCheckExtensions |
834 X86_CMPXCHG8Instruction |
836 X86_SYSENTER_SYSEXIT |
837 X86_MemoryTypeRangeRegisters |
838 X86_PageGlobalEnable |
839 X86_MachineCheckArchitecture |
840 X86_CMOVInstruction |
841 X86_PageAttributeTable |
844 X86_CLFLUSHInstruction |
847 X86_MultimediaExtensions |
849 X86_StreamingSIMDExtensions |
850 X86_StreamingSIMDExtensions2 |
898 int sentry_size = intSize;
902 int file_name_size = filename.size() + 1;
904 const int numRandomBytes = 16;
905 int aux_data_size = numRandomBytes;
907 std::string platform =
"x86_64";
908 aux_data_size += platform.size() + 1;
910 int env_data_size = 0;
911 for (
int i = 0;
i <
envp.size(); ++
i)
912 env_data_size +=
envp[
i].size() + 1;
913 int arg_data_size = 0;
914 for (
int i = 0;
i <
argv.size(); ++
i)
915 arg_data_size +=
argv[
i].size() + 1;
921 int base_info_block_size =
922 sentry_size + file_name_size + env_data_size + arg_data_size;
924 int info_block_size =
roundUp(base_info_block_size, align);
926 int info_block_padding = info_block_size - base_info_block_size;
929 int aux_array_size = intSize * 2 * (auxv.size() + 1);
931 int envp_array_size = intSize * (
envp.size() + 1);
932 int argv_array_size = intSize * (
argv.size() + 1);
934 int argc_size = intSize;
945 int partial_size = frame_size + aux_data_size;
946 int aligned_partial_size =
roundUp(partial_size, align);
947 int aux_padding = aligned_partial_size - partial_size;
957 Addr stack_min = stack_base - space_needed;
960 unsigned stack_size = stack_base - stack_min;
961 stack_size =
roundUp(stack_size, pageSize);
965 Addr stack_end =
roundDown(stack_base - stack_size, pageSize);
967 DPRINTF(Stack,
"Mapping the stack: 0x%x %dB\n", stack_end, stack_size);
968 memState->mapRegion(stack_end, stack_size,
"stack");
971 IntType sentry_base = stack_base - sentry_size;
972 IntType file_name_base = sentry_base - file_name_size;
973 IntType env_data_base = file_name_base - env_data_size;
974 IntType arg_data_base = env_data_base - arg_data_size;
975 IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size;
976 IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding;
977 IntType envp_array_base = auxv_array_base - envp_array_size;
978 IntType argv_array_base = envp_array_base - argv_array_size;
979 IntType argc_base = argv_array_base - argc_size;
981 DPRINTF(Stack,
"The addresses of items on the initial stack:\n");
982 DPRINTF(Stack,
"0x%x - file name\n", file_name_base);
983 DPRINTF(Stack,
"0x%x - env data\n", env_data_base);
984 DPRINTF(Stack,
"0x%x - arg data\n", arg_data_base);
985 DPRINTF(Stack,
"0x%x - aux data\n", aux_data_base);
986 DPRINTF(Stack,
"0x%x - auxv array\n", auxv_array_base);
987 DPRINTF(Stack,
"0x%x - envp array\n", envp_array_base);
988 DPRINTF(Stack,
"0x%x - argv array\n", argv_array_base);
989 DPRINTF(Stack,
"0x%x - argc \n", argc_base);
990 DPRINTF(Stack,
"0x%x - stack min\n", stack_min);
995 IntType argc =
argv.size();
996 IntType guestArgc =
htole(argc);
999 IntType sentry_NULL = 0;
1000 initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
1003 initVirtMem->writeString(file_name_base, filename.c_str());
1007 auxv[auxv.size() - 3].val = aux_data_base;
1009 auxv[auxv.size() - 2].val = argv_array_base;
1011 auxv[auxv.size() - 1].val = aux_data_base + numRandomBytes;
1015 Addr auxv_array_end = auxv_array_base;
1016 for (
const auto &aux: auxv) {
1017 initVirtMem->write(auxv_array_end, aux, ByteOrder::little);
1018 auxv_array_end +=
sizeof(aux);
1023 auxv_array_end +=
sizeof(zero);
1025 initVirtMem->writeString(aux_data_base + numRandomBytes,
1033 initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
virtual void map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags=0)
Maps a virtual memory region to a physical memory region.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Declarations of a non-full system Page Table.