summaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2014-01-09 23:41:50 +0100
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:24 +0900
commit159fe9b8655a81b1e41f8039e58c0e2cbbd08929 (patch)
tree83584d9f32951afacd3bc8a1729c3830ac44c32d /sysdeps/linux-gnu
parent3da1b63c19adf0300546d2ead50149dac6126323 (diff)
downloadltrace-159fe9b8655a81b1e41f8039e58c0e2cbbd08929.tar.gz
ltrace-159fe9b8655a81b1e41f8039e58c0e2cbbd08929.tar.bz2
ltrace-159fe9b8655a81b1e41f8039e58c0e2cbbd08929.zip
Fix a problem in tracing across fork on PPC64
In order to avoid single-stepping through large portions of the dynamic linker, ltrace remembers at which address the instruction that resolved a PLT slot is. It then puts a breakpoint to this address so that it can fast-forward to that address next time it needs to catch a PLT slot being resolved. When a process is cloned, the pointer to this breakpoint is simply copied over to the new process, instead of being looked up in the new process structures. This patches fixes this.
Diffstat (limited to 'sysdeps/linux-gnu')
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 3ec1397..8715da6 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -1,6 +1,6 @@
/*
* This file is part of ltrace.
- * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2012,2013,2014 Petr Machata, Red Hat Inc.
* Copyright (C) 2004,2008,2009 Juan Cespedes
* Copyright (C) 2006 Paul Gilliam
*
@@ -1157,6 +1157,18 @@ int
arch_process_clone(struct process *retp, struct process *proc)
{
retp->arch = proc->arch;
+
+ if (retp->arch.dl_plt_update_bp != NULL) {
+ /* Point it to the corresponding breakpoint in RETP.
+ * It must be there, this part of PROC has already
+ * been cloned to RETP. */
+ retp->arch.dl_plt_update_bp
+ = address2bpstruct(retp,
+ retp->arch.dl_plt_update_bp->addr);
+
+ assert(retp->arch.dl_plt_update_bp != NULL);
+ }
+
return 0;
}