mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 07:18:30 +00:00
Fix metal bugs so deathstar.com runs in qemu (#20)
- Remove XD bit in page tables - Fix cylinder+head+sector arithmetic - Implement fstat() for serial file descriptors on metal Here's how to boot an Actually Portable Executable in QEMU: make -j12 o//tool/viz/deathstar.com qemu-system-x86_64 -serial stdio -fda o//tool/viz/deathstar.com Here's a screenshot of DEATHSTAR.COM booted in QEMU: https://justine.lol/cosmopolitan/cosmo-metal-qemu.png Thus metal support is in much better shape now, but still incomplete. Only a few system calls have been polyfilled. To figure out which ones your program needs, simply boot it in the blinkenlights emulator with a breakpoint, and press CTRL-C to continue to the system call breakpoint. If it doesn't break then you should be good. (Note: to emulate normally you can press 'c' and use CTRL-T and ALT-T to tune the speed.) m=tiny make -j12 SILENT=0 MODE=$m \ o/$m/tool/build/blinkenlights.com \ o/$m/tool/viz/deathstar.com o/$m/tool/build/blinkenlights.com \ -r -t -b systemfive.linux \ o/$m/tool/viz/deathstar.com Thank @Theldus for the bug report that made this change possible. Fixes #20 which explains this change further.
This commit is contained in:
parent
58d9659d53
commit
f0600a898c
13 changed files with 182 additions and 119 deletions
|
@ -35,34 +35,47 @@ textwindows int fstat$nt(int64_t handle, struct stat *st) {
|
|||
uint64_t actualsize;
|
||||
struct NtFileCompressionInfo fci;
|
||||
struct NtByHandleFileInformation wst;
|
||||
if (GetFileInformationByHandle(handle, &wst)) {
|
||||
if ((filetype = GetFileType(handle))) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
filetype = GetFileType(handle);
|
||||
st->st_mode =
|
||||
(S_IRUSR | S_IXUSR |
|
||||
(!(wst.dwFileAttributes & kNtFileAttributeReadonly) ? S_IWUSR : 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeNormal) ? S_IFREG : 0) |
|
||||
((wst.dwFileAttributes & kNtFileFlagOpenReparsePoint) ? S_IFLNK : 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeDirectory)
|
||||
? S_IFDIR
|
||||
: (((filetype == kNtFileTypeDisk) ? S_IFBLK : 0) |
|
||||
((filetype == kNtFileTypeChar) ? S_IFCHR : 0) |
|
||||
((filetype == kNtFileTypePipe) ? S_IFIFO : 0))));
|
||||
st->st_atim = FileTimeToTimeSpec(wst.ftLastAccessFileTime);
|
||||
st->st_mtim = FileTimeToTimeSpec(wst.ftLastWriteFileTime);
|
||||
st->st_ctim = FileTimeToTimeSpec(wst.ftCreationFileTime);
|
||||
st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow;
|
||||
st->st_blksize = PAGESIZE;
|
||||
st->st_dev = wst.dwVolumeSerialNumber;
|
||||
st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow;
|
||||
st->st_nlink = wst.nNumberOfLinks;
|
||||
if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci,
|
||||
sizeof(fci))) {
|
||||
actualsize = fci.CompressedFileSize;
|
||||
} else {
|
||||
actualsize = st->st_size;
|
||||
switch (filetype) {
|
||||
case kNtFileTypeChar:
|
||||
st->st_mode = S_IFCHR | 0600;
|
||||
break;
|
||||
case kNtFileTypePipe:
|
||||
st->st_mode = S_IFIFO | 0600;
|
||||
break;
|
||||
case kNtFileTypeDisk:
|
||||
if (GetFileInformationByHandle(handle, &wst)) {
|
||||
dprintf(1, "handle = %ld\n", handle);
|
||||
st->st_mode =
|
||||
(S_IRUSR | S_IXUSR |
|
||||
(!(wst.dwFileAttributes & kNtFileAttributeReadonly) ? S_IWUSR
|
||||
: 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeNormal) ? S_IFREG : 0) |
|
||||
((wst.dwFileAttributes & kNtFileFlagOpenReparsePoint) ? S_IFLNK
|
||||
: 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeDirectory) ? S_IFDIR
|
||||
: 0));
|
||||
st->st_atim = FileTimeToTimeSpec(wst.ftLastAccessFileTime);
|
||||
st->st_mtim = FileTimeToTimeSpec(wst.ftLastWriteFileTime);
|
||||
st->st_ctim = FileTimeToTimeSpec(wst.ftCreationFileTime);
|
||||
st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow;
|
||||
st->st_blksize = PAGESIZE;
|
||||
st->st_dev = wst.dwVolumeSerialNumber;
|
||||
st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow;
|
||||
st->st_nlink = wst.nNumberOfLinks;
|
||||
if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci,
|
||||
sizeof(fci))) {
|
||||
actualsize = fci.CompressedFileSize;
|
||||
} else {
|
||||
actualsize = st->st_size;
|
||||
}
|
||||
st->st_blocks = roundup(actualsize, PAGESIZE) / 512;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
st->st_blocks = roundup(actualsize, PAGESIZE) / 512;
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue