├── .gitignore ├── LICENSE ├── README.md ├── flinux.sln ├── flinux.vcxproj ├── flinux.vcxproj.filters ├── flog ├── flog.vcxproj ├── flog.vcxproj.filters ├── packages.config └── src │ ├── DPIAware.cpp │ ├── DPIAware.h │ ├── LogServer.cpp │ ├── LogServer.h │ ├── LogViewer.cpp │ ├── LogViewer.h │ ├── Main.cpp │ ├── MainWindow.cpp │ ├── MainWindow.h │ ├── Resource.h │ ├── Resource.rc │ ├── pch.cpp │ └── pch.h ├── gen_git_version.cmd └── src ├── binfmt ├── elf-em.h └── elf.h ├── common ├── auxvec.h ├── dirent.h ├── errno.h ├── eventpoll.h ├── fadvise.h ├── fcntl.h ├── fs.h ├── futex.h ├── in.h ├── inotify.h ├── ioctls.h ├── ldt.h ├── mman.h ├── net.h ├── param.h ├── poll.h ├── prctl.h ├── ptrace.h ├── resource.h ├── sched.h ├── select.h ├── sigcontext.h ├── sigframe.h ├── signal.h ├── socket.h ├── soundcard.h ├── stat.h ├── statfs.h ├── sysinfo.h ├── tcp.h ├── termios.h ├── time.h ├── types.h ├── uio.h ├── utime.h ├── utsname.h └── wait.h ├── datetime.c ├── datetime.h ├── dbt ├── cpuid.c ├── cpuid.h ├── x86.c ├── x86.h ├── x86_inst.c ├── x86_inst.h ├── x86_inst_table.c └── x86_trampoline.asm ├── flags.c ├── flags.h ├── fs ├── console.c ├── console.h ├── devfs.c ├── devfs.h ├── dsp.c ├── dsp.h ├── epollfd.c ├── epollfd.h ├── eventfd.c ├── eventfd.h ├── file.h ├── inotify.c ├── inotify.h ├── null.c ├── null.h ├── pipe.c ├── pipe.h ├── procfs.c ├── procfs.h ├── random.c ├── random.h ├── socket.c ├── socket.h ├── sysfs.c ├── sysfs.h ├── virtual.c ├── virtual.h ├── winfs.c ├── winfs.h ├── zero.c └── zero.h ├── heap.c ├── heap.h ├── lib ├── core.h ├── list.h ├── rbtree.c ├── rbtree.h └── slist.h ├── log.c ├── log.h ├── main.c ├── ntdll.h ├── platform.h ├── rc ├── flinux.rc └── resource1.h ├── shared.c ├── shared.h ├── str.c ├── str.h ├── syscall ├── exec.c ├── exec.h ├── fork.c ├── fork.h ├── futex.c ├── futex.h ├── mm.c ├── mm.h ├── process.c ├── process.h ├── process_info.h ├── sig.c ├── sig.h ├── stubs.asm ├── stubs64.asm ├── syscall.c ├── syscall.h ├── syscall_dispatch.c ├── syscall_dispatch.h ├── syscall_table_x64.h ├── syscall_table_x86.h ├── timer.c ├── timer.h ├── tls.c ├── tls.h ├── vfs.c └── vfs.h ├── vsprintf.c ├── vsprintf.h ├── vsscanf.c ├── vsscanf.h ├── wcwidth.c ├── win7compat.c └── win7compat.h /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | *.log 5 | *.exe 6 | src/version.h 7 | test/* 8 | 9 | # User-specific files 10 | *.suo 11 | *.user 12 | *.sln.docstates 13 | 14 | # Build results 15 | [Dd]ebug/ 16 | [Dd]ebugPublic/ 17 | [Rr]elease/ 18 | x64/ 19 | build/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | #NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | # Build Results of an ATL Project 33 | [Dd]ebugPS/ 34 | [Rr]eleasePS/ 35 | dlldata.c 36 | 37 | *_i.c 38 | *_p.c 39 | *_i.h 40 | *.ilk 41 | *.meta 42 | *.obj 43 | *.pch 44 | *.pdb 45 | *.pgc 46 | *.pgd 47 | *.rsp 48 | *.sbr 49 | *.tlb 50 | *.tli 51 | *.tlh 52 | *.tmp 53 | *.tmp_proj 54 | *.log 55 | *.vspscc 56 | *.vssscc 57 | .builds 58 | *.pidb 59 | *.svclog 60 | *.scc 61 | 62 | # Chutzpah Test files 63 | _Chutzpah* 64 | 65 | # Visual C++ cache files 66 | ipch/ 67 | *.aps 68 | *.ncb 69 | *.VC.opendb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | *.ncrunch* 101 | _NCrunch_* 102 | .*crunch*.local.xml 103 | 104 | # MightyMoose 105 | *.mm.* 106 | AutoTest.Net/ 107 | 108 | # Web workbench (sass) 109 | .sass-cache/ 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.[Pp]ublish.xml 129 | *.azurePubxml 130 | 131 | # NuGet Packages Directory 132 | packages/ 133 | ## TODO: If the tool you use requires repositories.config uncomment the next line 134 | #!packages/repositories.config 135 | 136 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 137 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 138 | !packages/build/ 139 | 140 | # Windows Azure Build Output 141 | csx/ 142 | *.build.csdef 143 | 144 | # Windows Store app package directory 145 | AppPackages/ 146 | 147 | # Others 148 | sql/ 149 | *.Cache 150 | ClientBin/ 151 | [Ss]tyle[Cc]op.* 152 | ~$* 153 | *~ 154 | *.dbmdl 155 | *.dbproj.schemaview 156 | *.pfx 157 | *.publishsettings 158 | node_modules/ 159 | 160 | # RIA/Silverlight projects 161 | Generated_Code/ 162 | 163 | # Backup & report files from converting an old project file to a newer 164 | # Visual Studio version. Backup files are not needed, because we have git ;-) 165 | _UpgradeReport_Files/ 166 | Backup*/ 167 | UpgradeLog*.XML 168 | UpgradeLog*.htm 169 | 170 | # SQL Server files 171 | *.mdf 172 | *.ldf 173 | 174 | # Business Intelligence projects 175 | *.rdl.data 176 | *.bim.layout 177 | *.bim_*.settings 178 | 179 | # Microsoft Fakes 180 | FakesAssemblies/ 181 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Foreign LINUX 2 | ====== 3 | 4 | [![Build status](https://ci.appveyor.com/api/projects/status/a340ver0l85l14tf?svg=true)](https://ci.appveyor.com/project/wishstudio/flinux) 5 | 6 | [![Join the chat at https://gitter.im/wishstudio/flinux](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/wishstudio/flinux?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 7 | 8 | IRC: #flinux at freenode 9 | 10 | Google groups: [flinux](https://groups.google.com/forum/#!forum/flinux) 11 | 12 | Foreign LINUX is a dynamic binary translator and a Linux system call interface emulator for the Windows platform. It is capable of running *unmodified* Linux binaries on Windows without any drivers or modifications to the system. This provides another way of running Linux applications under Windows in constrast to Cygwin and other tools. It now runs a large bunch of console applications and some GUI applications. 13 | 14 | Quick start 15 | ===== 16 | Download a premade archlinux environment [here](https://xysun.me/static/flinux-archlinux.7z). 17 | 18 | Extract it anywhere on your harddrive. Then run `run_bash.cmd` to open bash. You will get a minimal archlinux environment. 19 | 20 | Then you can run `pacman -Syu` to update all packages to the current version. Then use `pacman -S ` to install any packages you want. 21 | 22 | Development snapshots: you can download development versions of the software [here](https://ci.appveyor.com/project/wishstudio/flinux/build/artifacts). Just replace the two executables (flinux.exe and flog.exe) for an update. 23 | 24 | [Documentation](https://github.com/wishstudio/flinux/wiki) 25 | 26 | Contributing 27 | ===== 28 | This project still lacks functionality required for many Linux applications. Any help is greatly appreciated. You can contribute using the following ways: 29 | 30 | * Contribute code. Visit [development guideline](https://github.com/wishstudio/flinux/wiki/Development-Guideline) and our [TODO list](https://github.com/wishstudio/flinux/wiki/TODO-List). 31 | * Test programs and report bugs. Read [report a bug](https://github.com/wishstudio/flinux/wiki/Report-a-bug) first. 32 | * Help with the documentations. 33 | 34 | License 35 | ===== 36 | This software is licensed in GPLv3+. 37 | -------------------------------------------------------------------------------- /flinux.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flinux", "flinux.vcxproj", "{A2C5DF3A-D377-47F0-AC4C-0B1011585778}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flog", "flog\flog.vcxproj", "{7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | Release|Win32 = Release|Win32 15 | Release|x64 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Debug|Win32.Build.0 = Debug|Win32 20 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Debug|x64.ActiveCfg = Debug|Win32 21 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Debug|x64.Build.0 = Debug|Win32 22 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Release|Win32.ActiveCfg = Release|Win32 23 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Release|Win32.Build.0 = Release|Win32 24 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Release|x64.ActiveCfg = Release|Win32 25 | {A2C5DF3A-D377-47F0-AC4C-0B1011585778}.Release|x64.Build.0 = Release|Win32 26 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Debug|Win32.Build.0 = Debug|Win32 28 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Debug|x64.ActiveCfg = Debug|x64 29 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Debug|x64.Build.0 = Debug|x64 30 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Release|Win32.ActiveCfg = Release|Win32 31 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Release|Win32.Build.0 = Release|Win32 32 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Release|x64.ActiveCfg = Release|x64 33 | {7B5D4DCD-47F5-4ED9-B92B-8E9762DDB3BB}.Release|x64.Build.0 = Release|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /flog/flog.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /flog/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /flog/src/DPIAware.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015, 2016 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "pch.h" 21 | 22 | #include "DPIAware.h" 23 | 24 | void DPIAware::Init(HWND hWnd) 25 | { 26 | HDC hdc = GetDC(hWnd); 27 | m_dpix = GetDeviceCaps(hdc, LOGPIXELSX); 28 | m_dpiy = GetDeviceCaps(hdc, LOGPIXELSY); 29 | ReleaseDC(hWnd, hdc); 30 | } 31 | 32 | int DPIAware::GetPhysicalX(int logicalX) 33 | { 34 | return MulDiv(logicalX, m_dpix, 96); 35 | } 36 | 37 | int DPIAware::GetPhysicalY(int logicalY) 38 | { 39 | return MulDiv(logicalY, m_dpiy, 96); 40 | } 41 | -------------------------------------------------------------------------------- /flog/src/DPIAware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015, 2016 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define GetPhysicalXY(X, Y) GetPhysicalX(X), GetPhysicalY(Y) 23 | 24 | class DPIAware 25 | { 26 | protected: 27 | void Init(HWND hWnd); 28 | int GetPhysicalX(int logicalX); 29 | int GetPhysicalY(int logicalY); 30 | 31 | private: 32 | int m_dpix, m_dpiy; 33 | }; 34 | -------------------------------------------------------------------------------- /flog/src/LogServer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "pch.h" 21 | 22 | #include "LogServer.h" 23 | 24 | static DWORD WINAPI ThreadProc(LPVOID lpParameter) 25 | { 26 | ((LogServer *)lpParameter)->RunWorker(); 27 | return 0; 28 | } 29 | 30 | LogServer::~LogServer() 31 | { 32 | Stop(); 33 | } 34 | 35 | void LogServer::Start(HWND hMainWnd) 36 | { 37 | m_hMainWnd = hMainWnd; 38 | m_hWorker = CreateThread(NULL, 0, ThreadProc, this, 0, NULL); 39 | m_started = true; 40 | } 41 | 42 | void LogServer::Stop() 43 | { 44 | if (m_started) 45 | { 46 | PostQueuedCompletionStatus(m_hCompletionPort, 0, NULL, NULL); 47 | WaitForSingleObject(m_hWorker, INFINITE); 48 | } 49 | } 50 | 51 | void LogServer::AddClient() 52 | { 53 | /* Create named pipe instance */ 54 | std::unique_ptr client(new Client()); 55 | client->hPipe = CreateNamedPipeW(L"\\\\.\\pipe\\flog_server", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 56 | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, 57 | PIPE_UNLIMITED_INSTANCES, 32, LOG_BUFFER_SIZE, 0, nullptr); 58 | memset(&client->overlapped, 0, sizeof(client->overlapped)); 59 | 60 | /* Associate it with IOCP */ 61 | client->op = OP_CONNECT; 62 | 63 | CreateIoCompletionPort(client->hPipe, m_hCompletionPort, (ULONG_PTR)client.get(), 0); 64 | if (!ConnectNamedPipe(client->hPipe, &client->overlapped) && GetLastError() == ERROR_PIPE_CONNECTED) 65 | { 66 | /* Post a connection notification */ 67 | PostQueuedCompletionStatus(m_hCompletionPort, 0, (ULONG_PTR)client.get(), &client->overlapped); 68 | } 69 | m_clients.push_back(std::move(client)); 70 | } 71 | 72 | void LogServer::RemoveClient(Client *client) 73 | { 74 | CloseHandle(client->hPipe); 75 | for (auto i = m_clients.begin(); i != m_clients.end(); ++i) 76 | if (i->get() == client) 77 | { 78 | m_clients.erase(i); 79 | break; 80 | } 81 | } 82 | 83 | /* Communication sequence 84 | * Client Server 85 | * Connect -> 86 | * Request -> 87 | * Disconnect if request version mismatches 88 | * (execution) 89 | * Log data -> 90 | * (execution) 91 | * Disconnect 92 | */ 93 | 94 | #define PROTOCOL_VERSION 2 95 | #define PROTOCOL_MAGIC 'flog' 96 | struct Request 97 | { 98 | uint32_t magic; 99 | uint32_t version; 100 | uint32_t pid; 101 | uint32_t tid; 102 | }; 103 | 104 | void LogServer::RunWorker() 105 | { 106 | m_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); 107 | AddClient(); 108 | 109 | for (;;) 110 | { 111 | DWORD bytes; 112 | ULONG_PTR key; 113 | LPOVERLAPPED overlapped; 114 | BOOL succeed = GetQueuedCompletionStatus(m_hCompletionPort, &bytes, &key, &overlapped, INFINITE); 115 | 116 | if (key == NULL) 117 | break; 118 | 119 | Client *client = (Client *)key; 120 | switch (client->op) 121 | { 122 | case OP_CONNECT: 123 | { 124 | if (!succeed) 125 | RemoveClient(client); 126 | else 127 | { 128 | client->op = OP_READ_REQUEST; 129 | ReadFile(client->hPipe, client->buffer, sizeof(Request), NULL, &client->overlapped); 130 | } 131 | AddClient(); 132 | break; 133 | } 134 | 135 | case OP_READ_REQUEST: 136 | { 137 | if (!succeed) 138 | RemoveClient(client); 139 | else 140 | { 141 | Request *request = (Request *)client->buffer; 142 | if (request->magic != PROTOCOL_MAGIC || request->version != PROTOCOL_VERSION) 143 | RemoveClient(client); /* TODO: Error message */ 144 | else 145 | { 146 | client->pid = request->pid; 147 | client->tid = request->tid; 148 | client->op = OP_READ; 149 | SendMessageW(m_hMainWnd, WM_NEWCLIENT, (WPARAM)client->pid, (LPARAM)client->tid); 150 | ReadFile(client->hPipe, client->buffer, LOG_BUFFER_SIZE, NULL, &client->overlapped); 151 | } 152 | } 153 | break; 154 | } 155 | 156 | case OP_READ: 157 | { 158 | if (!succeed) 159 | RemoveClient(client); 160 | else 161 | { 162 | LogMessage msg; 163 | msg.pid = client->pid; 164 | msg.tid = client->tid; 165 | msg.buffer = client->buffer; 166 | msg.length = bytes; 167 | SendMessageW(m_hMainWnd, WM_LOGRECEIVE, (WPARAM)&msg, 0); 168 | ReadFile(client->hPipe, client->buffer, LOG_BUFFER_SIZE, NULL, &client->overlapped); 169 | } 170 | break; 171 | } 172 | } 173 | } 174 | for (auto const &client : m_clients) 175 | CloseHandle(client->hPipe); 176 | CloseHandle(m_hCompletionPort); 177 | } 178 | -------------------------------------------------------------------------------- /flog/src/LogServer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define LOG_BUFFER_SIZE 65536 23 | 24 | #define WM_NEWCLIENT WM_USER + 1 25 | #define WM_LOGRECEIVE WM_USER + 2 26 | 27 | struct LogMessage 28 | { 29 | uint32_t pid; 30 | uint32_t tid; 31 | int length; 32 | char *buffer; 33 | }; 34 | 35 | #define LOG_DEBUG 0 36 | #define LOG_INFO 1 37 | #define LOG_WARNING 2 38 | #define LOG_ERROR 3 39 | struct LogPacket 40 | { 41 | uint32_t packetSize; 42 | uint32_t type; 43 | uint32_t len; 44 | char text[1]; 45 | }; 46 | 47 | class LogServer 48 | { 49 | public: 50 | ~LogServer(); 51 | 52 | void Start(HWND hMainWnd); 53 | void Stop(); 54 | 55 | private: 56 | enum ClientOp 57 | { 58 | OP_CONNECT, 59 | OP_READ_REQUEST, 60 | OP_READ, 61 | }; 62 | struct Client 63 | { 64 | HANDLE hPipe; 65 | ClientOp op; 66 | uint32_t pid, tid; 67 | OVERLAPPED overlapped; 68 | char buffer[LOG_BUFFER_SIZE]; 69 | }; 70 | 71 | void AddClient(); 72 | void RemoveClient(Client *client); 73 | void RunWorker(); 74 | 75 | HANDLE m_hWorker; 76 | bool m_started; 77 | HWND m_hMainWnd; 78 | HANDLE m_hCompletionPort; 79 | std::vector> m_clients; 80 | 81 | friend DWORD WINAPI ThreadProc(LPVOID lpParameter); 82 | }; 83 | -------------------------------------------------------------------------------- /flog/src/LogViewer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "DPIAware.h" 23 | #include "LogServer.h" 24 | 25 | class LogViewer: public CWindowImpl, public CScrollImpl, public CDoubleBufferImpl, public DPIAware 26 | { 27 | public: 28 | static ATL::CWndClassInfo& GetWndClassInfo() 29 | { 30 | static ATL::CWndClassInfo wc = 31 | { 32 | { 33 | sizeof(WNDCLASSEX), CS_DBLCLKS, StartWindowProc, 34 | 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, _T("FLOG_LogViewer"), NULL 35 | }, 36 | NULL, NULL, IDC_IBEAM, TRUE, 0, _T("") 37 | }; 38 | return wc; 39 | } 40 | 41 | BEGIN_MSG_MAP(LogViewer) 42 | MSG_WM_TIMER(OnTimer) 43 | MSG_WM_SETFOCUS(OnSetFocus) 44 | MSG_WM_KILLFOCUS(OnKillFocus) 45 | MSG_WM_LBUTTONDOWN(OnLButtonDown) 46 | MSG_WM_LBUTTONUP(OnLButtonUp) 47 | MSG_WM_MOUSEMOVE(OnMouseMove) 48 | MSG_WM_RBUTTONDOWN(OnRButtonDown) 49 | MSG_WM_MBUTTONDOWN(OnMButtonDown) 50 | MSG_WM_KEYDOWN(OnKeyDown) 51 | CHAIN_MSG_MAP(CDoubleBufferImpl) 52 | CHAIN_MSG_MAP(CScrollImpl) 53 | END_MSG_MAP() 54 | 55 | HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL); 56 | void DoPaint(CDCHandle dc); 57 | void OnTimer(UINT_PTR id); 58 | void OnSetFocus(CWindow wndOld); 59 | void OnKillFocus(CWindow wndFocus); 60 | void OnLButtonDown(UINT nFlags, CPoint point); 61 | void OnLButtonUp(UINT nFlags, CPoint point); 62 | void OnMouseMove(UINT nFlags, CPoint point); 63 | void OnRButtonDown(UINT nFlags, CPoint point); 64 | void OnMButtonDown(UINT nFlags, CPoint point); 65 | void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); 66 | void AddLine(int type, const std::wstring &msg); 67 | 68 | private: 69 | std::pair TranslateMousePoint(CPoint mousePoint); 70 | std::pair TranslateClientPointToCharPos(CPoint clientPoint); 71 | CPoint TranslateCharPosToClientPoint(std::pair pos); 72 | void UpdateCaret(bool scrollToCaret = true); 73 | void CopySelectionToClipboard(); 74 | 75 | CFont m_font; 76 | bool m_timerShot, m_mouseDown; 77 | std::pair m_selStart, m_selEnd; 78 | int m_savedX; 79 | std::vector m_types; 80 | std::vector m_lines; 81 | }; 82 | -------------------------------------------------------------------------------- /flog/src/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "pch.h" 21 | 22 | #include "MainWindow.h" 23 | 24 | #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0'\ 25 | processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 26 | 27 | int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 28 | { 29 | CAppModule Module; 30 | Module.Init(NULL, hInstance); 31 | 32 | SetProcessDPIAware(); 33 | 34 | MainWindow mainWindow; 35 | if (mainWindow.Create(NULL, CWindow::rcDefault, L"Foreign Linux Logger")) 36 | { 37 | mainWindow.CenterWindow(); 38 | mainWindow.ShowWindow(nCmdShow); 39 | mainWindow.UpdateWindow(); 40 | MSG msg; 41 | while (GetMessageW(&msg, NULL, 0, 0) > 0) 42 | { 43 | TranslateMessage(&msg); 44 | DispatchMessageW(&msg); 45 | } 46 | } 47 | Module.Term(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /flog/src/MainWindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "DPIAware.h" 23 | #include "LogServer.h" 24 | #include "LogViewer.h" 25 | 26 | class MainWindow: public CFrameWindowImpl, public DPIAware 27 | { 28 | public: 29 | BEGIN_MSG_MAP(MainWindow) 30 | MSG_WM_CREATE(OnCreate) 31 | MSG_WM_CLOSE(OnClose) 32 | MSG_WM_DESTROY(OnDestroy) 33 | MESSAGE_HANDLER(WM_NEWCLIENT, OnNewClient) 34 | MESSAGE_HANDLER(WM_LOGRECEIVE, OnLogReceive) 35 | NOTIFY_CODE_HANDLER_EX(TVN_ITEMCHANGED, OnTreeItemChange) 36 | CHAIN_MSG_MAP(CFrameWindowImpl) 37 | END_MSG_MAP() 38 | 39 | LRESULT OnCreate(LPCREATESTRUCTW cs); 40 | void OnClose(); 41 | void OnDestroy(); 42 | LRESULT OnNewClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 43 | LRESULT OnLogReceive(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 44 | LRESULT OnTreeItemChange(LPNMHDR pnmh); 45 | 46 | private: 47 | struct Client 48 | { 49 | uint32_t pid; 50 | uint32_t tid; 51 | HTREEITEM item; 52 | LogViewer logViewer; 53 | std::string msgpart; 54 | }; 55 | void ProcessClientLog(Client *client, LogPacket *packet); 56 | void InitLogViewer(LogViewer &logViewer); 57 | void SetCurrentLogViewer(LogViewer &logViewer); 58 | 59 | LogServer m_logServer; 60 | CSplitterWindow m_splitter; 61 | CTreeViewCtrl m_processTree; 62 | LogViewer m_defaultLogViewer; 63 | std::vector>> m_clients; 64 | }; 65 | -------------------------------------------------------------------------------- /flog/src/Resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wishstudio/flinux/a041253e8706aa5e0543bbadfc0ff7b9f819c6af/flog/src/Resource.h -------------------------------------------------------------------------------- /flog/src/Resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wishstudio/flinux/a041253e8706aa5e0543bbadfc0ff7b9f819c6af/flog/src/Resource.rc -------------------------------------------------------------------------------- /flog/src/pch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "pch.h" 21 | -------------------------------------------------------------------------------- /flog/src/pch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #include "Resource.h" 41 | -------------------------------------------------------------------------------- /gen_git_version.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem 4 | rem This file is part of Foreign Linux. 5 | rem 6 | rem Copyright (C) 2014, 2015 Xiangyan Sun 7 | rem 8 | rem This program is free software: you can redistribute it and/or modify 9 | rem it under the terms of the GNU General Public License as published by 10 | rem the Free Software Foundation, either version 3 of the License, or 11 | rem (at your option) any later version. 12 | rem 13 | rem This program is distributed in the hope that it will be useful, 14 | rem but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | rem GNU General Public License for more details. 17 | rem 18 | rem You should have received a copy of the GNU General Public License 19 | rem along with this program. If not, see . 20 | rem 21 | 22 | setlocal ENABLEDELAYEDEXPANSION 23 | 24 | set HEADER_FILE=%~p0\src\version.h 25 | 26 | if not defined GIT ( 27 | set GIT="git" 28 | ) 29 | 30 | call !GIT! describe --tags > NUL 2> NUL 31 | if errorlevel 1 ( 32 | rem git not in path and GIT environment variable not set. 33 | rem Try default msysgit installation location. 34 | set GIT="%ProgramFiles(x86)%\Git\bin\git.exe" 35 | call !GIT! describe --tags > NUL 2> NUL 36 | if errorlevel 1 ( 37 | rem Potential x64 version... 38 | rem Visual Studio runs in 32bit mode, so %ProgramFiles% 39 | rem points to "Program Files (x86)" which won't work. 40 | rem Therefore we use a hack here. 41 | set GIT="%ProgramFiles%\..\Program Files\Git\bin\git.exe" 42 | ) 43 | ) 44 | 45 | call !GIT! describe --tags > NUL 2> NUL 46 | if errorlevel 1 ( 47 | echo Git not found. Cannot update version.h file. 48 | echo Make sure git is in your path or set the GIT environment variable. 49 | echo We will now build as an unknown verison. 50 | set VERSION=unknown-version 51 | ) else ( 52 | for /F %%i in ('call !GIT! describe --tags') do set VERSION=%%i 53 | ) 54 | 55 | rem Don't modify the header if it already contains the current version 56 | if exist "%HEADER_FILE%" ( 57 | findstr /C:"%VERSION%" "%HEADER_FILE%" > NUL 2> NUL 58 | if not errorlevel 1 ( 59 | goto done 60 | ) 61 | ) 62 | 63 | rem Generate the header file 64 | 65 | echo /* Automatically generated by gen_git_version.cmd, do not modify */ > "%HEADER_FILE%" 66 | echo #define GIT_VERSION "%VERSION%" >> "%HEADER_FILE%" 67 | 68 | :done 69 | -------------------------------------------------------------------------------- /src/binfmt/elf-em.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* These constants define the various ELF target machines */ 4 | #define EM_NONE 0 5 | #define EM_M32 1 6 | #define EM_SPARC 2 7 | #define EM_386 3 8 | #define EM_68K 4 9 | #define EM_88K 5 10 | #define EM_486 6 /* Perhaps disused */ 11 | #define EM_860 7 12 | #define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ 13 | /* Next two are historical and binaries and 14 | modules of these types will be rejected by 15 | Linux. */ 16 | #define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ 17 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ 18 | 19 | #define EM_PARISC 15 /* HPPA */ 20 | #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ 21 | #define EM_PPC 20 /* PowerPC */ 22 | #define EM_PPC64 21 /* PowerPC64 */ 23 | #define EM_SPU 23 /* Cell BE SPU */ 24 | #define EM_ARM 40 /* ARM 32 bit */ 25 | #define EM_SH 42 /* SuperH */ 26 | #define EM_SPARCV9 43 /* SPARC v9 64-bit */ 27 | #define EM_IA_64 50 /* HP/Intel IA-64 */ 28 | #define EM_X86_64 62 /* AMD x86-64 */ 29 | #define EM_S390 22 /* IBM S/390 */ 30 | #define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ 31 | #define EM_V850 87 /* NEC v850 */ 32 | #define EM_M32R 88 /* Renesas M32R */ 33 | #define EM_MN10300 89 /* Panasonic/MEI MN10300, AM33 */ 34 | #define EM_BLACKFIN 106 /* ADI Blackfin Processor */ 35 | #define EM_TI_C6000 140 /* TI C6X DSPs */ 36 | #define EM_AARCH64 183 /* ARM 64 bit */ 37 | #define EM_FRV 0x5441 /* Fujitsu FR-V */ 38 | #define EM_AVR32 0x18ad /* Atmel AVR32 */ 39 | 40 | /* 41 | * This is an interim value that we will use until the committee comes 42 | * up with a final number. 43 | */ 44 | #define EM_ALPHA 0x9026 45 | 46 | /* Bogus old v850 magic number, used by old tools. */ 47 | #define EM_CYGNUS_V850 0x9080 48 | /* Bogus old m32r magic number, used by old tools. */ 49 | #define EM_CYGNUS_M32R 0x9041 50 | /* This is the old interim value for S/390 architecture */ 51 | #define EM_S390_OLD 0xA390 52 | /* Also Panasonic/MEI MN10300, AM33 */ 53 | #define EM_CYGNUS_MN10300 0xbeef 54 | -------------------------------------------------------------------------------- /src/binfmt/elf.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wishstudio/flinux/a041253e8706aa5e0543bbadfc0ff7b9f819c6af/src/binfmt/elf.h -------------------------------------------------------------------------------- /src/common/auxvec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Symbolic values for the entries in the auxiliary table 4 | put on the initial stack */ 5 | #define AT_NULL 0 /* end of vector */ 6 | #define AT_IGNORE 1 /* entry should be ignored */ 7 | #define AT_EXECFD 2 /* file descriptor of program */ 8 | #define AT_PHDR 3 /* program headers for program */ 9 | #define AT_PHENT 4 /* size of program header entry */ 10 | #define AT_PHNUM 5 /* number of program headers */ 11 | #define AT_PAGESZ 6 /* system page size */ 12 | #define AT_BASE 7 /* base address of interpreter */ 13 | #define AT_FLAGS 8 /* flags */ 14 | #define AT_ENTRY 9 /* entry point of program */ 15 | #define AT_NOTELF 10 /* program is not ELF */ 16 | #define AT_UID 11 /* real uid */ 17 | #define AT_EUID 12 /* effective uid */ 18 | #define AT_GID 13 /* real gid */ 19 | #define AT_EGID 14 /* effective gid */ 20 | #define AT_PLATFORM 15 /* string identifying CPU for optimizations */ 21 | #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ 22 | #define AT_CLKTCK 17 /* frequency at which times() increments */ 23 | /* AT_* values 18 through 22 are reserved */ 24 | #define AT_SECURE 23 /* secure mode boolean */ 25 | #define AT_BASE_PLATFORM 24 /* string identifying real platform, may 26 | * differ from AT_PLATFORM. */ 27 | #define AT_RANDOM 25 /* address of 16 random bytes */ 28 | #define AT_HWCAP2 26 /* extension of AT_HWCAP */ 29 | 30 | #define AT_EXECFN 31 /* filename of program */ 31 | #define AT_SYSINFO 32 32 | #define AT_SYSINFO_EHDR 33 33 | -------------------------------------------------------------------------------- /src/common/dirent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct linux_dirent 6 | { 7 | uintptr_t d_ino; 8 | uintptr_t d_off; 9 | unsigned short d_reclen; 10 | char d_name[1]; 11 | }; 12 | 13 | struct linux_dirent64 14 | { 15 | uint64_t d_ino; 16 | int64_t d_off; 17 | unsigned short d_reclen; 18 | unsigned char d_type; 19 | char d_name[0]; 20 | }; 21 | 22 | #define DT_UNKNOWN 0 23 | #define DT_FIFO 1 24 | #define DT_CHR 2 25 | #define DT_DIR 4 26 | #define DT_BLK 6 27 | #define DT_REG 8 28 | #define DT_LNK 10 29 | #define DT_SOCK 12 30 | #define DT_WHT 14 31 | -------------------------------------------------------------------------------- /src/common/eventpoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* Flags for epoll_create1. */ 7 | #define EPOLL_CLOEXEC O_CLOEXEC 8 | 9 | /* Valid opcodes to issue to sys_epoll_ctl() */ 10 | #define EPOLL_CTL_ADD 1 11 | #define EPOLL_CTL_DEL 2 12 | #define EPOLL_CTL_MOD 3 13 | 14 | #define EPOLLWAKEUP (1 << 29) 15 | #define EPOLLONESHOT (1 << 30) 16 | #define EPOLLET (1 << 31) 17 | 18 | struct epoll_event 19 | { 20 | uint32_t events; /* Epoll events */ 21 | uint32_t data; /* User data variable */ 22 | }; 23 | -------------------------------------------------------------------------------- /src/common/fadvise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define POSIX_FADV_NORMAL 0 /* No further special treatment. */ 4 | #define POSIX_FADV_RANDOM 1 /* Expect random page references. */ 5 | #define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ 6 | #define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ 7 | #define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ 8 | #define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ 9 | -------------------------------------------------------------------------------- /src/common/fcntl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define O_ACCMODE 00000003 4 | #define O_RDONLY 00000000 5 | #define O_WRONLY 00000001 6 | #define O_RDWR 00000002 7 | #define O_CREAT 00000100 8 | #define O_EXCL 00000200 9 | #define O_NOCTTY 00000400 10 | #define O_TRUNC 00001000 11 | #define O_APPEND 00002000 12 | #define O_NONBLOCK 00004000 13 | #define O_DSYNC 00010000 14 | #define FASYNC 00020000 15 | #define O_DIRECT 00040000 16 | #define O_LARGEFILE 00100000 17 | #define O_DIRECTORY 00200000 18 | #define O_NOFOLLOW 00400000 19 | #define O_NOATIME 01000000 20 | #define O_CLOEXEC 02000000 21 | #define __O_SYNC 04000000 22 | #define O_SYNC (__O_SYNC | O_DSYNC) 23 | #define O_PATH 010000000 24 | #define __O_TMPFILE 020000000 25 | #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) 26 | #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) 27 | #define O_NDELAY O_NONBLOCK 28 | 29 | /* Internal modes */ 30 | #define INTERNAL_O_TMP 001000000 /* Temporary file, delete on close */ 31 | #define INTERNAL_O_SPECIAL 002000000 /* Open/create special file (symlink, sockets, etc) */ 32 | #define INTERNAL_O_DELETE 004000000 /* Open with DELETE permission */ 33 | #define INTERNAL_O_NOINHERIT 010000000 /* Any NT handles created should be non inheritable */ 34 | 35 | #define AT_FDCWD -100 /* Special value used to indicate openat should use the current working directory. */ 36 | #define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ 37 | #define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */ 38 | #define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ 39 | #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ 40 | #define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */ 41 | 42 | #define F_DUPFD 0 /* dup */ 43 | #define F_GETFD 1 /* get close_on_exec */ 44 | #define F_SETFD 2 /* set/clear close_on_exec */ 45 | #define F_GETFL 3 /* get file->f_flags */ 46 | #define F_SETFL 4 /* set file->f_flags */ 47 | #define F_GETLK 5 48 | #define F_SETLK 6 49 | #define F_SETLKW 7 50 | #define F_SETOWN 8 /* for sockets. */ 51 | #define F_GETOWN 9 /* for sockets. */ 52 | #define F_SETSIG 10 /* for sockets. */ 53 | #define F_GETSIG 11 /* for sockets. */ 54 | #define F_GETLK64 12 /* using 'struct flock64' */ 55 | #define F_SETLK64 13 56 | #define F_SETLKW64 14 57 | #define F_SETOWN_EX 15 58 | #define F_GETOWN_EX 16 59 | #define F_GETOWNER_UIDS 17 60 | 61 | /* for F_[GET|SET]FL */ 62 | #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ 63 | -------------------------------------------------------------------------------- /src/common/fs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEEK_SET 0 /* seek relative to beginning of file */ 4 | #define SEEK_CUR 1 /* seek relative to current file position */ 5 | #define SEEK_END 2 /* seek relative to end of file */ 6 | #define SEEK_DATA 3 /* seek to the next data */ 7 | #define SEEK_HOLE 4 /* seek to the next hole */ 8 | #define SEEK_MAX SEEK_HOLE 9 | -------------------------------------------------------------------------------- /src/common/futex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Second argument to futex syscall */ 4 | 5 | #define FUTEX_WAIT 0 6 | #define FUTEX_WAKE 1 7 | #define FUTEX_FD 2 8 | #define FUTEX_REQUEUE 3 9 | #define FUTEX_CMP_REQUEUE 4 10 | #define FUTEX_WAKE_OP 5 11 | #define FUTEX_LOCK_PI 6 12 | #define FUTEX_UNLOCK_PI 7 13 | #define FUTEX_TRYLOCK_PI 8 14 | #define FUTEX_WAIT_BITSET 9 15 | #define FUTEX_WAKE_BITSET 10 16 | #define FUTEX_WAIT_REQUEUE_PI 11 17 | #define FUTEX_CMP_REQUEUE_PI 12 18 | 19 | #define FUTEX_PRIVATE_FLAG 128 20 | #define FUTEX_CLOCK_REALTIME 256 21 | #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) 22 | 23 | /* 24 | * Support for robust futexes: the kernel cleans up held futexes at 25 | * thread exit time. 26 | */ 27 | 28 | /* 29 | * Per-lock list entry - embedded in user-space locks, somewhere close 30 | * to the futex field. (Note: user-space uses a double-linked list to 31 | * achieve O(1) list add and remove, but the kernel only needs to know 32 | * about the forward link) 33 | * 34 | * NOTE: this structure is part of the syscall ABI, and must not be 35 | * changed. 36 | */ 37 | struct robust_list { 38 | struct robust_list *next; 39 | }; 40 | 41 | /* 42 | * Per-thread list head: 43 | * 44 | * NOTE: this structure is part of the syscall ABI, and must only be 45 | * changed if the change is first communicated with the glibc folks. 46 | * (When an incompatible change is done, we'll increase the structure 47 | * size, which glibc will detect) 48 | */ 49 | struct robust_list_head { 50 | /* 51 | * The head of the list. Points back to itself if empty: 52 | */ 53 | struct robust_list list; 54 | /* 55 | * This relative offset is set by user-space, it gives the kernel 56 | * the relative position of the futex field to examine. This way 57 | * we keep userspace flexible, to freely shape its data-structure, 58 | * without hardcoding any particular offset into the kernel: 59 | */ 60 | long futex_offset; 61 | 62 | /* 63 | * The death of the thread may race with userspace setting 64 | * up a lock's links. So to handle this race, userspace first 65 | * sets this field to the address of the to-be-taken lock, 66 | * then does the lock acquire, and then adds itself to the 67 | * list, and then clears this field. Hence the kernel will 68 | * always have full knowledge of all locks that the thread 69 | * _might_ have taken. We check the owner TID in any case, 70 | * so only truly owned locks will be handled. 71 | */ 72 | struct robust_list *list_op_pending; 73 | }; 74 | 75 | /* 76 | * Are there any waiters for this robust futex: 77 | */ 78 | #define FUTEX_WAITERS 0x80000000 79 | 80 | /* 81 | * The kernel signals via this bit that a thread holding a futex 82 | * has exited without unlocking the futex. The kernel also does 83 | * a FUTEX_WAKE on such futexes, after setting the bit, to wake 84 | * up any possible waiters: 85 | */ 86 | #define FUTEX_OWNER_DIED 0x40000000 87 | 88 | /* 89 | * The rest of the robust-futex field is for the TID: 90 | */ 91 | #define FUTEX_TID_MASK 0x3fffffff 92 | 93 | /* 94 | * This limit protects against a deliberately circular list. 95 | * (Not worth introducing an rlimit for it) 96 | */ 97 | #define ROBUST_LIST_LIMIT 2048 98 | -------------------------------------------------------------------------------- /src/common/in.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LINUX_IP_TOS 1 4 | #define LINUX_IP_TTL 2 5 | #define LINUX_IP_HDRINCL 3 6 | #define LINUX_IP_OPTIONS 4 7 | #define LINUX_IP_ROUTER_ALERT 5 8 | #define LINUX_IP_RECVOPTS 6 9 | #define LINUX_IP_RETOPTS 7 10 | #define LINUX_IP_PKTINFO 8 11 | #define LINUX_IP_PKTOPTIONS 9 12 | #define LINUX_IP_MTU_DISCOVER 10 13 | #define LINUX_IP_RECVERR 11 14 | #define LINUX_IP_RECVTTL 12 15 | #define LINUX_IP_RECVTOS 13 16 | #define LINUX_IP_MTU 14 17 | #define LINUX_IP_FREEBIND 15 18 | #define LINUX_IP_IPSEC_POLICY 16 19 | #define LINUX_IP_XFRM_POLICY 17 20 | #define LINUX_IP_PASSSEC 18 21 | #define LINUX_IP_TRANSPARENT 19 22 | #define LINUX_IP_RECVRETOPTS IP_RETOPTS 23 | #define LINUX_IP_ORIGDSTADDR 20 24 | #define LINUX_IP_RECVORIGDSTADDR IP_ORIGDSTADDR 25 | #define LINUX_IP_MINTTL 21 26 | #define LINUX_IP_NODEFRAG 22 27 | 28 | #define LINUX_IP_MULTICAST_IF 32 29 | #define LINUX_IP_MULTICAST_TTL 33 30 | #define LINUX_IP_MULTICAST_LOOP 34 31 | #define LINUX_IP_ADD_MEMBERSHIP 35 32 | #define LINUX_IP_DROP_MEMBERSHIP 36 33 | #define LINUX_IP_UNBLOCK_SOURCE 37 34 | #define LINUX_IP_BLOCK_SOURCE 38 35 | #define LINUX_IP_ADD_SOURCE_MEMBERSHIP 39 36 | #define LINUX_IP_DROP_SOURCE_MEMBERSHIP 40 37 | #define LINUX_IP_MSFILTER 41 38 | #define LINUX_MCAST_JOIN_GROUP 42 39 | #define LINUX_MCAST_BLOCK_SOURCE 43 40 | #define LINUX_MCAST_UNBLOCK_SOURCE 44 41 | #define LINUX_MCAST_LEAVE_GROUP 45 42 | #define LINUX_MCAST_JOIN_SOURCE_GROUP 46 43 | #define LINUX_MCAST_LEAVE_SOURCE_GROUP 47 44 | #define LINUX_MCAST_MSFILTER 48 45 | #define LINUX_IP_MULTICAST_ALL 49 46 | #define LINUX_IP_UNICAST_IF 50 47 | 48 | /* IP_MTU_DISCOVER values */ 49 | #define LINUX_IP_PMTUDISC_DONT 0 /* Never send DF frames */ 50 | #define LINUX_IP_PMTUDISC_WANT 1 /* Use per route hints */ 51 | #define LINUX_IP_PMTUDISC_DO 2 /* Always DF */ 52 | #define LINUX_IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */ 53 | /* Always use interface mtu (ignores dst pmtu) but don't set DF flag. 54 | * Also incoming ICMP frag_needed notifications will be ignored on 55 | * this socket to prevent accepting spoofed ones. 56 | */ 57 | #define LINUX_IP_PMTUDISC_INTERFACE 4 58 | /* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get 59 | * fragmented if they exeed the interface mtu 60 | */ 61 | #define LINUX_IP_PMTUDISC_OMIT 5 62 | -------------------------------------------------------------------------------- /src/common/inotify.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * struct inotify_event - structure read from the inotify device for each event 8 | * 9 | * When you are watching a directory, you will receive the filename for events 10 | * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd. 11 | */ 12 | struct inotify_event { 13 | int32_t wd; /* watch descriptor */ 14 | uint32_t mask; /* watch mask */ 15 | uint32_t cookie; /* cookie to synchronize two events */ 16 | uint32_t len; /* length (including nulls) of name */ 17 | char name[0]; /* stub for possible name */ 18 | }; 19 | 20 | /* the following are legal, implemented events that user-space can watch for */ 21 | #define IN_ACCESS 0x00000001 /* File was accessed */ 22 | #define IN_MODIFY 0x00000002 /* File was modified */ 23 | #define IN_ATTRIB 0x00000004 /* Metadata changed */ 24 | #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ 25 | #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ 26 | #define IN_OPEN 0x00000020 /* File was opened */ 27 | #define IN_MOVED_FROM 0x00000040 /* File was moved from X */ 28 | #define IN_MOVED_TO 0x00000080 /* File was moved to Y */ 29 | #define IN_CREATE 0x00000100 /* Subfile was created */ 30 | #define IN_DELETE 0x00000200 /* Subfile was deleted */ 31 | #define IN_DELETE_SELF 0x00000400 /* Self was deleted */ 32 | 33 | /* the following are legal events. they are sent as needed to any watch */ 34 | #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ 35 | #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 36 | #define IN_IGNORED 0x00008000 /* File was ignored */ 37 | 38 | /* helper events */ 39 | #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */ 40 | #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ 41 | 42 | /* special flags */ 43 | #define IN_ISDIR 0x40000000 /* event occurred against dir */ 44 | #define IN_ONESHOT 0x80000000 /* only send event once */ 45 | 46 | /* Flags for sys_inotify_init1. */ 47 | #define IN_CLOEXEC O_CLOEXEC 48 | #define IN_NONBLOCK O_NONBLOCK 49 | -------------------------------------------------------------------------------- /src/common/ioctls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define L_TCGETS 0x5401 4 | #define L_TCSETS 0x5402 5 | #define L_TCSETSW 0x5403 6 | #define L_TCSETSF 0x5404 7 | #define L_TCGETA 0x5405 8 | #define L_TCSETA 0x5406 9 | #define L_TCSETAW 0x5407 10 | #define L_TCSETAF 0x5408 11 | #define L_TCSBRK 0x5409 12 | #define L_TCXONC 0x540A 13 | #define L_TCFLSH 0x540B 14 | #define L_TIOCEXCL 0x540C 15 | #define L_TIOCNXCL 0x540D 16 | #define L_TIOCSCTTY 0x540E 17 | #define L_TIOCGPGRP 0x540F 18 | #define L_TIOCSPGRP 0x5410 19 | #define L_TIOCOUTQ 0x5411 20 | #define L_TIOCSTI 0x5412 21 | #define L_TIOCGWINSZ 0x5413 22 | #define L_TIOCSWINSZ 0x5414 23 | #define L_TIOCMGET 0x5415 24 | #define L_TIOCMBIS 0x5416 25 | #define L_TIOCMBIC 0x5417 26 | #define L_TIOCMSET 0x5418 27 | #define L_TIOCGSOFTCAR 0x5419 28 | #define L_TIOCSSOFTCAR 0x541A 29 | #define L_FIONREAD 0x541B 30 | #define L_TIOCINQ L_FIONREAD 31 | #define L_TIOCLINUX 0x541C 32 | #define L_TIOCCONS 0x541D 33 | #define L_TIOCGSERIAL 0x541E 34 | #define L_TIOCSSERIAL 0x541F 35 | #define L_TIOCPKT 0x5420 36 | #define L_FIONBIO 0x5421 37 | #define L_TIOCNOTTY 0x5422 38 | #define L_TIOCSETD 0x5423 39 | #define L_TIOCGETD 0x5424 40 | #define L_TCSBRKP 0x5425 41 | #define L_TIOCSBRK 0x5427 42 | #define L_TIOCCBRK 0x5428 43 | #define L_TIOCGSID 0x5429 44 | #define L_TCGETS2 _IOR('T', 0x2A, struct termios2) 45 | #define L_TCSETS2 _IOW('T', 0x2B, struct termios2) 46 | #define L_TCSETSW2 _IOW('T', 0x2C, struct termios2) 47 | #define L_TCSETSF2 _IOW('T', 0x2D, struct termios2) 48 | #define L_TIOCGRS485 0x542E 49 | #define L_TIOCSRS485 0x542F 50 | #define L_TIOCGPTN _IOR('T', 0x30, unsigned int) 51 | #define L_TIOCSPTLCK _IOW('T', 0x31, int) 52 | #define L_TIOCGDEV _IOR('T', 0x32, unsigned int) 53 | #define L_TCGETX 0x5432 54 | #define L_TCSETX 0x5433 55 | #define L_TCSETXF 0x5434 56 | #define L_TCSETXW 0x5435 57 | #define L_TIOCSIG _IOW('T', 0x36, int) 58 | #define L_TIOCVHANGUP 0x5437 59 | #define L_TIOCGPKT _IOR('T', 0x38, int) 60 | #define L_TIOCGPTLCK _IOR('T', 0x39, int) 61 | #define L_TIOCGEXCL _IOR('T', 0x40, int) 62 | 63 | #define L_FIONCLEX 0x5450 64 | #define L_FIOCLEX 0x5451 65 | #define L_FIOASYNC 0x5452 66 | #define L_TIOCSERCONFIG 0x5453 67 | #define L_TIOCSERGWILD 0x5454 68 | #define L_TIOCSERSWILD 0x5455 69 | #define L_TIOCGLCKTRMIOS 0x5456 70 | #define L_TIOCSLCKTRMIOS 0x5457 71 | #define L_TIOCSERGSTRUCT 0x5458 72 | #define L_TIOCSERGETLSR 0x5459 73 | #define L_TIOCSERGETMULTI 0x545A 74 | #define L_TIOCSERSETMULTI 0x545B 75 | 76 | #define L_TIOCMIWAIT 0x545C 77 | #define L_TIOCGICOUNT 0x545D 78 | 79 | #define L_FIOQSIZE 0x5460 80 | 81 | #define L_TIOCPKT_DATA 0 82 | #define L_TIOCPKT_FLUSHREAD 1 83 | #define L_TIOCPKT_FLUSHWRITE 2 84 | #define L_TIOCPKT_STOP 4 85 | #define L_TIOCPKT_START 8 86 | #define L_TIOCPKT_NOSTOP 16 87 | #define L_TIOCPKT_DOSTOP 32 88 | #define L_TIOCPKT_IOCTL 64 89 | 90 | #define L_TIOCSER_TEMT 0x01 91 | -------------------------------------------------------------------------------- /src/common/ldt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct user_desc 4 | { 5 | unsigned int entry_number; 6 | unsigned int base_addr; 7 | unsigned int limit; 8 | unsigned int seg_32bit: 1; 9 | unsigned int contents: 2; 10 | unsigned int read_exec_only: 1; 11 | unsigned int limit_in_pages: 1; 12 | unsigned int seg_not_present: 1; 13 | unsigned int useable: 1; 14 | }; 15 | -------------------------------------------------------------------------------- /src/common/mman.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PROT_NONE 0 4 | #define PROT_READ 1 5 | #define PROT_WRITE 2 6 | #define PROT_EXEC 4 7 | 8 | #define MAP_FILE 0 9 | #define MAP_SHARED 1 10 | #define MAP_PRIVATE 2 11 | #define MAP_TYPE 0xf 12 | #define MAP_FIXED 0x10 13 | #define MAP_ANONYMOUS 0x20 14 | #define MAP_ANON MAP_ANONYMOUS 15 | #define MAP_32BIT 0x40 16 | 17 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ 18 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ 19 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ 20 | #define MAP_LOCKED 0x2000 /* pages are locked */ 21 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ 22 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ 23 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ 24 | #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ 25 | #define MAP_HUGETLB 0x40000 /* create a huge page mapping */ 26 | 27 | #define MAP_FAILED ((void *)-1) 28 | 29 | /* Flags for msync. */ 30 | #define MS_ASYNC 1 /* sync memory synchronously */ 31 | #define MS_INVALIDATE 2 /* invalidate the caches */ 32 | #define MS_SYNC 4 /* synchronous memory sync */ 33 | 34 | /* Flags for madvise. */ 35 | #define MADV_NORMAL 0 /* no further special treatment */ 36 | #define MADV_RANDOM 1 /* expect random page references */ 37 | #define MADV_SEQUENTIAL 2 /* expect sequential page references */ 38 | #define MADV_WILLNEED 3 /* will need these pages */ 39 | #define MADV_DONTNEED 4 /* don't need these pages */ 40 | #define MADV_REMOVE 9 /* remove these pages & resources */ 41 | #define MADV_DONTFORK 10 /* don't inherit across fork */ 42 | #define MADV_DOFORK 11 /* do inherit across fork */ 43 | #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ 44 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ 45 | #define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ 46 | #define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ 47 | #define MADV_DONTDUMP 16 /* Explicity exclude from the core dump, overrides the coredump filter bits */ 48 | #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ 49 | 50 | #define MADV_HWPOISON 100 /* poison a page for testing */ 51 | #define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ 52 | -------------------------------------------------------------------------------- /src/common/net.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SYS_SOCKET 1 /* sys_socket(2) */ 4 | #define SYS_BIND 2 /* sys_bind(2) */ 5 | #define SYS_CONNECT 3 /* sys_connect(2) */ 6 | #define SYS_LISTEN 4 /* sys_listen(2) */ 7 | #define SYS_ACCEPT 5 /* sys_accept(2) */ 8 | #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ 9 | #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ 10 | #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ 11 | #define SYS_SEND 9 /* sys_send(2) */ 12 | #define SYS_RECV 10 /* sys_recv(2) */ 13 | #define SYS_SENDTO 11 /* sys_sendto(2) */ 14 | #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ 15 | #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ 16 | #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ 17 | #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ 18 | #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ 19 | #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ 20 | #define SYS_ACCEPT4 18 /* sys_accept4(2) */ 21 | #define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */ 22 | #define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */ 23 | -------------------------------------------------------------------------------- /src/common/param.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define USER_HZ 100 4 | #define CLOCKS_PER_SEC (USER_HZ) 5 | -------------------------------------------------------------------------------- /src/common/poll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* These are specified by iBCS2 */ 4 | #define LINUX_POLLIN 0x0001 5 | #define LINUX_POLLPRI 0x0002 6 | #define LINUX_POLLOUT 0x0004 7 | #define LINUX_POLLERR 0x0008 8 | #define LINUX_POLLHUP 0x0010 9 | #define LINUX_POLLNVAL 0x0020 10 | 11 | /* The rest seem to be more-or-less nonstandard. Check them! */ 12 | #define LINUX_POLLRDNORM 0x0040 13 | #define LINUX_POLLRDBAND 0x0080 14 | #define LINUX_POLLWRNORM 0x0100 15 | #define LINUX_POLLWRBAND 0x0200 16 | #define LINUX_POLLMSG 0x0400 17 | #define LINUX_POLLREMOVE 0x1000 18 | #define LINUX_POLLRDHUP 0x2000 19 | 20 | #define LINUX_POLLFREE 0x4000 /* currently only for epoll */ 21 | 22 | #define LINUX_POLL_BUSY_LOOP 0x8000 23 | 24 | struct linux_pollfd { 25 | int fd; 26 | short events; 27 | short revents; 28 | }; 29 | -------------------------------------------------------------------------------- /src/common/prctl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ARCH_SET_GS 0x1001 4 | #define ARCH_SET_FS 0x1002 5 | #define ARCH_GET_FS 0x1003 6 | #define ARCH_GET_GS 0x1004 7 | -------------------------------------------------------------------------------- /src/common/ptrace.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct pt_regs 4 | { 5 | long ebx; 6 | long ecx; 7 | long edx; 8 | long esi; 9 | long edi; 10 | long ebp; 11 | long eax; 12 | int xds; 13 | int xes; 14 | int xfs; 15 | int xgs; 16 | long orig_eax; 17 | long eip; 18 | int xcs; 19 | long eflags; 20 | long esp; 21 | int xss; 22 | }; 23 | -------------------------------------------------------------------------------- /src/common/resource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define RLIMIT_CPU 0 /* CPU time in sec */ 7 | #define RLIMIT_FSIZE 1 /* Maximum filesize */ 8 | #define RLIMIT_DATA 2 /* max data size */ 9 | #define RLIMIT_STACK 3 /* max stack size */ 10 | #define RLIMIT_CORE 4 /* max core file size */ 11 | #define RLIMIT_RSS 5 /* max resident set size */ 12 | #define RLIMIT_NPROC 6 /* max number of processes */ 13 | #define RLIMIT_NOFILE 7 /* max number of open files */ 14 | #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ 15 | #define RLIMIT_AS 9 /* address space limit */ 16 | #define RLIMIT_LOCKS 10 /* maximum file locks held */ 17 | #define RLIMIT_SIGPENDING 11 /* max number of pending signals */ 18 | #define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */ 19 | #define RLIMIT_NICE 13 /* max nice prio allowed to raise to 0-39 for nice level 19 .. -20 */ 20 | #define RLIMIT_RTPRIO 14 /* maximum realtime priority */ 21 | #define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */ 22 | #define RLIM_NLIMITS 16 23 | 24 | #define RLIM_INFINITY (~0UL) 25 | 26 | struct rlimit { 27 | unsigned long rlim_cur; /* Soft limit */ 28 | unsigned long rlim_max; /* Hard limit (ceiling for rlim_cur) */ 29 | }; 30 | 31 | struct rlimit64 { 32 | uint64_t rlim_cur; /* Soft limit */ 33 | uint64_t rlim_max; /* Hard limit (ceiling for rlim_cur */ 34 | }; 35 | 36 | /* 37 | * Definition of struct rusage taken from BSD 4.3 Reno 38 | * 39 | * We don't support all of these yet, but we might as well have them.... 40 | * Otherwise, each time we add new items, programs which depend on this 41 | * structure will lose. This reduces the chances of that happening. 42 | */ 43 | #define RUSAGE_SELF 0 44 | #define RUSAGE_CHILDREN (-1) 45 | #define RUSAGE_BOTH (-2) /* sys_wait4() uses this */ 46 | #define RUSAGE_THREAD 1 /* only the calling thread */ 47 | 48 | struct rusage { 49 | struct linux_timeval ru_utime; /* user time used */ 50 | struct linux_timeval ru_stime; /* system time used */ 51 | intptr_t ru_maxrss; /* maximum resident set size */ 52 | intptr_t ru_ixrss; /* integral shared memory size */ 53 | intptr_t ru_idrss; /* integral unshared data size */ 54 | intptr_t ru_isrss; /* integral unshared stack size */ 55 | intptr_t ru_minflt; /* page reclaims */ 56 | intptr_t ru_majflt; /* page faults */ 57 | intptr_t ru_nswap; /* swaps */ 58 | intptr_t ru_inblock; /* block input operations */ 59 | intptr_t ru_oublock; /* block output operations */ 60 | intptr_t ru_msgsnd; /* messages sent */ 61 | intptr_t ru_msgrcv; /* messages received */ 62 | intptr_t ru_nsignals; /* signals received */ 63 | intptr_t ru_nvcsw; /* voluntary context switches */ 64 | intptr_t ru_nivcsw; /* involuntary " */ 65 | }; 66 | -------------------------------------------------------------------------------- /src/common/sched.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Cloning flags */ 4 | #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ 5 | #define CLONE_VM 0x00000100 /* set if VM shared between processes */ 6 | #define CLONE_FS 0x00000200 /* set if fs info shared between processes */ 7 | #define CLONE_FILES 0x00000400 /* set if open files shared between processes */ 8 | #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ 9 | #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ 10 | #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ 11 | #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ 12 | #define CLONE_THREAD 0x00010000 /* Same thread group? */ 13 | #define CLONE_NEWNS 0x00020000 /* New namespace group? */ 14 | #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ 15 | #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ 16 | #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ 17 | #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ 18 | #define CLONE_DETACHED 0x00400000 /* Unused, ignored */ 19 | #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ 20 | #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ 21 | /* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state) 22 | and is now available for re-use. */ 23 | #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ 24 | #define CLONE_NEWIPC 0x08000000 /* New ipcs */ 25 | #define CLONE_NEWUSER 0x10000000 /* New user namespace */ 26 | #define CLONE_NEWPID 0x20000000 /* New pid namespace */ 27 | #define CLONE_NEWNET 0x40000000 /* New network namespace */ 28 | #define CLONE_IO 0x80000000 /* Clone io context */ 29 | -------------------------------------------------------------------------------- /src/common/select.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LINUX_FD_SETSIZE 1024 4 | #define LINUX_FD_BITPERLONG (8 * sizeof(unsigned long)) 5 | 6 | struct fdset 7 | { 8 | unsigned long fds_bits[(LINUX_FD_SETSIZE + LINUX_FD_BITPERLONG - 1) / LINUX_FD_BITPERLONG]; 9 | }; 10 | 11 | #define LINUX_FD_ZERO(nfds, set) \ 12 | do \ 13 | { \ 14 | int _count = ((nfds) + LINUX_FD_BITPERLONG - 1) / LINUX_FD_BITPERLONG; \ 15 | for (int _i = 0; _i < _count; ++_i) \ 16 | (set)->fds_bits[_i] = 0; \ 17 | } while (0) 18 | #define LINUX_FD_CLR(fd, set) (set)->fds_bits[(fd) / LINUX_FD_BITPERLONG] &= ~(1 << ((fd) % LINUX_FD_BITPERLONG)) 19 | #define LINUX_FD_SET(fd, set) (set)->fds_bits[(fd) / LINUX_FD_BITPERLONG] |= 1 << ((fd) % LINUX_FD_BITPERLONG) 20 | #define LINUX_FD_ISSET(fd, set) (((set)->fds_bits[(fd) / LINUX_FD_BITPERLONG] >> ((fd) % LINUX_FD_BITPERLONG)) & 1) 21 | -------------------------------------------------------------------------------- /src/common/sigcontext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | struct i387_fsave_struct 7 | { 8 | uint32_t cwd; /* FPU Control Word */ 9 | uint32_t swd; /* FPU Status Word */ 10 | uint32_t twd; /* FPU Tag Word */ 11 | uint32_t fip; /* FPU IP Offset */ 12 | uint32_t fcs; /* FPU IP Selector */ 13 | uint32_t foo; /* FPU Operand Pointer Offset */ 14 | uint32_t fos; /* FPU Operand Pointer Selector */ 15 | 16 | /* 8*10 bytes for each FP-reg = 80 bytes: */ 17 | uint32_t st_space[20]; 18 | /* Software status information [not touched by FSAVE ]: */ 19 | uint32_t status; 20 | }; 21 | 22 | struct i387_fxsave_struct 23 | { 24 | uint16_t cwd; /* Control Word */ 25 | uint16_t swd; /* Status Word */ 26 | uint16_t twd; /* Tag Word */ 27 | uint16_t fop; /* Last Instruction Opcode */ 28 | union { 29 | struct { 30 | uint64_t rip; /* Instruction Pointer */ 31 | uint64_t rdp; /* Data Pointer */ 32 | }; 33 | struct { 34 | uint32_t fip; /* FPU IP Offset */ 35 | uint32_t fcs; /* FPU IP Selector */ 36 | uint32_t foo; /* FPU Operand Offset */ 37 | uint32_t fos; /* FPU Operand Selector */ 38 | }; 39 | }; 40 | uint32_t mxcsr; /* MXCSR Register State */ 41 | uint32_t mxcsr_mask; /* MXCSR Mask */ 42 | 43 | /* 8*16 bytes for each FP-reg = 128 bytes: */ 44 | uint32_t st_space[32]; 45 | 46 | /* 16*16 bytes for each XMM-reg = 256 bytes: */ 47 | uint32_t xmm_space[64]; 48 | 49 | uint32_t padding[12]; 50 | union { 51 | uint32_t padding1[12]; 52 | uint32_t sw_reserved[12]; 53 | }; 54 | }; 55 | 56 | struct fpx_sw_bytes 57 | { 58 | uint32_t magic1; /* FP_XSTATE_MAGIC1 */ 59 | uint32_t extended_size; /* total size of the layout referred by fpstate pointer in the sigcontext. */ 60 | uint64_t xstate_bv; /* feature bit mask (including fp/sse/extended state) that is present in the memory layout.*/ 61 | uint32_t xstate_size; /* actual xsave state size, based on the features saved in the layout, 'extended_size' will be greater than 'xstate_size'. */ 62 | uint32_t padding[7]; /* for future use. */ 63 | }; 64 | 65 | struct fpreg 66 | { 67 | uint16_t significand[4]; 68 | uint16_t exponent; 69 | }; 70 | 71 | struct fpxreg 72 | { 73 | uint16_t significand[4]; 74 | uint16_t exponent; 75 | uint16_t padding[3]; 76 | }; 77 | 78 | struct xmmreg 79 | { 80 | uint32_t element[4]; 81 | }; 82 | 83 | struct fpstate 84 | { 85 | /* Regular FPU environment */ 86 | uint32_t cw; 87 | uint32_t sw; 88 | uint32_t tag; /* not compatible to 64bit twd */ 89 | uint32_t ipoff; 90 | uint32_t cssel; 91 | uint32_t dataoff; 92 | uint32_t datasel; 93 | struct fpreg _st[8]; 94 | uint16_t status; 95 | uint16_t magic; /* 0xffff = regular FPU data only */ 96 | 97 | /* FXSR FPU environment */ 98 | uint32_t _fxsr_env[6]; /* FXSR FPU env is ignored */ 99 | uint32_t mxcsr; 100 | uint32_t reserved; 101 | struct fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ 102 | struct xmmreg _xmm[8]; 103 | uint32_t padding1[44]; 104 | union 105 | { 106 | uint32_t padding2[12]; 107 | struct fpx_sw_bytes sw_reserved; /* represents the extended state info */ 108 | }; 109 | }; 110 | 111 | struct xsave_hdr 112 | { 113 | uint64_t xstate_bv; 114 | uint64_t reserved1[2]; 115 | uint64_t reserved2[5]; 116 | }; 117 | 118 | struct ymmh_state 119 | { 120 | uint32_t ymmh_space[64]; 121 | }; 122 | 123 | struct xstate 124 | { 125 | struct fpstate fpstate; 126 | struct xsave_hdr xstate_hdr; 127 | struct ymmh_state ymmh; 128 | }; 129 | 130 | struct sigcontext 131 | { 132 | uint16_t gs, __gsh; 133 | uint16_t fs, __fsh; 134 | uint16_t es, __esh; 135 | uint16_t ds, __dsh; 136 | uint32_t di; 137 | uint32_t si; 138 | uint32_t bp; 139 | uint32_t sp; 140 | uint32_t bx; 141 | uint32_t dx; 142 | uint32_t cx; 143 | uint32_t ax; 144 | uint32_t trapno; 145 | uint32_t err; 146 | uint32_t ip; 147 | uint16_t cs, __csh; 148 | uint32_t flags; 149 | uint32_t sp_at_signal; 150 | uint16_t ss, __ssh; 151 | 152 | void *fpstate; 153 | uint32_t oldmask; 154 | uint32_t cr2; 155 | }; 156 | 157 | struct ucontext 158 | { 159 | uint32_t uc_flags; 160 | uint32_t uc_link; 161 | stack_t uc_stack; 162 | struct sigcontext uc_mcontext; 163 | sigset_t uc_sigmask; 164 | }; 165 | -------------------------------------------------------------------------------- /src/common/sigframe.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct sigframe 8 | { 9 | uint32_t pretcode; 10 | int sig; 11 | struct sigcontext sc; 12 | struct fpstate fpstate_unused; 13 | uint32_t extramask; 14 | char retcode[8]; 15 | /* fp state follows here */ 16 | }; 17 | 18 | struct rt_sigframe 19 | { 20 | uint32_t pretcode; 21 | int sig; 22 | uint32_t pinfo; 23 | uint32_t puc; 24 | struct siginfo info; 25 | struct ucontext uc; 26 | char retcode[8]; 27 | /* fp state follows here */ 28 | }; 29 | -------------------------------------------------------------------------------- /src/common/signal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define _NSIG 64 6 | #define _NSIG_WORDS (_NSIG / sizeof(unsigned long)) 7 | 8 | typedef uintptr_t old_sigset_t; 9 | typedef uint64_t sigset_t; 10 | 11 | #define sigaddset(set, sig) *(set) |= (1ULL << (sig)) 12 | #define sigdelset(set, sig) *(set) &= ~(1ULL << (sig)) 13 | #define sigemptyset(set) *(set) = 0ULL 14 | #define sigfillset(set) *(set) = (uint64_t)-1 15 | #define sigismember(set, sig) (*(set) & (1ULL << (sig))) 16 | 17 | typedef union sigval 18 | { 19 | int sival_int; 20 | void *sival_ptr; 21 | } sigval_t; 22 | 23 | #define SI_MAX_SIZE 128 24 | #ifdef _WIN64 25 | #define SI_PAD_SIZE ((SI_MAX_SIZE / sizeof(int)) - 4) 26 | #else 27 | #define SI_PAD_SIZE ((SI_MAX_SIZE / sizeof(int)) - 3) 28 | #endif 29 | 30 | #define SI_USER 0 /* sent by kill, sigsend, raise */ 31 | #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ 32 | #define SI_QUEUE -1 /* sent by sigqueue */ 33 | #define SI_TIMER -2 /* sent by timer expiration */ 34 | #define SI_MESGQ -3 /* sent by real time mesq state change */ 35 | #define SI_ASYNCIO -4 /* sent by AIO completion */ 36 | #define SI_SIGIO -5 /* sent by queued SIGIO */ 37 | #define SI_TKILL -6 /* sent by tkill system call */ 38 | #define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */ 39 | 40 | #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) 41 | #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) 42 | 43 | typedef struct siginfo { 44 | int si_signo; /* signal number */ 45 | int si_errno; /* if non-zero, an errno value associated with this signal */ 46 | int si_code; /* signal code */ 47 | 48 | union { 49 | int _pad[SI_PAD_SIZE]; 50 | 51 | /* kill() */ 52 | struct { 53 | pid_t _pid; /* sender's pid */ 54 | uid_t _uid; /* sender's uid */ 55 | } _kill; 56 | 57 | /* POSIX.1b timers */ 58 | struct { 59 | int _tid; /* timer id */ 60 | int _overrun; /* overrun count */ 61 | sigval_t _sigval; /* same as below */ 62 | } _timer; 63 | 64 | /* POSIX.1b signals */ 65 | struct { 66 | pid_t _pid; /* sender's pid */ 67 | uid_t _uid; /* sender's uid */ 68 | sigval_t _sigval; 69 | } _rt; 70 | 71 | /* SIGCHLD */ 72 | struct { 73 | pid_t _pid; /* which child */ 74 | uid_t _uid; /* sender's uid */ 75 | int _status; /* exit code */ 76 | clock_t _utime; 77 | clock_t _stime; 78 | } _sigchld; 79 | 80 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 81 | struct { 82 | void *_addr; /* faulting insn/memory ref. */ 83 | short _addr_lsb; /* LSB of the reported address */ 84 | } _sigfault; 85 | 86 | /* SIGPOLL */ 87 | struct { 88 | intptr_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ 89 | int _fd; 90 | } _sigpoll; 91 | 92 | /* SIGSYS */ 93 | struct { 94 | void *_call_addr; /* calling user insn */ 95 | int _syscall; /* triggering system call number */ 96 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ 97 | } _sigsys; 98 | } _sifields; 99 | } siginfo_t; 100 | 101 | struct sigaction 102 | { 103 | union 104 | { 105 | void (*sa_handler)(int); 106 | void (*sa_sigaction)(int, siginfo_t *, void *); 107 | }; 108 | sigset_t sa_mask; 109 | int sa_flags; 110 | void (*sa_restorer)(); 111 | }; 112 | 113 | #define SIGHUP 1 114 | #define SIGINT 2 115 | #define SIGQUIT 3 116 | #define SIGILL 4 117 | #define SIGTRAP 5 118 | #define SIGABRT 6 119 | #define SIGIOT 6 120 | #define SIGBUS 7 121 | #define SIGFPE 8 122 | #define SIGKILL 9 123 | #define SIGUSR1 10 124 | #define SIGSEGV 11 125 | #define SIGUSR2 12 126 | #define SIGPIPE 13 127 | #define SIGALRM 14 128 | #define SIGTERM 15 129 | #define SIGSTKFLT 16 130 | #define SIGCHLD 17 131 | #define SIGCONT 18 132 | #define SIGSTOP 19 133 | #define SIGTSTP 20 134 | #define SIGTTIN 21 135 | #define SIGTTOU 22 136 | #define SIGURG 23 137 | #define SIGXCPU 24 138 | #define SIGXFSZ 25 139 | #define SIGVTALRM 26 140 | #define SIGPROF 27 141 | #define SIGWINCH 28 142 | #define SIGIO 29 143 | #define SIGPOLL SIGIO 144 | /* 145 | #define SIGLOST 29 146 | */ 147 | #define SIGPWR 30 148 | #define SIGSYS 31 149 | #define SIGUNUSED 31 150 | 151 | #define SIGRTMIN 32 152 | #define SIGRTMAX _NSIG 153 | 154 | #define SA_NOCLDSTOP 0x00000001u 155 | #define SA_NOCLDWAIT 0x00000002u 156 | #define SA_SIGINFO 0x00000004u 157 | #define SA_ONSTACK 0x08000000u 158 | #define SA_RESTART 0x10000000u 159 | #define SA_NODEFER 0x40000000u 160 | #define SA_RESETHAND 0x80000000u 161 | 162 | #define SA_NOMASK SA_NODEFER 163 | #define SA_ONESHOT SA_RESETHAND 164 | 165 | #define SA_RESTORER 0x04000000 166 | 167 | #define SIG_BLOCK 0 168 | #define SIG_UNBLOCK 1 169 | #define SIG_SETMASK 2 170 | 171 | typedef void (*__sighandler_t)(int); 172 | #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ 173 | #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ 174 | #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ 175 | 176 | #define MINSIGSTKSZ 2048 177 | #define SIGSTKSZ 8192 178 | 179 | typedef struct sigaltstack { 180 | void *ss_sp; 181 | int ss_flags; 182 | size_t ss_size; 183 | } stack_t; 184 | -------------------------------------------------------------------------------- /src/common/soundcard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define _SIOC_NONE 0U 4 | #define _SIOC_WRITE 1U 5 | #define _SIOC_READ 2U 6 | 7 | #define _SIOC(dir,type,nr,size) \ 8 | (((dir) << 30) | \ 9 | ((type) << 8) | \ 10 | ((nr) << 0) | \ 11 | ((size) << 16)) 12 | 13 | #define _SIO(type,nr) _SIOC(_SIOC_NONE,(type),(nr),0) 14 | #define _SIOR(type,nr,size) _SIOC(_SIOC_READ,(type),(nr),sizeof(size)) 15 | #define _SIOW(type,nr,size) _STOC(_STOC_WRITE,(type),(nr),sizeof(size)) 16 | #define _SIOWR(type, nr, size) _SIOC(_SIOC_READ|_SIOC_WRITE,(type),(nr),sizeof(size)) 17 | 18 | /******************************************** 19 | * IOCTL commands for /dev/dsp and /dev/audio 20 | */ 21 | 22 | #define SNDCTL_DSP_RESET _SIO('P', 0) 23 | #define SNDCTL_DSP_SYNC _SIO('P', 1) 24 | #define SNDCTL_DSP_SPEED _SIOWR('P', 2, int) 25 | #define SNDCTL_DSP_STEREO _SIOWR('P', 3, int) 26 | #define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int) 27 | #define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT 28 | #define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int) 29 | #define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS 30 | #define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int) 31 | #define SNDCTL_DSP_POST _SIO('P', 8) 32 | #define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int) 33 | #define SNDCTL_DSP_SETFRAGMENT _SIOWR('P', 10, int) 34 | 35 | /* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ 36 | #define SNDCTL_DSP_GETFMTS _SIOR('P', 11, int) /* Returns a mask */ 37 | #define SNDCTL_DSP_SETFMT _SIOWR('P', 5, int) /* Selects ONE fmt*/ 38 | # define AFMT_QUERY 0x00000000 /* Return current fmt */ 39 | # define AFMT_MU_LAW 0x00000001 40 | # define AFMT_A_LAW 0x00000002 41 | # define AFMT_IMA_ADPCM 0x00000004 42 | # define AFMT_U8 0x00000008 43 | # define AFMT_S16_LE 0x00000010 /* Little endian signed 16*/ 44 | # define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */ 45 | # define AFMT_S8 0x00000040 46 | # define AFMT_U16_LE 0x00000080 /* Little endian U16 */ 47 | # define AFMT_U16_BE 0x00000100 /* Big endian U16 */ 48 | # define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ 49 | # define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */ 50 | -------------------------------------------------------------------------------- /src/common/stat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define S_IFMT 0170000 6 | #define S_IFSOCK 0140000 7 | #define S_IFLNK 0120000 8 | #define S_IFREG 0100000 9 | #define S_IFBLK 0060000 10 | #define S_IFDIR 0040000 11 | #define S_IFCHR 0020000 12 | #define S_IFIFO 0010000 13 | #define S_ISUID 0004000 14 | #define S_ISGID 0002000 15 | #define S_ISVTX 0001000 16 | 17 | #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 18 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 19 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 20 | #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 21 | #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 22 | #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 23 | #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) 24 | 25 | #define S_IRWXU 00700 26 | #define S_IRUSR 00400 27 | #define S_IWUSR 00200 28 | #define S_IXUSR 00100 29 | 30 | #define S_IRWXG 00070 31 | #define S_IRGRP 00040 32 | #define S_IWGRP 00020 33 | #define S_IXGRP 00010 34 | 35 | #define S_IRWXO 00007 36 | #define S_IROTH 00004 37 | #define S_IWOTH 00002 38 | #define S_IXOTH 00001 39 | 40 | struct stat 41 | { 42 | uint32_t st_dev; 43 | uint32_t st_ino; 44 | uint16_t st_mode; 45 | uint16_t st_nlink; 46 | uint16_t st_uid; 47 | uint16_t st_gid; 48 | uint32_t st_rdev; 49 | uint32_t st_size; 50 | uint32_t st_blksize; 51 | uint32_t st_blocks; 52 | uint32_t st_atime; 53 | uint32_t st_atime_nsec; 54 | uint32_t st_mtime; 55 | uint32_t st_mtime_nsec; 56 | uint32_t st_ctime; 57 | uint32_t st_ctime_nsec; 58 | uint32_t __unused4; 59 | uint32_t __unused5; 60 | }; 61 | 62 | #define INIT_STRUCT_STAT_PADDING(st) \ 63 | do { \ 64 | st->__unused4 = 0; \ 65 | st->__unused5 = 0; \ 66 | } while (0) 67 | 68 | #pragma pack(push, 4) 69 | struct stat64 70 | { 71 | uint64_t st_dev; 72 | uint32_t __pad1; 73 | uint32_t __st_ino; 74 | uint32_t st_mode; 75 | uint32_t st_nlink; 76 | uint32_t st_uid; 77 | uint32_t st_gid; 78 | uint64_t st_rdev; 79 | uint32_t __pad2; 80 | uint64_t st_size; 81 | uint32_t st_blksize; 82 | uint64_t st_blocks; 83 | uint32_t st_atime; 84 | uint32_t st_atime_nsec; 85 | uint32_t st_mtime; 86 | uint32_t st_mtime_nsec; 87 | uint32_t st_ctime; 88 | uint32_t st_ctime_nsec; 89 | uint64_t st_ino; 90 | }; 91 | #pragma pack(pop) 92 | 93 | #define INIT_STRUCT_STAT64_PADDING(st) \ 94 | do { \ 95 | st->__pad1 = 0; \ 96 | st->__pad2 = 0; \ 97 | } while (0) 98 | 99 | #pragma pack(push, 4) 100 | struct newstat 101 | { 102 | uint64_t st_dev; 103 | uint64_t st_ino; 104 | uint64_t st_nlink; 105 | uint32_t st_mode; 106 | uint32_t st_uid; 107 | uint32_t st_gid; 108 | uint32_t __pad0; 109 | uint64_t st_rdev; 110 | uint64_t st_size; 111 | uint64_t st_blksize; 112 | uint64_t st_blocks; 113 | uint64_t st_atime; 114 | uint64_t st_atime_nsec; 115 | uint64_t st_mtime; 116 | uint64_t st_mtime_nsec; 117 | uint64_t st_ctime; 118 | uint64_t st_ctime_nsec; 119 | uint64_t __unused[3]; 120 | }; 121 | #pragma pack(pop) 122 | 123 | #define INIT_STRUCT_NEWSTAT_PADDING(st) \ 124 | do { \ 125 | st->__pad0 = 0; \ 126 | st->__unused[0] = 0; \ 127 | st->__unused[1] = 0; \ 128 | st->__unused[2] = 0; \ 129 | } while (0) 130 | 131 | #define major(dev) ((unsigned int) ((dev) >> 8)) 132 | #define minor(dev) ((unsigned int) ((dev) & 0xFF)) 133 | #define mkdev(ma, mi) (((ma) << 8) | (mi)) 134 | -------------------------------------------------------------------------------- /src/common/statfs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct { 6 | int val[2]; 7 | } __kernel_fsid_t; 8 | 9 | #pragma pack(push, 4) 10 | struct statfs { 11 | uintptr_t f_type; 12 | uintptr_t f_bsize; 13 | uintptr_t f_blocks; 14 | uintptr_t f_bfree; 15 | uintptr_t f_bavail; 16 | uintptr_t f_files; 17 | uintptr_t f_ffree; 18 | __kernel_fsid_t f_fsid; 19 | uintptr_t f_namelen; 20 | uintptr_t f_frsize; 21 | uintptr_t f_flags; 22 | uintptr_t f_spare[4]; 23 | }; 24 | 25 | struct statfs64 { 26 | uintptr_t f_type; 27 | uintptr_t f_bsize; 28 | uint64_t f_blocks; 29 | uint64_t f_bfree; 30 | uint64_t f_bavail; 31 | uint64_t f_files; 32 | uint64_t f_ffree; 33 | __kernel_fsid_t f_fsid; 34 | uintptr_t f_namelen; 35 | uintptr_t f_frsize; 36 | uintptr_t f_flags; 37 | uintptr_t f_spare[4]; 38 | }; 39 | #pragma pack(pop) 40 | -------------------------------------------------------------------------------- /src/common/sysinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct sysinfo { 4 | intptr_t uptime; /* Seconds since boot */ 5 | unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ 6 | unsigned long totalram; /* Total usable main memory size */ 7 | unsigned long freeram; /* Available memory size */ 8 | unsigned long sharedram; /* Amount of shared memory */ 9 | unsigned long bufferram; /* Memory used by buffers */ 10 | unsigned long totalswap; /* Total swap space size */ 11 | unsigned long freeswap; /* swap space still available */ 12 | unsigned short procs; /* Number of current processes */ 13 | unsigned long totalhigh; /* Total high memory size */ 14 | unsigned long freehigh; /* Available high memory size */ 15 | unsigned int mem_unit; /* Memory unit size in bytes */ 16 | char _f[20 - 2 * sizeof(intptr_t) - sizeof(int)]; /* Padding to 64 bytes */ 17 | }; 18 | -------------------------------------------------------------------------------- /src/common/tcp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* TCP socket options */ 4 | #define LINUX_TCP_NODELAY 1 /* Turn off Nagle's algorithm. */ 5 | #define LINUX_TCP_MAXSEG 2 /* Limit MSS */ 6 | #define LINUX_TCP_CORK 3 /* Never send partially complete segments */ 7 | #define LINUX_TCP_KEEPIDLE 4 /* Start keeplives after this period */ 8 | #define LINUX_TCP_KEEPINTVL 5 /* Interval between keepalives */ 9 | #define LINUX_TCP_KEEPCNT 6 /* Number of keepalives before death */ 10 | #define LINUX_TCP_SYNCNT 7 /* Number of SYN retransmits */ 11 | #define LINUX_TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ 12 | #define LINUX_TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ 13 | #define LINUX_TCP_WINDOW_CLAMP 10 /* Bound advertised window */ 14 | #define LINUX_TCP_INFO 11 /* Information about this connection. */ 15 | #define LINUX_TCP_QUICKACK 12 /* Block/reenable quick acks */ 16 | #define LINUX_TCP_CONGESTION 13 /* Congestion control algorithm */ 17 | #define LINUX_TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ 18 | #define LINUX_TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ 19 | #define LINUX_TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ 20 | #define LINUX_TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ 21 | #define LINUX_TCP_REPAIR 19 /* TCP sock is under repair right now */ 22 | #define LINUX_TCP_REPAIR_QUEUE 20 23 | #define LINUX_TCP_QUEUE_SEQ 21 24 | #define LINUX_TCP_REPAIR_OPTIONS 22 25 | #define LINUX_TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ 26 | #define LINUX_TCP_TIMESTAMP 24 27 | #define LINUX_TCP_NOTSENT_LOWAT 25 /* limit number of unsent bytes in write queue */ 28 | -------------------------------------------------------------------------------- /src/common/termios.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef unsigned char cc_t; 4 | typedef unsigned int speed_t; 5 | typedef unsigned int tcflag_t; 6 | 7 | struct winsize { 8 | unsigned short ws_row; 9 | unsigned short ws_col; 10 | unsigned short ws_xpixel; 11 | unsigned short ws_ypixel; 12 | }; 13 | 14 | #define NCCS 19 15 | struct termios { 16 | tcflag_t c_iflag; /* input mode flags */ 17 | tcflag_t c_oflag; /* output mode flags */ 18 | tcflag_t c_cflag; /* control mode flags */ 19 | tcflag_t c_lflag; /* local mode flags */ 20 | cc_t c_line; /* line discipline */ 21 | cc_t c_cc[NCCS]; /* control characters */ 22 | }; 23 | 24 | /* c_cc characters */ 25 | #define VINTR 0 26 | #define VQUIT 1 27 | #define VERASE 2 28 | #define VKILL 3 29 | #define VEOF 4 30 | #define VTIME 5 31 | #define VMIN 6 32 | #define VSWTC 7 33 | #define VSTART 8 34 | #define VSTOP 9 35 | #define VSUSP 10 36 | #define VEOL 11 37 | #define VREPRINT 12 38 | #define VDISCARD 13 39 | #define VWERASE 14 40 | #define VLNEXT 15 41 | #define VEOL2 16 42 | 43 | /* c_iflag bits */ 44 | #define IGNBRK 0000001 45 | #define BRKINT 0000002 46 | #define IGNPAR 0000004 47 | #define PARMRK 0000010 48 | #define INPCK 0000020 49 | #define ISTRIP 0000040 50 | #define INLCR 0000100 51 | #define IGNCR 0000200 52 | #define ICRNL 0000400 53 | #define IUCLC 0001000 54 | #define IXON 0002000 55 | #define IXANY 0004000 56 | #define IXOFF 0010000 57 | #define IMAXBEL 0020000 58 | #define IUTF8 0040000 59 | 60 | /* c_oflag bits */ 61 | #define OPOST 0000001 62 | #define OLCUC 0000002 63 | #define ONLCR 0000004 64 | #define OCRNL 0000010 65 | #define ONOCR 0000020 66 | #define ONLRET 0000040 67 | #define OFILL 0000100 68 | #define OFDEL 0000200 69 | #define NLDLY 0000400 70 | #define NL0 0000000 71 | #define NL1 0000400 72 | #define CRDLY 0003000 73 | #define CR0 0000000 74 | #define CR1 0001000 75 | #define CR2 0002000 76 | #define CR3 0003000 77 | #define TABDLY 0014000 78 | #define TAB0 0000000 79 | #define TAB1 0004000 80 | #define TAB2 0010000 81 | #define TAB3 0014000 82 | #define XTABS 0014000 83 | #define BSDLY 0020000 84 | #define BS0 0000000 85 | #define BS1 0020000 86 | #define VTDLY 0040000 87 | #define VT0 0000000 88 | #define VT1 0040000 89 | #define FFDLY 0100000 90 | #define FF0 0000000 91 | #define FF1 0100000 92 | 93 | /* c_cflag bit meaning */ 94 | #define CBAUD 0010017 95 | #define B0 0000000 /* hang up */ 96 | #define B50 0000001 97 | #define B75 0000002 98 | #define B110 0000003 99 | #define B134 0000004 100 | #define B150 0000005 101 | #define B200 0000006 102 | #define B300 0000007 103 | #define B600 0000010 104 | #define B1200 0000011 105 | #define B1800 0000012 106 | #define B2400 0000013 107 | #define B4800 0000014 108 | #define B9600 0000015 109 | #define B19200 0000016 110 | #define B38400 0000017 111 | #define EXTA B19200 112 | #define EXTB B38400 113 | #define CSIZE 0000060 114 | #define CS5 0000000 115 | #define CS6 0000020 116 | #define CS7 0000040 117 | #define CS8 0000060 118 | #define CSTOPB 0000100 119 | #define CREAD 0000200 120 | #define PARENB 0000400 121 | #define PARODD 0001000 122 | #define HUPCL 0002000 123 | #define CLOCAL 0004000 124 | #define CBAUDEX 0010000 125 | #define BOTHER 0010000 126 | #define B57600 0010001 127 | #define B115200 0010002 128 | #define B230400 0010003 129 | #define B460800 0010004 130 | #define B500000 0010005 131 | #define B576000 0010006 132 | #define B921600 0010007 133 | #define B1000000 0010010 134 | #define B1152000 0010011 135 | #define B1500000 0010012 136 | #define B2000000 0010013 137 | #define B2500000 0010014 138 | #define B3000000 0010015 139 | #define B3500000 0010016 140 | #define B4000000 0010017 141 | #define CIBAUD 002003600000 /* input baud rate */ 142 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ 143 | #define CRTSCTS 020000000000 /* flow control */ 144 | 145 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ 146 | 147 | /* c_lflag bits */ 148 | #define ISIG 0000001 149 | #define ICANON 0000002 150 | #define XCASE 0000004 151 | #define ECHO 0000010 152 | #define ECHOE 0000020 153 | #define ECHOK 0000040 154 | #define ECHONL 0000100 155 | #define NOFLSH 0000200 156 | #define TOSTOP 0000400 157 | #define ECHOCTL 0001000 158 | #define ECHOPRT 0002000 159 | #define ECHOKE 0004000 160 | #define FLUSHO 0010000 161 | #define PENDIN 0040000 162 | #define IEXTEN 0100000 163 | #define EXTPROC 0200000 164 | 165 | /* tcflow() and TCXONC use these */ 166 | #define TCOOFF 0 167 | #define TCOON 1 168 | #define TCIOFF 2 169 | #define TCION 3 170 | 171 | /* tcflush() and TCFLSH use these */ 172 | #define TCIFLUSH 0 173 | #define TCOFLUSH 1 174 | #define TCIOFLUSH 2 175 | 176 | /* tcsetattr uses these */ 177 | #define TCSANOW 0 178 | #define TCSADRAIN 1 179 | #define TCSAFLUSH 2 180 | -------------------------------------------------------------------------------- /src/common/time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct timespec 4 | { 5 | long tv_sec; 6 | long tv_nsec; 7 | }; 8 | 9 | struct linux_timeval 10 | { 11 | long tv_sec; /* seconds */ 12 | long tv_usec; /* and microseconds */ 13 | }; 14 | 15 | struct timezone 16 | { 17 | int tz_minuteswest; /* minutes west of Greenwich */ 18 | int tz_dsttime; /* type of DST correction */ 19 | }; 20 | 21 | #define ITIMER_REAL 0 22 | #define ITIMER_VIRTUAL 1 23 | #define ITIMER_PROF 2 24 | 25 | struct itimerval 26 | { 27 | struct linux_timeval it_interval; /* timer interval */ 28 | struct linux_timeval it_value; /* current value */ 29 | }; 30 | 31 | typedef int clockid_t; 32 | typedef int timer_t; 33 | 34 | #define CLOCK_REALTIME 0 35 | #define CLOCK_MONOTONIC 1 36 | #define CLOCK_PROCESS_CPUTIME_ID 2 37 | #define CLOCK_THREAD_CPUTIME_ID 3 38 | #define CLOCK_MONOTONIC_RAW 4 39 | #define CLOCK_REALTIME_COARSE 5 40 | #define CLOCK_MONOTONIC_COARSE 6 41 | #define CLOCK_BOOTTIME 7 42 | #define CLOCK_REALTIME_ALARM 8 43 | #define CLOCK_BOOTTIME_ALARM 9 44 | #define CLOCK_SGI_CYCLE 10 /* Hardware specific */ 45 | #define CLOCK_TAI 11 46 | 47 | #define MAX_CLOCKS 16 48 | #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) 49 | #define CLOCKS_MONO CLOCK_MONOTONIC 50 | -------------------------------------------------------------------------------- /src/common/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef intptr_t off_t; 6 | typedef int64_t loff_t; 7 | typedef uintptr_t clock_t; 8 | typedef int pid_t; 9 | typedef unsigned int uid_t; 10 | typedef unsigned int gid_t; 11 | typedef intptr_t ssize_t; 12 | -------------------------------------------------------------------------------- /src/common/uio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct iovec 4 | { 5 | void *iov_base; /* Starting address */ 6 | size_t iov_len; /* Number of bytes to transfer */ 7 | }; 8 | -------------------------------------------------------------------------------- /src/common/utime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct utimbuf 4 | { 5 | long actime; 6 | long modtime; 7 | }; 8 | 9 | #define WIN32_LEAN_AND_MEAN 10 | #include 11 | /* Defined in WinSock2.h 12 | struct timeval 13 | { 14 | long tv_sec; 15 | long tv_usec; 16 | }; 17 | */ 18 | -------------------------------------------------------------------------------- /src/common/utsname.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __OLD_UTS_LEN 8 4 | #define __NEW_UTS_LEN 64 5 | 6 | struct oldold_utsname 7 | { 8 | char sysname[9]; 9 | char nodename[9]; 10 | char release[9]; 11 | char version[9]; 12 | char machine[9]; 13 | }; 14 | 15 | struct old_utsname 16 | { 17 | char sysname[65]; 18 | char nodename[65]; 19 | char release[65]; 20 | char version[65]; 21 | char machine[65]; 22 | }; 23 | 24 | struct utsname 25 | { 26 | char sysname[65]; 27 | char nodename[65]; 28 | char release[65]; 29 | char version[65]; 30 | char machine[65]; 31 | char domainname[65]; 32 | }; 33 | -------------------------------------------------------------------------------- /src/common/wait.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Options for wait() */ 4 | #define WNOHANG 0x00000001 5 | #define WUNTRACED 0x00000002 6 | #define WSTOPPED WUNTRACED 7 | #define WEXITED 0x00000004 8 | #define WCONTINUED 0x00000008 9 | #define WNOWAIT 0x01000000 /* Don't reap, just poll status. */ 10 | 11 | 12 | /* Status code returned by wait() */ 13 | /* Macros for constructing status values. */ 14 | #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) 15 | #define W_STOPCODE(sig) ((sig) << 8 | 0x7f) 16 | #define W_CONTINUED 0xffff 17 | #define WCOREFLAG 0x80 18 | 19 | /* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ 20 | #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) 21 | 22 | /* If WIFSIGNALED(STATUS), the terminating signal. */ 23 | #define WTERMSIG(status) ((status) & 0x7f) 24 | 25 | /* If WIFSTOPPED(STATUS), the signal that stopped the child. */ 26 | #define WSTOPSIG(status) WEXITSTATUS(status) 27 | 28 | /* Nonzero if STATUS indicates normal termination. */ 29 | #define WIFEXITED(status) (WTERMSIG(status) == 0) 30 | 31 | /* Nonzero if STATUS indicates termination by a signal. */ 32 | #define WIFSIGNALED(status) (((signed char) (((status) & 0x7f) + 1) >> 1) > 0) 33 | 34 | /* Nonzero if STATUS indicates the child is stopped. */ 35 | #define WIFSTOPPED(status) (((status) & 0xff) == 0x7f) 36 | 37 | /* Nonzero if STATUS indicates the child continued after a stop. */ 38 | #define WIFCONTINUED(status) ((status) == W_CONTINUED) 39 | 40 | /* Nonzero if STATUS indicates the child dumped core. */ 41 | #define WCOREDUMP(status) ((status) & WCOREFLAG 42 | -------------------------------------------------------------------------------- /src/datetime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | #define SEC_TO_UNIX_EPOCH 11644473600ULL 23 | #define TICKS_TO_UNIX_EPOCH (TICKS_PER_SECOND * SEC_TO_UNIX_EPOCH) 24 | 25 | static uint64_t filetime_to_unix(const FILETIME *filetime) 26 | { 27 | uint64_t ticks = ((uint64_t)filetime->dwHighDateTime << 32ULL) + filetime->dwLowDateTime; 28 | if (ticks < TICKS_TO_UNIX_EPOCH) /* Out of range */ 29 | return -1; 30 | ticks -= TICKS_TO_UNIX_EPOCH; 31 | return ticks * NANOSECONDS_PER_TICK; 32 | } 33 | 34 | uint64_t filetime_to_unix_sec(const FILETIME *filetime) 35 | { 36 | uint64_t nsec = filetime_to_unix(filetime); 37 | if (nsec == -1) 38 | return -1; 39 | return nsec / NANOSECONDS_PER_SECOND; 40 | } 41 | 42 | uint64_t filetime_to_unix_nsec(const FILETIME *filetime) 43 | { 44 | uint64_t nsec = filetime_to_unix(filetime); 45 | if (nsec == -1) 46 | return -1; 47 | return nsec % NANOSECONDS_PER_SECOND; 48 | } 49 | 50 | void filetime_to_unix_timeval(const FILETIME *filetime, struct timeval *tv) 51 | { 52 | uint64_t nsec = filetime_to_unix(filetime); 53 | /* TODO: Handle overflow? */ 54 | tv->tv_sec = nsec / NANOSECONDS_PER_SECOND; 55 | tv->tv_usec = (nsec % NANOSECONDS_PER_SECOND) / 1000; 56 | } 57 | 58 | void filetime_to_unix_timespec(const FILETIME *filetime, struct timespec *tv) 59 | { 60 | uint64_t nsec = filetime_to_unix(filetime); 61 | /* TODO: Handle overflow? */ 62 | tv->tv_sec = nsec / NANOSECONDS_PER_SECOND; 63 | tv->tv_nsec = nsec % NANOSECONDS_PER_SECOND; 64 | } 65 | 66 | static void unix_time_to_filetime(uint64_t nsec, FILETIME *filetime) 67 | { 68 | uint64_t ticks = nsec / NANOSECONDS_PER_TICK + TICKS_TO_UNIX_EPOCH; 69 | filetime->dwLowDateTime = (DWORD)(ticks % 0x100000000ULL); 70 | filetime->dwHighDateTime = (DWORD)(ticks / 0x100000000ULL); 71 | } 72 | 73 | void unix_timeval_to_filetime(const struct timeval *time, FILETIME *filetime) 74 | { 75 | unix_time_to_filetime((uint64_t)time->tv_sec * NANOSECONDS_PER_SECOND + (uint64_t)time->tv_usec * 1000ULL, filetime); 76 | } 77 | 78 | void unix_timespec_to_filetime(const struct timespec *time, FILETIME *filetime) 79 | { 80 | unix_time_to_filetime((uint64_t)time->tv_sec * NANOSECONDS_PER_SECOND + (uint64_t)time->tv_nsec, filetime); 81 | } 82 | 83 | void unix_timeval_to_unix_timespec(const struct timeval *timeval, struct timespec *timespec) 84 | { 85 | timespec->tv_sec = timeval->tv_sec; 86 | timespec->tv_nsec = timeval->tv_usec * 1000; 87 | } 88 | -------------------------------------------------------------------------------- /src/datetime.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #define NANOSECONDS_PER_TICK 100ULL 28 | #define NANOSECONDS_PER_SECOND 1000000000ULL 29 | #define TICKS_PER_SECOND 10000000ULL 30 | 31 | uint64_t filetime_to_unix_sec(const FILETIME *filetime); 32 | uint64_t filetime_to_unix_nsec(const FILETIME *filetime); 33 | void filetime_to_unix_timeval(const FILETIME *filetime, struct timeval *tv); 34 | void filetime_to_unix_timespec(const FILETIME *filetime, struct timespec *tv); 35 | void unix_timeval_to_filetime(const struct timeval *time, FILETIME *filetime); 36 | void unix_timespec_to_filetime(const struct timespec *time, FILETIME *filetime); 37 | void unix_timeval_to_unix_timespec(const struct timeval *timeval, struct timespec *timespec); 38 | -------------------------------------------------------------------------------- /src/dbt/cpuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | struct cpuid_t 26 | { 27 | uint32_t eax; 28 | uint32_t ebx; 29 | uint32_t ecx; 30 | uint32_t edx; 31 | }; 32 | 33 | /* Singature used in dbt trampoline */ 34 | void dbt_cpuid(int eax, int ecx, struct cpuid_t *cpuid); 35 | int dbt_get_cpuinfo(char *buf); 36 | -------------------------------------------------------------------------------- /src/dbt/x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #define WIN32_LEAN_AND_MEAN 27 | #include 28 | 29 | struct syscall_context 30 | { 31 | /* DO NOT REORDER */ 32 | /* Context for fork() */ 33 | DWORD ebx; 34 | DWORD ecx; 35 | DWORD edx; 36 | DWORD esi; 37 | DWORD edi; 38 | DWORD ebp; 39 | DWORD esp; 40 | DWORD eip; 41 | 42 | /* The following are not used by fork() */ 43 | DWORD eax; 44 | DWORD eflags; 45 | }; 46 | 47 | void dbt_init_thread(); 48 | void dbt_init(); 49 | void dbt_reset(); 50 | void dbt_shutdown(); 51 | 52 | void __declspec(noreturn) dbt_run(size_t pc, size_t sp); 53 | void __declspec(noreturn) dbt_restore_fork_context(struct syscall_context *context); 54 | 55 | /* Get current GS register value */ 56 | int dbt_get_gs(); 57 | 58 | /* Reload TLS information at thread entry */ 59 | void dbt_update_tls(int gs); 60 | 61 | /* Called when an executable code region changes, determines whether we need to flush code cache */ 62 | void dbt_code_changed(size_t pc, size_t len); 63 | 64 | /* Deliver the signal to the main thread's context 65 | * This function can only called from the signal thread */ 66 | void dbt_deliver_signal(HANDLE thread, CONTEXT *context); 67 | 68 | /* Return from signal */ 69 | void __declspec(noreturn) dbt_sigreturn(struct sigcontext *context); 70 | -------------------------------------------------------------------------------- /src/dbt/x86_inst.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | int get_imm_bytes(uint8_t op, bool opsize_prefix_present, bool addrsize_prefix_present) 23 | { 24 | if (op == IMM8 || op == REL8) 25 | return 1; 26 | else if (op == IMM16) 27 | return 2; 28 | else if (op == IMM16_32 || op == REL16_32 || op == IMM16_32_64) 29 | return opsize_prefix_present ? 2 : 4; 30 | else if (op == MOFFS8 || op == MOFFS16_32_64) 31 | return addrsize_prefix_present ? 2 : 4; 32 | else 33 | return 0; 34 | } 35 | 36 | /* Keep in sync with implicit register / memory definitions in x86_inst.h */ 37 | const uint8_t implicit_register_usage[16] = 38 | { 39 | /* __ */ 0, 40 | /* AL */ REG_AX, 41 | /* AH */ REG_AX, 42 | /* AX_EAX */ REG_AX, 43 | /* AX_EAX_RAX */ REG_AX, 44 | /* CL */ REG_CX, 45 | /* DX */ REG_DX, 46 | /* Undefined */ 0, 47 | /* Undefined */ 0, 48 | /* Undefined */ 0, 49 | /* SI_M8 */ REG_SI, 50 | /* SI_M16_32 */ REG_SI, 51 | /* SI_M16_32_64 */ REG_SI, 52 | /* DI_M8 */ REG_DI, 53 | /* DI_M16_32 */ REG_DI, 54 | /* DI_M16_32_64 */ REG_DI, 55 | }; 56 | 57 | uint8_t get_implicit_register_usage(uint8_t op, uint8_t opcode) 58 | { 59 | if (!FROM_MODRM(op)) 60 | { 61 | if (op < 16) 62 | return implicit_register_usage[op]; 63 | else /* OP_Rxx */ 64 | return REG_MASK(op & 8); 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /src/dbt/x86_trampoline.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; This file is part of Foreign Linux. 3 | ; 4 | ; Copyright (C) 2014, 2015 Xiangyan Sun 5 | ; 6 | ; This program is free software: you can redistribute it and/or modify 7 | ; it under the terms of the GNU General Public License as published by 8 | ; the Free Software Foundation, either version 3 of the License, or 9 | ; (at your option) any later version. 10 | ; 11 | ; This program is distributed in the hope that it will be useful, 12 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ; GNU General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU General Public License 17 | ; along with this program. If not, see . 18 | ; 19 | 20 | .MODEL FLAT, C 21 | .CODE 22 | 23 | EXTERN dbt_return_trampoline:NEAR 24 | OPTION PROLOGUE: NONE 25 | OPTION EPILOGUE: NONE 26 | EXTERN dbt_find_direct:NEAR 27 | dbt_find_direct_internal PROC ; pc, patch_addr 28 | ; save context 29 | push eax 30 | push ecx 31 | push edx 32 | pushfd 33 | ; copy pc and patch_addr 34 | mov ecx, [esp+20] 35 | mov edx, [esp+16] 36 | push ecx 37 | push edx 38 | call dbt_find_direct 39 | lea esp, [esp+8] 40 | ; restore context 41 | popfd 42 | pop edx 43 | pop ecx 44 | pop eax 45 | lea esp, [esp+8] ; we have two extra argument garbage at the stack 46 | jmp dword ptr [dbt_return_trampoline] 47 | dbt_find_direct_internal ENDP 48 | 49 | EXTERN dbt_find_next:NEAR 50 | dbt_find_indirect_internal PROC 51 | ; save context 52 | push eax 53 | push ecx 54 | push edx 55 | pushfd 56 | mov ecx, [esp+16] ; original address 57 | push ecx 58 | call dbt_find_next 59 | lea esp, [esp+4] 60 | ; restore context 61 | popfd 62 | pop edx 63 | pop ecx 64 | pop eax 65 | lea esp, [esp+4] 66 | jmp dword ptr [dbt_return_trampoline] 67 | dbt_find_indirect_internal ENDP 68 | 69 | EXTERN dbt_find_next_sieve:NEAR 70 | dbt_sieve_fallback PROC 71 | ; stack: address 72 | ; stack: ecx 73 | push eax 74 | push edx 75 | pushfd 76 | mov ecx, [esp+4*4] ; original address 77 | push ecx 78 | call dbt_find_next_sieve 79 | lea esp, [esp+4] 80 | ; restore context 81 | popfd 82 | pop edx 83 | pop eax 84 | pop ecx 85 | lea esp, [esp+4] 86 | jmp dword ptr [dbt_return_trampoline] 87 | dbt_sieve_fallback ENDP 88 | 89 | ; TODO: Return through return trampoline 90 | EXTERN dbt_cpuid:NEAR 91 | dbt_cpuid_internal PROC 92 | ; Allocate buffer 93 | lea esp, [esp-4*4] 94 | ; Push arguments 95 | push esp 96 | push ecx 97 | push eax 98 | call dbt_cpuid 99 | mov eax, [esp+4*3 + 0] 100 | mov ebx, [esp+4*3 + 4] 101 | mov ecx, [esp+4*3 + 8] 102 | mov edx, [esp+4*3 + 12] 103 | lea esp, [esp+4*7] 104 | ret 105 | dbt_cpuid_internal ENDP 106 | 107 | EXTERN sys_unimplemented_imp:NEAR 108 | sys_unimplemented PROC 109 | push eax 110 | call sys_unimplemented_imp 111 | lea esp, [esp+4] 112 | jmp syscall_done 113 | sys_unimplemented ENDP 114 | 115 | EXTERN sys_fork_imp: NEAR 116 | sys_fork PROC 117 | ; inject context pointer as the first argument 118 | lea eax, [esp + 4] 119 | mov [esp], eax 120 | call sys_fork_imp 121 | lea esp, [esp+4] 122 | jmp syscall_done 123 | sys_fork ENDP 124 | 125 | EXTERN sys_vfork_imp: NEAR 126 | sys_vfork PROC 127 | ; inject context pointer as the first argument 128 | lea eax, [esp + 4] 129 | mov [esp], eax 130 | call sys_vfork_imp 131 | lea esp, [esp+4] 132 | jmp syscall_done 133 | sys_vfork ENDP 134 | 135 | EXTERN sys_clone_imp: NEAR 136 | sys_clone PROC 137 | ; inject context pointer as the first argument 138 | lea eax, [esp + 4] 139 | mov [esp], eax 140 | call sys_clone_imp 141 | lea esp, [esp+4] 142 | jmp syscall_done 143 | sys_clone ENDP 144 | 145 | EXTERN syscall_table: DWORD 146 | syscall_handler PROC 147 | ; save context 148 | push ecx 149 | push edx 150 | ; test validity 151 | cmp eax, 359 152 | jae out_of_range 153 | 154 | ; push esp and eip context in case of fork() 155 | push [esp + 8] 156 | lea edx, [esp + 16] 157 | push edx 158 | mov edx, [esp + 8] 159 | ; push arguments 160 | push ebp 161 | push edi 162 | push esi 163 | push edx 164 | push ecx 165 | push ebx 166 | ; call syscall 167 | call [syscall_table + eax * 4] 168 | syscall_done:: 169 | lea esp, [esp + 32] 170 | ; restore context 171 | pop edx 172 | pop ecx 173 | jmp dbt_find_indirect_internal 174 | 175 | out_of_range: 176 | call sys_unimplemented 177 | pop edx 178 | pop ecx 179 | jmp dbt_find_indirect_internal 180 | syscall_handler ENDP 181 | 182 | END 183 | -------------------------------------------------------------------------------- /src/flags.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | struct _flags *cmdline_flags; 24 | 25 | void flags_init() 26 | { 27 | cmdline_flags = (struct _flags *)mm_static_alloc(sizeof(struct _flags)); 28 | strcpy(cmdline_flags->global_session_id, DEFAULT_SESSION_ID); 29 | } 30 | 31 | void flags_afterfork_parent() 32 | { 33 | } 34 | 35 | void flags_afterfork_child() 36 | { 37 | cmdline_flags = (struct _flags *)mm_static_alloc(sizeof(struct _flags)); 38 | } 39 | -------------------------------------------------------------------------------- /src/flags.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define MAX_SESSION_ID_LEN 8 25 | #define DEFAULT_SESSION_ID "default" 26 | 27 | struct _flags 28 | { 29 | char global_session_id[MAX_SESSION_ID_LEN]; 30 | /* DBT flags */ 31 | bool dbt_trace; 32 | bool dbt_trace_all; 33 | }; 34 | 35 | extern struct _flags *cmdline_flags; 36 | 37 | void flags_init(); 38 | void flags_afterfork_parent(); 39 | void flags_afterfork_child(); 40 | -------------------------------------------------------------------------------- /src/fs/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #define WIN32_LEAN_AND_MEAN 26 | #include 27 | 28 | void console_init(); 29 | int console_fork(HANDLE process); 30 | void console_afterfork(); 31 | 32 | struct virtualfs_custom_desc console_desc; 33 | size_t console_read(void *buf, size_t count); 34 | size_t console_write(const void *buf, size_t count); 35 | struct file *console_alloc(); 36 | -------------------------------------------------------------------------------- /src/fs/devfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | static const struct virtualfs_directory_desc devfs = 29 | { 30 | .type = VIRTUALFS_TYPE_DIRECTORY, 31 | .entries = { 32 | VIRTUALFS_ENTRY("dsp", dsp_desc) 33 | VIRTUALFS_ENTRY("null", null_desc) 34 | VIRTUALFS_ENTRY("zero", zero_desc) 35 | VIRTUALFS_ENTRY("random", random_desc) 36 | VIRTUALFS_ENTRY("urandom", urandom_desc) 37 | VIRTUALFS_ENTRY("console", console_desc) 38 | VIRTUALFS_ENTRY("tty", console_desc) 39 | VIRTUALFS_ENTRY_END() 40 | } 41 | }; 42 | 43 | struct file_system *devfs_alloc() 44 | { 45 | return virtualfs_alloc("/dev", &devfs); 46 | } 47 | -------------------------------------------------------------------------------- /src/fs/devfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct file_system *devfs_alloc(); 25 | -------------------------------------------------------------------------------- /src/fs/dsp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct virtualfs_custom_desc dsp_desc; 25 | -------------------------------------------------------------------------------- /src/fs/epollfd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #define MAX_EPOLLFD_COUNT 128 29 | 30 | struct epoll_fd 31 | { 32 | int fd; 33 | struct epoll_event event; 34 | }; 35 | 36 | struct epollfd_file 37 | { 38 | struct file base_file; 39 | int fd_count; 40 | struct epoll_fd fds[MAX_EPOLLFD_COUNT]; 41 | }; 42 | 43 | static int epollfd_close(struct file *f) 44 | { 45 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 46 | kfree(epollfd, sizeof(struct epollfd_file)); 47 | return 0; 48 | } 49 | 50 | int epollfd_ctl_add(struct file *f, int fd, struct epoll_event *event) 51 | { 52 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 53 | AcquireSRWLockExclusive(&epollfd->base_file.rw_lock); 54 | int r = 0; 55 | /* Ensure the monitoring file is not registered before */ 56 | for (int i = 0; i < epollfd->fd_count; i++) 57 | if (epollfd->fds[i].fd == fd) 58 | { 59 | r = -L_EEXIST; 60 | goto out; 61 | } 62 | /* Add the file */ 63 | epollfd->fds[epollfd->fd_count].fd = fd; 64 | epollfd->fds[epollfd->fd_count].event = *event; 65 | epollfd->fd_count++; 66 | out: 67 | ReleaseSRWLockExclusive(&epollfd->base_file.rw_lock); 68 | return r; 69 | } 70 | 71 | int epollfd_ctl_del(struct file *f, int fd) 72 | { 73 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 74 | AcquireSRWLockExclusive(&epollfd->base_file.rw_lock); 75 | int r = 0; 76 | /* Find and delete the monitoring file */ 77 | for (int i = 0; i < epollfd->fd_count; i++) 78 | if (epollfd->fds[i].fd == fd) 79 | { 80 | for (int j = i; j + 1 < epollfd->fd_count; j++) 81 | epollfd->fds[j] = epollfd->fds[j + 1]; 82 | epollfd->fd_count--; 83 | goto out; 84 | } 85 | r = -L_ENOENT; 86 | out: 87 | ReleaseSRWLockExclusive(&epollfd->base_file.rw_lock); 88 | return r; 89 | } 90 | 91 | int epollfd_ctl_mod(struct file *f, int fd, struct epoll_event *event) 92 | { 93 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 94 | AcquireSRWLockExclusive(&epollfd->base_file.rw_lock); 95 | int r = 0; 96 | /* Find and modify the monitoring file */ 97 | for (int i = 0; i < epollfd->fd_count; i++) 98 | if (epollfd->fds[i].fd == fd) 99 | { 100 | epollfd->fds[i].event = *event; 101 | goto out; 102 | } 103 | r = -L_ENOENT; 104 | out: 105 | ReleaseSRWLockExclusive(&epollfd->base_file.rw_lock); 106 | return r; 107 | } 108 | 109 | static const struct file_ops epollfd_ops = { 110 | .close = epollfd_close, 111 | }; 112 | 113 | int epollfd_alloc(struct file **f) 114 | { 115 | struct epollfd_file *epollfd = (struct epollfd_file *)kmalloc(sizeof(struct epollfd_file)); 116 | file_init(&epollfd->base_file, &epollfd_ops, 0); 117 | epollfd->fd_count = 0; 118 | *f = (struct file *)epollfd; 119 | return 0; 120 | } 121 | 122 | bool epollfd_is_epollfd(struct file *f) 123 | { 124 | return f->op_vtable == &epollfd_ops; 125 | } 126 | 127 | int epollfd_get_nfds(struct file *f) 128 | { 129 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 130 | return epollfd->fd_count; 131 | } 132 | 133 | void epollfd_to_pollfds(struct file *f, struct linux_pollfd *fds) 134 | { 135 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 136 | for (int i = 0; i < epollfd->fd_count; i++) 137 | { 138 | fds[i].fd = epollfd->fds[i].fd; 139 | fds[i].events = epollfd->fds[i].event.events & (POLLIN | POLLOUT | POLLERR); 140 | fds[i].revents = 0; 141 | } 142 | } 143 | 144 | int epollfd_to_events(struct file *f, const struct linux_pollfd *fds, struct epoll_event *events, int maxevents) 145 | { 146 | struct epollfd_file *epollfd = (struct epollfd_file *)f; 147 | int r = 0; 148 | for (int i = 0; i < epollfd->fd_count; i++) 149 | { 150 | if (r >= maxevents) 151 | return r; 152 | if (fds[i].revents) 153 | { 154 | events[r].events = fds[i].revents; 155 | events[r].data = epollfd->fds[i].event.data; 156 | r++; 157 | } 158 | } 159 | return r; 160 | } 161 | -------------------------------------------------------------------------------- /src/fs/epollfd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | int epollfd_alloc(struct file **epollfd); 28 | bool epollfd_is_epollfd(struct file *f); 29 | 30 | int epollfd_ctl_add(struct file *f, int fd, struct epoll_event *event); 31 | int epollfd_ctl_del(struct file *f, int fd); 32 | int epollfd_ctl_mod(struct file *f, int fd, struct epoll_event *event); 33 | int epollfd_get_nfds(struct file *f); 34 | void epollfd_to_pollfds(struct file *f, struct linux_pollfd *fds); 35 | int epollfd_to_events(struct file *f, const struct linux_pollfd *fds, struct epoll_event *events, int maxevents); 36 | -------------------------------------------------------------------------------- /src/fs/eventfd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | int eventfd_alloc(struct file **eventfd, uint64_t count, int flags); 25 | -------------------------------------------------------------------------------- /src/fs/inotify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | struct inotify_file 29 | { 30 | struct file base_file; 31 | }; 32 | 33 | static int inotify_close(struct file *f) 34 | { 35 | struct inotify_file *inotify = (struct inotify_file *)f; 36 | kfree(inotify, sizeof(struct inotify_file)); 37 | return 0; 38 | } 39 | 40 | static int inotify_get_poll_status(struct file *f) 41 | { 42 | return 0; 43 | } 44 | 45 | static int inotify_stat(struct file *f, struct newstat *buf) 46 | { 47 | struct inotify_file *inotify = (struct inotify_file *)f; 48 | INIT_STRUCT_NEWSTAT_PADDING(buf); 49 | buf->st_dev = 0; 50 | buf->st_ino = 0; 51 | buf->st_mode = S_IFCHR + 0644; 52 | buf->st_nlink = 1; 53 | buf->st_uid = 0; 54 | buf->st_gid = 0; 55 | buf->st_rdev = 0; 56 | buf->st_size = 0; 57 | buf->st_blksize = PAGE_SIZE; 58 | buf->st_blocks = 0; 59 | buf->st_atime = 0; 60 | buf->st_atime_nsec = 0; 61 | buf->st_mtime = 0; 62 | buf->st_mtime_nsec = 0; 63 | buf->st_ctime = 0; 64 | buf->st_ctime_nsec = 0; 65 | return 0; 66 | } 67 | 68 | static struct file_ops inotify_ops = 69 | { 70 | .get_poll_status = inotify_get_poll_status, 71 | .close = inotify_close, 72 | .stat = inotify_stat, 73 | }; 74 | 75 | static int inotify_init1(int flags) 76 | { 77 | struct inotify_file *inotify = (struct inotify_file *)kmalloc(sizeof(struct inotify_file)); 78 | int fl = 0; 79 | if (flags & IN_NONBLOCK) 80 | fl |= O_NONBLOCK; 81 | file_init(&inotify->base_file, &inotify_ops, fl); 82 | int fd = vfs_store_file((struct file *)inotify, flags & IN_CLOEXEC); 83 | if (fd < 0) 84 | vfs_release((struct file *)inotify); 85 | return fd; 86 | } 87 | 88 | DEFINE_SYSCALL(inotify_init) 89 | { 90 | log_info("inotify_init()"); 91 | return inotify_init1(0); 92 | } 93 | 94 | DEFINE_SYSCALL(inotify_init1, int, flags) 95 | { 96 | log_info("inotify_init1(%d)", flags); 97 | return inotify_init1(flags); 98 | } 99 | 100 | DEFINE_SYSCALL(inotify_add_watch, int, fd, const char *, pathname, uint32_t, mask) 101 | { 102 | log_info("inotify_add_watch(%d, \"%s\", %x)", fd, pathname, mask); 103 | return 0; 104 | } 105 | 106 | DEFINE_SYSCALL(inotify_rm_watch, int, fd, int, wd) 107 | { 108 | log_info("inotify_rm_watch(%d, %d)", fd, wd); 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /src/fs/inotify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | -------------------------------------------------------------------------------- /src/fs/null.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | static size_t null_read(int tag, void *buf, size_t count) 23 | { 24 | return 0; 25 | } 26 | 27 | static size_t null_write(int tag, const void *buf, size_t count) 28 | { 29 | return count; 30 | } 31 | 32 | struct virtualfs_char_desc null_desc = VIRTUALFS_CHAR(mkdev(1, 3), null_read, null_write); 33 | -------------------------------------------------------------------------------- /src/fs/null.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct virtualfs_char_desc null_desc; 25 | -------------------------------------------------------------------------------- /src/fs/pipe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | int pipe_alloc(struct file **fread, struct file **fwrite, int flags); 25 | -------------------------------------------------------------------------------- /src/fs/procfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct file_system *procfs_alloc(); 25 | -------------------------------------------------------------------------------- /src/fs/random.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define SystemFunction036 NTAPI SystemFunction036 27 | #include 28 | #undef SystemFunction036 29 | 30 | DEFINE_SYSCALL(getrandom, void *, buf, size_t, buflen, unsigned int, flags) 31 | { 32 | log_info("getrandom(%p, %d, %x)", buf, buflen, flags); 33 | if (!mm_check_write(buf, buflen)) 34 | return -L_EFAULT; 35 | if (!RtlGenRandom(buf, buflen)) 36 | return 0; 37 | return buflen; 38 | } 39 | 40 | static size_t random_read(int tag, void *buf, size_t count) 41 | { 42 | if (!RtlGenRandom(buf, count)) 43 | return 0; 44 | return count; 45 | } 46 | 47 | static size_t random_write(int tag, const void *buf, size_t count) 48 | { 49 | return count; 50 | } 51 | 52 | struct virtualfs_char_desc random_desc = VIRTUALFS_CHAR(mkdev(1, 8), random_read, random_write); 53 | struct virtualfs_char_desc urandom_desc = VIRTUALFS_CHAR(mkdev(1, 9), random_read, random_write); 54 | -------------------------------------------------------------------------------- /src/fs/random.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct virtualfs_char_desc random_desc; 25 | struct virtualfs_char_desc urandom_desc; 26 | -------------------------------------------------------------------------------- /src/fs/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | void socket_init(); 23 | -------------------------------------------------------------------------------- /src/fs/sysfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define WIN32_LEAN_AND_MEAN 25 | #include 26 | 27 | static const struct virtualfs_directory_desc sysfs = 28 | { 29 | .type = VIRTUALFS_TYPE_DIRECTORY, 30 | .entries = { 31 | VIRTUALFS_ENTRY_END() 32 | } 33 | }; 34 | 35 | struct file_system *sysfs_alloc() 36 | { 37 | return virtualfs_alloc("/sys", &sysfs); 38 | } 39 | -------------------------------------------------------------------------------- /src/fs/sysfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct file_system *sysfs_alloc(); 25 | -------------------------------------------------------------------------------- /src/fs/virtual.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define VIRTUALFS_TYPE_INVALID 0 /* Invalid entry */ 25 | #define VIRTUALFS_TYPE_DIRECTORY 1 /* Directory */ 26 | #define VIRTUALFS_TYPE_CUSTOM 2 /* Fully custom character file */ 27 | #define VIRTUALFS_TYPE_CHAR 3 /* Character device */ 28 | #define VIRTUALFS_TYPE_TEXT 4 /* In-memory read only text file */ 29 | #define VIRTUALFS_TYPE_PARAM 5 /* Kernel sysfs parameter */ 30 | 31 | struct virtualfs_desc 32 | { 33 | int type; 34 | }; 35 | 36 | #define VIRTUALFS_ENTRY_TYPE_END 0 37 | #define VIRTUALFS_ENTRY_TYPE_STATIC 1 38 | #define VIRTUALFS_ENTRY_TYPE_DYNAMIC 2 39 | #define VIRTUALFS_ITER_END -1 40 | struct virtualfs_entry 41 | { 42 | int type; 43 | union 44 | { 45 | /* For static entry */ 46 | struct 47 | { 48 | const char *name; 49 | struct virtualfs_desc *desc; 50 | }; 51 | /* For dynamic entry */ 52 | struct 53 | { 54 | void (*begin_iter)(int dir_tag); 55 | void (*end_iter)(int dir_tag); 56 | int (*iter)(int dir_tag, int iter_tag, int *type, char *name, int namelen); 57 | int (*open)(int dir_tag, const char *name, int namelen, int *file_tag, struct virtualfs_desc **desc); 58 | }; 59 | }; 60 | }; 61 | #define VIRTUALFS_ENTRY(_name, _desc) \ 62 | { .type = VIRTUALFS_ENTRY_TYPE_STATIC, .name = _name, \ 63 | .desc = (struct virtualfs_desc *)&_desc }, 64 | #define VIRTUALFS_ENTRY_DYNAMIC(_begin_iter, _end_iter, _iter, _open) \ 65 | { .type = VIRTUALFS_ENTRY_TYPE_DYNAMIC, .begin_iter = _begin_iter, \ 66 | .end_iter = _end_iter, .iter = _iter, .open = _open }, 67 | #define VIRTUALFS_ENTRY_END() \ 68 | { .type = VIRTUALFS_ENTRY_TYPE_END }, 69 | 70 | /* VIRTUALFS_TYPE_DIRECTORY */ 71 | struct virtualfs_directory_desc 72 | { 73 | int type; 74 | struct virtualfs_entry entries[]; 75 | }; 76 | 77 | /* VIRTUALFS_TYPE_CUSTOM */ 78 | /* To use this desc, implement a custom file allocation function. 79 | * Call virtualfs_custom_file_init() in it. 80 | * Set the file_ops.stat vptr to virtualfs_custom_file_stat(). 81 | */ 82 | struct virtualfs_custom_desc 83 | { 84 | int type; 85 | int device; 86 | struct file *(*alloc)(); 87 | }; 88 | #define VIRTUALFS_CUSTOM(_device, _alloc) \ 89 | { \ 90 | .type = VIRTUALFS_TYPE_CUSTOM, \ 91 | .device = _device, \ 92 | .alloc = _alloc, \ 93 | } 94 | 95 | /* VIRTUALFS_TYPE_CHAR */ 96 | struct virtualfs_char_desc 97 | { 98 | int type; 99 | int device; 100 | size_t (*read)(int tag, void *buf, size_t count); 101 | size_t (*write)(int tag, const void *buf, size_t count); 102 | }; 103 | #define VIRTUALFS_CHAR(_device, _read, _write) \ 104 | { \ 105 | .type = VIRTUALFS_TYPE_CHAR, \ 106 | .device = _device, \ 107 | .read = _read, \ 108 | .write = _write, \ 109 | } 110 | 111 | /* VIRTUALFS_TYPE_TEXT */ 112 | struct virtualfs_text_desc 113 | { 114 | int type; 115 | int (*gettext)(int tag, char *buf); 116 | }; 117 | #define VIRTUALFS_TEXT(_gettext) \ 118 | { \ 119 | .type = VIRTUALFS_TYPE_TEXT, \ 120 | .gettext = _gettext, \ 121 | } 122 | 123 | /* VIRTUALFS_TYPE_PARAM */ 124 | #define VIRTUALFS_PARAM_TYPE_RAW 0 125 | #define VIRTUALFS_PARAM_TYPE_INT 1 126 | #define VIRTUALFS_PARAM_TYPE_UINT 2 127 | struct virtualfs_param_desc 128 | { 129 | int type; 130 | int valtype; 131 | union { 132 | size_t (*get)(int tag, char *buf, size_t count); 133 | int (*get_int)(int tag); 134 | unsigned int (*get_uint)(int tag); 135 | }; 136 | union { 137 | void (*set)(int tag, const char *buf, size_t count); 138 | void (*set_int)(int tag, int value); 139 | void (*set_uint)(int tag, unsigned int value); 140 | }; 141 | }; 142 | #define __VIRTUALFS_PARAM_META(_valtype, _suffix, _getter, _setter) \ 143 | { \ 144 | .type = VIRTUALFS_TYPE_PARAM, \ 145 | .valtype = _valtype, \ 146 | .get##_suffix = _getter, \ 147 | .set##_suffix = _setter, \ 148 | } 149 | #define VIRTUALFS_PARAM(_getter, _setter) __VIRTUALFS_PARAM_META(VIRTUALFS_PARAM_TYPE_RAW, , _getter, _setter) 150 | #define VIRTUALFS_PARAM_READONLY(_getter) VIRTUALFS_PARAM(_getter, NULL) 151 | #define VIRTUALFS_PARAM_WRITEONLY(_setter) VIRTUALFS_PARAM(NULL, _setter) 152 | #define VIRTUALFS_PARAM_INT(_getter, _setter) __VIRTUALFS_PARAM_META(VIRTUALFS_PARAM_TYPE_INT, _int, _getter, _setter) 153 | #define VIRTUALFS_PARAM_INT_READONLY(_getter) VIRTUALFS_PARAM_INT(_getter, NULL) 154 | #define VIRTUALFS_PARAM_INT_WRITEONLY(_setter) VIRTUALFS_PARAM_INT(NULL, _setter) 155 | #define VIRTUALFS_PARAM_UINT(_getter, _setter) __VIRTUALFS_PARAM_META(VIRTUALFS_PARAM_TYPE_UINT, _uint, _getter, _setter) 156 | #define VIRTUALFS_PARAM_UINT_READONLY(_getter) VIRTUALFS_PARAM_UINT(_getter, NULL) 157 | #define VIRTUALFS_PARAM_UINT_WRITEONLY(_setter) VIRTUALFS_PARAM_UINT(NULL, _setter) 158 | 159 | struct virtualfs_custom 160 | { 161 | struct file base_file; 162 | struct virtualfs_desc *desc; 163 | }; 164 | 165 | int virtualfs_get_poll_status_inout(struct file *f); /* get_poll_status: Always POLLIN | POLLOUT */ 166 | 167 | /* For custom file */ 168 | void virtualfs_custom_init(void *file, struct virtualfs_desc *desc); 169 | int virtualfs_custom_stat(struct file *f, struct newstat *buf); 170 | 171 | /* File system calls */ 172 | struct file_system *virtualfs_alloc(const char *mountpoint, const struct virtualfs_directory_desc *dir); 173 | -------------------------------------------------------------------------------- /src/fs/winfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct file_system *winfs_alloc(); 25 | int winfs_is_winfile(struct file *f); 26 | int winfs_read_special_file(struct file *f, const char *header, int headerlen, char *buf, int buflen); 27 | int winfs_write_special_file(struct file *f, const char *header, int headerlen, char *buf, int buflen); 28 | -------------------------------------------------------------------------------- /src/fs/zero.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | static size_t zero_read(int tag, void *buf, size_t count) 23 | { 24 | RtlZeroMemory(buf, count); 25 | return count; 26 | } 27 | 28 | static size_t zero_write(int tag, const void *buf, size_t count) 29 | { 30 | return count; 31 | } 32 | 33 | struct virtualfs_char_desc zero_desc = VIRTUALFS_CHAR(mkdev(1, 5), zero_read, zero_write); 34 | -------------------------------------------------------------------------------- /src/fs/zero.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct virtualfs_char_desc zero_desc; 25 | -------------------------------------------------------------------------------- /src/heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | 25 | void heap_init(); 26 | void heap_shutdown(); 27 | int heap_fork(HANDLE process); 28 | void heap_afterfork_parent(); 29 | void heap_afterfork_child(); 30 | 31 | void *kmalloc(int size); 32 | void kfree(void *mem, int size); 33 | -------------------------------------------------------------------------------- /src/lib/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define container_of(ptr, type, member) \ 25 | ((type *)((char *)(ptr) - offsetof(type, member))) 26 | -------------------------------------------------------------------------------- /src/lib/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct list_node 25 | { 26 | struct list_node *prev; 27 | struct list_node *next; 28 | }; 29 | 30 | struct list 31 | { 32 | struct list_node *head; 33 | struct list_node *tail; 34 | }; 35 | 36 | #define list_entry(node, type, member) \ 37 | container_of(node, type, member) 38 | 39 | #define list_empty(list) \ 40 | ((list)->head == NULL) 41 | 42 | #define list_head(list) \ 43 | ((list)->head) 44 | 45 | #define list_tail(list) \ 46 | ((list)->tail) 47 | 48 | #define list_prev(node) \ 49 | ((node)->prev) 50 | 51 | #define list_next(node) \ 52 | ((node)->next) 53 | 54 | #define list_init(list) \ 55 | do \ 56 | { \ 57 | (list)->head = NULL; \ 58 | (list)->tail = NULL; \ 59 | } while (0) 60 | 61 | #define list_add(list, node) \ 62 | do \ 63 | { \ 64 | if ((list)->tail) \ 65 | { \ 66 | (node)->prev = list_tail(list); \ 67 | (node)->next = NULL; \ 68 | (list)->tail->next = (node); \ 69 | (list)->tail = (node); \ 70 | } \ 71 | else \ 72 | { \ 73 | (node)->prev = (node)->next = NULL; \ 74 | (list)->head = (node); \ 75 | (list)->tail = (node); \ 76 | } \ 77 | } while (0) 78 | 79 | #define list_remove(list, node) \ 80 | do \ 81 | { \ 82 | if ((list)->head == node) \ 83 | (list)->head = (node)->next; \ 84 | if ((list)->tail == node) \ 85 | (list)->tail = (node)->prev; \ 86 | if ((node)->prev) \ 87 | (node)->prev->next = (node)->next; \ 88 | if ((node)->next) \ 89 | (node)->next->prev = (node)->prev; \ 90 | } while (0) 91 | 92 | #define list_iterate(list, cur) \ 93 | for (cur = (list)->head; cur; cur = cur->next) 94 | -------------------------------------------------------------------------------- /src/lib/rbtree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct rb_node 6 | { 7 | size_t _parent; 8 | struct rb_node *left, *right; 9 | }; 10 | 11 | #define rb_entry(node, type, member) \ 12 | container_of(node, type, member) 13 | 14 | struct rb_tree 15 | { 16 | struct rb_node *root; 17 | }; 18 | 19 | typedef int rb_cmp(const struct rb_node *left, const struct rb_node *right); 20 | 21 | /* Test if the tree is empty */ 22 | #define rb_empty(tree) ((tree)->root == NULL) 23 | 24 | /* Initialize a tree */ 25 | #define rb_init(tree) \ 26 | do { \ 27 | (tree)->root = NULL; \ 28 | } while (0) 29 | 30 | /* Add a node to a tree */ 31 | void rb_add(struct rb_tree *tree, struct rb_node *node, rb_cmp *cmp); 32 | 33 | /* Remove a node from a tree, the data in it is lost */ 34 | void rb_remove(struct rb_tree *tree, struct rb_node *node); 35 | 36 | /* Find a node in tree which is equal to value */ 37 | struct rb_node *rb_find(struct rb_tree *tree, const struct rb_node *value, rb_cmp *cmp); 38 | 39 | /* Find the smallest node in tree which is not less than value */ 40 | struct rb_node *rb_lower_bound(struct rb_tree *tree, const struct rb_node *value, rb_cmp *cmp); 41 | 42 | /* Find the largest node in tree which is not larger than value */ 43 | struct rb_node *rb_upper_bound(struct rb_tree *tree, const struct rb_node *value, rb_cmp *cmp); 44 | 45 | /* Get the first node of a tree, NULL if the tree is empty */ 46 | struct rb_node *rb_first(struct rb_tree *tree); 47 | 48 | /* Get the last node of a tree, NULL if the tree is empty */ 49 | struct rb_node *rb_last(struct rb_tree *tree); 50 | 51 | /* Get the precedent of a node, NULL if none */ 52 | struct rb_node *rb_prev(struct rb_node *node); 53 | 54 | /* Get the precedent of a node, NULL if none */ 55 | struct rb_node *rb_next(struct rb_node *node); 56 | -------------------------------------------------------------------------------- /src/lib/slist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | struct slist 25 | { 26 | struct slist *next; 27 | }; 28 | 29 | #define slist_entry(node, type, member) \ 30 | container_of(node, type, member) 31 | 32 | #define slist_init(node) \ 33 | do \ 34 | { \ 35 | (node)->next = NULL; \ 36 | } while(0) 37 | 38 | #define slist_empty(node) \ 39 | ((node)->next == NULL) 40 | 41 | #define slist_next(node) \ 42 | (node)->next 43 | 44 | #define slist_next_entry(node, type, member) \ 45 | slist_entry(slist_next(node), type, member) 46 | 47 | #define slist_add(prev, node) \ 48 | do \ 49 | { \ 50 | (node)->next = (prev)->next; \ 51 | (prev)->next = (node); \ 52 | } while(0) 53 | 54 | #define slist_remove(prev, node) \ 55 | do \ 56 | { \ 57 | (prev)->next = (node)->next; \ 58 | } while(0) 59 | 60 | #define slist_iterate(list, prev, cur) \ 61 | for (struct slist *prev = (list), *cur = slist_next(prev); \ 62 | cur; \ 63 | prev = cur, cur = slist_next(cur)) 64 | 65 | #define slist_iterate_safe(list, prev, cur) \ 66 | for (struct slist *prev = (list), *cur = slist_next(prev); \ 67 | cur; \ 68 | slist_next(prev) == cur? \ 69 | prev = cur, cur = slist_next(cur): (cur = slist_next(prev))) 70 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define WIN32_LEAN_AND_MEAN 26 | #include 27 | #include 28 | 29 | int logger_attached; 30 | static __declspec(thread) HANDLE hLoggerPipe; 31 | static __declspec(thread) char buffer[1024]; 32 | 33 | #define PROTOCOL_VERSION 2 34 | #define PROTOCOL_MAGIC 'flog' 35 | struct request 36 | { 37 | uint32_t magic; 38 | uint32_t version; 39 | uint32_t pid; 40 | uint32_t tid; 41 | }; 42 | 43 | #define LOG_DEBUG 0 44 | #define LOG_INFO 1 45 | #define LOG_WARNING 2 46 | #define LOG_ERROR 3 47 | struct packet 48 | { 49 | uint32_t packet_size; 50 | uint32_t type; 51 | uint32_t len; 52 | char text[]; 53 | }; 54 | 55 | void log_init_thread() 56 | { 57 | if (!logger_attached) 58 | return; 59 | LPCWSTR pipeName = L"\\\\.\\pipe\\flog_server"; 60 | for (;;) 61 | { 62 | hLoggerPipe = CreateFileW(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 63 | if (hLoggerPipe == INVALID_HANDLE_VALUE) 64 | { 65 | /* Non critical error code, just wait and try connecting again */ 66 | if (GetLastError() != ERROR_PIPE_BUSY || !WaitNamedPipeW(pipeName, NMPWAIT_WAIT_FOREVER)) 67 | { 68 | logger_attached = 0; 69 | break; 70 | } 71 | continue; 72 | } 73 | /* Send initial request */ 74 | struct request request; 75 | request.magic = PROTOCOL_MAGIC; 76 | request.version = PROTOCOL_VERSION; 77 | request.pid = GetProcessId(GetCurrentProcess()); 78 | request.tid = GetThreadId(GetCurrentThread()); 79 | DWORD written; 80 | if (!WriteFile(hLoggerPipe, &request, sizeof(request), &written, NULL)) 81 | { 82 | CloseHandle(hLoggerPipe); 83 | logger_attached = 0; 84 | } 85 | break; 86 | } 87 | } 88 | 89 | void log_init() 90 | { 91 | logger_attached = 1; 92 | log_init_thread(); 93 | } 94 | 95 | void log_shutdown() 96 | { 97 | /* TODO */ 98 | if (logger_attached) 99 | CloseHandle(hLoggerPipe); 100 | } 101 | 102 | static void log_internal(int type, char typech, const char *format, va_list ap) 103 | { 104 | struct packet *packet = (struct packet*)buffer; 105 | packet->type = type; 106 | FILETIME tf; 107 | SYSTEMTIME ts; 108 | win7compat_GetSystemTimePreciseAsFileTime(&tf); 109 | /* Convert FILETIME to human readable text */ 110 | uint64_t time = ((uint64_t)tf.dwHighDateTime << 32ULL) + tf.dwLowDateTime; 111 | /* FILETIME is in 100-nanosecond units */ 112 | uint64_t seconds = (time / 10'000'000ULL); 113 | int nano = (int)(time % 10'000'000ULL); 114 | int sec = (int)(seconds % 60); 115 | int min = (int)((seconds / 60) % 60); 116 | int hr = (int)((seconds / 3600) % 24); 117 | packet->len = ksprintf(packet->text, "[%02u:%02u:%02u.%07u] (%c%c) ", 118 | hr, min, sec, nano, typech, typech); 119 | packet->len += kvsprintf(packet->text + packet->len, format, ap); 120 | packet->packet_size = sizeof(struct packet) + packet->len; 121 | DWORD bytes_written; 122 | if (!WriteFile(hLoggerPipe, buffer, packet->packet_size, &bytes_written, NULL)) 123 | { 124 | CloseHandle(hLoggerPipe); 125 | logger_attached = 0; 126 | } 127 | } 128 | 129 | void log_debug_internal(const char *format, ...) 130 | { 131 | va_list ap; 132 | va_start(ap, format); 133 | log_internal(LOG_DEBUG, 'D', format, ap); 134 | } 135 | 136 | void log_info_internal(const char *format, ...) 137 | { 138 | va_list ap; 139 | va_start(ap, format); 140 | log_internal(LOG_INFO, 'I', format, ap); 141 | } 142 | 143 | void log_warning_internal(const char *format, ...) 144 | { 145 | va_list ap; 146 | va_start(ap, format); 147 | log_internal(LOG_WARNING, 'W', format, ap); 148 | } 149 | 150 | void log_error_internal(const char *format, ...) 151 | { 152 | va_list ap; 153 | va_start(ap, format); 154 | log_internal(LOG_ERROR, 'E', format, ap); 155 | } 156 | 157 | #ifdef _DEBUG 158 | 159 | void log_assert_internal(const char *format, ...) 160 | { 161 | va_list ap; 162 | va_start(ap, format); 163 | log_internal(LOG_DEBUG, 'D', format, ap); 164 | process_exit(LOG_ASSERT_EXIT, 0); 165 | } 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | void log_init_thread(); 23 | void log_init(); 24 | void log_shutdown(); 25 | void log_debug_internal(const char *format, ...); 26 | void log_info_internal(const char *format, ...); 27 | void log_warning_internal(const char *format, ...); 28 | void log_error_internal(const char *format, ...); 29 | 30 | extern int logger_attached; 31 | #define log_debug(format, ...) do { if (logger_attached) log_debug_internal(format, __VA_ARGS__); } while (0) 32 | #define log_info(format, ...) do { if (logger_attached) log_info_internal(format, __VA_ARGS__); } while (0) 33 | #define log_warning(format, ...) do { if (logger_attached) log_warning_internal(format, __VA_ARGS__); } while (0) 34 | #define log_error(format, ...) do { if (logger_attached) log_error_internal(format, __VA_ARGS__); } while (0) 35 | 36 | #ifdef _DEBUG 37 | 38 | #define LOG_ASSERT_EXIT 127 39 | #define log_assert_format "Assertion expression `%s` failed in function %s, at file %s: %d.\n" 40 | #define log_assert(exp) do { if (logger_attached && !exp) log_assert_internal(log_assert_format, #exp, __FUNCTION__, __FILE__, __LINE__); } while (0) 41 | 42 | #else 43 | 44 | #define log_assert(exp) 45 | 46 | #endif // _DEBUG 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #ifdef _WIN64 23 | #define Xip Rip 24 | #define XWORD QWORD 25 | #else 26 | #define Xip Eip 27 | #define XWORD DWORD 28 | #endif 29 | -------------------------------------------------------------------------------- /src/rc/flinux.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wishstudio/flinux/a041253e8706aa5e0543bbadfc0ff7b9f819c6af/src/rc/flinux.rc -------------------------------------------------------------------------------- /src/rc/resource1.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by flinux.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/shared.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define WIN32_LEAN_AND_MEAN 25 | #include 26 | #include 27 | 28 | HANDLE shared_get_object_directory(); 29 | void shared_init(); 30 | bool shared_fork(HANDLE child); 31 | void shared_afterfork_parent(); 32 | void shared_afterfork_child(); 33 | 34 | /* Static allocation for globally shared area 35 | * Currently the users of this API should make sure to work with zero initialization 36 | * Because they do not have any chance of manually initialize their shared data area 37 | */ 38 | #define SHARED_ALLOC_SIZE 4 * BLOCK_SIZE 39 | void *shared_alloc(size_t size); 40 | 41 | /* Memory allocation for shared data regions 42 | * The shared memory manager creates one or more pools for each size of shared 43 | * data region. Every pool is managed as a linked list allocator, which 44 | * is pretty like the heap. But they are equipped with carefully written procedures 45 | * to avoid races even in the tricky case where one process died when altering the 46 | * shared pool. 47 | * Currently the only possible heap sharing scheme is via forking. 48 | * To simplify the process, we remap all pools currently mapped to the child process 49 | * to the same memory address at fork time. Hence all shared pointers will stay the 50 | * same in the child. No additional handling is needed in caller. 51 | */ 52 | void *kmalloc_shared(size_t obj_size); 53 | void kfree_shared(void *obj, size_t obj_size); 54 | -------------------------------------------------------------------------------- /src/str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | int kprintf(const char *format, ...); 26 | int ksprintf(char *buffer, const char *format, ...); 27 | int ksscanf(const char *buffer, const char *format, ...); 28 | bool katoi(const char *str, int *out); 29 | bool katou(const char *str, unsigned int *out); 30 | 31 | void strip(char *str); 32 | 33 | int utf8_get_sequence_len(char ch); 34 | uint32_t utf8_decode(const char *data); 35 | int utf8_to_utf16(const char *data, int srclen, uint16_t *outdata, int dstlen); 36 | int utf8_to_utf16_filename(const char *data, int srclen, uint16_t *outdata, int dstlen); 37 | int utf16_to_utf8(const uint16_t *data, int srclen, char *outdata, int dstlen); 38 | int utf16_to_utf8_filename(const uint16_t *data, int srclen, char *outdata, int dstlen); 39 | int wcwidth(uint32_t ucs); /* Defined in wcwidth.c */ 40 | -------------------------------------------------------------------------------- /src/syscall/exec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | 25 | int do_execve(const char *filename, int argc, char *argv[], int env_size, char *envp[], char *buffer_base, 26 | void(*initialize_routine)()); 27 | 28 | int exec_fork(HANDLE process); 29 | -------------------------------------------------------------------------------- /src/syscall/fork.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | void fork_init(); 23 | -------------------------------------------------------------------------------- /src/syscall/futex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | 25 | int futex_wait(volatile int *addr, int val, DWORD timeout); 26 | int futex_wake(int *addr, int count); 27 | int futex_requeue(int *addr, int count, int *requeue_addr, int *requeue_val); 28 | -------------------------------------------------------------------------------- /src/syscall/mm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #define WIN32_LEAN_AND_MEAN 27 | #include 28 | 29 | /* Windows allocation granularity */ 30 | #ifdef _WIN64 31 | #define BLOCK_SIZE 0x00010000ULL 32 | #else 33 | #define BLOCK_SIZE 0x00010000U 34 | #endif 35 | 36 | /* Page size */ 37 | #ifdef _WIN64 38 | #define PAGE_SIZE 0x00001000ULL 39 | #else 40 | #define PAGE_SIZE 0x00001000U 41 | #endif 42 | 43 | #define ALIGN_TO(x, a) ((uintptr_t)((x) + (a) - 1) & -(a)) 44 | 45 | #ifdef _WIN64 46 | 47 | /* x64 Special: brk() base address */ 48 | #define MM_BRK_BASE 0x0000000300000000ULL 49 | 50 | #endif 51 | 52 | /* Internal flags for mm_mmap() */ 53 | #define INTERNAL_MAP_TOPDOWN 1 /* Allocate at highest possible address */ 54 | #define INTERNAL_MAP_NOOVERWRITE 2 /* Don't automatically overwrite existing mappings, report error in such case */ 55 | #define INTERNAL_MAP_NORESET 4 /* Don't unmap the memory region at mm_reset() */ 56 | #define INTERNAL_MAP_VIRTUALALLOC 8 /* This will cause the memory region to be allocated via VirtualAlloc() */ 57 | #define INTERNAL_MAP_SHARED 16 /* A MAP_SHARED memory region */ 58 | /* Macro to test if the given internal flags require block aligned memory region to be allocated */ 59 | #define BLOCK_ALIGNED(flag) ((flag & INTERNAL_MAP_VIRTUALALLOC) || (flag & INTERNAL_MAP_SHARED)) 60 | 61 | void mm_init(); 62 | void mm_init_global_shared(); 63 | void mm_reset(); 64 | void mm_shutdown(); 65 | void mm_update_brk(void *brk); 66 | 67 | void mm_dump_stack_trace(PCONTEXT context); 68 | void mm_dump_windows_memory_mappings(HANDLE process); 69 | void mm_dump_memory_mappings(); 70 | int mm_get_maps(char *buf); 71 | 72 | /* Check if the memory region is compatible with desired access */ 73 | int mm_check_read(const void *addr, size_t size); 74 | int mm_check_read_string(const char *addr); 75 | int mm_check_write(void *addr, size_t size); 76 | 77 | int mm_handle_page_fault(void *addr, bool is_write); 78 | int mm_fork(HANDLE process); 79 | void mm_afterfork_parent(); 80 | void mm_afterfork_child(); 81 | 82 | size_t mm_find_free_pages(size_t count_bytes); 83 | struct file; 84 | void *mm_mmap(void *addr, size_t len, int prot, int flags, int internal_flags, struct file *f, off_t offset_pages); 85 | int mm_munmap(void *addr, size_t len); 86 | 87 | /* Populate a memory region containing given address */ 88 | void mm_populate(void *addr); 89 | 90 | /* Static allocation 91 | * Many subsystems need to use static storage which are automatically forked 92 | * Since mm only accepts allocation granularity at PAGE_SIZE, there could be much space lost 93 | * Instead of allocating pages by their own, we preallocate a sufficient block 94 | * and let the subsystems to allocate their static forkable memory at initialization and 95 | * on fork(). We keep the initialization order consistent thus they will always get the same 96 | * static address. 97 | * 98 | * TODO: This scheme is really ugly, any better ideas? 99 | */ 100 | #define MM_STATIC_ALLOC_SIZE 3 * BLOCK_SIZE /* The total size */ 101 | void *mm_static_alloc(size_t size); 102 | -------------------------------------------------------------------------------- /src/syscall/process.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #define WIN32_LEAN_AND_MEAN 28 | #include 29 | 30 | #define STACK_SIZE 1048576 31 | 32 | void process_init(); 33 | int process_fork(HANDLE process); 34 | void process_afterfork_parent(); 35 | void process_afterfork_child(void *stack_base, pid_t pid); 36 | void process_shutdown(); 37 | void *process_get_stack_base(); 38 | pid_t process_init_child(DWORD win_pid, DWORD win_tid, HANDLE process_handle); 39 | void process_thread_entry(pid_t tid); 40 | pid_t process_create_thread(DWORD win_tid); 41 | 42 | __declspec(noreturn) void process_exit(int exit_code, int exit_signal); 43 | __declspec(noreturn) void thread_exit(int exit_code, int exit_signal); 44 | bool process_pid_exist(pid_t pid); 45 | pid_t process_get_pid(); 46 | pid_t process_get_ppid(); 47 | pid_t process_get_tgid(pid_t pid); 48 | pid_t process_get_pgid(pid_t pid); 49 | pid_t process_get_sid(); 50 | 51 | enum 52 | { 53 | PROCESS_QUERY_STAT, /* /proc/[pid]/stat */ 54 | PROCESS_QUERY_MAPS, /* /proc/[pid]/maps */ 55 | }; 56 | int process_query(int query_type, char *buf); 57 | int process_query_pid(pid_t pid, int query_type, char *buf); 58 | -------------------------------------------------------------------------------- /src/syscall/process_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #define WIN32_LEAN_AND_MEAN 28 | #include 29 | 30 | struct child_process 31 | { 32 | struct slist list; 33 | pid_t pid; 34 | HANDLE hProcess, hPipe; 35 | OVERLAPPED overlapped; 36 | bool terminated; 37 | }; 38 | 39 | struct thread 40 | { 41 | /* Thread list of a process */ 42 | struct list_node list; 43 | /* pid of thread */ 44 | pid_t pid; 45 | /* Handle to the thread */ 46 | HANDLE handle; 47 | /* Stack base of the thread */ 48 | void *stack_base; 49 | /* clear_tid address for CLONE_CHILD_CLEARTID */ 50 | pid_t *clear_tid; 51 | /*********** For futex() ***********/ 52 | HANDLE wait_event; 53 | /*********** Signal related information ***********/ 54 | /* Signal mask */ 55 | sigset_t sigmask; 56 | /* Signal event: set when a signal is arrived. 57 | * Used in signal_wait() to detect EINTR conditions */ 58 | HANDLE sigevent; 59 | /* Current siginfo, this is used as temporary storage when delivering a signal */ 60 | siginfo_t current_siginfo; 61 | /* Whether the thread can receive signals now 62 | * A thread cannot receive signals if a signal ism being delivered to the thread 63 | */ 64 | bool can_accept_signal; 65 | }; 66 | 67 | extern __declspec(thread) struct thread *current_thread; 68 | 69 | #define MAX_PROCESS_COUNT 4096 70 | #define MAX_CHILD_COUNT 1024 71 | 72 | struct process_data 73 | { 74 | /* RW lock guard */ 75 | SRWLOCK rw_lock; 76 | /* pid of this process */ 77 | pid_t pid; 78 | /* Information of threads of this process */ 79 | int thread_count; 80 | struct list thread_list, thread_freelist; 81 | struct thread threads[MAX_PROCESS_COUNT]; 82 | /* Information of child processes */ 83 | int child_count; 84 | struct slist child_list, child_freelist; 85 | struct child_process child[MAX_CHILD_COUNT]; 86 | /* Mutex for process_shared_data */ 87 | /* You have to lock this mutex on the following scenarios: 88 | * 1. When writing to shared area 89 | * 2. When reading process slots other than the current process 90 | * 91 | * TODO: It's better to have a lightweight interprocess RW lock. 92 | * Windows only provides an intraprocess one. 93 | */ 94 | HANDLE shared_mutex; 95 | }; 96 | 97 | extern struct process_data *const process; 98 | 99 | #define PROCESS_NOTEXIST 0 /* The process does not exist */ 100 | #define PROCESS_RUNNING 1 /* The process is running normally */ 101 | #define PROCESS_ZOMBIE 2 /* The process is a zombie */ 102 | struct process_info 103 | { 104 | /* Status for current slot */ 105 | int status; 106 | /* Exit code */ 107 | int exit_code : 8; 108 | /* Exit signal */ 109 | int exit_signal : 8; 110 | /* Windows process and thread identifier */ 111 | DWORD win_pid, win_tid; 112 | /* Thread group id (= pid of main thread) */ 113 | pid_t tgid; 114 | /* Process group id */ 115 | pid_t pgid; 116 | /* Parent process id */ 117 | pid_t ppid; 118 | /* Session id */ 119 | pid_t sid; 120 | /* Handle to sigwrite pipe in the process */ 121 | HANDLE sigwrite; 122 | /* Handle to information query mutex in the process */ 123 | HANDLE query_mutex; 124 | }; 125 | -------------------------------------------------------------------------------- /src/syscall/sig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #define WIN32_LEAN_AND_MEAN 27 | #include 28 | 29 | HANDLE signal_get_process_wait_semaphore(); 30 | HANDLE signal_get_process_sigwrite(); 31 | HANDLE signal_get_process_query_mutex(); 32 | void signal_init_child(struct child_process *proc); 33 | 34 | void signal_setup_handler(struct syscall_context *context); 35 | 36 | void signal_init(); 37 | void signal_reset(); 38 | int signal_fork(HANDLE process); 39 | void signal_afterfork_parent(); 40 | void signal_afterfork_child(); 41 | void signal_shutdown(); 42 | void signal_init_thread(struct thread *thread); 43 | void signal_exit_thread(struct thread *thread); 44 | int signal_kill(pid_t pid, siginfo_t *siginfo); 45 | DWORD signal_wait(int count, HANDLE *handles, DWORD milliseconds); 46 | void signal_before_pwait(const sigset_t *sigmask, sigset_t *oldmask); 47 | void signal_after_pwait(const sigset_t *oldmask); 48 | 49 | /* signal_wait() is interrupted by an incoming signal */ 50 | #define WAIT_INTERRUPTED 0x80000000 51 | 52 | int signal_query(DWORD win_pid, HANDLE sigwrite, HANDLE query_mutex, int query_type, char *buf); 53 | -------------------------------------------------------------------------------- /src/syscall/stubs.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; This file is part of Foreign Linux. 3 | ; 4 | ; Copyright (C) 2014, 2015 Xiangyan Sun 5 | ; 6 | ; This program is free software: you can redistribute it and/or modify 7 | ; it under the terms of the GNU General Public License as published by 8 | ; the Free Software Foundation, either version 3 of the License, or 9 | ; (at your option) any later version. 10 | ; 11 | ; This program is distributed in the hope that it will be useful, 12 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ; GNU General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU General Public License 17 | ; along with this program. If not, see . 18 | ; 19 | 20 | .model flat, C 21 | .code 22 | 23 | PUBLIC mm_check_read_begin, mm_check_read_end, mm_check_read_fail 24 | mm_check_read PROC check_addr, check_size 25 | mov edx, check_addr 26 | mov ecx, check_size 27 | jecxz SUCC 28 | 29 | mm_check_read_begin LABEL PTR 30 | mov al, byte ptr [edx] 31 | ; test first page which may be unaligned 32 | 33 | mov eax, edx 34 | shr eax, 12 35 | ; eax - start page 36 | lea ecx, [edx + ecx - 1] 37 | shr ecx, 12 38 | ; ecx - end page 39 | sub ecx, eax 40 | ; ecx - remaining pages 41 | je SUCC 42 | 43 | and dx, 0f000h 44 | L: 45 | add edx, 01000h 46 | mov al, byte ptr [edx] 47 | loop L 48 | mm_check_read_end LABEL PTR 49 | 50 | SUCC: 51 | xor eax, eax 52 | inc eax 53 | ret 54 | 55 | mm_check_read_fail LABEL PTR 56 | xor eax, eax 57 | ret 58 | mm_check_read ENDP 59 | 60 | PUBLIC mm_check_read_string_begin, mm_check_read_string_end, mm_check_read_string_fail 61 | mm_check_read_string PROC check_addr 62 | mov edx, check_addr 63 | 64 | mm_check_read_string_begin LABEL PTR 65 | L: 66 | mov al, byte ptr [edx] 67 | test al, al 68 | jz SUCC 69 | inc edx 70 | mm_check_read_string_end LABEL PTR 71 | 72 | SUCC: 73 | xor eax, eax 74 | inc eax 75 | ret 76 | 77 | mm_check_read_string_fail LABEL PTR 78 | xor eax, eax 79 | ret 80 | mm_check_read_string ENDP 81 | 82 | PUBLIC mm_check_write_begin, mm_check_write_end, mm_check_write_fail 83 | mm_check_write PROC check_addr, check_size 84 | mov edx, check_addr 85 | mov ecx, check_size 86 | jecxz SUCC 87 | 88 | mm_check_write_begin LABEL PTR 89 | mov al, byte ptr [edx] 90 | mov byte ptr [edx], al 91 | ; test first page which may be unaligned 92 | 93 | mov eax, edx 94 | shr eax, 12 95 | ; eax - start page 96 | lea ecx, [edx + ecx - 1] 97 | shr ecx, 12 98 | ; ecx - end page 99 | sub ecx, eax 100 | ; ecx - remaining pages 101 | je SUCC 102 | 103 | and dx, 0f000h 104 | L: 105 | add edx, 01000h 106 | mov al, byte ptr [edx] 107 | mov byte ptr [edx], al 108 | loop L 109 | mm_check_write_end LABEL PTR 110 | 111 | SUCC: 112 | xor eax, eax 113 | inc eax 114 | ret 115 | 116 | mm_check_write_fail LABEL PTR 117 | xor eax, eax 118 | ret 119 | mm_check_write ENDP 120 | 121 | fpu_fxsave PROC save_area 122 | mov eax, save_area 123 | fxsave [eax] 124 | ret 125 | fpu_fxsave ENDP 126 | 127 | fpu_fxrstor PROC save_area 128 | mov eax, save_area 129 | fxrstor [eax] 130 | ret 131 | fpu_fxrstor ENDP 132 | 133 | OPTION PROLOGUE: NONE 134 | OPTION EPILOGUE: NONE 135 | ; this function will be translated by dbt before run 136 | signal_restorer PROC 137 | mov eax, 173 ; rt_sigreturn 138 | int 080h 139 | signal_restorer ENDP 140 | 141 | END 142 | -------------------------------------------------------------------------------- /src/syscall/stubs64.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; This file is part of Foreign Linux. 3 | ; 4 | ; Copyright (C) 2014, 2015 Xiangyan Sun 5 | ; 6 | ; This program is free software: you can redistribute it and/or modify 7 | ; it under the terms of the GNU General Public License as published by 8 | ; the Free Software Foundation, either version 3 of the License, or 9 | ; (at your option) any later version. 10 | ; 11 | ; This program is distributed in the hope that it will be useful, 12 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ; GNU General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU General Public License 17 | ; along with this program. If not, see . 18 | ; 19 | 20 | .code 21 | M128A STRUCT 22 | _Low QWORD ? 23 | _High QWORD ? 24 | M128A ENDS 25 | 26 | CONTEXT STRUCT 27 | P1Home QWORD ? 28 | P2Home QWORD ? 29 | P3Home QWORD ? 30 | P4Home QWORD ? 31 | P5Home QWORD ? 32 | P6Home QWORD ? 33 | ContextFlags DWORD ? 34 | MxCsr DWORD ? 35 | SegCs WORD ? 36 | SegDs WORD ? 37 | SegEs WORD ? 38 | SegFs WORD ? 39 | SegGs WORD ? 40 | SegSs WORD ? 41 | EFlags DWORD ? 42 | _Dr0 QWORD ? 43 | _Dr1 QWORD ? 44 | _Dr2 QWORD ? 45 | _Dr3 QWORD ? 46 | _Dr6 QWORD ? 47 | _Dr7 QWORD ? 48 | _Rax QWORD ? 49 | _Rcx QWORD ? 50 | _Rdx QWORD ? 51 | _Rbx QWORD ? 52 | _Rsp QWORD ? 53 | _Rbp QWORD ? 54 | _Rsi QWORD ? 55 | _Rdi QWORD ? 56 | _R8 QWORD ? 57 | _R9 QWORD ? 58 | _R10 QWORD ? 59 | _R11 QWORD ? 60 | _R12 QWORD ? 61 | _R13 QWORD ? 62 | _R14 QWORD ? 63 | _R15 QWORD ? 64 | _Rip QWORD ? 65 | ; UNION XMM_SAVE_AREA32 66 | Header M128A 2 DUP(<>) 67 | Legacy M128A 8 DUP(<>) 68 | _Xmm0 M128A <> 69 | _Xmm1 M128A <> 70 | _Xmm2 M128A <> 71 | _Xmm3 M128A <> 72 | _Xmm4 M128A <> 73 | _Xmm5 M128A <> 74 | _Xmm6 M128A <> 75 | _Xmm7 M128A <> 76 | _Xmm8 M128A <> 77 | _Xmm9 M128A <> 78 | _Xmm10 M128A <> 79 | _Xmm11 M128A <> 80 | _Xmm12 M128A <> 81 | _Xmm13 M128A <> 82 | _Xmm14 M128A <> 83 | _Xmm15 M128A <> 84 | ; END OF UNION XMM_SAVE_AREA32 85 | 86 | VectorRegister M128A 26 DUP(<>) 87 | VectorControl QWORD ? 88 | DebugControl QWORD ? 89 | LastBranchToRip QWORD ? 90 | LastBranchFromRip QWORD ? 91 | LastExceptionToRip QWORD ? 92 | LastExceptionFromRip QWORD ? 93 | CONTEXT ENDS 94 | 95 | goto_entrypoint PROC ; stack: QWORD, entrypoint: QWORD 96 | 97 | mov rax, rdx ; entrypoint 98 | mov rsp, rcx ; stack 99 | push rax 100 | xor rax, rax 101 | xor rbx, rbx 102 | xor rcx, rcx 103 | xor rdx, rdx 104 | xor rsi, rsi 105 | xor rdi, rdi 106 | xor rbp, rbp 107 | xor r8, r8 108 | xor r9, r9 109 | xor r10, r10 110 | xor r11, r11 111 | xor r12, r12 112 | xor r13, r13 113 | xor r14, r14 114 | xor r15, r15 115 | ret 116 | 117 | goto_entrypoint ENDP 118 | 119 | restore_context PROC ; ctx: QWORD 120 | 121 | mov rax, rcx ; ctx 122 | mov rcx, [rax + CONTEXT._Rcx] 123 | mov rdx, [rax + CONTEXT._Rdx] 124 | mov rbx, [rax + CONTEXT._Rbx] 125 | mov rsi, [rax + CONTEXT._Rsi] 126 | mov rdi, [rax + CONTEXT._Rdi] 127 | mov rsp, [rax + CONTEXT._Rsp] 128 | mov rbp, [rax + CONTEXT._Rbp] 129 | mov r8, [rax + CONTEXT._R8] 130 | mov r9, [rax + CONTEXT._R9] 131 | mov r10, [rax + CONTEXT._R10] 132 | mov r11, [rax + CONTEXT._R11] 133 | mov r12, [rax + CONTEXT._R12] 134 | mov r13, [rax + CONTEXT._R13] 135 | mov r14, [rax + CONTEXT._R14] 136 | mov r15, [rax + CONTEXT._R15] 137 | push [rax + CONTEXT._Rip] 138 | mov rax, [rax + CONTEXT._Rax] 139 | ret 140 | 141 | restore_context ENDP 142 | 143 | PUBLIC mm_check_read_begin, mm_check_read_end, mm_check_read_fail 144 | mm_check_read PROC ; check_addr: QWORD, check_size: QWORD 145 | xchg rcx, rdx 146 | ; rcx = check_size 147 | ; rdx = check_addr 148 | jrcxz SUCC 149 | 150 | mm_check_read_begin LABEL PTR 151 | mov al, byte ptr [rdx] 152 | ; test first page which may be unaligned 153 | 154 | mov rax, rdx 155 | shr rax, 12 156 | ; rax - start page 157 | lea rcx, [rdx + rcx - 1] 158 | shr rcx, 12 159 | ; rcx - end page 160 | sub rcx, rax 161 | ; rcx - remaining pages 162 | je SUCC 163 | 164 | and dx, 0f000h 165 | L: 166 | add rdx, 01000h 167 | mov al, byte ptr [rdx] 168 | loop L 169 | mm_check_read_end LABEL PTR 170 | 171 | SUCC: 172 | xor rax, rax 173 | inc eax 174 | ret 175 | 176 | mm_check_read_fail LABEL PTR 177 | xor rax, rax 178 | ret 179 | mm_check_read ENDP 180 | 181 | PUBLIC mm_check_read_string_begin, mm_check_read_string_end, mm_check_read_string_fail 182 | mm_check_read_string PROC ; check_addr: QWORD 183 | mov rdx, rcx ; check_addr 184 | 185 | mm_check_read_string_begin LABEL PTR 186 | L: 187 | mov al, byte ptr [rdx] 188 | test al, al 189 | jz SUCC 190 | inc rdx 191 | mm_check_read_string_end LABEL PTR 192 | 193 | SUCC: 194 | xor rax, rax 195 | inc eax 196 | ret 197 | 198 | mm_check_read_string_fail LABEL PTR 199 | xor rax, rax 200 | ret 201 | mm_check_read_string ENDP 202 | 203 | PUBLIC mm_check_write_begin, mm_check_write_end, mm_check_write_fail 204 | mm_check_write PROC ; check_addr: QWORD, check_size: QWORD 205 | xchg rcx, rdx 206 | ; rcx = check_size 207 | ; rdx = check_addr 208 | jrcxz SUCC 209 | 210 | mm_check_write_begin LABEL PTR 211 | mov al, byte ptr [rdx] 212 | mov byte ptr [rdx], al 213 | ; test first page which may be unaligned 214 | 215 | mov rax, rdx 216 | shr rax, 12 217 | ; rax - start page 218 | lea rcx, [rdx + rcx - 1] 219 | shr rcx, 12 220 | ; rcx - end page 221 | sub rcx, rax 222 | ; rcx - remaining pages 223 | je SUCC 224 | 225 | and dx, 0f000h 226 | L: 227 | add rdx, 01000h 228 | mov al, byte ptr [rdx] 229 | mov byte ptr [rdx], al 230 | loop L 231 | mm_check_write_end LABEL PTR 232 | 233 | SUCC: 234 | xor rax, rax 235 | inc eax 236 | ret 237 | 238 | mm_check_write_fail LABEL PTR 239 | xor rax, rax 240 | ret 241 | mm_check_write ENDP 242 | 243 | END 244 | -------------------------------------------------------------------------------- /src/syscall/syscall.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #define WIN32_LEAN_AND_MEAN 29 | #include 30 | 31 | extern void *mm_check_read_begin, *mm_check_read_end, *mm_check_read_fail; 32 | extern void *mm_check_read_string_begin, *mm_check_read_string_end, *mm_check_read_string_fail; 33 | extern void *mm_check_write_begin, *mm_check_write_end, *mm_check_write_fail; 34 | 35 | extern int sys_gettimeofday(struct timeval *tv, struct timezone *tz); 36 | extern intptr_t sys_time(intptr_t *t); 37 | 38 | static LONG CALLBACK exception_handler(PEXCEPTION_POINTERS ep) 39 | { 40 | if (ep->ExceptionRecord->ExceptionCode == DBG_CONTROL_C) 41 | return EXCEPTION_CONTINUE_SEARCH; 42 | if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) 43 | return EXCEPTION_CONTINUE_SEARCH; 44 | if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) 45 | { 46 | uint8_t* code = (uint8_t *)ep->ContextRecord->Xip; 47 | if (ep->ExceptionRecord->ExceptionInformation[0] == 8) 48 | { 49 | /* DEP problem */ 50 | if (mm_handle_page_fault(code, false)) 51 | return EXCEPTION_CONTINUE_EXECUTION; 52 | else 53 | { 54 | /* The problem may be actually in the next page */ 55 | if (mm_handle_page_fault(code + PAGE_SIZE, false)) 56 | return EXCEPTION_CONTINUE_EXECUTION; 57 | } 58 | } 59 | else 60 | { 61 | /* Read/write problem */ 62 | log_info("IP: 0x%p", ep->ContextRecord->Xip); 63 | bool is_write = (ep->ExceptionRecord->ExceptionInformation[0] == 1); 64 | if (mm_handle_page_fault((void *)ep->ExceptionRecord->ExceptionInformation[1], is_write)) 65 | return EXCEPTION_CONTINUE_EXECUTION; 66 | void *ip = (void *)ep->ContextRecord->Xip; 67 | if (ip >= &mm_check_read_begin && ip <= &mm_check_read_end) 68 | { 69 | ep->ContextRecord->Xip = (XWORD)&mm_check_read_fail; 70 | log_warning("mm_check_read() failed at location 0x%x", ep->ExceptionRecord->ExceptionInformation[1]); 71 | return EXCEPTION_CONTINUE_EXECUTION; 72 | } 73 | if (ip >= &mm_check_read_string_begin && ip <= &mm_check_read_string_end) 74 | { 75 | ep->ContextRecord->Xip = (XWORD)&mm_check_read_string_fail; 76 | log_warning("mm_check_read_string() failed at location 0x%x", ep->ExceptionRecord->ExceptionInformation[1]); 77 | return EXCEPTION_CONTINUE_EXECUTION; 78 | } 79 | if (ip >= &mm_check_write_begin && ip <= &mm_check_write_end) 80 | { 81 | ep->ContextRecord->Xip = (XWORD)&mm_check_write_fail; 82 | log_warning("mm_check_write() failed at location 0x%x", ep->ExceptionRecord->ExceptionInformation[1]); 83 | return EXCEPTION_CONTINUE_EXECUTION; 84 | } 85 | } 86 | if (ep->ExceptionRecord->ExceptionInformation[0] == 0) 87 | log_error("Page fault(read): %p at %p", ep->ExceptionRecord->ExceptionInformation[1], ep->ContextRecord->Xip); 88 | else if (ep->ExceptionRecord->ExceptionInformation[0] == 1) 89 | log_error("Page fault(write): %p at %p", ep->ExceptionRecord->ExceptionInformation[1], ep->ContextRecord->Xip); 90 | else if (ep->ExceptionRecord->ExceptionInformation[0] == 8) 91 | log_error("Page fault(DEP): %p at %p", ep->ExceptionRecord->ExceptionInformation[1], ep->ContextRecord->Xip); 92 | } 93 | log_info("Application crashed, dumping debug information..."); 94 | mm_dump_memory_mappings(); 95 | mm_dump_windows_memory_mappings(GetCurrentProcess()); 96 | mm_dump_stack_trace(ep->ContextRecord); 97 | #ifdef _WIN64 98 | log_info("RAX: 0x%p", ep->ContextRecord->Rax); 99 | log_info("RCX: 0x%p", ep->ContextRecord->Rcx); 100 | log_info("RDX: 0x%p", ep->ContextRecord->Rdx); 101 | log_info("RBX: 0x%p", ep->ContextRecord->Rbx); 102 | log_info("RSP: 0x%p", ep->ContextRecord->Rsp); 103 | log_info("RBP: 0x%p", ep->ContextRecord->Rbp); 104 | log_info("RSI: 0x%p", ep->ContextRecord->Rsi); 105 | log_info("RDI: 0x%p", ep->ContextRecord->Rdi); 106 | log_info("R8: 0x%p", ep->ContextRecord->R8); 107 | log_info("R9: 0x%p", ep->ContextRecord->R9); 108 | log_info("R10: 0x%p", ep->ContextRecord->R10); 109 | log_info("R11: 0x%p", ep->ContextRecord->R11); 110 | log_info("R12: 0x%p", ep->ContextRecord->R12); 111 | log_info("R13: 0x%p", ep->ContextRecord->R13); 112 | log_info("R14: 0x%p", ep->ContextRecord->R14); 113 | log_info("R15: 0x%p", ep->ContextRecord->R15); 114 | #else 115 | log_info("EAX: 0x%p", ep->ContextRecord->Eax); 116 | log_info("ECX: 0x%p", ep->ContextRecord->Ecx); 117 | log_info("EDX: 0x%p", ep->ContextRecord->Edx); 118 | log_info("EBX: 0x%p", ep->ContextRecord->Ebx); 119 | log_info("ESP: 0x%p", ep->ContextRecord->Esp); 120 | log_info("EBP: 0x%p", ep->ContextRecord->Ebp); 121 | log_info("ESI: 0x%p", ep->ContextRecord->Esi); 122 | log_info("EDI: 0x%p", ep->ContextRecord->Edi); 123 | #endif 124 | /* If we come here we're sure to crash, so gracefully close logging */ 125 | log_shutdown(); 126 | return EXCEPTION_CONTINUE_SEARCH; 127 | } 128 | 129 | void install_syscall_handler() 130 | { 131 | if (!AddVectoredExceptionHandler(TRUE, exception_handler)) 132 | log_error("AddVectoredExceptionHandler() failed."); 133 | } 134 | -------------------------------------------------------------------------------- /src/syscall/syscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define _MACROCALL() 25 | 26 | #define _SYSCALL_NARG(...) _SYSCALL_NARG_ _MACROCALL() (__VA_ARGS__, _SYSCALL_RSEQ_N()) 27 | #define _SYSCALL_NARG_(...) _SYSCALL_ARG_N _MACROCALL() (__VA_ARGS__) 28 | #define _SYSCALL_ARG_N(_T1, _N1, _T2, _N2, _T3, _N3, _T4, _N4, _T5, _N5, _T6, _N6, _T7, _N7, _T8, _N8, _N, ...) _N 29 | #define _SYSCALL_RSEQ_N() \ 30 | _SYSCALL_MAP8, _SYSCALL_MAP8, \ 31 | _SYSCALL_MAP7, _SYSCALL_MAP7, \ 32 | _SYSCALL_MAP6, _SYSCALL_MAP6, \ 33 | _SYSCALL_MAP5, _SYSCALL_MAP5, \ 34 | _SYSCALL_MAP4, _SYSCALL_MAP4, \ 35 | _SYSCALL_MAP3, _SYSCALL_MAP3, \ 36 | _SYSCALL_MAP2, _SYSCALL_MAP2, \ 37 | _SYSCALL_MAP1, _SYSCALL_MAP0 38 | 39 | #define _SYSCALL_MAP0(f) 40 | #define _SYSCALL_MAP1(f, t, n, ...) f(t, n) 41 | #define _SYSCALL_MAP2(f, t, n, ...) f(t, n), _SYSCALL_MAP1 _MACROCALL() (f, __VA_ARGS__) 42 | #define _SYSCALL_MAP3(f, t, n, ...) f(t, n), _SYSCALL_MAP2 _MACROCALL() (f, __VA_ARGS__) 43 | #define _SYSCALL_MAP4(f, t, n, ...) f(t, n), _SYSCALL_MAP3 _MACROCALL() (f, __VA_ARGS__) 44 | #define _SYSCALL_MAP5(f, t, n, ...) f(t, n), _SYSCALL_MAP4 _MACROCALL() (f, __VA_ARGS__) 45 | #define _SYSCALL_MAP6(f, t, n, ...) f(t, n), _SYSCALL_MAP5 _MACROCALL() (f, __VA_ARGS__) 46 | #define _SYSCALL_MAP7(f, t, n, ...) f(t, n), _SYSCALL_MAP6 _MACROCALL() (f, __VA_ARGS__) 47 | #define _SYSCALL_MAP8(f, t, n, ...) f(t, n), _SYSCALL_MAP7 _MACROCALL() (f, __VA_ARGS__) 48 | #define _SYSCALL_MAP(f, ...) \ 49 | _SYSCALL_NARG _MACROCALL() (__VA_ARGS__) _MACROCALL() (f, __VA_ARGS__) 50 | 51 | #define _SYSCALL_WRAPPER(t, n) intptr_t n 52 | #define _SYSCALL_CALL(t, n) (t)n 53 | #define _SYSCALL_ACTUAL(t, n) t n 54 | 55 | #define DEFINE_SYSCALL(name, ...) \ 56 | intptr_t sys_##name(_SYSCALL_MAP _MACROCALL() (_SYSCALL_ACTUAL, __VA_ARGS__)); \ 57 | static intptr_t _sys_##name(_SYSCALL_MAP _MACROCALL() (_SYSCALL_WRAPPER, __VA_ARGS__)) \ 58 | { \ 59 | return sys_##name(_SYSCALL_MAP _MACROCALL() (_SYSCALL_CALL, __VA_ARGS__)); \ 60 | } \ 61 | intptr_t sys_##name(_SYSCALL_MAP _MACROCALL() (_SYSCALL_ACTUAL, __VA_ARGS__)) 62 | 63 | void install_syscall_handler(); 64 | -------------------------------------------------------------------------------- /src/syscall/syscall_dispatch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #ifdef _WIN64 28 | 29 | typedef int64_t syscall_fn(int64_t rdi, int64_t rsi, int64_t rdx, int64_t r10, intptr_t r8, intptr_t r9, PCONTEXT context); 30 | 31 | #define SYSCALL_COUNT 323 32 | #define SYSCALL(name) extern int64_t sys_##name(int64_t rdi, int64_t rsi, int64_t rdx, int64_t r10, intptr_t r8, intptr_t r9, PCONTEXT context); 33 | SYSCALL(read) /* syscall 0 */ 34 | #include "syscall_table_x64.h" 35 | #undef SYSCALL 36 | 37 | #define SYSCALL(name) sys_##name, 38 | static syscall_fn* syscall_table[SYSCALL_COUNT] = 39 | { 40 | SYSCALL(read) /* syscall 0 */ 41 | #include "syscall_table_x64.h" 42 | }; 43 | #undef SYSCALL 44 | 45 | #else 46 | 47 | typedef int syscall_fn(int ebx, int ecx, int edx, int esi, int edi, int ebp, PCONTEXT context); 48 | 49 | #define SYSCALL_COUNT 359 50 | #define SYSCALL(name) extern int sys_##name(int ebx, int ecx, int edx, int esi, int edi, int ebp, PCONTEXT context); 51 | #include "syscall_table_x86.h" 52 | #undef SYSCALL 53 | 54 | #define SYSCALL(name) sys_##name, 55 | syscall_fn* syscall_table[SYSCALL_COUNT] = 56 | { 57 | SYSCALL(unimplemented) /* syscall 0 */ 58 | #include "syscall_table_x86.h" 59 | }; 60 | #undef SYSCALL 61 | #endif 62 | 63 | void sys_unimplemented_imp(intptr_t id) 64 | { 65 | log_error("FATAL: Unimplemented syscall: %d", id); 66 | __debugbreak(); 67 | process_exit(1, 0); 68 | } 69 | 70 | void dispatch_syscall(PCONTEXT context) 71 | { 72 | #ifdef _WIN64 73 | context->Rax = (*syscall_table[context->Rax])(context->Rdi, context->Rsi, context->Rdx, context->R10, context->R8, context->R9, context); 74 | #endif 75 | } 76 | -------------------------------------------------------------------------------- /src/syscall/syscall_dispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | 25 | void dispatch_syscall(PCONTEXT context); 26 | -------------------------------------------------------------------------------- /src/syscall/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | -------------------------------------------------------------------------------- /src/syscall/tls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | #define WIN32_LEAN_AND_MEAN 26 | #include 27 | 28 | enum 29 | { 30 | /* Used by dbt */ 31 | TLS_ENTRY_DBT, 32 | TLS_ENTRY_SCRATCH, 33 | TLS_ENTRY_GS, 34 | TLS_ENTRY_GS_ADDR, 35 | TLS_ENTRY_RETURN_ADDR, 36 | TLS_ENTRY_KERNEL_ESP, 37 | TLS_ENTRY_ESP, 38 | TLS_ENTRY_EIP, 39 | 40 | TLS_KERNEL_ENTRY_COUNT 41 | }; 42 | 43 | void tls_init(); 44 | void tls_reset(); 45 | void tls_shutdown(); 46 | int tls_fork(HANDLE process); 47 | void tls_afterfork_parent(); 48 | void tls_afterfork_child(); 49 | 50 | int tls_kernel_entry_to_offset(int entry); 51 | int tls_user_entry_to_offset(int entry); 52 | 53 | int tls_set_thread_area(struct user_desc *u_info); 54 | -------------------------------------------------------------------------------- /src/syscall/vfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define WIN32_LEAN_AND_MEAN 30 | #include 31 | #include 32 | 33 | #define PATH_MAX 4096 34 | #define MAX_FD_COUNT 1024 35 | #define MAX_SYMLINK_LEVEL 8 36 | 37 | void vfs_init(); 38 | void vfs_reset(); 39 | void vfs_shutdown(); 40 | int vfs_fork(HANDLE process, DWORD process_id); 41 | void vfs_afterfork_parent(); 42 | void vfs_afterfork_child(); 43 | int vfs_store_file(struct file *f, int cloexec); 44 | 45 | int vfs_openat(int dirfd, const char *pathname, int flags, int internal_flags, int mode, struct file **f); 46 | struct file *vfs_get(int fd); 47 | void vfs_ref(struct file *f); 48 | void vfs_release(struct file *f); 49 | void vfs_get_root_mountpoint(struct mount_point *mp); 50 | bool vfs_get_mountpoint(int key, struct mount_point *mp); 51 | -------------------------------------------------------------------------------- /src/vsprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | 24 | static const char *lowercase = "0123456789abcdef"; 25 | static const char *uppercase = "0123456789ABCDEF"; 26 | 27 | #define IS_SIGNED(type) \ 28 | ((type)-1 < (type)0) 29 | 30 | #define PRINT_NUM(buf, x, type, utype, base, ch, width, fillchar) \ 31 | do \ 32 | { \ 33 | int b = (base); \ 34 | char nbuf[128]; \ 35 | type y = (x); \ 36 | int sign = 0; \ 37 | if (IS_SIGNED(type) && y < 0) \ 38 | { \ 39 | sign = 1; \ 40 | y = -y; \ 41 | } \ 42 | utype z = (utype)y; \ 43 | int len = 0; \ 44 | if (y == 0) \ 45 | nbuf[len++] = '0'; \ 46 | else \ 47 | { \ 48 | while (y > 0) \ 49 | { \ 50 | nbuf[len++] = ch[y % b]; \ 51 | y /= b; \ 52 | } \ 53 | } \ 54 | if (sign) \ 55 | nbuf[len++] = '-'; \ 56 | int w = (width) - len; \ 57 | while (w-- > 0) \ 58 | *buf++ = fillchar; \ 59 | while (len--) \ 60 | *buf++ = nbuf[len]; \ 61 | } while (0) 62 | 63 | int kvsprintf(char *buffer, const char *format, va_list args) 64 | { 65 | char *buf = buffer; 66 | while (*format) 67 | { 68 | if (*format == '%') 69 | { 70 | const char *f = format + 1; 71 | char fillchar = ' '; 72 | if (*f == '0') 73 | { 74 | fillchar = '0'; 75 | f++; 76 | } 77 | int width = 0; 78 | if (*f >= '1' && *f <= '9') 79 | { 80 | while (*f >= '0' && *f <= '9') 81 | width = width * 10 + (*f++ - '0'); 82 | } 83 | switch (*f++) 84 | { 85 | case '%': 86 | format = f; 87 | *buf++ = '%'; 88 | continue; 89 | 90 | case 'c': 91 | { 92 | format = f; 93 | *buf++ = va_arg(args, char); 94 | continue; 95 | } 96 | 97 | case 's': 98 | { 99 | format = f; 100 | const char *ch = va_arg(args, const char *); 101 | if (!ch) 102 | continue; 103 | while (*ch) 104 | *buf++ = *ch++; 105 | continue; 106 | } 107 | 108 | case 'S': 109 | { 110 | format = f; 111 | const wchar_t *ch = va_arg(args, const wchar_t *); 112 | if (!ch) 113 | continue; 114 | while (*ch) 115 | *buf++ = (char)*ch++; 116 | continue; 117 | } 118 | 119 | case 'd': 120 | { 121 | format = f; 122 | PRINT_NUM(buf, va_arg(args, int32_t), int32_t, uint32_t, 10, lowercase, width, fillchar); 123 | continue; 124 | } 125 | 126 | case 'u': 127 | { 128 | format = f; 129 | PRINT_NUM(buf, va_arg(args, uint32_t), uint32_t, uint32_t, 10, lowercase, width, fillchar); 130 | continue; 131 | } 132 | 133 | case 'o': 134 | { 135 | format = f; 136 | PRINT_NUM(buf, va_arg(args, uint32_t), uint32_t, uint32_t, 8, lowercase, width, fillchar); 137 | continue; 138 | } 139 | 140 | case 'x': 141 | { 142 | format = f; 143 | PRINT_NUM(buf, va_arg(args, uint32_t), uint32_t, uint32_t, 16, lowercase, width, fillchar); 144 | continue; 145 | } 146 | 147 | case 'X': 148 | { 149 | format = f; 150 | PRINT_NUM(buf, va_arg(args, uint32_t), uint32_t, uint32_t, 16, uppercase, width, fillchar); 151 | continue; 152 | } 153 | 154 | case 'l': 155 | { 156 | if (f[0] == 'd') 157 | { 158 | format = f + 1; 159 | PRINT_NUM(buf, va_arg(args, intptr_t), intptr_t, uintptr_t, 10, lowercase, width, fillchar); 160 | continue; 161 | } 162 | if (f[0] == 'u') 163 | { 164 | format = f + 1; 165 | PRINT_NUM(buf, va_arg(args, uintptr_t), uintptr_t, uintptr_t, 10, lowercase, width, fillchar); 166 | continue; 167 | } 168 | if (f[0] == 'l' && f[1] == 'x') 169 | { 170 | format = f + 2; 171 | PRINT_NUM(buf, va_arg(args, uint64_t), uint64_t, uint64_t, 16, lowercase, width, fillchar); 172 | continue; 173 | } 174 | if (f[0] == 'l' && f[1] == 'd') 175 | { 176 | format = f + 2; 177 | PRINT_NUM(buf, va_arg(args, int64_t), int64_t, uint64_t, 10, lowercase, width, fillchar); 178 | continue; 179 | } 180 | if (f[0] == 'l' && f[1] == 'u') 181 | { 182 | format = f + 2; 183 | PRINT_NUM(buf, va_arg(args, uint64_t), uint64_t, uint64_t, 10, lowercase, width, fillchar); 184 | continue; 185 | } 186 | } 187 | 188 | case 'p': 189 | { 190 | format = f; 191 | PRINT_NUM(buf, va_arg(args, uintptr_t), uintptr_t, uintptr_t, 16, lowercase, sizeof(void *) * 2, '0'); 192 | continue; 193 | } 194 | } 195 | } 196 | else if (*format == '\n') 197 | *buf++ = '\r'; 198 | *buf++ = *format++; 199 | } 200 | return (int)(buf - buffer); 201 | } 202 | -------------------------------------------------------------------------------- /src/vsprintf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | int kvsprintf(char *buffer, const char *format, va_list args); 25 | -------------------------------------------------------------------------------- /src/vsscanf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | static int kisspace(unsigned char ch) 26 | { 27 | return ch == ' ' || ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\v'; 28 | } 29 | 30 | #define IS_SIGNED(type) \ 31 | ((type)-1 < (type)0) 32 | 33 | #define PARSE_NUM(buf, out, type, utype) \ 34 | do \ 35 | { \ 36 | utype value = 0; \ 37 | bool neg = false; \ 38 | if (IS_SIGNED(type) & *buf == '-') \ 39 | { \ 40 | neg = true; \ 41 | buf++; \ 42 | } \ 43 | if (!(*buf >= '0' && *buf <= '9')) \ 44 | return count; \ 45 | while (*buf >= '0' && *buf <= '9') \ 46 | { \ 47 | utype v = value * 10 + *buf - '0'; \ 48 | if (v < value) \ 49 | return count; \ 50 | value = v; \ 51 | buf++; \ 52 | } \ 53 | if (neg) \ 54 | { \ 55 | if ((type)value < 0 && -(type)value != 0) \ 56 | return count; \ 57 | *out = -(type)value; \ 58 | } \ 59 | else if (IS_SIGNED(type)) \ 60 | { \ 61 | if ((type)value < 0) \ 62 | return count; \ 63 | *out = (type)value; \ 64 | } \ 65 | else \ 66 | *out = value; \ 67 | count++; \ 68 | } while (false) 69 | 70 | int kvsscanf(const char *buffer, const char *format, va_list args) 71 | { 72 | const char *buf = buffer; 73 | int count = 0; 74 | while (*format) 75 | { 76 | if (kisspace(*format)) 77 | { 78 | while (kisspace(*buf)) 79 | buf++; 80 | } 81 | else if (*format == '%') 82 | { 83 | format++; 84 | switch (*format++) 85 | { 86 | case '%': 87 | { 88 | if (*buffer++ != '%') 89 | return count; 90 | continue; 91 | } 92 | 93 | case 'n': 94 | { 95 | int *out = va_arg(args, int *); 96 | *out = buf - buffer; 97 | continue; 98 | } 99 | 100 | case 'd': 101 | { 102 | int32_t *out = va_arg(args, int32_t *); 103 | PARSE_NUM(buf, out, int32_t, uint32_t); 104 | continue; 105 | } 106 | 107 | case 'u': 108 | { 109 | uint32_t *out = va_arg(args, uint32_t *); 110 | PARSE_NUM(buf, out, uint32_t, uint32_t); 111 | continue; 112 | } 113 | } 114 | } 115 | else 116 | { 117 | if (*buffer++ != *format++) 118 | break; 119 | } 120 | } 121 | return count; 122 | } 123 | -------------------------------------------------------------------------------- /src/vsscanf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2014, 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | int kvsscanf(const char *buffer, const char *format, va_list args); 25 | -------------------------------------------------------------------------------- /src/win7compat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | typedef ULONGLONG (NTAPI RtlGetSystemTimePrecise_t)(); 24 | static RtlGetSystemTimePrecise_t *pfnRtlGetSystemTimePrecise; 25 | 26 | void win7compat_GetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimePreciseAsFileTime) 27 | { 28 | if (pfnRtlGetSystemTimePrecise) 29 | { 30 | ULONGLONG result = pfnRtlGetSystemTimePrecise(); 31 | lpSystemTimePreciseAsFileTime->dwLowDateTime = result & 0xFFFFFFFFULL; 32 | lpSystemTimePreciseAsFileTime->dwHighDateTime = result >> 32ULL; 33 | } 34 | else 35 | GetSystemTimeAsFileTime(lpSystemTimePreciseAsFileTime); 36 | } 37 | 38 | void win7compat_init() 39 | { 40 | HANDLE ntdll_handle; 41 | UNICODE_STRING module_file_name; 42 | RtlInitUnicodeString(&module_file_name, L"ntdll.dll"); 43 | NTSTATUS status = LdrLoadDll(NULL, 0, &module_file_name, &ntdll_handle); 44 | if (!NT_SUCCESS(status)) 45 | return; 46 | ANSI_STRING function_name; 47 | RtlInitAnsiString(&function_name, "RtlGetSystemTimePrecise"); 48 | LdrGetProcedureAddress(ntdll_handle, &function_name, 0, (PVOID *)&pfnRtlGetSystemTimePrecise); 49 | } 50 | -------------------------------------------------------------------------------- /src/win7compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Foreign Linux. 3 | * 4 | * Copyright (C) 2015 Xiangyan Sun 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | 25 | void win7compat_GetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimePreciseAsFileTime); 26 | void win7compat_init(); 27 | --------------------------------------------------------------------------------