diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 3f4a05c8..40b6ad4c 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "101.17"; + static const string Version = "101.18"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/icarus/Database/Super Famicom.bml b/icarus/Database/Super Famicom.bml index 723a7f4f..4e168bff 100644 --- a/icarus/Database/Super Famicom.bml +++ b/icarus/Database/Super Famicom.bml @@ -12,6 +12,128 @@ cartridge sha256:dd499445275fca6692c0487a8bd70a23f6c8e78e766df0e3c58fbbe53f8adb0 : name: Legende de Zelda - La Triforce des Dieux, La : title: La Legende de Zelda: La Triforce des Dieux +cartridge sha256:41084f83e269d46b9d589f11c802a15e84fede57d604c7986053f2858f757adc + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-ASDP-EUR + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Archer Maclean's Super Dropzone + : title: Archer Maclean's Super Dropzone + +cartridge sha256:6fe482f91a59a71992e14014a0a4e23fb866cf4e870c10d57c81b0c20ae6688e + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-3U-EUR + : board: SHVC-1A0N-30 + : revision: 1.0 + : name: International Superstar Soccer + : title: International Superstar Soccer + +cartridge sha256:2516843fa405ab1aa1f242b57f19977519aefb68599474d2c7065aaef88ecb88 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-AJGP-EUR + : board: SHVC-1A0N-30 + : revision: 1.0 + : name: Jungle Strike + : title: Jungle Strike + +cartridge sha256:964f8391806bc8d674f24aa2f201b20982d2f2f3e3efb2f730c4a34a289c3007 + :board region=pal + : rom name=program.rom size=0x300000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : + :information + : serial: SNSP-28-EUR + : board: SHVC-BJ0N-01 + : revision: 1.1 + : name: Mortal Kombat 2 + : title: Mortal Kombat II + +cartridge sha256:b7fa4b79590ecdef2d0303b5cbccf1e1a3af31fca289652acbdb3d5381137f24 + :board region=pal + : rom name=program.rom size=0x400000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : + :information + : serial: SNSP-A3MP-EUR + : board: SHVC-1J0N-20 + : revision: 1.0 + : name: Mortal Kombat 3 + : title: Mortal Kombat 3 + +cartridge sha256:166fe888ac03f88cce5759c1008021082bd81254aab8fea8203cdb13080709d7 + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-APFP-EUR + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Pinball Fantasies + : title: Pinball Fantasies + +cartridge sha256:09fdef0c959e7275563f65d8267d95a20104f054e9438e9ac739ef7f46120a2d + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-JA-EUR + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Smash Tennis + : title: Smash Tennis + +cartridge sha256:9638d4daa7bc63fd178b77c4487c3b080def5b808c0b7ccc959101f33e221b42 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-AMCP-EUR + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Spider-Man & Venom - Maximum Carnage + : title: Spider-Man & Venom: Maximum Carnage + +cartridge sha256:abe8db202f9bd12d845a4c7ecb97d85fb149d7f17a608b3eae015d92f52f2c04 + :board region=pal + : superfx + : map address=00-3f,80-bf:3000-34ff + : rom name=program.rom size=0x100000 + : map address=00-3f,80-bf:8000-ffff mask=0x8000 + : map address=40-5f,c0-df:0000-ffff + : ram name=save.ram size=0x10000 + : map address=00-3f,80-bf:6000-7fff size=0x2000 + : map address=70-71,f0-f1:0000-ffff + : + :information + : serial: SNSP-CQ-FAH + : board: SHVC-1CA6B-01 + : revision: 1.0 + : name: Stunt Race FX + : title: Stunt Race FX + cartridge sha256:e678a29a93111cf2016c487ba9977b14de8f719040651a42c74bd74eea2d0d81 :board region=ntsc : rom name=program.rom size=0x200000 @@ -70,6 +192,35 @@ cartridge sha256:1444ab11f96f7750db992e9a4160532b27abede8a7054128c09f448300c91eb : name: Secret of Mana : title: Secret of Mana +cartridge sha256:35c1d6623748f66e254843cf340121e3e268a8301951f35c7ba3ef666bc293bf + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-S2-NOE + : board: SHVC-1A0N-10 + : revision: 1.0 + : name: Street Fighter II - The World Warrior + : title: Street Fighter II: The World Warrior + +cartridge sha256:4d7fc331a811b8dc630b469262fd6f45e289243cef83101f32038158967d1b28 + :board region=pal + : rom name=program.rom size=0x40000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : icd2 revision=1 + : map address=00-3f,80-bf:6000-67ff,7000-7fff + : rom name=sgb.boot.rom size=0x100 + : + :information + : serial: SNSP-A-SG-NOE + : board: SGB-R-10 + : revision: 1.2 + : name: Super Game Boy + : title: Super Game Boy + cartridge sha256:613cd1a31eaded18648168bd7453a57830ca9a6f3c10de5154625436fbd49556 :board region=pal : rom name=program.rom size=0x400000 @@ -85,6 +236,202 @@ cartridge sha256:613cd1a31eaded18648168bd7453a57830ca9a6f3c10de5154625436fbd4955 : name: Terranigma : title: Terranigma +cartridge sha256:a1105819d48c04d680c8292bbfa9abbce05224f1bc231afd66af43b7e0a1fd4e + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-4L-NOE + : board: SHVC-1A3M-30 + : revision: 1.0 + : name: Unirally + : title: Unirally + +cartridge sha256:0a49023824d812c64cd262db6e85ce9900c88af7ac6dab3e47078ab0dd1e546c + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-YN-UKV + : board: SHVC-2A0N-10 + : revision: 1.0 + : name: Bubsy I - Claws Encounters of the Furred Kind + : title: Bubsy in Claws Encounters of the Furred Kind + +cartridge sha256:dddacae010766c1201f50810fcf15dff7c0f6d41ac1a1004c8eea4873a71db12 + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-1f,80-9f:8000-ffff mask=0x8000 + : ram name=save.ram size=0x800 + : map address=70-7d,f0-ff:0000-ffff + : + :information + : serial: SNSP-FZ-UKV + : board: SHVC-1A1B-05 + : revision: 1.0 + : name: F-Zero + : title: F-Zero + +cartridge sha256:e9e2152411fec3bd10e8cd4587b62717169a25a4cd28f491f8e477b9aae2fcee + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-7N-UKV + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Fun & Games + : title: fun 'n games + +cartridge sha256:9d936f3b0b5bea0b7c4588e65fa147fff1108d0e630337dd75eb16133a55e317 + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-8S-UKV + : board: SHVC-1A3M-20 + : revision: 1.1 + : name: International Sensible Soccer - World Champions + : title: International Sensible Soccer: World Champions + +cartridge sha256:ddad4a3708b8cf760e520b784f42d7085154b0699f3824b8d722512ccab687cb + :board region=pal + : rom name=program.rom size=0x400000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : + :information + : serial: SNSP-AKLP-UKV + : board: SHVC-1J0N-20 + : revision: 1.0 + : name: Killer Instinct + : title: Killer Instinct + +cartridge sha256:654183585e88abf965b19570c194f3d69ef209a7f2d32f71881eceaea6a3487e + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-1f,80-9f:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-ffff + : + :information + : serial: SNSP-ZL-UKV + : board: SHVC-1A3B-13 + : revision: 1.0 + : name: Legend of Zelda - A Link to the Past, The + : title: The Legend of Zelda: A Link to the Past + +cartridge sha256:d147bfe392e8c2129fb887379410804d79be426bbffdd01cec7bd2332e03f39e + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-1f,80-9f:8000-ffff mask=0x8000 + : necdsp model=uPD7725 frequency=8000000 + : map address=30-3f,b0-bf:8000-ffff mask=0x3fff + : prom name=dsp1b.program.rom size=0x1800 + : drom name=dsp1b.data.rom size=0x800 + : dram name=dsp1b.data.ram size=0x200 volatile + : + :information + : serial: SNSP-PW-UKV + : board: SHVC-1B0N-10 + : revision: 1.0 + : name: Pilotwings + : title: Pilotwings + +cartridge sha256:5702fb6978229e398075cf0d20927b47a5881b572532813557e86b8e9cf63db0 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : ram name=save.ram size=0x2000 + : map address=20-3f,a0-bf:6000-7fff mask=0xe000 + : + :information + : serial: SNSP-K2-UKV + : board: SHVC-1J3M-20 + : revision: 1.1 + : name: Secret of Mana + : title: Secret of Mana + +cartridge sha256:e95278ec68bf983111a52e38d5e6031c41141858e87e2cb8ef92fdfe17e41a15 + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-8S-UKV + : board: SHVC-1A3M-20 + : revision: 1.0 + : name: Sensible Soccer - European Champions + : title: Sensible Soccer: European Champions + +cartridge sha256:8c7a8aa1d16aeef31244b016ac951eab0b9ccd46daea61adbe890e5c5daa29c6 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-XN-UKV + : board: SHVC-1A0N-30 + : revision: 1.0 + : name: Star Trek - The Next Generation - Future's Past + : title: Star Trek: The Next Generation - Future's Past + +cartridge sha256:80e7ba7c756c70eedd55ca4548c1965f84f9ef01d3a5ca91a2e5465a6930c49a + :board region=pal + : superfx + : map address=00-3f,80-bf:3000-34ff + : rom name=program.rom size=0x100000 + : map address=00-1f,80-9f:8000-ffff mask=0x8000 + : ram name=save.ram size=0x8000 + : map address=60-7d,e0-ff:0000-ffff + : + :information + : serial: SNSP-FO-UKV + : board: SNSP-1C0N5S-01 + : revision: 1.1 + : name: Starwing + : title: Starwing + +cartridge sha256:b8ee1b5b9deae5c84fa209815515030109cc271b645a18de882aaf1b254cda1f + :board region=pal + : rom name=program.rom size=0x280000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : + :information + : serial: SNSP-TI-UKV + : board: SHVC-BJ0N-01 + : revision: 1.0 + : name: Street Fighter II Turbo - Hyper Fighting + : title: Street Fighter II Turbo: Hyper Fighting + +cartridge sha256:df43b3a4f511401a4d162ee6e7e3b08485533600dc44a29ee0a829b937b144d4 + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-KE-UKV + : board: SHVC-1A0N-20 + : revision: 1.0 + : name: Striker + : title: Striker + cartridge sha256:f1a75578e6711716340bb26ea93bf05d5762bc7da21dbc19576fc65de1e885b5 :board region=pal : rom name=program.rom size=0x100000 @@ -98,6 +445,81 @@ cartridge sha256:f1a75578e6711716340bb26ea93bf05d5762bc7da21dbc19576fc65de1e885b : name: Super Aleste : title: Super Aleste +cartridge sha256:9760fb407282d91005044fb08f9c15dc3e0ae65063a02eedfbbd285566501fd0 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-4M-UKV + : board: SHVC-2A3M-01 + : revision: 1.0 + : name: Super Mario All-Stars + : title: Super Mario All-Stars + +cartridge sha256:12d04359329bd646fc65c62db6121b4a7e4ece68556d68252e81ced421069f4c + :board region=pal + : rom name=program.rom size=0x80000 + : map address=00-3f,80-bf:8000-ffff + : map address=40-7d,c0-ff:0000-ffff + : ram name=save.ram size=0x800 + : map address=20-3f,a0-bf:6000-7fff mask=0xe000 + : necdsp model=uPD7725 frequency=8000000 + : map address=00-1f,80-9f:6000-7fff mask=0xfff + : prom name=dsp1.program.rom size=0x1800 + : drom name=dsp1.data.rom size=0x800 + : dram name=dsp1.data.ram size=0x200 volatile + : + :information + : serial: SNSP-MK-UKV + : board: SHVC-1K1B-01 + : revision: 1.0 + : name: Super Mario Kart + : title: Super Mario Kart + +cartridge sha256:640acb63dae038ad6f0ae65e103416f5a1f84d4a37ddaeeab5046122def774d5 + :board region=pal + : rom name=program.rom size=0x300000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-RI-UKV + : board: SHVC-BA3M-10 + : revision: 1.0 + : name: Super Metroid + : title: Super Metroid + +cartridge sha256:3438e78d35634d0ed7f58cb395c77da548fb601248725a18365edaed38a565d5 + :board region=pal + : rom name=program.rom size=0x200000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : ram name=save.ram size=0x2000 + : map address=70-7d,f0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-4Q-UKV + : board: SHVC-1A3M-30 + : revision: 1.0 + : name: Super Punch-Out!! + : title: Super Punch-Out!! + +cartridge sha256:7c7e90fb7c762769219234baf7b5fa6bf574fff7dc63b7134d49ec7c8b38ea7e + :board region=pal + : rom name=program.rom size=0x100000 + : map address=00-7d,80-ff:8000-ffff mask=0x8000 + : map address=40-7d,c0-ff:0000-7fff mask=0x8000 + : + :information + : serial: SNSP-SR-UKV + : board: SHVC-1A0N-02 + : revision: 1.0 + : name: Super R-Type + : title: Super R-Type + cartridge sha256:2ffe8828480f943056fb1ab5c3c84d48a0bf8cbe3ed7c9960b349b59adb07f3b :board region=ntsc : rom name=program.rom size=0x200000 diff --git a/libco/amd64.c b/libco/amd64.c index 37122f44..235708ab 100644 --- a/libco/amd64.c +++ b/libco/amd64.c @@ -1,15 +1,12 @@ /* - libco.amd64 (2015-06-19) + libco.amd64 (2016-09-14) author: byuu license: public domain */ #define LIBCO_C #include "libco.h" - -//Win64 only: provides a substantial speed-up, but will thrash XMM regs -//do not use this unless you are certain your application won't use SSE -//#define LIBCO_AMD64_NO_SSE +#include "settings.h" #include #include @@ -22,9 +19,14 @@ static thread_local long long co_active_buffer[64]; static thread_local cothread_t co_active_handle = 0; static void (*co_swap)(cothread_t, cothread_t) = 0; +#ifdef LIBCO_MPROTECT + alignas(4096) +#else + section(text) +#endif #ifdef _WIN32 /* ABI: Win64 */ - static unsigned char co_swap_function[] = { + static const unsigned char co_swap_function[4096] = { 0x48, 0x89, 0x22, /* mov [rdx],rsp */ 0x48, 0x8b, 0x21, /* mov rsp,[rcx] */ 0x58, /* pop rax */ @@ -36,7 +38,7 @@ static void (*co_swap)(cothread_t, cothread_t) = 0; 0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+48],r13 */ 0x4c, 0x89, 0x72, 0x38, /* mov [rdx+56],r14 */ 0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+64],r15 */ - #if !defined(LIBCO_AMD64_NO_SSE) + #if !defined(LIBCO_NO_SSE) 0x0f, 0x29, 0x72, 0x50, /* movaps [rdx+ 80],xmm6 */ 0x0f, 0x29, 0x7a, 0x60, /* movaps [rdx+ 96],xmm7 */ 0x44, 0x0f, 0x29, 0x42, 0x70, /* movaps [rdx+112],xmm8 */ @@ -57,7 +59,7 @@ static void (*co_swap)(cothread_t, cothread_t) = 0; 0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+48] */ 0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+56] */ 0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+64] */ - #if !defined(LIBCO_AMD64_NO_SSE) + #if !defined(LIBCO_NO_SSE) 0x0f, 0x28, 0x71, 0x50, /* movaps xmm6, [rcx+ 80] */ 0x0f, 0x28, 0x79, 0x60, /* movaps xmm7, [rcx+ 96] */ 0x44, 0x0f, 0x28, 0x41, 0x70, /* movaps xmm8, [rcx+112] */ @@ -75,13 +77,15 @@ static void (*co_swap)(cothread_t, cothread_t) = 0; #include - void co_init() { + static void co_init() { + #ifdef LIBCO_MPROTECT DWORD old_privileges; - VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); + VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges); + #endif } #else /* ABI: SystemV */ - static unsigned char co_swap_function[] = { + static const unsigned char co_swap_function[4096] = { 0x48, 0x89, 0x26, /* mov [rsi],rsp */ 0x48, 0x8b, 0x27, /* mov rsp,[rdi] */ 0x58, /* pop rax */ @@ -103,11 +107,13 @@ static void (*co_swap)(cothread_t, cothread_t) = 0; #include #include - void co_init() { + static void co_init() { + #ifdef LIBCO_MPROTECT unsigned long long addr = (unsigned long long)co_swap_function; unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE)); unsigned long long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); + mprotect((void*)base, size, PROT_READ | PROT_EXEC); + #endif } #endif diff --git a/libco/arm.c b/libco/arm.c index 70dbdd1b..25f0b16c 100644 --- a/libco/arm.c +++ b/libco/arm.c @@ -1,11 +1,12 @@ /* - libco.arm (2015-06-18) + libco.arm (2016-09-14) author: byuu license: public domain */ #define LIBCO_C #include "libco.h" +#include "settings.h" #include #include @@ -20,17 +21,24 @@ static thread_local unsigned long co_active_buffer[64]; static thread_local cothread_t co_active_handle = 0; static void (*co_swap)(cothread_t, cothread_t) = 0; -static unsigned long co_swap_function[] = { +#ifdef LIBCO_MPROTECT + alignas(4096) +#else + section(text) +#endif +static const unsigned long co_swap_function[1024] = { 0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */ 0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */ 0xe12fff1e, /* bx lr */ }; -void co_init() { +static void co_init() { + #ifdef LIBCO_MPROTECT unsigned long addr = (unsigned long)co_swap_function; unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); unsigned long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); + mprotect((void*)base, size, PROT_READ | PROT_EXEC); + #endif } cothread_t co_active() { diff --git a/libco/fiber.c b/libco/fiber.c index f57c0799..f2c5b726 100644 --- a/libco/fiber.c +++ b/libco/fiber.c @@ -17,7 +17,7 @@ extern "C" { static thread_local cothread_t co_active_ = 0; -static void __stdcall co_thunk(void *coentry) { +static void __stdcall co_thunk(void* coentry) { ((void (*)(void))coentry)(); } diff --git a/libco/libco.h b/libco/libco.h index 1851696e..792df0bd 100644 --- a/libco/libco.h +++ b/libco/libco.h @@ -1,6 +1,5 @@ /* - libco - version: 0.17 (2015-06-18) + libco v18 (2016-09-14) author: byuu license: public domain */ @@ -8,14 +7,6 @@ #ifndef LIBCO_H #define LIBCO_H -#ifdef LIBCO_C - #ifdef LIBCO_MP - #define thread_local __thread - #else - #define thread_local - #endif -#endif - #ifdef __cplusplus extern "C" { #endif diff --git a/libco/ppc.c b/libco/ppc.c index d509cd9e..efec3aa8 100644 --- a/libco/ppc.c +++ b/libco/ppc.c @@ -1,37 +1,33 @@ /* - libco.ppc (2010-10-17) + libco.ppc (2016-09-14) author: blargg license: public domain */ -/* PowerPC 32/64 using embedded or external asm, with optional -floating-point and AltiVec save/restore */ - #define LIBCO_C #include "libco.h" +#include "settings.h" #include #include #include -#define LIBCO_MPROTECT (__unix__ && !LIBCO_PPC_ASM) - #if LIBCO_MPROTECT - #include - #include + #include + #include #endif -/* State format (offsets in 32-bit words) +/* state format (offsets in 32-bit words) -+0 Pointer to swap code - Rest of function descriptor for entry function -+8 PC -+10 SP - Special regs - GPRs - FPRs - VRs - stack + +0 pointer to swap code + rest of function descriptor for entry function + +8 PC ++10 SP + special registers + GPRs + FPRs + VRs + stack */ enum { state_size = 1024 }; @@ -40,369 +36,332 @@ enum { stack_align = 256 }; static thread_local cothread_t co_active_handle = 0; -/**** Determine environment ****/ +/* determine environment */ #define LIBCO_PPC64 (_ARCH_PPC64 || __PPC64__ || __ppc64__ || __powerpc64__) -/* Whether function calls are indirect through a descriptor, -or are directly to function */ +/* whether function calls are indirect through a descriptor, or are directly to function */ #ifndef LIBCO_PPCDESC - #if !_CALL_SYSV && (_CALL_AIX || _CALL_AIXDESC || LIBCO_PPC64) - #define LIBCO_PPCDESC 1 - #endif + #if !_CALL_SYSV && (_CALL_AIX || _CALL_AIXDESC || LIBCO_PPC64) + #define LIBCO_PPCDESC 1 + #endif #endif -#ifdef LIBCO_PPC_ASM - - #ifdef __cplusplus - extern "C" - #endif - - /* Swap code is in ppc.S */ - void co_swap_asm( cothread_t, cothread_t ); - #define CO_SWAP_ASM( x, y ) co_swap_asm( x, y ) - +#ifdef LIBCO_MPROTECT + alignas(4096) #else - -/* Swap code is here in array. Please leave dieassembly comments, -as they make it easy to see what it does, and reorder instructions -if one wants to see whether that improves performance. */ -static const uint32_t libco_ppc_code [] = { -#if LIBCO_PPC64 - 0x7d000026, /* mfcr r8 */ - 0xf8240028, /* std r1,40(r4) */ - 0x7d2802a6, /* mflr r9 */ - 0xf9c40048, /* std r14,72(r4) */ - 0xf9e40050, /* std r15,80(r4) */ - 0xfa040058, /* std r16,88(r4) */ - 0xfa240060, /* std r17,96(r4) */ - 0xfa440068, /* std r18,104(r4) */ - 0xfa640070, /* std r19,112(r4) */ - 0xfa840078, /* std r20,120(r4) */ - 0xfaa40080, /* std r21,128(r4) */ - 0xfac40088, /* std r22,136(r4) */ - 0xfae40090, /* std r23,144(r4) */ - 0xfb040098, /* std r24,152(r4) */ - 0xfb2400a0, /* std r25,160(r4) */ - 0xfb4400a8, /* std r26,168(r4) */ - 0xfb6400b0, /* std r27,176(r4) */ - 0xfb8400b8, /* std r28,184(r4) */ - 0xfba400c0, /* std r29,192(r4) */ - 0xfbc400c8, /* std r30,200(r4) */ - 0xfbe400d0, /* std r31,208(r4) */ - 0xf9240020, /* std r9,32(r4) */ - 0xe8e30020, /* ld r7,32(r3) */ - 0xe8230028, /* ld r1,40(r3) */ - 0x48000009, /* bl 1 */ - 0x7fe00008, /* trap */ - 0x91040030,/*1:stw r8,48(r4) */ - 0x80c30030, /* lwz r6,48(r3) */ - 0x7ce903a6, /* mtctr r7 */ - 0xe9c30048, /* ld r14,72(r3) */ - 0xe9e30050, /* ld r15,80(r3) */ - 0xea030058, /* ld r16,88(r3) */ - 0xea230060, /* ld r17,96(r3) */ - 0xea430068, /* ld r18,104(r3) */ - 0xea630070, /* ld r19,112(r3) */ - 0xea830078, /* ld r20,120(r3) */ - 0xeaa30080, /* ld r21,128(r3) */ - 0xeac30088, /* ld r22,136(r3) */ - 0xeae30090, /* ld r23,144(r3) */ - 0xeb030098, /* ld r24,152(r3) */ - 0xeb2300a0, /* ld r25,160(r3) */ - 0xeb4300a8, /* ld r26,168(r3) */ - 0xeb6300b0, /* ld r27,176(r3) */ - 0xeb8300b8, /* ld r28,184(r3) */ - 0xeba300c0, /* ld r29,192(r3) */ - 0xebc300c8, /* ld r30,200(r3) */ - 0xebe300d0, /* ld r31,208(r3) */ - 0x7ccff120, /* mtcr r6 */ -#else - 0x7d000026, /* mfcr r8 */ - 0x90240028, /* stw r1,40(r4) */ - 0x7d2802a6, /* mflr r9 */ - 0x91a4003c, /* stw r13,60(r4) */ - 0x91c40040, /* stw r14,64(r4) */ - 0x91e40044, /* stw r15,68(r4) */ - 0x92040048, /* stw r16,72(r4) */ - 0x9224004c, /* stw r17,76(r4) */ - 0x92440050, /* stw r18,80(r4) */ - 0x92640054, /* stw r19,84(r4) */ - 0x92840058, /* stw r20,88(r4) */ - 0x92a4005c, /* stw r21,92(r4) */ - 0x92c40060, /* stw r22,96(r4) */ - 0x92e40064, /* stw r23,100(r4) */ - 0x93040068, /* stw r24,104(r4) */ - 0x9324006c, /* stw r25,108(r4) */ - 0x93440070, /* stw r26,112(r4) */ - 0x93640074, /* stw r27,116(r4) */ - 0x93840078, /* stw r28,120(r4) */ - 0x93a4007c, /* stw r29,124(r4) */ - 0x93c40080, /* stw r30,128(r4) */ - 0x93e40084, /* stw r31,132(r4) */ - 0x91240020, /* stw r9,32(r4) */ - 0x80e30020, /* lwz r7,32(r3) */ - 0x80230028, /* lwz r1,40(r3) */ - 0x48000009, /* bl 1 */ - 0x7fe00008, /* trap */ - 0x91040030,/*1:stw r8,48(r4) */ - 0x80c30030, /* lwz r6,48(r3) */ - 0x7ce903a6, /* mtctr r7 */ - 0x81a3003c, /* lwz r13,60(r3) */ - 0x81c30040, /* lwz r14,64(r3) */ - 0x81e30044, /* lwz r15,68(r3) */ - 0x82030048, /* lwz r16,72(r3) */ - 0x8223004c, /* lwz r17,76(r3) */ - 0x82430050, /* lwz r18,80(r3) */ - 0x82630054, /* lwz r19,84(r3) */ - 0x82830058, /* lwz r20,88(r3) */ - 0x82a3005c, /* lwz r21,92(r3) */ - 0x82c30060, /* lwz r22,96(r3) */ - 0x82e30064, /* lwz r23,100(r3) */ - 0x83030068, /* lwz r24,104(r3) */ - 0x8323006c, /* lwz r25,108(r3) */ - 0x83430070, /* lwz r26,112(r3) */ - 0x83630074, /* lwz r27,116(r3) */ - 0x83830078, /* lwz r28,120(r3) */ - 0x83a3007c, /* lwz r29,124(r3) */ - 0x83c30080, /* lwz r30,128(r3) */ - 0x83e30084, /* lwz r31,132(r3) */ - 0x7ccff120, /* mtcr r6 */ + section(text) #endif +static const uint32_t libco_ppc_code[1024] = { + #if LIBCO_PPC64 + 0x7d000026, /* mfcr r8 */ + 0xf8240028, /* std r1,40(r4) */ + 0x7d2802a6, /* mflr r9 */ + 0xf9c40048, /* std r14,72(r4) */ + 0xf9e40050, /* std r15,80(r4) */ + 0xfa040058, /* std r16,88(r4) */ + 0xfa240060, /* std r17,96(r4) */ + 0xfa440068, /* std r18,104(r4) */ + 0xfa640070, /* std r19,112(r4) */ + 0xfa840078, /* std r20,120(r4) */ + 0xfaa40080, /* std r21,128(r4) */ + 0xfac40088, /* std r22,136(r4) */ + 0xfae40090, /* std r23,144(r4) */ + 0xfb040098, /* std r24,152(r4) */ + 0xfb2400a0, /* std r25,160(r4) */ + 0xfb4400a8, /* std r26,168(r4) */ + 0xfb6400b0, /* std r27,176(r4) */ + 0xfb8400b8, /* std r28,184(r4) */ + 0xfba400c0, /* std r29,192(r4) */ + 0xfbc400c8, /* std r30,200(r4) */ + 0xfbe400d0, /* std r31,208(r4) */ + 0xf9240020, /* std r9,32(r4) */ + 0xe8e30020, /* ld r7,32(r3) */ + 0xe8230028, /* ld r1,40(r3) */ + 0x48000009, /* bl 1 */ + 0x7fe00008, /* trap */ + 0x91040030, /*1:stw r8,48(r4) */ + 0x80c30030, /* lwz r6,48(r3) */ + 0x7ce903a6, /* mtctr r7 */ + 0xe9c30048, /* ld r14,72(r3) */ + 0xe9e30050, /* ld r15,80(r3) */ + 0xea030058, /* ld r16,88(r3) */ + 0xea230060, /* ld r17,96(r3) */ + 0xea430068, /* ld r18,104(r3) */ + 0xea630070, /* ld r19,112(r3) */ + 0xea830078, /* ld r20,120(r3) */ + 0xeaa30080, /* ld r21,128(r3) */ + 0xeac30088, /* ld r22,136(r3) */ + 0xeae30090, /* ld r23,144(r3) */ + 0xeb030098, /* ld r24,152(r3) */ + 0xeb2300a0, /* ld r25,160(r3) */ + 0xeb4300a8, /* ld r26,168(r3) */ + 0xeb6300b0, /* ld r27,176(r3) */ + 0xeb8300b8, /* ld r28,184(r3) */ + 0xeba300c0, /* ld r29,192(r3) */ + 0xebc300c8, /* ld r30,200(r3) */ + 0xebe300d0, /* ld r31,208(r3) */ + 0x7ccff120, /* mtcr r6 */ + #else + 0x7d000026, /* mfcr r8 */ + 0x90240028, /* stw r1,40(r4) */ + 0x7d2802a6, /* mflr r9 */ + 0x91a4003c, /* stw r13,60(r4) */ + 0x91c40040, /* stw r14,64(r4) */ + 0x91e40044, /* stw r15,68(r4) */ + 0x92040048, /* stw r16,72(r4) */ + 0x9224004c, /* stw r17,76(r4) */ + 0x92440050, /* stw r18,80(r4) */ + 0x92640054, /* stw r19,84(r4) */ + 0x92840058, /* stw r20,88(r4) */ + 0x92a4005c, /* stw r21,92(r4) */ + 0x92c40060, /* stw r22,96(r4) */ + 0x92e40064, /* stw r23,100(r4) */ + 0x93040068, /* stw r24,104(r4) */ + 0x9324006c, /* stw r25,108(r4) */ + 0x93440070, /* stw r26,112(r4) */ + 0x93640074, /* stw r27,116(r4) */ + 0x93840078, /* stw r28,120(r4) */ + 0x93a4007c, /* stw r29,124(r4) */ + 0x93c40080, /* stw r30,128(r4) */ + 0x93e40084, /* stw r31,132(r4) */ + 0x91240020, /* stw r9,32(r4) */ + 0x80e30020, /* lwz r7,32(r3) */ + 0x80230028, /* lwz r1,40(r3) */ + 0x48000009, /* bl 1 */ + 0x7fe00008, /* trap */ + 0x91040030, /*1:stw r8,48(r4) */ + 0x80c30030, /* lwz r6,48(r3) */ + 0x7ce903a6, /* mtctr r7 */ + 0x81a3003c, /* lwz r13,60(r3) */ + 0x81c30040, /* lwz r14,64(r3) */ + 0x81e30044, /* lwz r15,68(r3) */ + 0x82030048, /* lwz r16,72(r3) */ + 0x8223004c, /* lwz r17,76(r3) */ + 0x82430050, /* lwz r18,80(r3) */ + 0x82630054, /* lwz r19,84(r3) */ + 0x82830058, /* lwz r20,88(r3) */ + 0x82a3005c, /* lwz r21,92(r3) */ + 0x82c30060, /* lwz r22,96(r3) */ + 0x82e30064, /* lwz r23,100(r3) */ + 0x83030068, /* lwz r24,104(r3) */ + 0x8323006c, /* lwz r25,108(r3) */ + 0x83430070, /* lwz r26,112(r3) */ + 0x83630074, /* lwz r27,116(r3) */ + 0x83830078, /* lwz r28,120(r3) */ + 0x83a3007c, /* lwz r29,124(r3) */ + 0x83c30080, /* lwz r30,128(r3) */ + 0x83e30084, /* lwz r31,132(r3) */ + 0x7ccff120, /* mtcr r6 */ + #endif -#ifndef LIBCO_PPC_NOFP - 0xd9c400e0, /* stfd f14,224(r4) */ - 0xd9e400e8, /* stfd f15,232(r4) */ - 0xda0400f0, /* stfd f16,240(r4) */ - 0xda2400f8, /* stfd f17,248(r4) */ - 0xda440100, /* stfd f18,256(r4) */ - 0xda640108, /* stfd f19,264(r4) */ - 0xda840110, /* stfd f20,272(r4) */ - 0xdaa40118, /* stfd f21,280(r4) */ - 0xdac40120, /* stfd f22,288(r4) */ - 0xdae40128, /* stfd f23,296(r4) */ - 0xdb040130, /* stfd f24,304(r4) */ - 0xdb240138, /* stfd f25,312(r4) */ - 0xdb440140, /* stfd f26,320(r4) */ - 0xdb640148, /* stfd f27,328(r4) */ - 0xdb840150, /* stfd f28,336(r4) */ - 0xdba40158, /* stfd f29,344(r4) */ - 0xdbc40160, /* stfd f30,352(r4) */ - 0xdbe40168, /* stfd f31,360(r4) */ - 0xc9c300e0, /* lfd f14,224(r3) */ - 0xc9e300e8, /* lfd f15,232(r3) */ - 0xca0300f0, /* lfd f16,240(r3) */ - 0xca2300f8, /* lfd f17,248(r3) */ - 0xca430100, /* lfd f18,256(r3) */ - 0xca630108, /* lfd f19,264(r3) */ - 0xca830110, /* lfd f20,272(r3) */ - 0xcaa30118, /* lfd f21,280(r3) */ - 0xcac30120, /* lfd f22,288(r3) */ - 0xcae30128, /* lfd f23,296(r3) */ - 0xcb030130, /* lfd f24,304(r3) */ - 0xcb230138, /* lfd f25,312(r3) */ - 0xcb430140, /* lfd f26,320(r3) */ - 0xcb630148, /* lfd f27,328(r3) */ - 0xcb830150, /* lfd f28,336(r3) */ - 0xcba30158, /* lfd f29,344(r3) */ - 0xcbc30160, /* lfd f30,352(r3) */ - 0xcbe30168, /* lfd f31,360(r3) */ -#endif + #ifndef LIBCO_PPC_NOFP + 0xd9c400e0, /* stfd f14,224(r4) */ + 0xd9e400e8, /* stfd f15,232(r4) */ + 0xda0400f0, /* stfd f16,240(r4) */ + 0xda2400f8, /* stfd f17,248(r4) */ + 0xda440100, /* stfd f18,256(r4) */ + 0xda640108, /* stfd f19,264(r4) */ + 0xda840110, /* stfd f20,272(r4) */ + 0xdaa40118, /* stfd f21,280(r4) */ + 0xdac40120, /* stfd f22,288(r4) */ + 0xdae40128, /* stfd f23,296(r4) */ + 0xdb040130, /* stfd f24,304(r4) */ + 0xdb240138, /* stfd f25,312(r4) */ + 0xdb440140, /* stfd f26,320(r4) */ + 0xdb640148, /* stfd f27,328(r4) */ + 0xdb840150, /* stfd f28,336(r4) */ + 0xdba40158, /* stfd f29,344(r4) */ + 0xdbc40160, /* stfd f30,352(r4) */ + 0xdbe40168, /* stfd f31,360(r4) */ + 0xc9c300e0, /* lfd f14,224(r3) */ + 0xc9e300e8, /* lfd f15,232(r3) */ + 0xca0300f0, /* lfd f16,240(r3) */ + 0xca2300f8, /* lfd f17,248(r3) */ + 0xca430100, /* lfd f18,256(r3) */ + 0xca630108, /* lfd f19,264(r3) */ + 0xca830110, /* lfd f20,272(r3) */ + 0xcaa30118, /* lfd f21,280(r3) */ + 0xcac30120, /* lfd f22,288(r3) */ + 0xcae30128, /* lfd f23,296(r3) */ + 0xcb030130, /* lfd f24,304(r3) */ + 0xcb230138, /* lfd f25,312(r3) */ + 0xcb430140, /* lfd f26,320(r3) */ + 0xcb630148, /* lfd f27,328(r3) */ + 0xcb830150, /* lfd f28,336(r3) */ + 0xcba30158, /* lfd f29,344(r3) */ + 0xcbc30160, /* lfd f30,352(r3) */ + 0xcbe30168, /* lfd f31,360(r3) */ + #endif -#ifdef __ALTIVEC__ - 0x7ca042a6, /* mfvrsave r5 */ - 0x39040180, /* addi r8,r4,384 */ - 0x39240190, /* addi r9,r4,400 */ - 0x70a00fff, /* andi. r0,r5,4095 */ - 0x90a40034, /* stw r5,52(r4) */ - 0x4182005c, /* beq- 2 */ - 0x7e8041ce, /* stvx v20,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ea049ce, /* stvx v21,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7ec041ce, /* stvx v22,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ee049ce, /* stvx v23,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f0041ce, /* stvx v24,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f2049ce, /* stvx v25,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f4041ce, /* stvx v26,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f6049ce, /* stvx v27,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f8041ce, /* stvx v28,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7fa049ce, /* stvx v29,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7fc041ce, /* stvx v30,r0,r8 */ - 0x7fe049ce, /* stvx v31,r0,r9 */ - 0x80a30034,/*2:lwz r5,52(r3) */ - 0x39030180, /* addi r8,r3,384 */ - 0x39230190, /* addi r9,r3,400 */ - 0x70a00fff, /* andi. r0,r5,4095 */ - 0x7ca043a6, /* mtvrsave r5 */ - 0x4d820420, /* beqctr */ - 0x7e8040ce, /* lvx v20,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ea048ce, /* lvx v21,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7ec040ce, /* lvx v22,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ee048ce, /* lvx v23,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f0040ce, /* lvx v24,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f2048ce, /* lvx v25,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f4040ce, /* lvx v26,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f6048ce, /* lvx v27,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f8040ce, /* lvx v28,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7fa048ce, /* lvx v29,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7fc040ce, /* lvx v30,r0,r8 */ - 0x7fe048ce, /* lvx v31,r0,r9 */ -#endif + #ifdef __ALTIVEC__ + 0x7ca042a6, /* mfvrsave r5 */ + 0x39040180, /* addi r8,r4,384 */ + 0x39240190, /* addi r9,r4,400 */ + 0x70a00fff, /* andi. r0,r5,4095 */ + 0x90a40034, /* stw r5,52(r4) */ + 0x4182005c, /* beq- 2 */ + 0x7e8041ce, /* stvx v20,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7ea049ce, /* stvx v21,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7ec041ce, /* stvx v22,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7ee049ce, /* stvx v23,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f0041ce, /* stvx v24,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7f2049ce, /* stvx v25,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f4041ce, /* stvx v26,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7f6049ce, /* stvx v27,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f8041ce, /* stvx v28,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7fa049ce, /* stvx v29,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7fc041ce, /* stvx v30,r0,r8 */ + 0x7fe049ce, /* stvx v31,r0,r9 */ + 0x80a30034, /*2:lwz r5,52(r3) */ + 0x39030180, /* addi r8,r3,384 */ + 0x39230190, /* addi r9,r3,400 */ + 0x70a00fff, /* andi. r0,r5,4095 */ + 0x7ca043a6, /* mtvrsave r5 */ + 0x4d820420, /* beqctr */ + 0x7e8040ce, /* lvx v20,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7ea048ce, /* lvx v21,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7ec040ce, /* lvx v22,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7ee048ce, /* lvx v23,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f0040ce, /* lvx v24,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7f2048ce, /* lvx v25,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f4040ce, /* lvx v26,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7f6048ce, /* lvx v27,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7f8040ce, /* lvx v28,r0,r8 */ + 0x39080020, /* addi r8,r8,32 */ + 0x7fa048ce, /* lvx v29,r0,r9 */ + 0x39290020, /* addi r9,r9,32 */ + 0x7fc040ce, /* lvx v30,r0,r8 */ + 0x7fe048ce, /* lvx v31,r0,r9 */ + #endif - 0x4e800420, /* bctr */ + 0x4e800420, /* bctr */ }; - #if LIBCO_PPCDESC - /* Function call goes through indirect descriptor */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) x)( x, y ) - #else - /* Function call goes directly to code */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) libco_ppc_code)( x, y ) - #endif - +#if LIBCO_PPCDESC + /* function call goes through indirect descriptor */ + #define CO_SWAP_ASM(x, y) ((void (*)(cothread_t, cothread_t))(uintptr_t)x)(x, y) +#else + /* function call goes directly to code */ + #define CO_SWAP_ASM(x, y) ((void (*)(cothread_t, cothread_t))(uintptr_t)libco_ppc_code)(x, y) #endif -static uint32_t* co_create_( unsigned size, uintptr_t entry ) -{ - uint32_t* t = (uint32_t*) malloc( size ); - - (void) entry; - - #if LIBCO_PPCDESC - if ( t ) - { - /* Copy entry's descriptor */ - memcpy( t, (void*) entry, sizeof (void*) * 3 ); - - /* Set function pointer to swap routine */ - #ifdef LIBCO_PPC_ASM - *(const void**) t = *(void**) &co_swap_asm; - #else - *(const void**) t = libco_ppc_code; - #endif - } - #endif - - return t; +static uint32_t* co_create_(unsigned size, uintptr_t entry) { + (void)entry; + + uint32_t* t = (uint32_t*)malloc(size); + + #if LIBCO_PPCDESC + if(t) { + memcpy(t, (void*)entry, sizeof(void*) * 3); /* copy entry's descriptor */ + *(const void**)t = libco_ppc_code; /* set function pointer to swap routine */ + } + #endif + + return t; } -cothread_t co_create( unsigned int size, void (*entry_)( void ) ) -{ - uintptr_t entry = (uintptr_t) entry_; - uint32_t* t = NULL; - - /* Be sure main thread was successfully allocated */ - if ( co_active() ) - { - size += state_size + above_stack + stack_align; - t = co_create_( size, entry ); - } - - if ( t ) - { - uintptr_t sp; - int shift; - - /* Save current registers into new thread, so that any special ones will - have proper values when thread is begun */ - CO_SWAP_ASM( t, t ); - - #if LIBCO_PPCDESC - /* Get real address */ - entry = (uintptr_t) *(void**) entry; - #endif - - /* Put stack near end of block, and align */ - sp = (uintptr_t) t + size - above_stack; - sp -= sp % stack_align; - - /* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we - save and restore them as 64 bits, regardless of the size the ABI - uses. So, we manually write pointers at the proper size. We always - save and restore at the same address, and since PPC is big-endian, - we must put the low byte first on PPC32. */ - - /* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts - and don't have to care how many bits uintptr_t is. */ - #if LIBCO_PPC64 - shift = 16; - #else - shift = 0; - #endif - - /* Set up so entry will be called on next swap */ - t [8] = (uint32_t) (entry >> shift >> shift); - t [9] = (uint32_t) entry; - - t [10] = (uint32_t) (sp >> shift >> shift); - t [11] = (uint32_t) sp; - } - - return t; +cothread_t co_create(unsigned int size, void (*entry_)(void)) { + uintptr_t entry = (uintptr_t)entry_; + uint32_t* t = 0; + + /* be sure main thread was successfully allocated */ + if(co_active()) { + size += state_size + above_stack + stack_align; + t = co_create_(size, entry); + } + + if(t) { + uintptr_t sp; + int shift; + + /* save current registers into new thread, so that any special ones will have proper values when thread is begun */ + CO_SWAP_ASM(t, t); + + #if LIBCO_PPCDESC + entry = (uintptr_t)*(void**)entry; /* get real address */ + #endif + + /* put stack near end of block, and align */ + sp = (uintptr_t)t + size - above_stack; + sp -= sp % stack_align; + + /* on PPC32, we save and restore GPRs as 32 bits. for PPC64, we + save and restore them as 64 bits, regardless of the size the ABI + uses. so, we manually write pointers at the proper size. we always + save and restore at the same address, and since PPC is big-endian, + we must put the low byte first on PPC32. */ + + /* if uintptr_t is 32 bits, >>32 is undefined behavior, + so we do two shifts and don't have to care how many bits uintptr_t is. */ + #if LIBCO_PPC64 + shift = 16; + #else + shift = 0; + #endif + + /* set up so entry will be called on next swap */ + t[ 8] = (uint32_t)(entry >> shift >> shift); + t[ 9] = (uint32_t)entry; + + t[10] = (uint32_t)(sp >> shift >> shift); + t[11] = (uint32_t)sp; + } + + return t; } -void co_delete( cothread_t t ) -{ - free( t ); +void co_delete(cothread_t t) { + free(t); } -static void co_init_( void ) -{ - #if LIBCO_MPROTECT - /* TODO: pre- and post-pad PPC code so that this doesn't make other - data executable and writable */ - long page_size = sysconf( _SC_PAGESIZE ); - if ( page_size > 0 ) - { - uintptr_t align = page_size; - uintptr_t begin = (uintptr_t) libco_ppc_code; - uintptr_t end = begin + sizeof libco_ppc_code; - - /* Align beginning and end */ - end += align - 1; - end -= end % align; - begin -= begin % align; - - mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC ); - } - #endif - - co_active_handle = co_create_( state_size, (uintptr_t) &co_switch ); +static void co_init_(void) { + #if LIBCO_MPROTECT + long page_size = sysconf(_SC_PAGESIZE); + if(page_size > 0) { + uintptr_t align = page_size; + uintptr_t begin = (uintptr_t)libco_ppc_code; + uintptr_t end = begin + sizeof libco_ppc_code; + + /* align beginning and end */ + end += align - 1; + end -= end % align; + begin -= begin % align; + + mprotect((void*)begin, end - begin, PROT_READ | PROT_EXEC); + } + #endif + + co_active_handle = co_create_(state_size, (uintptr_t)&co_switch); } -cothread_t co_active() -{ - if ( !co_active_handle ) - co_init_(); - - return co_active_handle; +cothread_t co_active() { + if(!co_active_handle) co_init_(); + + return co_active_handle; } -void co_switch( cothread_t t ) -{ - cothread_t old = co_active_handle; - co_active_handle = t; - - CO_SWAP_ASM( t, old ); +void co_switch(cothread_t t) { + cothread_t old = co_active_handle; + co_active_handle = t; + + CO_SWAP_ASM(t, old); } diff --git a/libco/settings.h b/libco/settings.h new file mode 100644 index 00000000..b419683a --- /dev/null +++ b/libco/settings.h @@ -0,0 +1,36 @@ +#ifdef LIBCO_C + +/*[amd64, arm, ppc, x86]: + by default, co_swap_function is marked as a text (code) section + if not supported, uncomment the below line to use mprotect instead */ +/* #define LIBCO_MPROTECT */ + +/*[amd64]: + Win64 only: provides a substantial speed-up, but will thrash XMM regs + do not use this unless you are certain your application won't use SSE */ +/* #define LIBCO_NO_SSE */ + +#ifdef LIBCO_C + #ifdef LIBCO_MP + #define thread_local __thread + #else + #define thread_local + #endif +#endif + +#if __STDC_VERSION__ >= 201112L + #ifndef _MSC_VER + #include + #endif +#else + #define alignas(bytes) +#endif + +#ifndef _MSC_VER + #define section(name) __attribute__((section("." #name "#"))) +#else + #define section(name) __declspec(allocate("." #name)) +#endif + +/* ifdef LIBCO_C */ +#endif diff --git a/libco/sjlj.c b/libco/sjlj.c index 9203efe7..dfa0aa45 100644 --- a/libco/sjlj.c +++ b/libco/sjlj.c @@ -5,11 +5,9 @@ */ /* - * Note this was designed for UNIX systems. Based on ideas expressed in a paper - * by Ralf Engelschall. - * For SJLJ on other systems, one would want to rewrite springboard() and - * co_create() and hack the jmb_buf stack pointer. - */ + note this was designed for UNIX systems. Based on ideas expressed in a paper by Ralf Engelschall. + for SJLJ on other systems, one would want to rewrite springboard() and co_create() and hack the jmb_buf stack pointer. +*/ #define LIBCO_C #include "libco.h" @@ -25,11 +23,12 @@ extern "C" { typedef struct { sigjmp_buf context; void (*coentry)(void); - void *stack; + void* stack; } cothread_struct; static thread_local cothread_struct co_primary; -static thread_local cothread_struct *creating, *co_running = 0; +static thread_local cothread_struct* creating; +static thread_local cothread_struct* co_running = 0; static void springboard(int ignored) { if(sigsetjmp(creating->context, 0)) { diff --git a/libco/ucontext.c b/libco/ucontext.c index 2e9e90ec..72ea8719 100644 --- a/libco/ucontext.c +++ b/libco/ucontext.c @@ -5,16 +5,16 @@ */ /* - * WARNING: the overhead of POSIX ucontext is very high, - * assembly versions of libco or libco_sjlj should be much faster - * - * This library only exists for two reasons: - * 1 - as an initial test for the viability of a ucontext implementation - * 2 - to demonstrate the power and speed of libco over existing implementations, - * such as pth (which defaults to wrapping ucontext on unix targets) - * - * Use this library only as a *last resort* - */ + WARNING: the overhead of POSIX ucontext is very high, + assembly versions of libco or libco_sjlj should be much faster + + this library only exists for two reasons: + 1: as an initial test for the viability of a ucontext implementation + 2: to demonstrate the power and speed of libco over existing implementations, + such as pth (which defaults to wrapping ucontext on unix targets) + + use this library only as a *last resort* +*/ #define LIBCO_C #include "libco.h" @@ -28,7 +28,7 @@ extern "C" { #endif static thread_local ucontext_t co_primary; -static thread_local ucontext_t *co_running = 0; +static thread_local ucontext_t* co_running = 0; cothread_t co_active() { if(!co_running) co_running = &co_primary; @@ -37,7 +37,7 @@ cothread_t co_active() { cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { if(!co_running) co_running = &co_primary; - ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t)); + ucontext_t* thread = (ucontext_t*)malloc(sizeof(ucontext_t)); if(thread) { if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { thread->uc_link = co_running; @@ -59,7 +59,7 @@ void co_delete(cothread_t cothread) { } void co_switch(cothread_t cothread) { - ucontext_t *old_thread = co_running; + ucontext_t* old_thread = co_running; co_running = (ucontext_t*)cothread; swapcontext(old_thread, co_running); } diff --git a/libco/x86.c b/libco/x86.c index 44bbe4b8..def3ac1c 100644 --- a/libco/x86.c +++ b/libco/x86.c @@ -1,11 +1,12 @@ /* - libco.x86 (2009-10-12) + libco.x86 (2016-09-14) author: byuu license: public domain */ #define LIBCO_C #include "libco.h" +#include "settings.h" #include #include @@ -26,8 +27,13 @@ static thread_local long co_active_buffer[64]; static thread_local cothread_t co_active_handle = 0; static void (fastcall *co_swap)(cothread_t, cothread_t) = 0; +#ifdef LIBCO_MPROTECT + alignas(4096) +#else + section(text) +#endif /* ABI: fastcall */ -static unsigned char co_swap_function[] = { +static const unsigned char co_swap_function[4096] = { 0x89, 0x22, /* mov [edx],esp */ 0x8b, 0x21, /* mov esp,[ecx] */ 0x58, /* pop eax */ @@ -45,19 +51,23 @@ static unsigned char co_swap_function[] = { #ifdef _WIN32 #include - void co_init() { + static void co_init() { + #ifdef LIBCO_MPROTECT DWORD old_privileges; - VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); + VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges); + #endif } #else #include #include - void co_init() { + static void co_init() { + #ifdef LIBCO_MPROTECT unsigned long addr = (unsigned long)co_swap_function; unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); unsigned long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); + mprotect((void*)base, size, PROT_READ | PROT_EXEC); + #endif } #endif diff --git a/nall/GNUmakefile b/nall/GNUmakefile index ec63d5ee..59f07f6b 100644 --- a/nall/GNUmakefile +++ b/nall/GNUmakefile @@ -36,8 +36,8 @@ ifeq ($(platform),) endif endif -cflags := -x c -std=c99 -objcflags := -x objective-c -std=c99 +cflags := -x c -std=c11 +objcflags := -x objective-c -std=c11 cppflags := -x c++ -std=c++14 objcppflags := -x objective-c++ -std=c++14 flags := @@ -61,10 +61,10 @@ endif # clang settings ifeq ($(findstring clang++,$(compiler)),clang++) - flags += -fwrapv + flags += -fno-strict-aliasing -fwrapv # gcc settings else ifeq ($(findstring g++,$(compiler)),g++) - flags += -fwrapv + flags += -fno-strict-aliasing -fwrapv endif # windows settings diff --git a/nall/certificates/byuu.crt b/nall/certificates/byuu.crt index 05babc39..d4c2ccbe 100644 --- a/nall/certificates/byuu.crt +++ b/nall/certificates/byuu.crt @@ -1,12 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIByDCCAU6gAwIBAgIJAI83xahWv0iSMAoGCCqGSM49BAMDMB4xDTALBgNVBAMM -BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwODMxMDQ1MjEzWhgPMjA5MTA4MTMw -NDUyMTNaMB4xDTALBgNVBAMMBGJ5dXUxDTALBgNVBAoMBGJ5dXUwdjAQBgcqhkjO -PQIBBgUrgQQAIgNiAAT5ArnlLKmJZrkmDwBNroM+djFS1CM/KLVXGZQUmkjyDJSB -/JeC/aT3v4g236kzcHu4+FBDPT1MhPUmtFC+mGjnWjtQsGHuTknGYXpjOEK77PXy -LL2m9gXB0eKE0SkMIdijVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYE -FErJPHQ5yHMo18r8c0LI4XmrKjnRMB8GA1UdIwQYMBaAFErJPHQ5yHMo18r8c0LI -4XmrKjnRMAoGCCqGSM49BAMDA2gAMGUCMQDAcBz38wdb5lJmcMf8Y1eqPZxXkgCt -OZklW1cXZnoB2w3yjdImujHVyEfhK684HCkCMEjsxEUPRf8tB0UKO836qKmAKFHW -OYBX8Sx6jlzonkb1miqjxiNQdTmGdkWk1IsP8Q== +MIIByTCCAU6gAwIBAgIJAMGBxB7ujnmaMAoGCCqGSM49BAMDMB4xDTALBgNVBAMM +BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwOTExMTM1MjE3WhgPMjA5MTA4MjQx +MzUyMTdaMB4xDTALBgNVBAMMBGJ5dXUxDTALBgNVBAoMBGJ5dXUwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAATgdIzJOkXMo3vfw+wshinYYt76IAox5sRcXYfbkTHZ5dGU +Sf/DlrCe/kTIhXe6mKUI6eUjPH7U5UruvHtwi6I7QILHoar1tp4rVGKp7mB3KuIS +qfuu90JhXMfUcwQp3WOjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYE +FKD7mEF6/bmtxOUSu05E0iYjRCrJMB8GA1UdIwQYMBaAFKD7mEF6/bmtxOUSu05E +0iYjRCrJMAoGCCqGSM49BAMDA2kAMGYCMQD3Nv8o4qbHOZUd8GUh4ye6Y08WkJ2w +8BZWTJFzAp+4nP9XZJeROQJd97+kQOCdLAICMQC2DtybVIQXaxefAaGi7IvtYcbL +fAWdtu5/dc7bzMpy9GicQkpw8uluxauX8gdnU/4= -----END CERTIFICATE----- diff --git a/nall/certificates/byuu.net.crt b/nall/certificates/byuu.net.crt new file mode 100644 index 00000000..bbb72444 --- /dev/null +++ b/nall/certificates/byuu.net.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6jCCAXCgAwIBAgIJAOrEeJHQ9mppMAoGCCqGSM49BAMDMB4xDTALBgNVBAMM +BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwOTExMTM1NDIwWhgPMjA5MTA4MjQx +MzU0MjBaMCIxETAPBgNVBAMMCGJ5dXUubmV0MQ0wCwYDVQQKDARieXV1MHYwEAYH +KoZIzj0CAQYFK4EEACIDYgAEL4l9yJtcslBRuaTr7wHJ/Wc7DIspKGv2S2+LYsxE +k3dZI902+J726IX2yiurWlLUEc3B+ooKs3VmhaW1QsStKdYVJVVGBD29zz3rvD/V +oeWjw63yZrSqNQ5S41qXNcMho3QwcjAMBgNVHRMBAf8EAjAAMCIGA1UdEQEB/wQY +MBaCCGJ5dXUubmV0ggoqLmJ5dXUubmV0MB0GA1UdDgQWBBTeXV7JKLjCikQbk+Um +ayFF8yRiSTAfBgNVHSMEGDAWgBSg+5hBev25rcTlErtORNImI0QqyTAKBggqhkjO +PQQDAwNoADBlAjEAgk0ud6h0OAfWNH6pSvMiyHAWQuh24cvkQY3mUNsZzAy36QEQ +X4UBWewxz1lyaFzLAjACXJZ1rZsMnGIgWXvFAsO2v53A612Ba3vH76naExASKbmx +VafrFb6bHXEc3aH/Xws= +-----END CERTIFICATE----- diff --git a/nall/certificates/byuu.org.crt b/nall/certificates/byuu.org.crt index 4e6ab30a..629007c7 100644 --- a/nall/certificates/byuu.org.crt +++ b/nall/certificates/byuu.org.crt @@ -1,13 +1,13 @@ -----BEGIN CERTIFICATE----- -MIIB6zCCAXCgAwIBAgIJAPQ6cLpDt9l8MAoGCCqGSM49BAMDMB4xDTALBgNVBAMM -BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwODMxMDQ1MzQyWhgPMjA5MTA4MTMw -NDUzNDJaMCIxETAPBgNVBAMMCGJ5dXUub3JnMQ0wCwYDVQQKDARieXV1MHYwEAYH -KoZIzj0CAQYFK4EEACIDYgAEuYjwx8y8nO9yAR7Hb8AB8lB1SSXk1lBm9ofcEzkN -SLOvrC+ESHR1C+w9krlbJlSq2wPA482DIW3aLukfNIdwhuTciVFBZfk0bgRgVqXq -Ha+iyL64/naqzWGxk5m/HDkFo3QwcjAMBgNVHRMBAf8EAjAAMCIGA1UdEQEB/wQY -MBaCCGJ5dXUub3JnggoqLmJ5dXUub3JnMB0GA1UdDgQWBBSJd/vrUirTNFcxur/9 -hN+Q55H+AzAfBgNVHSMEGDAWgBRKyTx0OchzKNfK/HNCyOF5qyo50TAKBggqhkjO -PQQDAwNpADBmAjEAh5Jc3nepWmrRJDLaGzy7ews23uEcrz3PfBbtJrTC3qw5b2Ig -fqZ6h5/nG7BXAeq9AjEAnxwn221GihthlL6nzSS5SRyjmR6crGfqWcQwSQTp8b+8 -DqXqRKiYVHoiedKJslCF +MIIB6jCCAXCgAwIBAgIJAOrEeJHQ9mpoMAoGCCqGSM49BAMDMB4xDTALBgNVBAMM +BGJ5dXUxDTALBgNVBAoMBGJ5dXUwIBcNMTYwOTExMTM1MzU1WhgPMjA5MTA4MjQx +MzUzNTVaMCIxETAPBgNVBAMMCGJ5dXUub3JnMQ0wCwYDVQQKDARieXV1MHYwEAYH +KoZIzj0CAQYFK4EEACIDYgAEH+ny1an5De9P1TJ0vmpGlpmrZszuV1lKTPut28Vx +98ieuBdmSNG493sJ+ga+adXPtItkck5M0jITR1NxcWvVlZtJG8L6ctEuVF6smkoy +1dbxzEeTIs+xjRQqaLN4U67ho3QwcjAMBgNVHRMBAf8EAjAAMCIGA1UdEQEB/wQY +MBaCCGJ5dXUub3JnggoqLmJ5dXUub3JnMB0GA1UdDgQWBBRhhKSsc+qUaBUNiyJX +j17UDBFuuTAfBgNVHSMEGDAWgBSg+5hBev25rcTlErtORNImI0QqyTAKBggqhkjO +PQQDAwNoADBlAjEApEbI/wT/cU7DRFvBEmfFMtVDJCJCTz4UEo1lJI9SPOEtgX3x +gJZg4deqeoAEffVGAjB2RWI1UPi/jnpJwTsuw4sp5UqFhY48qfqddPiSO4qlmb8s +1aEdP6gHoji22pHrKbY= -----END CERTIFICATE----- diff --git a/nall/emulation/21fx.hpp b/nall/emulation/21fx.hpp index a1396e20..03d451a4 100644 --- a/nall/emulation/21fx.hpp +++ b/nall/emulation/21fx.hpp @@ -4,6 +4,18 @@ #include using namespace nall; +using int8 = Integer< 8>; +using int16 = Integer<16>; +using int24 = Integer<24>; +using int32 = Integer<32>; +using int64 = Integer<64>; + +using uint8 = Natural< 8>; +using uint16 = Natural<16>; +using uint24 = Natural<24>; +using uint32 = Natural<32>; +using uint64 = Natural<64>; + struct FX { auto open(string_vector& args) -> bool; auto close() -> void; diff --git a/nall/http/client.hpp b/nall/http/client.hpp index 716d4e94..fa017546 100644 --- a/nall/http/client.hpp +++ b/nall/http/client.hpp @@ -5,18 +5,18 @@ namespace nall { namespace HTTP { struct Client : Role { - inline auto open(const string& hostname, unsigned port = 80) -> bool; + inline auto open(const string& hostname, uint port = 80) -> bool; inline auto upload(const Request& request) -> bool; inline auto download(const Request& request) -> Response; inline auto close() -> void; ~Client() { close(); } private: - signed fd = -1; + int fd = -1; addrinfo* info = nullptr; }; -auto Client::open(const string& hostname, unsigned port) -> bool { +auto Client::open(const string& hostname, uint port) -> bool { addrinfo hint = {0}; hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; diff --git a/nall/http/message.hpp b/nall/http/message.hpp index 0bb7c6b7..a7828540 100644 --- a/nall/http/message.hpp +++ b/nall/http/message.hpp @@ -83,10 +83,10 @@ struct Variables { struct Message { using type = Message; - virtual auto head(const function& callback) const -> bool = 0; + virtual auto head(const function& callback) const -> bool = 0; virtual auto setHead() -> bool = 0; - virtual auto body(const function& callback) const -> bool = 0; + virtual auto body(const function& callback) const -> bool = 0; virtual auto setBody() -> bool = 0; Variables header; diff --git a/nall/http/request.hpp b/nall/http/request.hpp index eba72179..b55ee308 100644 --- a/nall/http/request.hpp +++ b/nall/http/request.hpp @@ -9,14 +9,14 @@ namespace nall { namespace HTTP { struct Request : Message { using type = Request; - enum class RequestType : unsigned { None, Head, Get, Post }; + enum class RequestType : uint { None, Head, Get, Post }; explicit operator bool() const { return requestType() != RequestType::None; } - inline auto head(const function& callback) const -> bool override; + inline auto head(const function& callback) const -> bool override; inline auto setHead() -> bool override; - inline auto body(const function& callback) const -> bool override; + inline auto body(const function& callback) const -> bool override; inline auto setBody() -> bool override; auto ipv4() const -> bool { return _ipv6 == false; } @@ -40,7 +40,7 @@ struct Request : Message { string _path; }; -auto Request::head(const function& callback) const -> bool { +auto Request::head(const function& callback) const -> bool { if(!callback) return false; string output; @@ -122,7 +122,7 @@ auto Request::setHead() -> bool { return true; } -auto Request::body(const function& callback) const -> bool { +auto Request::body(const function& callback) const -> bool { if(!callback) return false; if(_body) { diff --git a/nall/http/response.hpp b/nall/http/response.hpp index ec0dcf7a..a72f2b85 100644 --- a/nall/http/response.hpp +++ b/nall/http/response.hpp @@ -11,19 +11,19 @@ struct Response : Message { Response(const Request& request) { setRequest(request); } explicit operator bool() const { return responseType() != 0; } - auto operator()(unsigned responseType) -> type& { return setResponseType(responseType); } + auto operator()(uint responseType) -> type& { return setResponseType(responseType); } - inline auto head(const function& callback) const -> bool override; + inline auto head(const function& callback) const -> bool override; inline auto setHead() -> bool override; - inline auto body(const function& callback) const -> bool override; + inline auto body(const function& callback) const -> bool override; inline auto setBody() -> bool override; auto request() const -> const Request* { return _request; } auto setRequest(const Request& value) -> type& { _request = &value; return *this; } - auto responseType() const -> unsigned { return _responseType; } - auto setResponseType(unsigned value) -> type& { _responseType = value; return *this; } + auto responseType() const -> uint { return _responseType; } + auto setResponseType(uint value) -> type& { _responseType = value; return *this; } auto hasData() const -> bool { return (bool)_data; } auto data() const -> const vector& { return _data; } @@ -38,20 +38,20 @@ struct Response : Message { inline auto setText(const string& value) -> type&; inline auto hasBody() const -> bool; - inline auto findContentLength() const -> unsigned; + inline auto findContentLength() const -> uint; inline auto findContentType() const -> string; inline auto findContentType(const string& suffix) const -> string; inline auto findResponseType() const -> string; inline auto setFileETag() -> void; const Request* _request = nullptr; - unsigned _responseType = 0; + uint _responseType = 0; vector _data; string _file; string _text; }; -auto Response::head(const function& callback) const -> bool { +auto Response::head(const function& callback) const -> bool { if(!callback) return false; string output; @@ -106,7 +106,7 @@ auto Response::setHead() -> bool { return true; } -auto Response::body(const function& callback) const -> bool { +auto Response::body(const function& callback) const -> bool { if(!callback) return false; if(!hasBody()) return true; bool chunked = header["Transfer-Encoding"].value() == "chunked"; @@ -154,7 +154,7 @@ auto Response::hasBody() const -> bool { return true; } -auto Response::findContentLength() const -> unsigned { +auto Response::findContentLength() const -> uint { if(auto contentLength = header["Content-Length"]) return contentLength.value().natural(); if(_body) return _body.size(); if(hasData()) return data().size(); @@ -229,6 +229,17 @@ auto Response::setData(const vector& value) -> type& { } auto Response::setFile(const string& value) -> type& { + //block path escalation exploits ("../" and "..\" in the file location) + bool valid = true; + for(uint n : range(value.size())) { + if(value(n + 0, '\0') != '.') continue; + if(value(n + 1, '\0') != '.') continue; + if(value(n + 2, '\0') != '/' && value(n + 2, '\0') != '\\') continue; + valid = false; + break; + } + if(!valid) return *this; + _file = value; string eTag = {"\"", chrono::utc::datetime(file::timestamp(value, file::time::modify)), "\""}; header.assign("Content-Length", file::size(value)); diff --git a/nall/http/role.hpp b/nall/http/role.hpp index 57c083ef..522cf5c0 100644 --- a/nall/http/role.hpp +++ b/nall/http/role.hpp @@ -10,18 +10,18 @@ namespace nall { namespace HTTP { struct Role { struct Settings { - signed connectionLimit = 1 * 1024; //server - signed headSizeLimit = 16 * 1024; //client, server - signed bodySizeLimit = 8192 * 1024; //client, server - signed chunkSize = 32 * 1024; //client, server - signed threadStackSize = 128 * 1024; //server - signed timeoutReceive = 15 * 1000; //server - signed timeoutSend = 15 * 1000; //server + int connectionLimit = 1 * 1024; //server + int headSizeLimit = 16 * 1024; //client, server + int bodySizeLimit = 8192 * 1024; //client, server + int chunkSize = 32 * 1024; //client, server + int threadStackSize = 128 * 1024; //server + int timeoutReceive = 15 * 1000; //server + int timeoutSend = 15 * 1000; //server } settings; inline auto configure(const string& parameters) -> bool; - inline auto download(signed fd, Message& message) -> bool; - inline auto upload(signed fd, const Message& message) -> bool; + inline auto download(int fd, Message& message) -> bool; + inline auto upload(int fd, const Message& message) -> bool; }; auto Role::configure(const string& parameters) -> bool { @@ -42,7 +42,7 @@ auto Role::configure(const string& parameters) -> bool { return true; } -auto Role::download(signed fd, Message& message) -> bool { +auto Role::download(int fd, Message& message) -> bool { auto& head = message._head; auto& body = message._body; string chunk; @@ -55,9 +55,9 @@ auto Role::download(signed fd, Message& message) -> bool { bool chunked = false; bool chunkReceived = false; bool chunkFooterReceived = true; - signed length = 0; - signed chunkLength = 0; - signed contentLength = 0; + int length = 0; + int chunkLength = 0; + int contentLength = 0; while(true) { if(auto limit = settings.headSizeLimit) if(head.size() >= limit) return false; @@ -116,7 +116,7 @@ auto Role::download(signed fd, Message& message) -> bool { p += length; length = 0; } else { - signed transferLength = min(length, chunkLength); + int transferLength = min(length, chunkLength); body.resize(body.size() + transferLength); memory::copy(body.get() + body.size() - transferLength, p, transferLength); @@ -135,10 +135,10 @@ auto Role::download(signed fd, Message& message) -> bool { return true; } -auto Role::upload(signed fd, const Message& message) -> bool { - auto transfer = [&](const uint8_t* data, unsigned size) -> bool { +auto Role::upload(int fd, const Message& message) -> bool { + auto transfer = [&](const uint8_t* data, uint size) -> bool { while(size) { - signed length = send(fd, data, min(size, settings.chunkSize), MSG_NOSIGNAL); + int length = send(fd, data, min(size, settings.chunkSize), MSG_NOSIGNAL); if(length < 0) return false; data += length; size -= length; @@ -146,8 +146,8 @@ auto Role::upload(signed fd, const Message& message) -> bool { return true; }; - if(message.head([&](const uint8_t* data, unsigned size) -> bool { return transfer(data, size); })) { - if(message.body([&](const uint8_t* data, unsigned size) -> bool { return transfer(data, size); })) { + if(message.head([&](const uint8_t* data, uint size) -> bool { return transfer(data, size); })) { + if(message.body([&](const uint8_t* data, uint size) -> bool { return transfer(data, size); })) { return true; } } diff --git a/nall/http/server.hpp b/nall/http/server.hpp index 6110603c..a987e2b3 100644 --- a/nall/http/server.hpp +++ b/nall/http/server.hpp @@ -6,7 +6,7 @@ namespace nall { namespace HTTP { struct Server : Role, service { - inline auto open(unsigned port = 8080, const string& serviceName = "", const string& command = "") -> bool; + inline auto open(uint port = 8080, const string& serviceName = "", const string& command = "") -> bool; inline auto main(const function& function = {}) -> void; inline auto scan() -> string; inline auto close() -> void; @@ -14,10 +14,10 @@ struct Server : Role, service { private: function callback; - std::atomic connections{0}; + std::atomic connections{0}; - signed fd4 = -1; - signed fd6 = -1; + int fd4 = -1; + int fd6 = -1; struct sockaddr_in addrin4 = {0}; struct sockaddr_in6 addrin6 = {0}; @@ -31,7 +31,7 @@ private: auto ipv6_scan() -> bool; }; -auto Server::open(unsigned port, const string& serviceName, const string& command) -> bool { +auto Server::open(uint port, const string& serviceName, const string& command) -> bool { if(serviceName) { if(!service::command(serviceName, command)) return false; } @@ -62,21 +62,21 @@ auto Server::open(unsigned port, const string& serviceName, const string& comman #endif #if defined(SO_NOSIGPIPE) //BSD, OSX - signed nosigpipe = 1; - if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(signed)); - if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(signed)); + int nosigpipe = 1; + if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(int)); + if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(int)); #endif #if defined(SO_REUSEADDR) //BSD, Linux, OSX - signed reuseaddr = 1; - if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(signed)); - if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(signed)); + int reuseaddr = 1; + if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)); + if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)); #endif #if defined(SO_REUSEPORT) //BSD, OSX - signed reuseport = 1; - if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(signed)); - if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(signed)); + int reuseport = 1; + if(ipv4()) setsockopt(fd4, SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(int)); + if(ipv6()) setsockopt(fd6, SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(int)); #endif } @@ -117,7 +117,7 @@ auto Server::ipv4_scan() -> bool { thread::create([&](uintptr) { thread::detach(); - signed clientfd = -1; + int clientfd = -1; struct sockaddr_in settings = {0}; socklen_t socklen = sizeof(sockaddr_in); @@ -164,7 +164,7 @@ auto Server::ipv6_scan() -> bool { thread::create([&](uintptr) { thread::detach(); - signed clientfd = -1; + int clientfd = -1; struct sockaddr_in6 settings = {0}; socklen_t socklen = sizeof(sockaddr_in6); @@ -178,9 +178,9 @@ auto Server::ipv6_scan() -> bool { Request request; request._ipv6 = true; //RFC5952 IPv6 encoding: the first longest 2+ consecutive zero-sequence is compressed to "::" - signed zeroOffset = -1; - signed zeroLength = 0; - signed zeroCounter = 0; + int zeroOffset = -1; + int zeroLength = 0; + int zeroCounter = 0; for(auto n : range(8)) { uint16_t value = ipSegment[n]; if(value == 0) zeroCounter++; @@ -191,7 +191,7 @@ auto Server::ipv6_scan() -> bool { if(value != 0) zeroCounter = 0; } if(zeroLength == 1) zeroOffset = -1; - for(unsigned n = 0; n < 8;) { + for(uint n = 0; n < 8;) { if(n == zeroOffset) { request._ip.append(n == 0 ? "::" : ":"); n += zeroLength; diff --git a/nall/string.hpp b/nall/string.hpp index 5e0a5c24..835a2680 100644 --- a/nall/string.hpp +++ b/nall/string.hpp @@ -329,3 +329,8 @@ struct string_format : vector { #include #include #include + +namespace nall { +//inline auto range(const string& value) { return range_t{0, (int)value.size(), 1}; } +//inline auto rrange(const string& value) { return range_t{(int)value.size() - 1, -1, -1}; } +} diff --git a/nall/string/markup/node.hpp b/nall/string/markup/node.hpp index ffc818b0..c29b8d50 100644 --- a/nall/string/markup/node.hpp +++ b/nall/string/markup/node.hpp @@ -8,8 +8,8 @@ using SharedNode = shared_pointer; struct ManagedNode { ManagedNode() = default; - ManagedNode(const string& name) : _name(name) {} - ManagedNode(const string& name, const string& value) : _name(name), _value(value) {} + explicit ManagedNode(const string& name) : _name(name) {} + explicit ManagedNode(const string& name, const string& value) : _name(name), _value(value) {} auto clone() const -> SharedNode { SharedNode clone{new ManagedNode(_name, _value)}; @@ -46,8 +46,8 @@ protected: struct Node { Node() : shared(new ManagedNode) {} Node(const SharedNode& source) : shared(source ? source : new ManagedNode) {} - Node(const string& name) : shared(new ManagedNode(name)) {} - Node(const string& name, const string& value) : shared(new ManagedNode(name, value)) {} + explicit Node(const string& name) : shared(new ManagedNode(name)) {} + explicit Node(const string& name, const string& value) : shared(new ManagedNode(name, value)) {} auto unique() const -> bool { return shared.unique(); } auto clone() const -> Node { return shared->clone(); } @@ -133,9 +133,6 @@ protected: }} namespace nall { - -inline range_t range(const Markup::Node& node) { - return range_t{0, (int)node.size(), 1}; -} - + inline auto range(const Markup::Node& value) { return range_t{0, (int)value.size(), 1}; } + inline auto rrange(const Markup::Node& value) { return range_t{(int)value.size() - 1, -1, -1}; } } diff --git a/nall/vector.hpp b/nall/vector.hpp index ad3d0edf..6a99019c 100644 --- a/nall/vector.hpp +++ b/nall/vector.hpp @@ -107,3 +107,8 @@ private: #include #include #include + +namespace nall { + template inline auto range(const vector& value) { return range_t{0, (int)value.size(), 1}; } + template inline auto rrange(const vector& value) { return range_t{(int)value.size() - 1, -1, -1}; } +} diff --git a/nall/vector/iterator.hpp b/nall/vector/iterator.hpp index 641a1c5f..ae8c9d91 100644 --- a/nall/vector/iterator.hpp +++ b/nall/vector/iterator.hpp @@ -26,12 +26,4 @@ private: uint offset; }; -template inline auto range(const vector& container) { - return range_t{0, (int)container.size(), 1}; -} - -template inline auto rrange(const vector& container) { - return range_t{(int)container.size() - 1, -1, -1}; -} - }