https://sourceware.org/cgit/valgrind/commit/?id=e4559d9fc88df83dc7a727871020e9d66bad11c9
commit e4559d9fc88df83dc7a727871020e9d66bad11c9
Author: Paul Floyd <pj...@wa...>
Date: Sun Nov 30 15:51:20 2025 +0100
Darwin: add code for text_slide
Code from Louis Brunner
Diff:
---
coregrind/m_mach/mach_basics.c | 12 +++++++++++-
coregrind/m_mach/mach_msg.c | 20 ++++++++++----------
coregrind/m_ume/macho.c | 12 ++++++++++--
3 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/coregrind/m_mach/mach_basics.c b/coregrind/m_mach/mach_basics.c
index f0f45f5735..73b802bdd6 100644
--- a/coregrind/m_mach/mach_basics.c
+++ b/coregrind/m_mach/mach_basics.c
@@ -30,6 +30,7 @@
#include "pub_core_basics.h"
#include "pub_core_mach.h"
+#include "pub_core_libcassert.h" // vg_assert
#include <mach/mach.h>
#include <mach/machine/ndr_def.h>
@@ -40,6 +41,7 @@ extern mach_port_name_t thread_self_trap(void);
extern mach_port_t mach_reply_port(void);
/* Global variables set in mach_init() */
+int vm_page_shift = 0;
vm_size_t vm_page_size = 0;
mach_port_name_t mach_task_self_ = 0;
@@ -60,6 +62,10 @@ mach_port_t mig_get_reply_port(void)
// its own behalf, and doesn't call mig outside the semaphore
}
+void mach_msg_destroy(mach_msg_header_t *msg)
+{
+ // TODO: copy from XNU?
+}
void mig_dealloc_reply_port(mach_port_t reply_port)
{
@@ -79,7 +85,11 @@ void VG_(mach_init)(void)
mach_task_self_ = task_self_trap();
// GrP fixme host_page_size(host_self_trap(), &vm_page_size);
- vm_page_size = 4096;
+ vm_page_shift = 12;
+ // FIXME: stored in COMM_PAGE + 0x025, (1 << 12) = 4096
+ vm_page_size = 0x1000;
+
+ vg_assert(1 << vm_page_shift == vm_page_size);
}
#endif // defined(VGO_darwin)
diff --git a/coregrind/m_mach/mach_msg.c b/coregrind/m_mach/mach_msg.c
index c21425472a..adf95c1cf4 100644
--- a/coregrind/m_mach/mach_msg.c
+++ b/coregrind/m_mach/mach_msg.c
@@ -39,6 +39,7 @@
#if defined(VGO_darwin)
+#include "config.h" // for DARWIN_VERS
#include "pub_core_basics.h"
#include "pub_core_mach.h"
@@ -56,16 +57,15 @@ mach_msg_trap(mach_msg_header_t *msg,
mach_msg_timeout_t timeout,
mach_port_t notify);
-mach_msg_return_t
-mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t timeout;
- mach_port_t notify;
-{
+mach_msg_return_t mach_msg(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify
+) {
mach_msg_return_t mr;
/*
diff --git a/coregrind/m_ume/macho.c b/coregrind/m_ume/macho.c
index 239b7fc026..a8fdfd7088 100644
--- a/coregrind/m_ume/macho.c
+++ b/coregrind/m_ume/macho.c
@@ -74,6 +74,7 @@ typedef struct load_info_t {
vki_uint8_t *linker_entry; // dylinker entry point
Addr linker_offset; // dylinker text offset
vki_size_t max_addr; // biggest address reached while loading segments
+ Addr text_slide; // slide of the text segment because of "ASLR" (arm64-only)
} load_info_t;
static void print(const HChar *str)
@@ -180,7 +181,7 @@ load_segment(int fd, vki_off_t offset, vki_off_t size,
vki_size_t vmsize; // page-aligned
vki_size_t vmend; // page-aligned
unsigned int prot;
- Addr slided_addr = segcmd->vmaddr + out_info->linker_offset;
+ Addr slided_addr = segcmd->vmaddr + out_info->linker_offset + out_info->text_slide;
// GrP fixme mark __UNIXSTACK as SF_STACK
@@ -449,6 +450,7 @@ load_dylinker(struct dylinker_command *dycmd, load_info_t *out_info)
linker_info.entry = NULL;
linker_info.linker_entry = NULL;
linker_info.linker_offset = 0;
+ linker_info.text_slide = 0;
linker_info.max_addr = out_info->max_addr;
if (dycmd->name.offset >= dycmd->cmdsize) {
@@ -816,7 +818,7 @@ Bool VG_(match_macho)(const void *hdr, SizeT len)
// GrP fixme check more carefully for matching fat arch?
- return (len >= VKI_PAGE_SIZE &&
+ return (len >= sizeof(*magic) &&
(*magic == MAGIC || *magic == VG_(ntohl)(FAT_MAGIC)))
? True : False;
}
@@ -834,6 +836,7 @@ Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info)
load_info.linker_entry = NULL;
load_info.linker_offset = 0;
load_info.max_addr = 0;
+ load_info.text_slide = 0;
err = VG_(fstat)(fd, &sb);
if (err) {
@@ -856,6 +859,11 @@ Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info)
info->text = (Addr) load_info.text;
info->dynamic = load_info.linker_entry ? True : False;
+ if (!info->dynamic && load_info.text_slide) {
+ print("cannot slide static executables\n");
+ return VKI_ENOEXEC;
+ }
+
info->executable_path = VG_(strdup)("ume.macho.executable_path", name);
SysRes res = VG_(dup)(fd);
|