about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-07-03 14:14:17 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-07-03 14:14:17 +0200
commit672a41a79cbcfa095d6951112d592354e0efbd5a (patch)
tree3a0b361da40ab3cb2562f7e18e7de20a9018c93e
parent48b881f4912bc795e0467e334e359e9876f73c4f (diff)
downloadbox64-672a41a79cbcfa095d6951112d592354e0efbd5a.tar.gz
box64-672a41a79cbcfa095d6951112d592354e0efbd5a.zip
Added support for R_X86_64_IRELATIVE reloc, along with a test for it (for #303)
-rwxr-xr-xCMakeLists.txt7
-rwxr-xr-xsrc/elfs/elfloader.c8
-rw-r--r--tests/ref20.txt2
-rwxr-xr-xtests/test20bin0 -> 17616 bytes
-rw-r--r--tests/test20.c21
5 files changed, 37 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c8373d3..a8950cf4 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -736,7 +736,12 @@ add_test(backtrace ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
     -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref19.txt
     -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
 
-file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
+add_test(irelative_reloc ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+    -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test20 -D TEST_OUTPUT=tmpfile20.txt
+    -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref20.txt
+    -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+    file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
 foreach(file ${extension_tests})
     get_filename_component(testname "${file}" NAME_WE)
     add_test(NAME "${testname}" COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 44582846..eacafa0d 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -620,6 +620,14 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 printf_dump(LOG_NEVER, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)(head->delta+ rela[i].r_addend));
                 *p = head->delta+ rela[i].r_addend;
                 break;
+            case R_X86_64_IRELATIVE:
+                {
+                    x64emu_t* emu = thread_get_emu();
+                    EmuCall(emu, head->delta+rela[i].r_addend);
+                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_IRELATIVE @%p (%p -> %p()=%p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)(head->delta+ rela[i].r_addend), (void*)(R_RAX));
+                    *p = R_RAX;
+                }
+                break;
             case R_X86_64_COPY:
                 globoffs = offs;
                 globend = end;
diff --git a/tests/ref20.txt b/tests/ref20.txt
new file mode 100644
index 00000000..fa4fb4f7
--- /dev/null
+++ b/tests/ref20.txt
@@ -0,0 +1,2 @@
+
+Called function number 2
diff --git a/tests/test20 b/tests/test20
new file mode 100755
index 00000000..98de9e83
--- /dev/null
+++ b/tests/test20
Binary files differdiff --git a/tests/test20.c b/tests/test20.c
new file mode 100644
index 00000000..d80a5f5b
--- /dev/null
+++ b/tests/test20.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+int myfunc1() { return 1; }
+int myfunc2() { return 2; }
+
+// Prototype for the common entry point
+/*extern "C" */int myfunc();
+__asm__ (".type myfunc, @gnu_indirect_function");
+// Make the dispatcher function. This returns a pointer to the desired function version
+typeof(myfunc) * myfunc_dispatch (void) __asm__ ("myfunc");
+typeof(myfunc) * myfunc_dispatch (void)  {
+if (0) 
+  return &myfunc1;
+else
+  return &myfunc2;
+}
+
+int main() {
+   printf("\nCalled function number %i\n", myfunc());
+   return 0;
+}
+