39 lines
1.7 KiB
CMake
39 lines
1.7 KiB
CMake
file(GLOB modules "${MODULES}/*.prx")
|
|
if(NOT modules)
|
|
message(FATAL_ERROR "no modules in ${MODULES}")
|
|
endif()
|
|
set(explicit "__cxa_thread_atexit_nid_postfix|__cxa_thread_atexit_impl_nid_postfix|LibcInternalExtCxaThreadAtexit_nid_postfix")
|
|
set(failures "")
|
|
foreach(module IN LISTS modules)
|
|
get_filename_component(name "${module}" NAME)
|
|
execute_process(COMMAND "${NM}" --defined-only "${module}" OUTPUT_VARIABLE symbols RESULT_VARIABLE result ERROR_QUIET)
|
|
if(NOT result EQUAL 0 OR symbols STREQUAL "")
|
|
list(APPEND failures "${name}: no symbol table to inspect")
|
|
continue()
|
|
endif()
|
|
if(NOT symbols MATCHES " T __mingw_cxa_thread_atexit\n")
|
|
continue()
|
|
endif()
|
|
execute_process(COMMAND "${OBJDUMP}" -d --no-show-raw-insn "${module}" OUTPUT_VARIABLE code RESULT_VARIABLE result ERROR_QUIET)
|
|
if(NOT result EQUAL 0)
|
|
list(APPEND failures "${name}: cannot disassemble")
|
|
continue()
|
|
endif()
|
|
string(REGEX MATCHALL "\n[0-9a-f]+ <[^>\n]+>:|(call|jmp)[^\n]*<__cxa_thread_atexit>" lines "${code}")
|
|
set(function "")
|
|
foreach(line IN LISTS lines)
|
|
if(line MATCHES "^\n[0-9a-f]+ <([^>\n]+)>:$")
|
|
set(function "${CMAKE_MATCH_1}")
|
|
elseif(NOT function MATCHES "^(${explicit})$")
|
|
list(APPEND failures "${name}: ${function} registers a thread_local destructor")
|
|
endif()
|
|
endforeach()
|
|
endforeach()
|
|
if(failures)
|
|
list(REMOVE_DUPLICATES failures)
|
|
list(JOIN failures "\n " text)
|
|
message(FATAL_ERROR "On Windows a thread_local destructor in a module runs after emulated TLS freed the object; keep such objects in HostThreadLocal:\n ${text}")
|
|
endif()
|
|
list(LENGTH modules count)
|
|
message(STATUS "${count} modules register no thread_local destructors")
|