From c829dc3dab47b9d1643535424f222ffde3135262 Mon Sep 17 00:00:00 2001 From: superfury Date: Sat, 9 Mar 2024 21:29:48 +0100 Subject: [PATCH 01/32] - Added support for SMEP not being available on the CPU. --- src/common/cpuid.cpp | 6 ++++++ src/common/include/cpuid.hpp | 3 +++ src/x86_32/arch.cpp | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index 573a275..dab22a2 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -47,3 +47,9 @@ bool has_nx() return get_cpuid_max_ext_level() >= 0x80000001 and (get_cpuid(0x80000001).edx & (1 << 20)); } + +bool has_smep() +{ + return get_cpuid_max_std_level() >= 7 + and (get_cpuid(0x7).ebx & (1 << 7)); +} diff --git a/src/common/include/cpuid.hpp b/src/common/include/cpuid.hpp index 05d6462..ebaee49 100644 --- a/src/common/include/cpuid.hpp +++ b/src/common/include/cpuid.hpp @@ -26,3 +26,6 @@ uint32_t get_cpuid_max_ext_level(); // Returns true, if the CPU reports being able to use the NX bit. bool has_nx(); + +// Returns true, if the CPU reports being able to use SMEP. +bool has_smep(); diff --git a/src/x86_32/arch.cpp b/src/x86_32/arch.cpp index 27cac9a..829a6f1 100644 --- a/src/x86_32/arch.cpp +++ b/src/x86_32/arch.cpp @@ -69,7 +69,7 @@ static void setup_paging() pdt[bit_select(32, 22, up)] = reinterpret_cast(user_pt) | PTE_U | PTE_P; user_pt[bit_select(22, 12, up)] = reinterpret_cast(get_user_page_backing()) | PTE_U | PTE_P; - set_cr4(get_cr4() | CR4_PSE | CR4_SMEP); + set_cr4(get_cr4() | CR4_PSE | (has_smep()?CR4_SMEP:0)); set_cr3((uintptr_t)pdt); set_cr0(get_cr0() | CR0_PG | CR0_WP); } From d6923538e30795055d2d2c28952ed2f47de95bd8 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 04:24:07 +0100 Subject: [PATCH 02/32] - Implemented 80386 paging and CPUID support. --- src/common/cpuid.cpp | 46 ++++++++++++++++++++++++++++++++++++ src/common/include/cpuid.hpp | 3 +++ src/x86_32/arch.cpp | 46 +++++++++++++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index dab22a2..309ed17 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -2,9 +2,49 @@ #include "cpuid.hpp" +bool cpuid_supported() +{ + #ifndef __x86_64__ + //We need to check for the existence of CPUID on 32-bit platforms! + unsigned int res1,res2; + asm( + "pushfd\n\t", //Save original interrupt state + "cli\n\t", //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section + "push %%ebp\n\t", //Save original stack base pointer + "mov %%esp,%%ebp\n\t", //Save original stack alignment + "and -4,%%esp\n\t", //align stack + "pushfd\n\t", //Load... + "pop %%eax\n\t", //... old EFLAGS + "mov %%ebx,%%eax\n\t" //Copy of it for the result check + "xor %%eax,$200000\n\t", //Flip CPUID bit now + "push %%eax\n\t", + "popfd\n\t", //Store changed bit into flags + "pushfd\n\t", //New eflags back on the stack + "pop %%eax\n\t", //Get if it changed + "mov %%eax, %0\n\t", //Original eflags result + "mov %%ebx, %1\n\t", //Flipped eflags result + "mov %%ebp,%%esp\n\t", //Restore original stack alignment + "pop %%ebp\n\t", //Restore stack base pointer + "popfd", //Restore original interrupt state + : "=a" (res1), "=b" (res2) + : + : "=a", "=b"); + return (((res1 ^ res2) & 0x200000)!=0); //Has the CPUID bit changed and is supported? + #else + return true; //Always assumed supported! + #endif +} + cpuid_result get_cpuid(uint32_t leaf, uint32_t subleaf) { cpuid_result res; + if (!cpuid_supported()) //CPUID not supported? + { + res.eax = res.ebx = reg.edx = res.ecx = 0; //Simply give empty result! + return res; //Give empty result! + } + + //CPUID is supported! asm ("cpuid" : "=a" (res.eax), "=b" (res.ebx), "=d" (res.edx), "=c" (res.ecx) @@ -53,3 +93,9 @@ bool has_smep() return get_cpuid_max_std_level() >= 7 and (get_cpuid(0x7).ebx & (1 << 7)); } + +bool has_pse() +{ + return get_cpuid_max_std_level() >= 1 + and (get_cpuid(0x1).edx & (1 << 3)); +} \ No newline at end of file diff --git a/src/common/include/cpuid.hpp b/src/common/include/cpuid.hpp index ebaee49..dcb9be7 100644 --- a/src/common/include/cpuid.hpp +++ b/src/common/include/cpuid.hpp @@ -29,3 +29,6 @@ bool has_nx(); // Returns true, if the CPU reports being able to use SMEP. bool has_smep(); + +// Returns true, if the CPU reports being able to use PSE. +bool has_pse(); diff --git a/src/x86_32/arch.cpp b/src/x86_32/arch.cpp index 829a6f1..e60cccc 100644 --- a/src/x86_32/arch.cpp +++ b/src/x86_32/arch.cpp @@ -51,15 +51,52 @@ static bool is_aligned(uint64_t v, int order) static void setup_paging() { + int pse_supported = has_pse(); //pse is supported on the CPU? uintptr_t istart = reinterpret_cast(_image_start); uintptr_t iend = reinterpret_cast(_image_end); + uintptr_t page_tables_start = iend+(1U<<22); //Point to the end of the image to store our page tables! + //For now just store it there if required (assuming enough memory is installed)! + if (page_tables_start & 0xFFF) //Make sure to start on the next 4KB boundary if needed! + { + page_tables_start = (page_table_start + 0xFFF) & ~0xFFF; //4KB boundary of next page! + } assert(is_aligned(istart, 22), "Image needs to start on large page boundary"); + uintptr_t tablepos = page_tables_start; //For looping sub-page tables in the PDE entries! + // Map our binary 1:1 for (uintptr_t c = istart; c <= iend; c += (1U << 22)) { - uintptr_t idx = c >> 22; - pdt[idx] = c | PTE_P | PTE_W | PTE_PS; + uintptr_t idx; + uintptr_t p; //The physical location! + idx = c >> 22; //What index in the page directory + if (pse_supported) //PSE supported? Map 4MB page tables! + { + p = c | PTE_PS; //Directly mapped! + } + else //Map 4KB PDE page directories to their page tables + { + p = tablepos; //Page table position! + tablepos += (1 << 12); //Move in 4KB chunks! + } + pdt[idx] = PTE_P | PTE_W | p; //Map PDE to page table or page + } + // Map additional page tables, if required (non-PSE systems). + if (!pse_supported) //4KB page tables are required? + { + tablepos = page_table_start; //Generating pagetables here, requiring up to 4MB! + for (uintptr_t c = istart; c <= iend;) //Process our range again for the page tables! + { + uintptr_t m = c; //Where to start mapping 4MB to! + uint32_t* t = tablepos; //Backing page table in physical memory! + for (uintptr_t d = 0; d <= 1024;) //Map one 4MB page to linear memory + { + t[d] = m | PTE_P | PTE_W; //4KB PTE + m += 4096; //Mapped 4KB of memory! + } + tablepos += 4096; //Next page table to fill! + c += (1U << 22); //Mapped 4MB of memory + } } // Map user page @@ -69,7 +106,10 @@ static void setup_paging() pdt[bit_select(32, 22, up)] = reinterpret_cast(user_pt) | PTE_U | PTE_P; user_pt[bit_select(22, 12, up)] = reinterpret_cast(get_user_page_backing()) | PTE_U | PTE_P; - set_cr4(get_cr4() | CR4_PSE | (has_smep()?CR4_SMEP:0)); + if (pse_supported || has_smep()) //Enable either pse or smep and supported? + { + set_cr4(get_cr4() | (pse_supported ? CR4_PSE : 0) | (has_smep() ? CR4_SMEP : 0)); + } set_cr3((uintptr_t)pdt); set_cr0(get_cr0() | CR0_PG | CR0_WP); } From 10a6ad05a9bd91c379db72ffce4e5b6c23444153 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 04:44:21 +0100 Subject: [PATCH 03/32] - Fixed some compiler warnings. --- src/common/cpuid.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index 309ed17..e5bb4d8 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -8,24 +8,24 @@ bool cpuid_supported() //We need to check for the existence of CPUID on 32-bit platforms! unsigned int res1,res2; asm( - "pushfd\n\t", //Save original interrupt state - "cli\n\t", //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section - "push %%ebp\n\t", //Save original stack base pointer - "mov %%esp,%%ebp\n\t", //Save original stack alignment - "and -4,%%esp\n\t", //align stack - "pushfd\n\t", //Load... - "pop %%eax\n\t", //... old EFLAGS + "pushfd\n\t" //Save original interrupt state + "cli\n\t" //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section + "push %%ebp\n\t" //Save original stack base pointer + "mov %%esp,%%ebp\n\t" //Save original stack alignment + "and -4,%%esp\n\t" //align stack + "pushfd\n\t" //Load... + "pop %%eax\n\t" //... old EFLAGS "mov %%ebx,%%eax\n\t" //Copy of it for the result check - "xor %%eax,$200000\n\t", //Flip CPUID bit now - "push %%eax\n\t", - "popfd\n\t", //Store changed bit into flags - "pushfd\n\t", //New eflags back on the stack - "pop %%eax\n\t", //Get if it changed - "mov %%eax, %0\n\t", //Original eflags result - "mov %%ebx, %1\n\t", //Flipped eflags result - "mov %%ebp,%%esp\n\t", //Restore original stack alignment - "pop %%ebp\n\t", //Restore stack base pointer - "popfd", //Restore original interrupt state + "xor %%eax,$200000\n\t" //Flip CPUID bit now + "push %%eax\n\t" + "popfd\n\t" //Store changed bit into flags + "pushfd\n\t" //New eflags back on the stack + "pop %%eax\n\t" //Get if it changed + "mov %%eax, %0\n\t" //Original eflags result + "mov %%ebx, %1\n\t" //Flipped eflags result + "mov %%ebp,%%esp\n\t" //Restore original stack alignment + "pop %%ebp\n\t" //Restore stack base pointer + "popfd" //Restore original interrupt state : "=a" (res1), "=b" (res2) : : "=a", "=b"); @@ -40,7 +40,7 @@ cpuid_result get_cpuid(uint32_t leaf, uint32_t subleaf) cpuid_result res; if (!cpuid_supported()) //CPUID not supported? { - res.eax = res.ebx = reg.edx = res.ecx = 0; //Simply give empty result! + res.eax = res.ebx = res.edx = res.ecx = 0; //Simply give empty result! return res; //Give empty result! } From 11b08593ba700f7a1e312178d96600e4d456ec89 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 04:46:43 +0100 Subject: [PATCH 04/32] - Improved CPUID check code. --- src/common/cpuid.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index e5bb4d8..47f7aca 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -26,9 +26,7 @@ bool cpuid_supported() "mov %%ebp,%%esp\n\t" //Restore original stack alignment "pop %%ebp\n\t" //Restore stack base pointer "popfd" //Restore original interrupt state - : "=a" (res1), "=b" (res2) - : - : "=a", "=b"); + : "=a" (res1), "=b" (res2)); return (((res1 ^ res2) & 0x200000)!=0); //Has the CPUID bit changed and is supported? #else return true; //Always assumed supported! From 31a916c2da02d64ee37801d3684c5104b6563746 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 04:50:41 +0100 Subject: [PATCH 05/32] - Fixed issues with CPUID detection assembly code. --- src/common/cpuid.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index 47f7aca..ef960cd 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -8,24 +8,24 @@ bool cpuid_supported() //We need to check for the existence of CPUID on 32-bit platforms! unsigned int res1,res2; asm( - "pushfd\n\t" //Save original interrupt state + "pushfl\n\t" //Save original interrupt state "cli\n\t" //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section "push %%ebp\n\t" //Save original stack base pointer "mov %%esp,%%ebp\n\t" //Save original stack alignment "and -4,%%esp\n\t" //align stack - "pushfd\n\t" //Load... + "pushfl\n\t" //Load... "pop %%eax\n\t" //... old EFLAGS "mov %%ebx,%%eax\n\t" //Copy of it for the result check - "xor %%eax,$200000\n\t" //Flip CPUID bit now + "xor $200000,%%eax\n\t" //Flip CPUID bit now "push %%eax\n\t" - "popfd\n\t" //Store changed bit into flags - "pushfd\n\t" //New eflags back on the stack + "popfl\n\t" //Store changed bit into flags + "pushfl\n\t" //New eflags back on the stack "pop %%eax\n\t" //Get if it changed "mov %%eax, %0\n\t" //Original eflags result "mov %%ebx, %1\n\t" //Flipped eflags result "mov %%ebp,%%esp\n\t" //Restore original stack alignment "pop %%ebp\n\t" //Restore stack base pointer - "popfd" //Restore original interrupt state + "popfl" //Restore original interrupt state : "=a" (res1), "=b" (res2)); return (((res1 ^ res2) & 0x200000)!=0); //Has the CPUID bit changed and is supported? #else From e288d53438831be6fa84eae87ade477adfac6e30 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 05:01:40 +0100 Subject: [PATCH 06/32] - Implemented various code 4KB page table compilation bugfixes. --- src/x86_32/arch.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/x86_32/arch.cpp b/src/x86_32/arch.cpp index e60cccc..1a03e0b 100644 --- a/src/x86_32/arch.cpp +++ b/src/x86_32/arch.cpp @@ -58,7 +58,7 @@ static void setup_paging() //For now just store it there if required (assuming enough memory is installed)! if (page_tables_start & 0xFFF) //Make sure to start on the next 4KB boundary if needed! { - page_tables_start = (page_table_start + 0xFFF) & ~0xFFF; //4KB boundary of next page! + page_tables_start = (page_tables_start + 0xFFF) & ~0xFFF; //4KB boundary of next page! } assert(is_aligned(istart, 22), "Image needs to start on large page boundary"); @@ -84,18 +84,17 @@ static void setup_paging() // Map additional page tables, if required (non-PSE systems). if (!pse_supported) //4KB page tables are required? { - tablepos = page_table_start; //Generating pagetables here, requiring up to 4MB! - for (uintptr_t c = istart; c <= iend;) //Process our range again for the page tables! + tablepos = page_tables_start; //Generating pagetables here, requiring up to 4MB! + for (uintptr_t c = istart; c <= iend; c += (1U << 22)) //Process our range again for the page tables! { uintptr_t m = c; //Where to start mapping 4MB to! - uint32_t* t = tablepos; //Backing page table in physical memory! + uint32_t* t = reinterpret_casttablepos; //Backing page table in physical memory! for (uintptr_t d = 0; d <= 1024;) //Map one 4MB page to linear memory { - t[d] = m | PTE_P | PTE_W; //4KB PTE + t[d++] = m | PTE_P | PTE_W; //4KB PTE m += 4096; //Mapped 4KB of memory! } tablepos += 4096; //Next page table to fill! - c += (1U << 22); //Mapped 4MB of memory } } From 23fc0dc92d960a866717f92b2dbdadcf7a560582 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 05:03:31 +0100 Subject: [PATCH 07/32] - Fixed invalid reinterpret_cast on 4KB page table pointer. --- src/x86_32/arch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86_32/arch.cpp b/src/x86_32/arch.cpp index 1a03e0b..5aab872 100644 --- a/src/x86_32/arch.cpp +++ b/src/x86_32/arch.cpp @@ -88,7 +88,7 @@ static void setup_paging() for (uintptr_t c = istart; c <= iend; c += (1U << 22)) //Process our range again for the page tables! { uintptr_t m = c; //Where to start mapping 4MB to! - uint32_t* t = reinterpret_casttablepos; //Backing page table in physical memory! + uint32_t* t = reinterpret_cast(tablepos); //Backing page table in physical memory! for (uintptr_t d = 0; d <= 1024;) //Map one 4MB page to linear memory { t[d++] = m | PTE_P | PTE_W; //4KB PTE From 7e9dcd5d3ab4902323a39f251eab4620a5ddc895 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 06:40:01 +0100 Subject: [PATCH 08/32] - Fixed issues with the assembly code for detecting CPUID support. --- src/common/cpuid.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index ef960cd..4c661ec 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -15,14 +15,14 @@ bool cpuid_supported() "and -4,%%esp\n\t" //align stack "pushfl\n\t" //Load... "pop %%eax\n\t" //... old EFLAGS - "mov %%ebx,%%eax\n\t" //Copy of it for the result check - "xor $200000,%%eax\n\t" //Flip CPUID bit now + "mov %%eax,%%ebx\n\t" //Copy of it for the result check + "xor $0x200000,%%eax\n\t" //Flip CPUID bit now "push %%eax\n\t" "popfl\n\t" //Store changed bit into flags "pushfl\n\t" //New eflags back on the stack "pop %%eax\n\t" //Get if it changed - "mov %%eax, %0\n\t" //Original eflags result - "mov %%ebx, %1\n\t" //Flipped eflags result + "mov %%eax, %0\n\t" //Flipped eflags result + "mov %%ebx, %1\n\t" //Original eflags result "mov %%ebp,%%esp\n\t" //Restore original stack alignment "pop %%ebp\n\t" //Restore stack base pointer "popfl" //Restore original interrupt state From 5a5db401ff339422153e73e068e69fbdf691dc6b Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 07:12:54 +0100 Subject: [PATCH 09/32] - Fixed masking of ESP to align the stack when checking for CPUID capability. --- src/common/cpuid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index 4c661ec..2210b38 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -12,7 +12,7 @@ bool cpuid_supported() "cli\n\t" //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section "push %%ebp\n\t" //Save original stack base pointer "mov %%esp,%%ebp\n\t" //Save original stack alignment - "and -4,%%esp\n\t" //align stack + "and $-4,%%esp\n\t" //align stack "pushfl\n\t" //Load... "pop %%eax\n\t" //... old EFLAGS "mov %%eax,%%ebx\n\t" //Copy of it for the result check From 24b98d463400a686848e5db97236960469d9c283 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 08:09:44 +0100 Subject: [PATCH 10/32] - Added support for CPUs without the alignment flag supported to not set the WP bit in CR0. --- src/common/cpuid.cpp | 31 +++++++++++++++++++++++++++++++ src/common/include/cpuid.hpp | 3 +++ src/x86_32/arch.cpp | 5 +++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/common/cpuid.cpp b/src/common/cpuid.cpp index 2210b38..3618fc9 100644 --- a/src/common/cpuid.cpp +++ b/src/common/cpuid.cpp @@ -96,4 +96,35 @@ bool has_pse() { return get_cpuid_max_std_level() >= 1 and (get_cpuid(0x1).edx & (1 << 3)); +} + +bool has_wp() +{ +#ifndef __x86_64__ + //We need to check for the existence of CR0 WP on 32-bit platforms! + unsigned int res1, res2; + asm( + "pushfl\n\t" //Save original interrupt state + "cli\n\t" //Block interrupts to be safe, as we're modifying the stack alignment, making this a critical section + "push %%ebp\n\t" //Save original stack base pointer + "mov %%esp,%%ebp\n\t" //Save original stack alignment + "and $-4,%%esp\n\t" //align stack. Important to prevent faulting on this down the road! + "pushfl\n\t" //Load... + "pop %%eax\n\t" //... old EFLAGS + "mov %%eax,%%ebx\n\t" //Copy of it for the result check + "xor $0x40000,%%eax\n\t" //Flip AC bit now + "push %%eax\n\t" + "popfl\n\t" //Store changed bit into flags + "pushfl\n\t" //New eflags back on the stack + "pop %%eax\n\t" //Get if it changed + "mov %%eax, %0\n\t" //Flipped eflags result + "mov %%ebx, %1\n\t" //Original eflags result + "mov %%ebp,%%esp\n\t" //Restore original stack alignment + "pop %%ebp\n\t" //Restore stack base pointer + "popfl" //Restore original interrupt state + : "=a" (res1), "=b" (res2)); + return (((res1 ^ res2) & 0x40000) != 0); //Has the AC bit changed and is supported (indicates WP bit is supported)? +#else + return true; //Always assumed supported! +#endif } \ No newline at end of file diff --git a/src/common/include/cpuid.hpp b/src/common/include/cpuid.hpp index dcb9be7..9bb4148 100644 --- a/src/common/include/cpuid.hpp +++ b/src/common/include/cpuid.hpp @@ -32,3 +32,6 @@ bool has_smep(); // Returns true, if the CPU reports being able to use PSE. bool has_pse(); + +// Returns true, if the CPU reports being able to use the WP bit in CR0. +bool has_wp(); diff --git a/src/x86_32/arch.cpp b/src/x86_32/arch.cpp index 5aab872..342c0ec 100644 --- a/src/x86_32/arch.cpp +++ b/src/x86_32/arch.cpp @@ -51,7 +51,8 @@ static bool is_aligned(uint64_t v, int order) static void setup_paging() { - int pse_supported = has_pse(); //pse is supported on the CPU? + bool pse_supported = has_pse(); //pse is supported on the CPU? + bool wp_supported = has_wp(); //wp is supported on the CPU? uintptr_t istart = reinterpret_cast(_image_start); uintptr_t iend = reinterpret_cast(_image_end); uintptr_t page_tables_start = iend+(1U<<22); //Point to the end of the image to store our page tables! @@ -110,7 +111,7 @@ static void setup_paging() set_cr4(get_cr4() | (pse_supported ? CR4_PSE : 0) | (has_smep() ? CR4_SMEP : 0)); } set_cr3((uintptr_t)pdt); - set_cr0(get_cr0() | CR0_PG | CR0_WP); + set_cr0(get_cr0() | CR0_PG | (wp_supported?CR0_WP:0)); } static void setup_gdt() From ce99ac006ea7e0b4066bc3a7478e1f5c77328b54 Mon Sep 17 00:00:00 2001 From: superfury Date: Sun, 10 Mar 2024 13:08:36 +0100 Subject: [PATCH 11/32] - Compile for i386 instead of i686. --- src/SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SConstruct b/src/SConstruct index 19988c6..4e134ce 100644 --- a/src/SConstruct +++ b/src/SConstruct @@ -35,7 +35,7 @@ bare64_env.Append(CCFLAGS=" -m64 -march=x86-64 -mno-red-zone", ASFLAGS=" -felf64") bare32_env = common_bare_env.Clone(ARCH_NAME="x86_32") -bare32_env.Append(CCFLAGS=" -m32 -march=i686 -mregparm=3 -fomit-frame-pointer", +bare32_env.Append(CCFLAGS=" -m32 -march=i386 -mregparm=3 -fomit-frame-pointer", ASFLAGS=" -felf32") bins = [] From ffa417c53df4976c3d6586e0d5272b77d126b6b8 Mon Sep 17 00:00:00 2001 From: superfury Date: Mon, 11 Mar 2024 20:26:06 +0100 Subject: [PATCH 12/32] - There are no REX prefixes on x86. --- src/common/search.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/search.cpp b/src/common/search.cpp index 62831c4..14473fa 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -32,10 +32,12 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x67: // address size override group = 3; break; +#ifndef __x86_64__ case 0x40 ... 0x4F: // REX prefixes group = 4; break; } +#endif return group; } From a53485ca4fd4628c8c7f64680cbb62167634687e Mon Sep 17 00:00:00 2001 From: superfury Date: Mon, 11 Mar 2024 20:39:41 +0100 Subject: [PATCH 13/32] - Fixed x64 vs x86 REX prefixes. --- src/common/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 14473fa..7a41d8d 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -32,7 +32,7 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x67: // address size override group = 3; break; -#ifndef __x86_64__ +#ifdef __x86_64__ case 0x40 ... 0x4F: // REX prefixes group = 4; break; From c322510584fee84226c94b0419202fbf04b7f56e Mon Sep 17 00:00:00 2001 From: superfury Date: Mon, 11 Mar 2024 21:12:49 +0100 Subject: [PATCH 14/32] - Fixed REX prefix code to compile again on x86. --- src/common/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 7a41d8d..da2bea1 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -36,8 +36,8 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x40 ... 0x4F: // REX prefixes group = 4; break; - } #endif + } return group; } From b5c886deac04091a3a71206570170f159c2d8d3e Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 14:32:24 +0100 Subject: [PATCH 15/32] Update search.hpp Added support for used prefixes. --- src/common/include/search.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index 455b7b7..be0729b 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -18,6 +18,7 @@ class search_engine { size_t increment_at_ = 0; const size_t max_prefixes_; + const size_t used_prefixes_; public: @@ -37,7 +38,7 @@ class search_engine { return current_; } - search_engine(size_t max_prefixes = 0, instruction_bytes const &start = {}) - : current_(start), max_prefixes_(max_prefixes) + search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, instruction_bytes const &start = {}) + : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes) {} }; From 72305e1a09cec2340142caa6931257d28f803a69 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 14:37:18 +0100 Subject: [PATCH 16/32] - Pass detect and used prefixes settings to the search engine. --- src/main.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 78a0415..db62ab2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -140,6 +140,12 @@ struct options { // After how many instructions do we stop. Zero means don't stop. size_t stop_after = 0; + + // What prefixes to use. Zero means no prefixes are valid to use. The bits of the number are the opcode groups. + size_t used_prefixes = 0xFF; + + // What prefixes to detect. Zero means no prefixes are valid. The bits of the number are the opcode groups. + size_t detect_prefixes = 0xFF; }; // This will modify cmdline. @@ -182,7 +188,7 @@ void start(cpu_features const &features, char *cmdline) if (options.stop_after) format(">>> Stopping after ", options.stop_after, " execution attemps.\n"); - search_engine search { options.prefixes }; + search_engine search { options.prefixes, options.used_prefixes, options.detect_prefixes }; execution_attempt last_attempt; do { From 9929cff11753ab45c4644ba1689a996118c307a3 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 14:39:54 +0100 Subject: [PATCH 17/32] Update search.hpp - Full used and detected prefixes storage in the search engine. --- src/common/include/search.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index be0729b..c28c29e 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -17,8 +17,9 @@ class search_engine { instruction_bytes current_; size_t increment_at_ = 0; - const size_t max_prefixes_; - const size_t used_prefixes_; + const size_t max_prefixes_; //How many prefixes to use at once. + const size_t used_prefixes_; //What prefixes to scan through. + const size_t detect_prefixes_; //What prefixes to detect as prefixes. public: @@ -38,7 +39,7 @@ class search_engine { return current_; } - search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, instruction_bytes const &start = {}) - : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes) + search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, size_t detect_prefixes = 0xFF, instruction_bytes const &start = {}) + : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), detect_prefixes_(detect_prefixes) {} }; From e81dbc8bbbdda15b362f90e165f7cc38bcb2b992 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 14:47:10 +0100 Subject: [PATCH 18/32] Update search.cpp Implemented the filter on detecting of prefixes. --- src/common/search.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index da2bea1..68c2555 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -16,7 +16,10 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0xF0: // LOCK case 0xF2: // REPNE case 0xF3: // REP - group = 0; + if (detect_prefixes & (1<<0)) //To detect? + { + group = 0; + } break; case 0x2E: // CS case 0x36: // SS @@ -24,19 +27,29 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x26: // ES case 0x64: // FS case 0x65: // GS + if (detect_prefixes & (1<<0)) //To detect? + { group = 1; + } break; case 0x66: // operand size override + if (detect_prefixes & (1<<1)) //To detect? + { group = 2; + } break; case 0x67: // address size override - group = 3; + if (detect_prefixes & (1<<2)) //To detect? + { + group = 3; + } break; -#ifdef __x86_64__ case 0x40 ... 0x4F: // REX prefixes - group = 4; + if (detect_prefixes & (1<<3)) //To detect? + { + group = 4; + } break; -#endif } return group; @@ -77,6 +90,7 @@ struct prefix_state { if (c >= 2) return true; } + //TODO: detect used_prefixed and filter them out. return false; } From 379731b8069256666141d768eb3ea62c5e958660 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 14:48:10 +0100 Subject: [PATCH 19/32] Update search.cpp - Fixed detecting of prefixes. --- src/common/search.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 68c2555..f49c125 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -27,25 +27,25 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x26: // ES case 0x64: // FS case 0x65: // GS - if (detect_prefixes & (1<<0)) //To detect? + if (detect_prefixes & (1<<1)) //To detect? { group = 1; } break; case 0x66: // operand size override - if (detect_prefixes & (1<<1)) //To detect? + if (detect_prefixes & (1<<2)) //To detect? { group = 2; } break; case 0x67: // address size override - if (detect_prefixes & (1<<2)) //To detect? + if (detect_prefixes & (1<<3)) //To detect? { group = 3; } break; case 0x40 ... 0x4F: // REX prefixes - if (detect_prefixes & (1<<3)) //To detect? + if (detect_prefixes & (1<<4)) //To detect? { group = 4; } From 7e2159ed0c14925a2e741ba9508a00962b240cb0 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 15:48:39 +0100 Subject: [PATCH 20/32] Update search.cpp Implemented prefix groups not to be used if specified to exclude. --- src/common/search.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index f49c125..68bca87 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -29,13 +29,13 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x65: // GS if (detect_prefixes & (1<<1)) //To detect? { - group = 1; + group = 1; } break; case 0x66: // operand size override if (detect_prefixes & (1<<2)) //To detect? { - group = 2; + group = 2; } break; case 0x67: // address size override @@ -90,8 +90,17 @@ struct prefix_state { if (c >= 2) return true; } - //TODO: detect used_prefixed and filter them out. + + return false; + } + bool has_unused_prefixes() const + { + //Detect used_prefixes and filter them out. + for (size_t i = 0; i < array_size(count); i++) + if (count[i] and ((used_prefixes&(1< max_prefixes_ or state.has_duplicated_prefixes() or + state.has_unused_prefixes() or not state.has_ordered_prefixes()) { goto again; } From 4dbe1a2ab7b4ccccadf66722afe901dd7216cc87 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 15:54:03 +0100 Subject: [PATCH 21/32] Update main.cpp - Implemented proper parsing of used and detected prefixes on the command line. --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index db62ab2..1b11d95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -164,6 +164,10 @@ static options parse_and_destroy_cmdline(char *cmdline) if (strcmp(key, "prefixes") == 0) res.prefixes = atoi(value); + if (strcmp(key, "used_prefixes") == 0) + res.used_prefixes = atoi(value); + if (strcmp(key, "detect_prefixes") == 0) + res.detect_prefixes = atoi(value); if (strcmp(key, "stop_after") == 0) res.stop_after = atoi(value); } From 2ffd34e1093a010e4e12541ded04380d251a4a9e Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 16:21:57 +0100 Subject: [PATCH 22/32] - Optimized unused prefix check using a variable to shift. - Fixed detect_prefixes and used_prefixes variable names. --- src/common/search.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 68bca87..a882a1f 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -16,7 +16,7 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0xF0: // LOCK case 0xF2: // REPNE case 0xF3: // REP - if (detect_prefixes & (1<<0)) //To detect? + if (detect_prefixes_ & (1<<0)) //To detect? { group = 0; } @@ -27,25 +27,25 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) case 0x26: // ES case 0x64: // FS case 0x65: // GS - if (detect_prefixes & (1<<1)) //To detect? + if (detect_prefixes_ & (1<<1)) //To detect? { group = 1; } break; case 0x66: // operand size override - if (detect_prefixes & (1<<2)) //To detect? + if (detect_prefixes_ & (1<<2)) //To detect? { group = 2; } break; case 0x67: // address size override - if (detect_prefixes & (1<<3)) //To detect? + if (detect_prefixes_ & (1<<3)) //To detect? { group = 3; } break; case 0x40 ... 0x4F: // REX prefixes - if (detect_prefixes & (1<<4)) //To detect? + if (detect_prefixes_ & (1<<4)) //To detect? { group = 4; } @@ -97,9 +97,11 @@ struct prefix_state { bool has_unused_prefixes() const { //Detect used_prefixes and filter them out. - for (size_t i = 0; i < array_size(count); i++) - if (count[i] and ((used_prefixes&(1< Date: Wed, 13 Mar 2024 16:42:05 +0100 Subject: [PATCH 23/32] - Moved the prefix group LUT into the search engine class. - Made the prefix group LUT depend on the prefixes specified. --- src/common/include/search.hpp | 9 ++++++++- src/common/search.cpp | 14 ++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index c28c29e..1e4aa04 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -13,8 +13,15 @@ struct instruction_bytes { {} }; +typedef struct prefix_lut { + int8_t data[256]; +}; + +static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_); //Prototype! + class search_engine { instruction_bytes current_; + prefix_lut prefix_group_lut; size_t increment_at_ = 0; const size_t max_prefixes_; //How many prefixes to use at once. @@ -40,6 +47,6 @@ class search_engine { } search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, size_t detect_prefixes = 0xFF, instruction_bytes const &start = {}) - : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), detect_prefixes_(detect_prefixes) + : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), detect_prefixes_(detect_prefixes), prefix_group_lut{create_prefix_group_lut(detect_prefixes)} {} }; diff --git a/src/common/search.cpp b/src/common/search.cpp index a882a1f..57cad82 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -4,11 +4,7 @@ #include "search.hpp" #include "util.hpp" -struct prefix_lut { - int8_t data[256]; -}; - -static constexpr int opcode_to_prefix_group(uint8_t byte) +static constexpr int opcode_to_prefix_group(uint8_t byte, uint8_t detect_prefixes_) { int group = -1; @@ -55,19 +51,17 @@ static constexpr int opcode_to_prefix_group(uint8_t byte) return group; } -static constexpr prefix_lut create_prefix_group_lut() +static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_) { prefix_lut group_lut {}; for (size_t i = 0; i < array_size(group_lut.data); i++) { - group_lut.data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i); + group_lut.data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i,detect_prefixes_); } return group_lut; } -static prefix_lut prefix_group_lut {create_prefix_group_lut()}; - // Encapsulates which prefixes are there, where and how many there are. struct prefix_state { uint8_t count[5] {}; // Count of prefixes in each group. @@ -97,7 +91,7 @@ struct prefix_state { bool has_unused_prefixes() const { //Detect used_prefixes and filter them out. - for (size_t i = 0, size_t b = 1;; i < array_size(count); i++, b <<= 1) + for (size_t i = 0, size_t b = 1; i < array_size(count); i++, b <<= 1) { if (count[i] and ((used_prefixes_ & b) == 0)) //Prefix not to be used? return true; From 64dd5cb5638bb70359580b9406fe90161745f889 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 16:45:55 +0100 Subject: [PATCH 24/32] - More code fixes. --- src/common/include/search.hpp | 4 ++-- src/common/search.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index 1e4aa04..829d11a 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -13,9 +13,9 @@ struct instruction_bytes { {} }; -typedef struct prefix_lut { +typedef struct { int8_t data[256]; -}; +} prefix_lut; static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_); //Prototype! diff --git a/src/common/search.cpp b/src/common/search.cpp index 57cad82..55fb12b 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -91,7 +91,8 @@ struct prefix_state { bool has_unused_prefixes() const { //Detect used_prefixes and filter them out. - for (size_t i = 0, size_t b = 1; i < array_size(count); i++, b <<= 1) + size_t b = 1; + for (size_t i = 0; i < array_size(count); i++, b <<= 1) { if (count[i] and ((used_prefixes_ & b) == 0)) //Prefix not to be used? return true; From f068892389263068468713b1907763c5a1749be6 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 16:52:05 +0100 Subject: [PATCH 25/32] - Fixed prefix LUT initialization. --- src/common/include/search.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index 829d11a..b6c7217 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -21,12 +21,10 @@ static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_); / class search_engine { instruction_bytes current_; - prefix_lut prefix_group_lut; size_t increment_at_ = 0; const size_t max_prefixes_; //How many prefixes to use at once. const size_t used_prefixes_; //What prefixes to scan through. - const size_t detect_prefixes_; //What prefixes to detect as prefixes. public: @@ -47,6 +45,6 @@ class search_engine { } search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, size_t detect_prefixes = 0xFF, instruction_bytes const &start = {}) - : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), detect_prefixes_(detect_prefixes), prefix_group_lut{create_prefix_group_lut(detect_prefixes)} + : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), prefix_group_lut{create_prefix_group_lut(detect_prefixes)} {} }; From dba24809e33da5ad7a7d02adc3e14b5826d8f29a Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:14:45 +0100 Subject: [PATCH 26/32] - Modified the prefix group LUT into a class. --- src/common/include/search.hpp | 12 +++++++----- src/common/search.cpp | 14 +++++--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index b6c7217..1805b2f 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -13,18 +13,20 @@ struct instruction_bytes { {} }; -typedef struct { +class prefix_group_lut { +public: int8_t data[256]; -} prefix_lut; -static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_); //Prototype! + prefix_group_lut(uint8_t detect_prefixes_); //Prototype! +}; -class search_engine { +class search_engine : { instruction_bytes current_; size_t increment_at_ = 0; const size_t max_prefixes_; //How many prefixes to use at once. const size_t used_prefixes_; //What prefixes to scan through. + prefix_group_lut group_lut_; //What group lut to use! public: @@ -45,6 +47,6 @@ class search_engine { } search_engine(size_t max_prefixes = 0, size_t used_prefixes = 0xFF, size_t detect_prefixes = 0xFF, instruction_bytes const &start = {}) - : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), prefix_group_lut{create_prefix_group_lut(detect_prefixes)} + : current_(start), max_prefixes_(max_prefixes), used_prefixes_(used_prefixes), group_lut_(detect_prefixes) {} }; diff --git a/src/common/search.cpp b/src/common/search.cpp index 55fb12b..2a80764 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -4,7 +4,7 @@ #include "search.hpp" #include "util.hpp" -static constexpr int opcode_to_prefix_group(uint8_t byte, uint8_t detect_prefixes_) +static constexpr int opcode_to_prefix_group(uint8_t byte, size_t detect_prefixes_) { int group = -1; @@ -51,15 +51,11 @@ static constexpr int opcode_to_prefix_group(uint8_t byte, uint8_t detect_prefixe return group; } -static constexpr prefix_lut create_prefix_group_lut(uint8_t detect_prefixes_) +prefix_group_lut::prefix_group_lut(size_t detect_prefixes_) { - prefix_lut group_lut {}; - - for (size_t i = 0; i < array_size(group_lut.data); i++) { - group_lut.data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i,detect_prefixes_); + for (size_t i = 0; i < array_size(data); i++) { + data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i,detect_prefixes_); } - - return group_lut; } // Encapsulates which prefixes are there, where and how many there are. @@ -123,7 +119,7 @@ static prefix_state analyze_prefixes(instruction_bytes const &instr) prefix_state state; for (size_t i = 0; i < sizeof(instr.raw); i++) { - int group = prefix_group_lut.data[instr.raw[i]]; + int group = group_lut_.data[instr.raw[i]]; if (group < 0) break; From d217a479a8028856381a1efea94baf16ae486b06 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:15:34 +0100 Subject: [PATCH 27/32] - Fixed search engine class. --- src/common/include/search.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index 1805b2f..ba76998 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -20,7 +20,7 @@ class prefix_group_lut { prefix_group_lut(uint8_t detect_prefixes_); //Prototype! }; -class search_engine : { +class search_engine { instruction_bytes current_; size_t increment_at_ = 0; From 86e7ce84e00c1e2701fda863a2c7c47058bf5511 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:21:19 +0100 Subject: [PATCH 28/32] - Improved prefix_group_lut initialization. --- src/common/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 2a80764..ae3a56a 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -51,7 +51,7 @@ static constexpr int opcode_to_prefix_group(uint8_t byte, size_t detect_prefixes return group; } -prefix_group_lut::prefix_group_lut(size_t detect_prefixes_) +constexpr prefix_group_lut::prefix_group_lut(size_t detect_prefixes_) { for (size_t i = 0; i < array_size(data); i++) { data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i,detect_prefixes_); From 2e65fadc13e2f3e616abdec68ea37839412d6ac1 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:24:37 +0100 Subject: [PATCH 29/32] - More prefix group LUT code fixes. --- src/common/include/search.hpp | 2 +- src/common/search.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/include/search.hpp b/src/common/include/search.hpp index ba76998..2e320f0 100644 --- a/src/common/include/search.hpp +++ b/src/common/include/search.hpp @@ -17,7 +17,7 @@ class prefix_group_lut { public: int8_t data[256]; - prefix_group_lut(uint8_t detect_prefixes_); //Prototype! + prefix_group_lut(size_t detect_prefixes_); //Prototype! }; class search_engine { diff --git a/src/common/search.cpp b/src/common/search.cpp index ae3a56a..2a80764 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -51,7 +51,7 @@ static constexpr int opcode_to_prefix_group(uint8_t byte, size_t detect_prefixes return group; } -constexpr prefix_group_lut::prefix_group_lut(size_t detect_prefixes_) +prefix_group_lut::prefix_group_lut(size_t detect_prefixes_) { for (size_t i = 0; i < array_size(data); i++) { data[i] = (int8_t)opcode_to_prefix_group((uint8_t)i,detect_prefixes_); From 9203312f850435dd4185421e817d39f7af1c30c6 Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:27:03 +0100 Subject: [PATCH 30/32] - Fixed unused prefixes detection. --- src/common/search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 2a80764..6f03319 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -84,7 +84,7 @@ struct prefix_state { return false; } - bool has_unused_prefixes() const + bool search_engine::has_unused_prefixes(size_t used_prefixes_) const { //Detect used_prefixes and filter them out. size_t b = 1; @@ -163,7 +163,7 @@ bool search_engine::find_next_candidate() // And also filter out prefixes that are declared not to be used. if (state.total_prefix_bytes() > max_prefixes_ or state.has_duplicated_prefixes() or - state.has_unused_prefixes() or + state.has_unused_prefixes(used_prefixes_) or not state.has_ordered_prefixes()) { goto again; } From 34e58a1f6e1514d4b156c141e1adc18e228e7e9c Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:27:58 +0100 Subject: [PATCH 31/32] - Restored unused prefix detection code. --- src/common/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 6f03319..718cffb 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -84,7 +84,7 @@ struct prefix_state { return false; } - bool search_engine::has_unused_prefixes(size_t used_prefixes_) const + bool has_unused_prefixes(size_t used_prefixes_) const { //Detect used_prefixes and filter them out. size_t b = 1; From 576c00e8eeb10464b318458334a595ebd824f47d Mon Sep 17 00:00:00 2001 From: superfury Date: Wed, 13 Mar 2024 17:30:29 +0100 Subject: [PATCH 32/32] - Fixed group LUT lookups. --- src/common/search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/search.cpp b/src/common/search.cpp index 718cffb..15d3e65 100644 --- a/src/common/search.cpp +++ b/src/common/search.cpp @@ -114,7 +114,7 @@ struct prefix_state { } }; -static prefix_state analyze_prefixes(instruction_bytes const &instr) +static prefix_state analyze_prefixes(prefix_group_lut const &group_lut_, instruction_bytes const &instr) { prefix_state state; @@ -156,7 +156,7 @@ bool search_engine::find_next_candidate() goto again; } - auto const state = analyze_prefixes(current_); + auto const state = analyze_prefixes(group_lut_, current_); // Duplicated prefixes make the search space explode without generating // insight. Also enforce order on prefixes to further reduce search space.