Skip to content

ARMJIT_Linkage.S: add .note.GNU-stack to the JIT linkage - #218

Open
veralvx wants to merge 1 commit into
libretro:masterfrom
veralvx:master
Open

ARMJIT_Linkage.S: add .note.GNU-stack to the JIT linkage#218
veralvx wants to merge 1 commit into
libretro:masterfrom
veralvx:master

Conversation

@veralvx

@veralvx veralvx commented Sep 1, 2026

Copy link
Copy Markdown

ARMJIT_Linkage.S: add .note.GNU-stack to the JIT linkage files

Fixes the core failing to load on glibc 2.41 and newer:

Failed to open libretro core: .../melonds_libretro.so
Error(s): .../melonds_libretro.so: cannot enable executable stack as
shared object requires: Invalid argument

Both ARMJIT_Linkage.S files are assembled without a .note.GNU-stack section. The linker treats an object without that note as needing an executable stack and marks the whole .so RWE. glibc 2.41 changed dlopen to fail on such objects rather than making the stack executable, so RetroArch cannot load the core.

Four lines appended to each file, using upstream melonDS's current form:

/* src/ARMJIT_x64/ARMJIT_Linkage.S */
#if !defined(__APPLE__) && !defined(_WIN64) && !defined(_MSC_VER)
.section .note.GNU-stack,"",@progbits
#endif

/* src/ARMJIT_A64/ARMJIT_Linkage.S */
#if !defined(__APPLE__) && !defined(__WIN32__)
.section .note.GNU-stack,"",@progbits
#endif

Upstream added these in 3ab752b and refined the guards in 2a86ee7 (non-MinGW Clang) and 63e4b68 (_WIN64 instead of a workaround).

Guards are needed because .note.GNU-stack is ELF-only, and Mach-O and PE/COFF targets must not see the directive. Makefile:548 builds these files with $(CC) -x assembler-with-cpp, so the preprocessor runs and the guards take effect. Windows and Apple builds assemble as before.

Testing

On x86_64 Linux with glibc 2.41+:

  • built the core before the change, confirmed readelf -lW melonds_libretro.so reports GNU_STACK ... RWE, and RetroArch fails to load it with the error above.
  • built after the change, GNU_STACK ... RW, core loads and runs content
  • assembled ARMJIT_Linkage.S alone both ways: ld prints "missing .note.GNU-stack section implies executable stack" before, and nothing after.
  • checked the guards by preprocessing with -D_WIN64 and -D__APPLE__: the directive is dropped in both cases and kept on a plain ELF target

The aarch64 change is the same edit to the same construct and matches upstream, but I have not built it on hardware.

 files

Without the note, the linker marks the whole core as requiring an
executable stack. glibc 2.41 and newer refuse to dlopen such objects
instead of granting the request, so RetroArch cannot load the core:

  Failed to open libretro core: .../melonds_libretro.so
  Error(s): .../melonds_libretro.so: cannot enable executable stack as
  shared object requires: Invalid argument

The requirement is spurious. The JIT allocates its executable memory
with mmap (ARMJIT_Memory.cpp), never on the stack.

Upstream melonDS added the same note to both files in 3ab752b and
refined the guards in 2a86ee7 and 63e4b68. This uses the current
upstream form.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant