From add81f308230ba6e686527ae7eb8577458ace9e6 Mon Sep 17 00:00:00 2001 From: LeandroLP23 Date: Sun, 1 Nov 2026 00:58:34 +0100 Subject: [PATCH] test(relinker): load two converted modules with colliding exports on Windows Two guest modules export the same `shared` function and `tls_value` TLS symbol with default visibility; the second has DF_SYMBOLIC. Each module's entry calls its own `shared` through R_X86_64_64, GLOB_DAT and JUMP_SLOT relocations and adds its own `tls_value` read through a TPOFF64 relocation. The converted Windows executable calls both entries and must exit with the value only reachable when every reference binds to its own module: (3 * 1 + 4) + (3 * 2 + 8) * 16. Co-Authored-By: Claude Opus 5.5 --- core/relinker/CMakeLists.txt | 2 + .../tests/test_guest_symbolic_modules.py | 102 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 core/relinker/relinker/tests/test_guest_symbolic_modules.py diff --git a/core/relinker/CMakeLists.txt b/core/relinker/CMakeLists.txt index 6ede0aab5f..5853c71b84 100644 --- a/core/relinker/CMakeLists.txt +++ b/core/relinker/CMakeLists.txt @@ -831,6 +831,8 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_absolute_symbols.py $) add_test(NAME guest_module_identity COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_module_identity.py $) + add_test(NAME guest_symbolic_modules COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_symbolic_modules.py $) add_test(NAME linux_guest_zero_address_exports COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_linux_guest_zero_address_exports.py $ $) diff --git a/core/relinker/relinker/tests/test_guest_symbolic_modules.py b/core/relinker/relinker/tests/test_guest_symbolic_modules.py new file mode 100644 index 0000000000..3168cfcdfd --- /dev/null +++ b/core/relinker/relinker/tests/test_guest_symbolic_modules.py @@ -0,0 +1,102 @@ +from pathlib import Path +import os +import struct +import subprocess +import sys + +from guest_import_fixtures import dynamic, fixture_directory +from test_guest_intel_trampolines import PLAIN_SITE, guest_fixture, main_fixture + +ENTRY = 0x1010 +SHARED = 0x1000 +CALL_SLOTS = (0x23a0, 0x23a8, 0x23b0) +TLS_SLOT = 0x23b8 + + +def module(value, tls_value, identity, entry_symbol, symbolic): + image = guest_fixture(PLAIN_SITE, symbolic=symbolic) + strings = b'\0shared#A#B\0' + entry_symbol.encode() + b'#A#B\0tls_value#A#B\0' + entry_name = strings.index(entry_symbol.encode()) + tls_name = strings.index(b'tls_value') + identity_offset = len(strings) + strings += identity.encode() + b'\0' + assert len(strings) <= 0x40 + image[0x800:0x800 + len(strings)] = strings + tags = [(5, 0x2200), (10, len(strings)), (6, 0x2280), (11, 24), + (4, 0x2240), (7, 0x2300), (8, 24 * (len(CALL_SLOTS) + 1)), (9, 24), + (0x61000043, (1 << 48) | (0x101 << 32) | identity_offset)] + if symbolic: + tags.append((30, 2)) + dynamic(image, 0x600, 176, tags) + struct.pack_into('