diff --git a/src/nix/plthook/plthook_osx.c b/src/nix/plthook/plthook_osx.c index 5a0010e..8d4cd5f 100644 --- a/src/nix/plthook/plthook_osx.c +++ b/src/nix/plthook/plthook_osx.c @@ -983,6 +983,7 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo const char *name; void **addr; int rv; + int matches = 0; if (plthook == NULL) { set_errmsg("invalid argument: The first argument is null."); @@ -1013,7 +1014,12 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo } continue; matched: - if (oldfunc) { + /* A symbol can appear as more than one PLT/lazy-bind entry (observed + on arm64 builds where the classic-bind fallback produces duplicate + stub slots). Patch every matching entry instead of stopping at the + first, since the real call site may resolve through a later one. */ + matches++; + if (oldfunc && matches == 1) { *oldfunc = *addr; } if (plthook->readonly_segment) { @@ -1028,6 +1034,8 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo } else { *addr = funcaddr; } + } + if (matches > 0) { return 0; } if (rv == EOF) {