--- a/vm.c +++ b/vm.c @@ -728,6 +728,15 @@ #ifdef RB_THREAD_LOCAL_SPECIFIER RB_THREAD_LOCAL_SPECIFIER rb_execution_context_t *ruby_current_ec; +#if defined(__linux__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(__aarch64__)) && \ + (defined(__GNUC__) || defined(__clang__)) && \ + RBIMPL_HAS_ATTRIBUTE(alias) && RBIMPL_HAS_ATTRIBUTE(visibility) +/* Best-effort debugging symbol: same TLS storage, not a public C API. */ +extern RB_THREAD_LOCAL_SPECIFIER __typeof__(ruby_current_ec) ruby_debug_current_ec + __attribute__((alias("ruby_current_ec"), visibility("protected"))); +#endif + #ifdef RUBY_NT_SERIAL RB_THREAD_LOCAL_SPECIFIER rb_atomic_t ruby_nt_serial; #endif @@ -2938,6 +2947,15 @@ return result; } +#if defined(__linux__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(__aarch64__)) && \ + (defined(__GNUC__) || defined(__clang__)) && \ + RBIMPL_HAS_ATTRIBUTE(alias) && RBIMPL_HAS_ATTRIBUTE(visibility) +/* vm_exec is macro-renamed to the actual assembler symbol rb_vm_exec above. */ +extern __typeof__(vm_exec) ruby_debug_vm_exec + __attribute__((alias("rb_vm_exec"), visibility("protected"))); +#endif + static inline VALUE vm_exec_loop(rb_execution_context_t *ec, enum ruby_tag_type state, struct rb_vm_tag *tag, VALUE result) --- a/symbol.c +++ b/symbol.c @@ -92,6 +92,15 @@ .next_id = tNEXT_ID, }; +#if defined(__linux__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(__aarch64__)) && \ + (defined(__GNUC__) || defined(__clang__)) && \ + RBIMPL_HAS_ATTRIBUTE(alias) && RBIMPL_HAS_ATTRIBUTE(visibility) +/* Best-effort debugging symbol: the original table storage, never a copy. */ +extern __typeof__(ruby_global_symbols) ruby_debug_global_symbols + __attribute__((alias("ruby_global_symbols"), visibility("protected"))); +#endif + struct sym_set_static_sym_entry { VALUE sym; VALUE str;