diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e8406..2c5327f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,11 +38,6 @@ if(NOT APPLE) add_compile_options(-g -fno-omit-frame-pointer) endif() -# work around lack of musttail for gcc -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_BUILD_TYPE STREQUAL "Debug") - add_compile_options(-O1 -foptimize-sibling-calls) -endif() - set(full_relro_flags "-pie;LINKER:-z,relro,-z,now,-z,noexecstack") cmake_push_check_state() list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${full_relro_flags}) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 143ef30..8b153b7 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -3262,10 +3262,29 @@ struct CheckContext { ReadContext *tls; }; +#if __has_attribute(musttail) FLATTEN PRESERVE_NONE void keepGoing(CheckJob *job, CheckContext *context) { job = job->next; MUSTTAIL return job->continuation(job, context); } +#else +static_assert(offsetof(CheckJob, next) == 0x38); +static_assert(offsetof(CheckJob, continuation) == 0x28); +extern "C" void keepGoing(CheckJob *, CheckContext *); + +#if defined(__x86_64__) +asm("keepGoing:\n" + " mov 0x38(%rdi),%rdi\n" + " jmp *0x28(%rdi)\n"); +#elif defined(__aarch64__) +asm("keepGoing:\n" + " ldr x0, [x0, #0x38]\n" + " ldr x16, [x0, #0x28]\n" + " br x16\n"); +#else +#error "Only x64 and aarch64 are supported" +#endif +#endif FLATTEN PRESERVE_NONE void complete(CheckJob *job, CheckContext *context) { if (context->started == context->count) {