From 9ab8c3fd9e271bd7774fa1f3fd0c3497e2c216d0 Mon Sep 17 00:00:00 2001 From: Johnny Hughes Date: Wed, 2 Oct 2024 16:28:42 +0000 Subject: [PATCH] gcc-toolset-10-ltrace package is retired on branch c10s for CS-2551 --- .gitignore | 2 - README.md | 3 + dead.package | 1 + ltrace-0.7.2-e_machine.patch | 20 - ltrace-0.7.91-aarch64-params.patch | 37 - ltrace-0.7.91-aarch64.patch | 2416 --------------------- ltrace-0.7.91-account_execl.patch | 834 ------- ltrace-0.7.91-arm.patch | 610 ------ ltrace-0.7.91-breakpoint-on_install.patch | 81 - ltrace-0.7.91-cant_open.patch | 36 - ltrace-0.7.91-cet.patch | 121 -- ltrace-0.7.91-man.patch | 45 - ltrace-0.7.91-multithread-no-f-1.patch | 175 -- ltrace-0.7.91-multithread-no-f-2.patch | 50 - ltrace-0.7.91-null.patch | 14 - ltrace-0.7.91-parser-ws_after_id.patch | 144 -- ltrace-0.7.91-ppc-bias.patch | 91 - ltrace-0.7.91-ppc64-fork.patch | 52 - ltrace-0.7.91-ppc64-unprelink.patch | 221 -- ltrace-0.7.91-ppc64le-configure.patch | 44 - ltrace-0.7.91-ppc64le-fixes.patch | 421 ---- ltrace-0.7.91-ppc64le-support.patch | 786 ------- 22 files changed, 4 insertions(+), 6200 deletions(-) delete mode 100644 .gitignore create mode 100644 README.md create mode 100644 dead.package delete mode 100644 ltrace-0.7.2-e_machine.patch delete mode 100644 ltrace-0.7.91-aarch64-params.patch delete mode 100644 ltrace-0.7.91-aarch64.patch delete mode 100644 ltrace-0.7.91-account_execl.patch delete mode 100644 ltrace-0.7.91-arm.patch delete mode 100644 ltrace-0.7.91-breakpoint-on_install.patch delete mode 100644 ltrace-0.7.91-cant_open.patch delete mode 100644 ltrace-0.7.91-cet.patch delete mode 100644 ltrace-0.7.91-man.patch delete mode 100644 ltrace-0.7.91-multithread-no-f-1.patch delete mode 100644 ltrace-0.7.91-multithread-no-f-2.patch delete mode 100644 ltrace-0.7.91-null.patch delete mode 100644 ltrace-0.7.91-parser-ws_after_id.patch delete mode 100644 ltrace-0.7.91-ppc-bias.patch delete mode 100644 ltrace-0.7.91-ppc64-fork.patch delete mode 100644 ltrace-0.7.91-ppc64-unprelink.patch delete mode 100644 ltrace-0.7.91-ppc64le-configure.patch delete mode 100644 ltrace-0.7.91-ppc64le-fixes.patch delete mode 100644 ltrace-0.7.91-ppc64le-support.patch diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0b6200d..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES/ltrace-0.7.91.tar.bz2 -/ltrace-0.7.91.tar.bz2 diff --git a/README.md b/README.md new file mode 100644 index 0000000..24b9ea2 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Package Not Available +This package is not available on CentOS Stream 10. +It may be available on another branch. \ No newline at end of file diff --git a/dead.package b/dead.package new file mode 100644 index 0000000..312c0c3 --- /dev/null +++ b/dead.package @@ -0,0 +1 @@ +gcc-toolset-10-ltrace package is retired on branch c10s for CS-2551 \ No newline at end of file diff --git a/ltrace-0.7.2-e_machine.patch b/ltrace-0.7.2-e_machine.patch deleted file mode 100644 index 2cfc15a..0000000 --- a/ltrace-0.7.2-e_machine.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -up ltrace-0.7.2/proc.c\~ ltrace-0.7.2/proc.c ---- ltrace-0.7.2/proc.c~ 2014-02-13 12:16:33.000000000 +0100 -+++ ltrace-0.7.2/proc.c 2014-02-13 15:44:25.000000000 +0100 -@@ -194,9 +197,11 @@ process_init(struct process *proc, const - goto fail; - } - -- if (proc->leader != proc) -- return 0; -- if (process_init_main(proc) < 0) { -+ if (proc->leader != proc) { -+ proc->e_machine = proc->leader->e_machine; -+ proc->e_class = proc->leader->e_class; -+ get_arch_dep(proc); -+ } else if (process_init_main(proc) < 0) { - process_bare_destroy(proc, 0); - goto fail; - } - -Diff finished. Thu Feb 13 15:50:21 2014 diff --git a/ltrace-0.7.91-aarch64-params.patch b/ltrace-0.7.91-aarch64-params.patch deleted file mode 100644 index 29767c5..0000000 --- a/ltrace-0.7.91-aarch64-params.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -rup a/sysdeps/linux-gnu/aarch64/fetch.c b/sysdeps/linux-gnu/aarch64/fetch.c ---- a/sysdeps/linux-gnu/aarch64/fetch.c 2018-07-05 16:06:10.066626252 -0400 -+++ b/sysdeps/linux-gnu/aarch64/fetch.c 2018-07-05 16:17:17.659748481 -0400 -@@ -308,12 +308,9 @@ arch_fetch_arg_init(enum tof type, struc - struct fetch_script how = pass_arg(context, proc, ret_info); - if (how.c == CVT_ERR) - goto fail; -- if (how.c == CVT_NOP && how.f == FETCH_STACK) { -+ if (how.c == CVT_BYREF && how.f == FETCH_GPR) { - /* XXX double cast. */ - context->x8 = (arch_addr_t) (uintptr_t) context->gregs.regs[8]; -- /* See the comment above about the assert. */ -- assert(! "Unexpected: first argument passed on stack."); -- abort(); - } - - return context; -diff -rup a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp ---- a/testsuite/ltrace.main/system_call_params.exp 2018-07-05 16:06:10.516624926 -0400 -+++ b/testsuite/ltrace.main/system_call_params.exp 2018-07-05 16:58:01.549830643 -0400 -@@ -61,13 +61,13 @@ set conf [ltraceNamedSource "$dir/syscal - # doesn't list readdir, that would be taken from somelib.conf with a - # wrong prototype. - --ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path"} == 0 -+ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path", 0\)} == 0 - - # On the other hand, if -F somedir/ is given, we want to accept - # syscalls.conf found there. - - ltraceMatch [ltraceRun -L -S -F $dir -- $bin] { -- {{^open@SYS\("/some/path"} == 1} -+ {{^open@SYS\("/some/path", 0\)} == 1} - {{^write@SYS\(1, "something", 10\)} == 1} - {{^mount@SYS\("source", "target", "filesystemtype"} == 1} - } -Only in b/testsuite/ltrace.main: system_call_params.exp~ diff --git a/ltrace-0.7.91-aarch64.patch b/ltrace-0.7.91-aarch64.patch deleted file mode 100644 index 123cfe1..0000000 --- a/ltrace-0.7.91-aarch64.patch +++ /dev/null @@ -1,2416 +0,0 @@ -diff --git a/README b/README -index 414bdfb..a04b767 100644 ---- a/README -+++ b/README -@@ -24,6 +24,7 @@ The following targets are currently (at least somewhat) supported. - Some of them may be more or less broken in reality, it is not feasible - to test each release comprehensively on each target. - -+ aarch64-*-linux-gnu - armv6l-*-linux-gnueabi - armv7l-*-linux-gnueabihf - i[4567]86-*-linux-gnu -@@ -81,7 +82,7 @@ quick one-liner), it is advisable to send an e-mail beforehand. - - - ------------------------------------------------------------------------------- --Copyright (C) 2012,2013 Petr Machata -+Copyright (C) 2012-2014 Petr Machata - Copyright (C) 1997-2009 Juan Cespedes - This file is part of ltrace. - -diff --git a/configure.ac b/configure.ac -index c6e6bf0..0e9a124 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1,6 +1,6 @@ - # -*- Autoconf -*- - # This file is part of ltrace. --# Copyright (C) 2010,2012,2013 Petr Machata, Red Hat Inc. -+# Copyright (C) 2010,2012,2013,2014 Petr Machata, Red Hat Inc. - # Copyright (C) 2010,2011 Joe Damato - # Copyright (C) 2010 Marc Kleine-Budde - # Copyright (C) 2010 Zachary T Welch -@@ -399,6 +399,7 @@ AC_CONFIG_FILES([ - Makefile - sysdeps/Makefile - sysdeps/linux-gnu/Makefile -+ sysdeps/linux-gnu/aarch64/Makefile - sysdeps/linux-gnu/alpha/Makefile - sysdeps/linux-gnu/arm/Makefile - sysdeps/linux-gnu/cris/Makefile -diff --git a/etc/libc.so.conf b/etc/libc.so.conf -index 669c50a..48b3b01 100644 ---- a/etc/libc.so.conf -+++ b/etc/libc.so.conf -@@ -1,5 +1,12 @@ - # See ltrace.conf(5) for description of syntax of this file. - -+# XXX ltrace misses long double and long long support -+typedef ldouble = double; -+typedef llong = long; -+typedef ullong = ulong; -+ -+void __libc_start_main(hide(void*), hide(int), array(string, arg2)); -+ - # arpa/inet.h - typedef in_addr = struct(hex(uint)); - int inet_aton(string, +in_addr*); -@@ -233,9 +240,22 @@ void setbuffer(file,addr,ulong); - void setlinebuf(file); - int rename(string,string); - -+# xlocale.h -+typedef locale_t = void*; -+locale_t newlocale(hex(int), string, locale_t); -+ - # stdlib.h --long __strtol_internal(string,addr,int); --ulong __strtoul_internal(string,addr,int); -+long __strtol_internal(string, +string*, int); -+ulong __strtoul_internal(string, +string*, int); -+ -+double strtod(string, +string*); -+float strtof(string, +string*); -+ldouble strtold(string, +string*); -+ -+double strtod_l(string, +string*, locale_t); -+float strtof_l(string, +string*, locale_t); -+ldouble strtold_l(string, +string*, locale_t); -+ - int atexit(addr); - addr bsearch(string, addr, ulong, ulong, addr); - addr calloc(ulong, ulong); -@@ -343,6 +363,10 @@ addr gmtime(addr); - addr localtime(addr); - ulong strftime(+string2,ulong,string,addr); - long time(addr); -+# XXX in fact (time_t, long), which may be (llong, long) on 32-bit -+# arches. We don't have llong as of this writing. -+typedef timespec = struct(long, long); -+int nanosleep(timespec*, timespec*); - - # unistd.h - void _exit(int); -diff --git a/etc/syscalls.conf b/etc/syscalls.conf -index 562f4e7..09d347d 100644 ---- a/etc/syscalls.conf -+++ b/etc/syscalls.conf -@@ -1,6 +1,10 @@ - # syscall.conf -- system call prototypes - # See ltrace.conf(5) for description of syntax of this file. - -+# Special value used to indicate the *at functions should use the -+# current working directory. -+typedef at_dirfd_t = enum[int](AT_FDCWD=-100); -+ - addr brk(addr); - int close(int); - int execve(string,addr,addr); -@@ -14,7 +18,7 @@ int getpid(); - addr mmap(addr,ulong,int,int,int,long); - - int munmap(addr,ulong); --int open(string,int,octal); -+int open(string, hex(uint), oct(uint)); - int personality(uint); - long read(int,+string0,ulong); - int stat(string,addr); -@@ -113,3 +117,30 @@ ulong writev(int,addr,int); - int mprotect(addr,int,int); - int access(string,octal); - int getdents(uint, void *, uint); -+ -+int openat(at_dirfd_t, string, hex(uint), oct(uint)); -+int mknodat(at_dirfd_t, string, oct(uint), ushort) -+int mkdirat(at_dirfd_t, string, oct(uint)); -+int unlinkat(at_dirfd_t, string, hex(uint)); -+int symlinkat(string, at_dirfd_t, string); -+int linkat(at_dirfd_t, string, at_dirfd_t, string, hex(uint)); -+int renameat(at_dirfd_t, string, at_dirfd_t, string); -+int faccessat(at_dirfd_t, string, oct(uint), hex(uint)); -+int fchmodat(at_dirfd_t, string, oct(uint), hex(uint)); -+int fchownat(at_dirfd_t, string, int, int, hex(uint)); -+int readlinkat(at_dirfd_t, string, +string[arg4], ulong); -+int fstatat(at_dirfd_t, string, addr, hex(uint)); -+int utimensat(at_dirfd_t, string, addr, hex(uint)); -+int futimens(int, addr); -+int futimesat(at_dirfd_t, string, addr); -+addr shmat(int, addr, hex(uint)); -+int shmdt(addr); -+ -+typedef fid_type = enum(FILEID_ROOT=0, FILEID_INO32_GEN=1, FILEID_INO32_GEN_PARENT=2, FILEID_BTRFS_WITHOUT_PARENT=0x4d, FILEID_BTRFS_WITH_PARENT=0x4e, FILEID_BTRFS_WITH_PARENT_ROOT=0x4f, FILEID_UDF_WITHOUT_PARENT=0x51, FILEID_UDF_WITH_PARENT=0x52, FILEID_NILFS_WITHOUT_PARENT=0x61, FILEID_NILFS_WITH_PARENT=0x62); -+typedef file_handle = struct(uint, fid_type, array(hex(char), elt1)*); -+int name_to_handle_at(at_dirfd_t, string, file_handle, int*, hex(uint)); -+int open_by_handle_at(at_dirfd_t, file_handle, hex(uint)); -+ -+int newfstatat(at_dirfd_t, string, addr, hex(uint)); -+int creat(string, oct(int)); -+int ustat(ushort, addr); -diff --git a/sysdeps/linux-gnu/Makefile.am b/sysdeps/linux-gnu/Makefile.am -index ecee577..ec26162 100644 ---- a/sysdeps/linux-gnu/Makefile.am -+++ b/sysdeps/linux-gnu/Makefile.am -@@ -1,4 +1,5 @@ - # This file is part of ltrace. -+# Copyright (C) 2014 Petr Machata, Red Hat, Inc. - # Copyright (C) 2010,2012 Marc Kleine-Budde, Pengutronix - # - # This program is free software; you can redistribute it and/or -@@ -16,7 +17,8 @@ - # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - # 02110-1301 USA - --DIST_SUBDIRS = alpha arm cris ia64 m68k metag mips ppc s390 sparc x86 -+DIST_SUBDIRS = aarch64 alpha arm cris ia64 m68k metag mips ppc s390 \ -+ sparc x86 - - SUBDIRS = \ - $(HOST_CPU) -diff --git a/sysdeps/linux-gnu/aarch64/Makefile.am b/sysdeps/linux-gnu/aarch64/Makefile.am -new file mode 100644 -index 0000000..0af4e6e ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/Makefile.am -@@ -0,0 +1,25 @@ -+# This file is part of ltrace. -+# Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+# -+# This program is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public License as -+# published by the Free Software Foundation; either version 2 of the -+# License, or (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+# 02110-1301 USA -+ -+noinst_LTLIBRARIES = ../libcpu.la -+ -+___libcpu_la_SOURCES = fetch.c plt.c regs.c trace.c -+ -+noinst_HEADERS = arch.h ptrace.h signalent.h syscallent.h -+ -+MAINTAINERCLEANFILES = Makefile.in -diff --git a/sysdeps/linux-gnu/aarch64/arch.h b/sysdeps/linux-gnu/aarch64/arch.h -new file mode 100644 -index 0000000..4137613 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/arch.h -@@ -0,0 +1,37 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+#ifndef LTRACE_AARCH64_ARCH_H -+#define LTRACE_AARCH64_ARCH_H -+ -+/* | 31 21 | 20 5 | 4 0 | * -+ * | 1 1 0 1 0 1 0 0 0 0 1 | imm16 | 0 0 0 0 0 | */ -+#define BREAKPOINT_VALUE { 0xd4, 0x20, 0, 0 } -+#define BREAKPOINT_LENGTH 4 -+#define DECR_PC_AFTER_BREAK 0 -+ -+#define LT_ELFCLASS ELFCLASS64 -+#define LT_ELF_MACHINE EM_AARCH64 -+ -+#define ARCH_HAVE_FETCH_ARG -+#define ARCH_ENDIAN_BIG -+#define ARCH_HAVE_SIZEOF -+#define ARCH_HAVE_ALIGNOF -+ -+#endif /* LTRACE_AARCH64_ARCH_H */ -diff --git a/sysdeps/linux-gnu/aarch64/fetch.c b/sysdeps/linux-gnu/aarch64/fetch.c -new file mode 100644 -index 0000000..8779f03 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/fetch.c -@@ -0,0 +1,365 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "fetch.h" -+#include "proc.h" -+#include "type.h" -+#include "value.h" -+ -+int aarch64_read_gregs(struct process *proc, struct user_pt_regs *regs); -+int aarch64_read_fregs(struct process *proc, struct user_fpsimd_state *regs); -+ -+ -+struct fetch_context -+{ -+ struct user_pt_regs gregs; -+ struct user_fpsimd_state fpregs; -+ arch_addr_t nsaa; -+ unsigned ngrn; -+ unsigned nsrn; -+ arch_addr_t x8; -+}; -+ -+static int -+context_init(struct fetch_context *context, struct process *proc) -+{ -+ if (aarch64_read_gregs(proc, &context->gregs) < 0 -+ || aarch64_read_fregs(proc, &context->fpregs) < 0) -+ return -1; -+ -+ context->ngrn = 0; -+ context->nsrn = 0; -+ /* XXX double cast */ -+ context->nsaa = (arch_addr_t) (uintptr_t) context->gregs.sp; -+ context->x8 = 0; -+ -+ return 0; -+} -+ -+struct fetch_context * -+arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) -+{ -+ struct fetch_context *ret = malloc(sizeof(*ret)); -+ if (ret == NULL) -+ return NULL; -+ return memcpy(ret, context, sizeof(*ret)); -+} -+ -+static void -+fetch_next_gpr(struct fetch_context *context, unsigned char *buf) -+{ -+ uint64_t u = context->gregs.regs[context->ngrn++]; -+ memcpy(buf, &u, 8); -+} -+ -+static int -+fetch_gpr(struct fetch_context *context, struct value *value, size_t sz) -+{ -+ if (sz < 8) -+ sz = 8; -+ -+ unsigned char *buf = value_reserve(value, sz); -+ if (buf == NULL) -+ return -1; -+ -+ size_t i; -+ for (i = 0; i < sz; i += 8) -+ fetch_next_gpr(context, buf + i); -+ -+ return 0; -+} -+ -+static void -+fetch_next_sse(struct fetch_context *context, unsigned char *buf, size_t sz) -+{ -+ __int128 u = context->fpregs.vregs[context->nsrn++]; -+ memcpy(buf, &u, sz); -+} -+ -+static int -+fetch_sse(struct fetch_context *context, struct value *value, size_t sz) -+{ -+ unsigned char *buf = value_reserve(value, sz); -+ if (buf == NULL) -+ return -1; -+ -+ fetch_next_sse(context, buf, sz); -+ return 0; -+} -+ -+static int -+fetch_hfa(struct fetch_context *context, -+ struct value *value, struct arg_type_info *hfa_t, size_t count) -+{ -+ size_t sz = type_sizeof(value->inferior, hfa_t); -+ unsigned char *buf = value_reserve(value, sz * count); -+ if (buf == NULL) -+ return -1; -+ -+ size_t i; -+ for (i = 0; i < count; ++i) { -+ fetch_next_sse(context, buf, sz); -+ buf += sz; -+ } -+ return 0; -+} -+ -+static int -+fetch_stack(struct fetch_context *context, struct value *value, -+ size_t align, size_t sz) -+{ -+ if (align < 8) -+ align = 8; -+ size_t amount = ((sz + align - 1) / align) * align; -+ -+ /* XXX double casts */ -+ uintptr_t sp = (uintptr_t) context->nsaa; -+ sp = ((sp + align - 1) / align) * align; -+ -+ value_in_inferior(value, (arch_addr_t) sp); -+ -+ sp += amount; -+ context->nsaa = (arch_addr_t) sp; -+ -+ return 0; -+} -+ -+enum convert_method { -+ CVT_ERR = -1, -+ CVT_NOP = 0, -+ CVT_BYREF, -+}; -+ -+enum fetch_method { -+ FETCH_NOP, -+ FETCH_STACK, -+ FETCH_GPR, -+ FETCH_SSE, -+ FETCH_HFA, -+}; -+ -+struct fetch_script { -+ enum convert_method c; -+ enum fetch_method f; -+ size_t sz; -+ struct arg_type_info *hfa_t; -+ size_t count; -+}; -+ -+static struct fetch_script -+pass_arg(struct fetch_context const *context, -+ struct process *proc, struct arg_type_info *info) -+{ -+ enum fetch_method cvt = CVT_NOP; -+ -+ size_t sz = type_sizeof(proc, info); -+ if (sz == (size_t) -1) -+ return (struct fetch_script) { CVT_ERR, FETCH_NOP, sz }; -+ -+ switch (info->type) { -+ case ARGTYPE_VOID: -+ return (struct fetch_script) { cvt, FETCH_NOP, sz }; -+ -+ case ARGTYPE_STRUCT: -+ case ARGTYPE_ARRAY:; -+ size_t count; -+ struct arg_type_info *hfa_t = type_get_hfa_type(info, &count); -+ if (hfa_t != NULL && count <= 4) { -+ if (context->nsrn + count <= 8) -+ return (struct fetch_script) -+ { cvt, FETCH_HFA, sz, hfa_t, count }; -+ return (struct fetch_script) -+ { cvt, FETCH_STACK, sz, hfa_t, count }; -+ } -+ -+ if (sz <= 16) { -+ size_t count = sz / 8; -+ if (context->ngrn + count <= 8) -+ return (struct fetch_script) -+ { cvt, FETCH_GPR, sz }; -+ } -+ -+ cvt = CVT_BYREF; -+ sz = 8; -+ /* Fall through. */ -+ -+ case ARGTYPE_POINTER: -+ case ARGTYPE_INT: -+ case ARGTYPE_UINT: -+ case ARGTYPE_LONG: -+ case ARGTYPE_ULONG: -+ case ARGTYPE_CHAR: -+ case ARGTYPE_SHORT: -+ case ARGTYPE_USHORT: -+ if (context->ngrn < 8 && sz <= 8) -+ return (struct fetch_script) { cvt, FETCH_GPR, sz }; -+ /* We don't support types wider than 8 bytes as of -+ * now. */ -+ assert(sz <= 8); -+ -+ return (struct fetch_script) { cvt, FETCH_STACK, sz }; -+ -+ case ARGTYPE_FLOAT: -+ case ARGTYPE_DOUBLE: -+ if (context->nsrn < 8) { -+ /* ltrace doesn't support float128. */ -+ assert(sz <= 8); -+ return (struct fetch_script) { cvt, FETCH_SSE, sz }; -+ } -+ -+ return (struct fetch_script) { cvt, FETCH_STACK, sz }; -+ } -+ -+ assert(! "Failed to allocate argument."); -+ abort(); -+} -+ -+static int -+convert_arg(struct value *value, struct fetch_script how) -+{ -+ switch (how.c) { -+ case CVT_NOP: -+ return 0; -+ case CVT_BYREF: -+ return value_pass_by_reference(value); -+ case CVT_ERR: -+ return -1; -+ } -+ -+ assert(! "Don't know how to convert argument."); -+ abort(); -+} -+ -+static int -+fetch_arg(struct fetch_context *context, -+ struct process *proc, struct arg_type_info *info, -+ struct value *value, struct fetch_script how) -+{ -+ if (convert_arg(value, how) < 0) -+ return -1; -+ -+ switch (how.f) { -+ case FETCH_NOP: -+ return 0; -+ -+ case FETCH_STACK: -+ if (how.hfa_t != NULL && how.count != 0 && how.count <= 8) -+ context->nsrn = 8; -+ return fetch_stack(context, value, -+ type_alignof(proc, info), how.sz); -+ -+ case FETCH_GPR: -+ return fetch_gpr(context, value, how.sz); -+ -+ case FETCH_SSE: -+ return fetch_sse(context, value, how.sz); -+ -+ case FETCH_HFA: -+ return fetch_hfa(context, value, how.hfa_t, how.count); -+ } -+ -+ assert(! "Don't know how to fetch argument."); -+ abort(); -+} -+ -+struct fetch_context * -+arch_fetch_arg_init(enum tof type, struct process *proc, -+ struct arg_type_info *ret_info) -+{ -+ struct fetch_context *context = malloc(sizeof *context); -+ if (context == NULL || context_init(context, proc) < 0) { -+ fail: -+ free(context); -+ return NULL; -+ } -+ -+ /* There's a provision in ARMv8 parameter passing convention -+ * for returning types that, if passed as first argument to a -+ * function, would be passed on stack. For those types, x8 -+ * contains an address where the return argument should be -+ * placed. The callee doesn't need to preserve the value of -+ * x8, so we need to fetch it now. -+ * -+ * To my knowledge, there are currently no types where this -+ * holds, but the code is here, utterly untested. */ -+ -+ struct fetch_script how = pass_arg(context, proc, ret_info); -+ if (how.c == CVT_ERR) -+ goto fail; -+ if (how.c == CVT_NOP && how.f == FETCH_STACK) { -+ /* XXX double cast. */ -+ context->x8 = (arch_addr_t) (uintptr_t) context->gregs.regs[8]; -+ /* See the comment above about the assert. */ -+ assert(! "Unexpected: first argument passed on stack."); -+ abort(); -+ } -+ -+ return context; -+} -+ -+int -+arch_fetch_arg_next(struct fetch_context *context, enum tof type, -+ struct process *proc, struct arg_type_info *info, -+ struct value *value) -+{ -+ return fetch_arg(context, proc, info, value, -+ pass_arg(context, proc, info)); -+} -+ -+int -+arch_fetch_retval(struct fetch_context *context, enum tof type, -+ struct process *proc, struct arg_type_info *info, -+ struct value *value) -+{ -+ if (context->x8 != 0) { -+ value_in_inferior(value, context->x8); -+ return 0; -+ } -+ -+ if (context_init(context, proc) < 0) -+ return -1; -+ -+ return fetch_arg(context, proc, info, value, -+ pass_arg(context, proc, info)); -+} -+ -+void -+arch_fetch_arg_done(struct fetch_context *context) -+{ -+ if (context != NULL) -+ free(context); -+} -+ -+size_t -+arch_type_sizeof(struct process *proc, struct arg_type_info *arg) -+{ -+ return (size_t) -2; -+} -+ -+size_t -+arch_type_alignof(struct process *proc, struct arg_type_info *arg) -+{ -+ return (size_t) -2; -+} -diff --git a/sysdeps/linux-gnu/aarch64/plt.c b/sysdeps/linux-gnu/aarch64/plt.c -new file mode 100644 -index 0000000..29dc4c9 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/plt.c -@@ -0,0 +1,38 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+ -+#include "backend.h" -+#include "proc.h" -+#include "library.h" -+#include "ltrace-elf.h" -+ -+arch_addr_t -+sym2addr(struct process *proc, struct library_symbol *sym) -+{ -+ return sym->enter_addr; -+} -+ -+GElf_Addr -+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) -+{ -+ return lte->plt_addr + 32 + ndx * 16; -+} -diff --git a/sysdeps/linux-gnu/aarch64/ptrace.h b/sysdeps/linux-gnu/aarch64/ptrace.h -new file mode 100644 -index 0000000..283c314 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/ptrace.h -@@ -0,0 +1,22 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+#include -diff --git a/sysdeps/linux-gnu/aarch64/regs.c b/sysdeps/linux-gnu/aarch64/regs.c -new file mode 100644 -index 0000000..06eb72b ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/regs.c -@@ -0,0 +1,130 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "backend.h" -+#include "proc.h" -+ -+#define PC_OFF (32 * 4) -+ -+int -+aarch64_read_gregs(struct process *proc, struct user_pt_regs *regs) -+{ -+ *regs = (struct user_pt_regs) {}; -+ struct iovec iovec; -+ iovec.iov_base = regs; -+ iovec.iov_len = sizeof *regs; -+ return ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, &iovec) < 0 -+ ? -1 : 0; -+} -+ -+int -+aarch64_write_gregs(struct process *proc, struct user_pt_regs *regs) -+{ -+ struct iovec iovec; -+ iovec.iov_base = regs; -+ iovec.iov_len = sizeof *regs; -+ return ptrace(PTRACE_SETREGSET, proc->pid, NT_PRSTATUS, &iovec) < 0 -+ ? -1 : 0; -+} -+ -+int -+aarch64_read_fregs(struct process *proc, struct user_fpsimd_state *regs) -+{ -+ *regs = (struct user_fpsimd_state) {}; -+ struct iovec iovec; -+ iovec.iov_base = regs; -+ iovec.iov_len = sizeof *regs; -+ return ptrace(PTRACE_GETREGSET, proc->pid, NT_FPREGSET, &iovec) < 0 -+ ? -1 : 0; -+} -+ -+arch_addr_t -+get_instruction_pointer(struct process *proc) -+{ -+ struct user_pt_regs regs; -+ if (aarch64_read_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "get_instruction_pointer: " -+ "Couldn't read registers of %d.\n", proc->pid); -+ return 0; -+ } -+ -+ /* -+ char buf[128]; -+ sprintf(buf, "cat /proc/%d/maps", proc->pid); -+ system(buf); -+ */ -+ -+ /* XXX double cast */ -+ return (arch_addr_t) (uintptr_t) regs.pc; -+} -+ -+void -+set_instruction_pointer(struct process *proc, arch_addr_t addr) -+{ -+ struct user_pt_regs regs; -+ if (aarch64_read_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "get_instruction_pointer: " -+ "Couldn't read registers of %d.\n", proc->pid); -+ return; -+ } -+ -+ /* XXX double cast */ -+ regs.pc = (uint64_t) (uintptr_t) addr; -+ -+ if (aarch64_write_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "get_instruction_pointer: " -+ "Couldn't write registers of %d.\n", proc->pid); -+ return; -+ } -+} -+ -+arch_addr_t -+get_stack_pointer(struct process *proc) -+{ -+ struct user_pt_regs regs; -+ if (aarch64_read_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "get_stack_pointer: " -+ "Couldn't read registers of %d.\n", proc->pid); -+ return 0; -+ } -+ -+ /* XXX double cast */ -+ return (arch_addr_t) (uintptr_t) regs.sp; -+} -+ -+arch_addr_t -+get_return_addr(struct process *proc, arch_addr_t stack_pointer) -+{ -+ struct user_pt_regs regs; -+ if (aarch64_read_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "get_return_addr: " -+ "Couldn't read registers of %d.\n", proc->pid); -+ return 0; -+ } -+ -+ /* XXX double cast */ -+ return (arch_addr_t) (uintptr_t) regs.regs[30]; -+} -diff --git a/sysdeps/linux-gnu/aarch64/signalent.h b/sysdeps/linux-gnu/aarch64/signalent.h -new file mode 100644 -index 0000000..bf56ebc ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/signalent.h -@@ -0,0 +1,52 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2006 Ian Wienand -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+ "SIG_0", /* 0 */ -+ "SIGHUP", /* 1 */ -+ "SIGINT", /* 2 */ -+ "SIGQUIT", /* 3 */ -+ "SIGILL", /* 4 */ -+ "SIGTRAP", /* 5 */ -+ "SIGABRT", /* 6 */ -+ "SIGBUS", /* 7 */ -+ "SIGFPE", /* 8 */ -+ "SIGKILL", /* 9 */ -+ "SIGUSR1", /* 10 */ -+ "SIGSEGV", /* 11 */ -+ "SIGUSR2", /* 12 */ -+ "SIGPIPE", /* 13 */ -+ "SIGALRM", /* 14 */ -+ "SIGTERM", /* 15 */ -+ "SIGSTKFLT", /* 16 */ -+ "SIGCHLD", /* 17 */ -+ "SIGCONT", /* 18 */ -+ "SIGSTOP", /* 19 */ -+ "SIGTSTP", /* 20 */ -+ "SIGTTIN", /* 21 */ -+ "SIGTTOU", /* 22 */ -+ "SIGURG", /* 23 */ -+ "SIGXCPU", /* 24 */ -+ "SIGXFSZ", /* 25 */ -+ "SIGVTALRM", /* 26 */ -+ "SIGPROF", /* 27 */ -+ "SIGWINCH", /* 28 */ -+ "SIGIO", /* 29 */ -+ "SIGPWR", /* 30 */ -+ "SIGSYS", /* 31 */ -diff --git a/sysdeps/linux-gnu/aarch64/syscallent.h b/sysdeps/linux-gnu/aarch64/syscallent.h -new file mode 100644 -index 0000000..aca8191 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/syscallent.h -@@ -0,0 +1,1100 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+ "io_setup", /* 0 */ -+ "io_destroy", /* 1 */ -+ "io_submit", /* 2 */ -+ "io_cancel", /* 3 */ -+ "io_getevents", /* 4 */ -+ "setxattr", /* 5 */ -+ "lsetxattr", /* 6 */ -+ "fsetxattr", /* 7 */ -+ "getxattr", /* 8 */ -+ "lgetxattr", /* 9 */ -+ "fgetxattr", /* 10 */ -+ "listxattr", /* 11 */ -+ "llistxattr", /* 12 */ -+ "flistxattr", /* 13 */ -+ "removexattr", /* 14 */ -+ "lremovexattr", /* 15 */ -+ "fremovexattr", /* 16 */ -+ "getcwd", /* 17 */ -+ "lookup_dcookie", /* 18 */ -+ "eventfd2", /* 19 */ -+ "epoll_create1", /* 20 */ -+ "epoll_ctl", /* 21 */ -+ "epoll_pwait", /* 22 */ -+ "dup", /* 23 */ -+ "dup3", /* 24 */ -+ "fcntl", /* 25 */ -+ "inotify_init1", /* 26 */ -+ "inotify_add_watch", /* 27 */ -+ "inotify_rm_watch", /* 28 */ -+ "ioctl", /* 29 */ -+ "ioprio_set", /* 30 */ -+ "ioprio_get", /* 31 */ -+ "flock", /* 32 */ -+ "mknodat", /* 33 */ -+ "mkdirat", /* 34 */ -+ "unlinkat", /* 35 */ -+ "symlinkat", /* 36 */ -+ "linkat", /* 37 */ -+ "renameat", /* 38 */ -+ "umount2", /* 39 */ -+ "mount", /* 40 */ -+ "pivot_root", /* 41 */ -+ "nfsservctl", /* 42 */ -+ "statfs", /* 43 */ -+ "fstatfs", /* 44 */ -+ "truncate", /* 45 */ -+ "ftruncate", /* 46 */ -+ "fallocate", /* 47 */ -+ "faccessat", /* 48 */ -+ "chdir", /* 49 */ -+ "fchdir", /* 50 */ -+ "chroot", /* 51 */ -+ "fchmod", /* 52 */ -+ "fchmodat", /* 53 */ -+ "fchownat", /* 54 */ -+ "fchown", /* 55 */ -+ "openat", /* 56 */ -+ "close", /* 57 */ -+ "vhangup", /* 58 */ -+ "pipe2", /* 59 */ -+ "quotactl", /* 60 */ -+ "getdents64", /* 61 */ -+ "lseek", /* 62 */ -+ "read", /* 63 */ -+ "write", /* 64 */ -+ "readv", /* 65 */ -+ "writev", /* 66 */ -+ "pread64", /* 67 */ -+ "pwrite64", /* 68 */ -+ "preadv", /* 69 */ -+ "pwritev", /* 70 */ -+ "sendfile", /* 71 */ -+ "pselect6", /* 72 */ -+ "ppoll", /* 73 */ -+ "signalfd4", /* 74 */ -+ "vmsplice", /* 75 */ -+ "splice", /* 76 */ -+ "tee", /* 77 */ -+ "readlinkat", /* 78 */ -+ "fstatat", /* 79 */ -+ "fstat", /* 80 */ -+ "sync", /* 81 */ -+ "fsync", /* 82 */ -+ "fdatasync", /* 83 */ -+ "sync_file_range", /* 84 */ -+ "timerfd_create", /* 85 */ -+ "timerfd_settime", /* 86 */ -+ "timerfd_gettime", /* 87 */ -+ "utimensat", /* 88 */ -+ "acct", /* 89 */ -+ "capget", /* 90 */ -+ "capset", /* 91 */ -+ "personality", /* 92 */ -+ "exit", /* 93 */ -+ "exit_group", /* 94 */ -+ "waitid", /* 95 */ -+ "set_tid_address", /* 96 */ -+ "unshare", /* 97 */ -+ "futex", /* 98 */ -+ "set_robust_list", /* 99 */ -+ "get_robust_list", /* 100 */ -+ "nanosleep", /* 101 */ -+ "getitimer", /* 102 */ -+ "setitimer", /* 103 */ -+ "kexec_load", /* 104 */ -+ "init_module", /* 105 */ -+ "delete_module", /* 106 */ -+ "timer_create", /* 107 */ -+ "timer_gettime", /* 108 */ -+ "timer_getoverrun", /* 109 */ -+ "timer_settime", /* 110 */ -+ "timer_delete", /* 111 */ -+ "clock_settime", /* 112 */ -+ "clock_gettime", /* 113 */ -+ "clock_getres", /* 114 */ -+ "clock_nanosleep", /* 115 */ -+ "syslog", /* 116 */ -+ "ptrace", /* 117 */ -+ "sched_setparam", /* 118 */ -+ "sched_setscheduler", /* 119 */ -+ "sched_getscheduler", /* 120 */ -+ "sched_getparam", /* 121 */ -+ "sched_setaffinity", /* 122 */ -+ "sched_getaffinity", /* 123 */ -+ "sched_yield", /* 124 */ -+ "sched_get_priority_max", /* 125 */ -+ "sched_get_priority_min", /* 126 */ -+ "sched_rr_get_interval", /* 127 */ -+ "restart_syscall", /* 128 */ -+ "kill", /* 129 */ -+ "tkill", /* 130 */ -+ "tgkill", /* 131 */ -+ "sigaltstack", /* 132 */ -+ "rt_sigsuspend", /* 133 */ -+ "rt_sigaction", /* 134 */ -+ "rt_sigprocmask", /* 135 */ -+ "rt_sigpending", /* 136 */ -+ "rt_sigtimedwait", /* 137 */ -+ "rt_sigqueueinfo", /* 138 */ -+ "rt_sigreturn", /* 139 */ -+ "setpriority", /* 140 */ -+ "getpriority", /* 141 */ -+ "reboot", /* 142 */ -+ "setregid", /* 143 */ -+ "setgid", /* 144 */ -+ "setreuid", /* 145 */ -+ "setuid", /* 146 */ -+ "setresuid", /* 147 */ -+ "getresuid", /* 148 */ -+ "setresgid", /* 149 */ -+ "getresgid", /* 150 */ -+ "setfsuid", /* 151 */ -+ "setfsgid", /* 152 */ -+ "times", /* 153 */ -+ "setpgid", /* 154 */ -+ "getpgid", /* 155 */ -+ "getsid", /* 156 */ -+ "setsid", /* 157 */ -+ "getgroups", /* 158 */ -+ "setgroups", /* 159 */ -+ "uname", /* 160 */ -+ "sethostname", /* 161 */ -+ "setdomainname", /* 162 */ -+ "getrlimit", /* 163 */ -+ "setrlimit", /* 164 */ -+ "getrusage", /* 165 */ -+ "umask", /* 166 */ -+ "prctl", /* 167 */ -+ "getcpu", /* 168 */ -+ "gettimeofday", /* 169 */ -+ "settimeofday", /* 170 */ -+ "adjtimex", /* 171 */ -+ "getpid", /* 172 */ -+ "getppid", /* 173 */ -+ "getuid", /* 174 */ -+ "geteuid", /* 175 */ -+ "getgid", /* 176 */ -+ "getegid", /* 177 */ -+ "gettid", /* 178 */ -+ "sysinfo", /* 179 */ -+ "mq_open", /* 180 */ -+ "mq_unlink", /* 181 */ -+ "mq_timedsend", /* 182 */ -+ "mq_timedreceive", /* 183 */ -+ "mq_notify", /* 184 */ -+ "mq_getsetattr", /* 185 */ -+ "msgget", /* 186 */ -+ "msgctl", /* 187 */ -+ "msgrcv", /* 188 */ -+ "msgsnd", /* 189 */ -+ "semget", /* 190 */ -+ "semctl", /* 191 */ -+ "semtimedop", /* 192 */ -+ "semop", /* 193 */ -+ "shmget", /* 194 */ -+ "shmctl", /* 195 */ -+ "shmat", /* 196 */ -+ "shmdt", /* 197 */ -+ "socket", /* 198 */ -+ "socketpair", /* 199 */ -+ "bind", /* 200 */ -+ "listen", /* 201 */ -+ "accept", /* 202 */ -+ "connect", /* 203 */ -+ "getsockname", /* 204 */ -+ "getpeername", /* 205 */ -+ "sendto", /* 206 */ -+ "recvfrom", /* 207 */ -+ "setsockopt", /* 208 */ -+ "getsockopt", /* 209 */ -+ "shutdown", /* 210 */ -+ "sendmsg", /* 211 */ -+ "recvmsg", /* 212 */ -+ "readahead", /* 213 */ -+ "brk", /* 214 */ -+ "munmap", /* 215 */ -+ "mremap", /* 216 */ -+ "add_key", /* 217 */ -+ "request_key", /* 218 */ -+ "keyctl", /* 219 */ -+ "clone", /* 220 */ -+ "execve", /* 221 */ -+ "mmap", /* 222 */ -+ "fadvise64", /* 223 */ -+ "swapon", /* 224 */ -+ "swapoff", /* 225 */ -+ "mprotect", /* 226 */ -+ "msync", /* 227 */ -+ "mlock", /* 228 */ -+ "munlock", /* 229 */ -+ "mlockall", /* 230 */ -+ "munlockall", /* 231 */ -+ "mincore", /* 232 */ -+ "madvise", /* 233 */ -+ "remap_file_pages", /* 234 */ -+ "mbind", /* 235 */ -+ "get_mempolicy", /* 236 */ -+ "set_mempolicy", /* 237 */ -+ "migrate_pages", /* 238 */ -+ "move_pages", /* 239 */ -+ "rt_tgsigqueueinfo", /* 240 */ -+ "perf_event_open", /* 241 */ -+ "accept4", /* 242 */ -+ "recvmmsg", /* 243 */ -+ "arch_specific_syscall", /* 244 */ -+ "245", /* 245 */ -+ "246", /* 246 */ -+ "247", /* 247 */ -+ "248", /* 248 */ -+ "249", /* 249 */ -+ "250", /* 250 */ -+ "251", /* 251 */ -+ "252", /* 252 */ -+ "253", /* 253 */ -+ "254", /* 254 */ -+ "255", /* 255 */ -+ "256", /* 256 */ -+ "257", /* 257 */ -+ "258", /* 258 */ -+ "259", /* 259 */ -+ "wait4", /* 260 */ -+ "prlimit64", /* 261 */ -+ "fanotify_init", /* 262 */ -+ "fanotify_mark", /* 263 */ -+ "name_to_handle_at", /* 264 */ -+ "open_by_handle_at", /* 265 */ -+ "clock_adjtime", /* 266 */ -+ "syncfs", /* 267 */ -+ "setns", /* 268 */ -+ "sendmmsg", /* 269 */ -+ "process_vm_readv", /* 270 */ -+ "process_vm_writev", /* 271 */ -+ "kcmp", /* 272 */ -+ "finit_module", /* 273 */ -+ "syscalls", /* 274 */ -+ "275", /* 275 */ -+ "276", /* 276 */ -+ "277", /* 277 */ -+ "278", /* 278 */ -+ "279", /* 279 */ -+ "280", /* 280 */ -+ "281", /* 281 */ -+ "282", /* 282 */ -+ "283", /* 283 */ -+ "284", /* 284 */ -+ "285", /* 285 */ -+ "286", /* 286 */ -+ "287", /* 287 */ -+ "288", /* 288 */ -+ "289", /* 289 */ -+ "290", /* 290 */ -+ "291", /* 291 */ -+ "292", /* 292 */ -+ "293", /* 293 */ -+ "294", /* 294 */ -+ "295", /* 295 */ -+ "296", /* 296 */ -+ "297", /* 297 */ -+ "298", /* 298 */ -+ "299", /* 299 */ -+ "300", /* 300 */ -+ "301", /* 301 */ -+ "302", /* 302 */ -+ "303", /* 303 */ -+ "304", /* 304 */ -+ "305", /* 305 */ -+ "306", /* 306 */ -+ "307", /* 307 */ -+ "308", /* 308 */ -+ "309", /* 309 */ -+ "310", /* 310 */ -+ "311", /* 311 */ -+ "312", /* 312 */ -+ "313", /* 313 */ -+ "314", /* 314 */ -+ "315", /* 315 */ -+ "316", /* 316 */ -+ "317", /* 317 */ -+ "318", /* 318 */ -+ "319", /* 319 */ -+ "320", /* 320 */ -+ "321", /* 321 */ -+ "322", /* 322 */ -+ "323", /* 323 */ -+ "324", /* 324 */ -+ "325", /* 325 */ -+ "326", /* 326 */ -+ "327", /* 327 */ -+ "328", /* 328 */ -+ "329", /* 329 */ -+ "330", /* 330 */ -+ "331", /* 331 */ -+ "332", /* 332 */ -+ "333", /* 333 */ -+ "334", /* 334 */ -+ "335", /* 335 */ -+ "336", /* 336 */ -+ "337", /* 337 */ -+ "338", /* 338 */ -+ "339", /* 339 */ -+ "340", /* 340 */ -+ "341", /* 341 */ -+ "342", /* 342 */ -+ "343", /* 343 */ -+ "344", /* 344 */ -+ "345", /* 345 */ -+ "346", /* 346 */ -+ "347", /* 347 */ -+ "348", /* 348 */ -+ "349", /* 349 */ -+ "350", /* 350 */ -+ "351", /* 351 */ -+ "352", /* 352 */ -+ "353", /* 353 */ -+ "354", /* 354 */ -+ "355", /* 355 */ -+ "356", /* 356 */ -+ "357", /* 357 */ -+ "358", /* 358 */ -+ "359", /* 359 */ -+ "360", /* 360 */ -+ "361", /* 361 */ -+ "362", /* 362 */ -+ "363", /* 363 */ -+ "364", /* 364 */ -+ "365", /* 365 */ -+ "366", /* 366 */ -+ "367", /* 367 */ -+ "368", /* 368 */ -+ "369", /* 369 */ -+ "370", /* 370 */ -+ "371", /* 371 */ -+ "372", /* 372 */ -+ "373", /* 373 */ -+ "374", /* 374 */ -+ "375", /* 375 */ -+ "376", /* 376 */ -+ "377", /* 377 */ -+ "378", /* 378 */ -+ "379", /* 379 */ -+ "380", /* 380 */ -+ "381", /* 381 */ -+ "382", /* 382 */ -+ "383", /* 383 */ -+ "384", /* 384 */ -+ "385", /* 385 */ -+ "386", /* 386 */ -+ "387", /* 387 */ -+ "388", /* 388 */ -+ "389", /* 389 */ -+ "390", /* 390 */ -+ "391", /* 391 */ -+ "392", /* 392 */ -+ "393", /* 393 */ -+ "394", /* 394 */ -+ "395", /* 395 */ -+ "396", /* 396 */ -+ "397", /* 397 */ -+ "398", /* 398 */ -+ "399", /* 399 */ -+ "400", /* 400 */ -+ "401", /* 401 */ -+ "402", /* 402 */ -+ "403", /* 403 */ -+ "404", /* 404 */ -+ "405", /* 405 */ -+ "406", /* 406 */ -+ "407", /* 407 */ -+ "408", /* 408 */ -+ "409", /* 409 */ -+ "410", /* 410 */ -+ "411", /* 411 */ -+ "412", /* 412 */ -+ "413", /* 413 */ -+ "414", /* 414 */ -+ "415", /* 415 */ -+ "416", /* 416 */ -+ "417", /* 417 */ -+ "418", /* 418 */ -+ "419", /* 419 */ -+ "420", /* 420 */ -+ "421", /* 421 */ -+ "422", /* 422 */ -+ "423", /* 423 */ -+ "424", /* 424 */ -+ "425", /* 425 */ -+ "426", /* 426 */ -+ "427", /* 427 */ -+ "428", /* 428 */ -+ "429", /* 429 */ -+ "430", /* 430 */ -+ "431", /* 431 */ -+ "432", /* 432 */ -+ "433", /* 433 */ -+ "434", /* 434 */ -+ "435", /* 435 */ -+ "436", /* 436 */ -+ "437", /* 437 */ -+ "438", /* 438 */ -+ "439", /* 439 */ -+ "440", /* 440 */ -+ "441", /* 441 */ -+ "442", /* 442 */ -+ "443", /* 443 */ -+ "444", /* 444 */ -+ "445", /* 445 */ -+ "446", /* 446 */ -+ "447", /* 447 */ -+ "448", /* 448 */ -+ "449", /* 449 */ -+ "450", /* 450 */ -+ "451", /* 451 */ -+ "452", /* 452 */ -+ "453", /* 453 */ -+ "454", /* 454 */ -+ "455", /* 455 */ -+ "456", /* 456 */ -+ "457", /* 457 */ -+ "458", /* 458 */ -+ "459", /* 459 */ -+ "460", /* 460 */ -+ "461", /* 461 */ -+ "462", /* 462 */ -+ "463", /* 463 */ -+ "464", /* 464 */ -+ "465", /* 465 */ -+ "466", /* 466 */ -+ "467", /* 467 */ -+ "468", /* 468 */ -+ "469", /* 469 */ -+ "470", /* 470 */ -+ "471", /* 471 */ -+ "472", /* 472 */ -+ "473", /* 473 */ -+ "474", /* 474 */ -+ "475", /* 475 */ -+ "476", /* 476 */ -+ "477", /* 477 */ -+ "478", /* 478 */ -+ "479", /* 479 */ -+ "480", /* 480 */ -+ "481", /* 481 */ -+ "482", /* 482 */ -+ "483", /* 483 */ -+ "484", /* 484 */ -+ "485", /* 485 */ -+ "486", /* 486 */ -+ "487", /* 487 */ -+ "488", /* 488 */ -+ "489", /* 489 */ -+ "490", /* 490 */ -+ "491", /* 491 */ -+ "492", /* 492 */ -+ "493", /* 493 */ -+ "494", /* 494 */ -+ "495", /* 495 */ -+ "496", /* 496 */ -+ "497", /* 497 */ -+ "498", /* 498 */ -+ "499", /* 499 */ -+ "500", /* 500 */ -+ "501", /* 501 */ -+ "502", /* 502 */ -+ "503", /* 503 */ -+ "504", /* 504 */ -+ "505", /* 505 */ -+ "506", /* 506 */ -+ "507", /* 507 */ -+ "508", /* 508 */ -+ "509", /* 509 */ -+ "510", /* 510 */ -+ "511", /* 511 */ -+ "512", /* 512 */ -+ "513", /* 513 */ -+ "514", /* 514 */ -+ "515", /* 515 */ -+ "516", /* 516 */ -+ "517", /* 517 */ -+ "518", /* 518 */ -+ "519", /* 519 */ -+ "520", /* 520 */ -+ "521", /* 521 */ -+ "522", /* 522 */ -+ "523", /* 523 */ -+ "524", /* 524 */ -+ "525", /* 525 */ -+ "526", /* 526 */ -+ "527", /* 527 */ -+ "528", /* 528 */ -+ "529", /* 529 */ -+ "530", /* 530 */ -+ "531", /* 531 */ -+ "532", /* 532 */ -+ "533", /* 533 */ -+ "534", /* 534 */ -+ "535", /* 535 */ -+ "536", /* 536 */ -+ "537", /* 537 */ -+ "538", /* 538 */ -+ "539", /* 539 */ -+ "540", /* 540 */ -+ "541", /* 541 */ -+ "542", /* 542 */ -+ "543", /* 543 */ -+ "544", /* 544 */ -+ "545", /* 545 */ -+ "546", /* 546 */ -+ "547", /* 547 */ -+ "548", /* 548 */ -+ "549", /* 549 */ -+ "550", /* 550 */ -+ "551", /* 551 */ -+ "552", /* 552 */ -+ "553", /* 553 */ -+ "554", /* 554 */ -+ "555", /* 555 */ -+ "556", /* 556 */ -+ "557", /* 557 */ -+ "558", /* 558 */ -+ "559", /* 559 */ -+ "560", /* 560 */ -+ "561", /* 561 */ -+ "562", /* 562 */ -+ "563", /* 563 */ -+ "564", /* 564 */ -+ "565", /* 565 */ -+ "566", /* 566 */ -+ "567", /* 567 */ -+ "568", /* 568 */ -+ "569", /* 569 */ -+ "570", /* 570 */ -+ "571", /* 571 */ -+ "572", /* 572 */ -+ "573", /* 573 */ -+ "574", /* 574 */ -+ "575", /* 575 */ -+ "576", /* 576 */ -+ "577", /* 577 */ -+ "578", /* 578 */ -+ "579", /* 579 */ -+ "580", /* 580 */ -+ "581", /* 581 */ -+ "582", /* 582 */ -+ "583", /* 583 */ -+ "584", /* 584 */ -+ "585", /* 585 */ -+ "586", /* 586 */ -+ "587", /* 587 */ -+ "588", /* 588 */ -+ "589", /* 589 */ -+ "590", /* 590 */ -+ "591", /* 591 */ -+ "592", /* 592 */ -+ "593", /* 593 */ -+ "594", /* 594 */ -+ "595", /* 595 */ -+ "596", /* 596 */ -+ "597", /* 597 */ -+ "598", /* 598 */ -+ "599", /* 599 */ -+ "600", /* 600 */ -+ "601", /* 601 */ -+ "602", /* 602 */ -+ "603", /* 603 */ -+ "604", /* 604 */ -+ "605", /* 605 */ -+ "606", /* 606 */ -+ "607", /* 607 */ -+ "608", /* 608 */ -+ "609", /* 609 */ -+ "610", /* 610 */ -+ "611", /* 611 */ -+ "612", /* 612 */ -+ "613", /* 613 */ -+ "614", /* 614 */ -+ "615", /* 615 */ -+ "616", /* 616 */ -+ "617", /* 617 */ -+ "618", /* 618 */ -+ "619", /* 619 */ -+ "620", /* 620 */ -+ "621", /* 621 */ -+ "622", /* 622 */ -+ "623", /* 623 */ -+ "624", /* 624 */ -+ "625", /* 625 */ -+ "626", /* 626 */ -+ "627", /* 627 */ -+ "628", /* 628 */ -+ "629", /* 629 */ -+ "630", /* 630 */ -+ "631", /* 631 */ -+ "632", /* 632 */ -+ "633", /* 633 */ -+ "634", /* 634 */ -+ "635", /* 635 */ -+ "636", /* 636 */ -+ "637", /* 637 */ -+ "638", /* 638 */ -+ "639", /* 639 */ -+ "640", /* 640 */ -+ "641", /* 641 */ -+ "642", /* 642 */ -+ "643", /* 643 */ -+ "644", /* 644 */ -+ "645", /* 645 */ -+ "646", /* 646 */ -+ "647", /* 647 */ -+ "648", /* 648 */ -+ "649", /* 649 */ -+ "650", /* 650 */ -+ "651", /* 651 */ -+ "652", /* 652 */ -+ "653", /* 653 */ -+ "654", /* 654 */ -+ "655", /* 655 */ -+ "656", /* 656 */ -+ "657", /* 657 */ -+ "658", /* 658 */ -+ "659", /* 659 */ -+ "660", /* 660 */ -+ "661", /* 661 */ -+ "662", /* 662 */ -+ "663", /* 663 */ -+ "664", /* 664 */ -+ "665", /* 665 */ -+ "666", /* 666 */ -+ "667", /* 667 */ -+ "668", /* 668 */ -+ "669", /* 669 */ -+ "670", /* 670 */ -+ "671", /* 671 */ -+ "672", /* 672 */ -+ "673", /* 673 */ -+ "674", /* 674 */ -+ "675", /* 675 */ -+ "676", /* 676 */ -+ "677", /* 677 */ -+ "678", /* 678 */ -+ "679", /* 679 */ -+ "680", /* 680 */ -+ "681", /* 681 */ -+ "682", /* 682 */ -+ "683", /* 683 */ -+ "684", /* 684 */ -+ "685", /* 685 */ -+ "686", /* 686 */ -+ "687", /* 687 */ -+ "688", /* 688 */ -+ "689", /* 689 */ -+ "690", /* 690 */ -+ "691", /* 691 */ -+ "692", /* 692 */ -+ "693", /* 693 */ -+ "694", /* 694 */ -+ "695", /* 695 */ -+ "696", /* 696 */ -+ "697", /* 697 */ -+ "698", /* 698 */ -+ "699", /* 699 */ -+ "700", /* 700 */ -+ "701", /* 701 */ -+ "702", /* 702 */ -+ "703", /* 703 */ -+ "704", /* 704 */ -+ "705", /* 705 */ -+ "706", /* 706 */ -+ "707", /* 707 */ -+ "708", /* 708 */ -+ "709", /* 709 */ -+ "710", /* 710 */ -+ "711", /* 711 */ -+ "712", /* 712 */ -+ "713", /* 713 */ -+ "714", /* 714 */ -+ "715", /* 715 */ -+ "716", /* 716 */ -+ "717", /* 717 */ -+ "718", /* 718 */ -+ "719", /* 719 */ -+ "720", /* 720 */ -+ "721", /* 721 */ -+ "722", /* 722 */ -+ "723", /* 723 */ -+ "724", /* 724 */ -+ "725", /* 725 */ -+ "726", /* 726 */ -+ "727", /* 727 */ -+ "728", /* 728 */ -+ "729", /* 729 */ -+ "730", /* 730 */ -+ "731", /* 731 */ -+ "732", /* 732 */ -+ "733", /* 733 */ -+ "734", /* 734 */ -+ "735", /* 735 */ -+ "736", /* 736 */ -+ "737", /* 737 */ -+ "738", /* 738 */ -+ "739", /* 739 */ -+ "740", /* 740 */ -+ "741", /* 741 */ -+ "742", /* 742 */ -+ "743", /* 743 */ -+ "744", /* 744 */ -+ "745", /* 745 */ -+ "746", /* 746 */ -+ "747", /* 747 */ -+ "748", /* 748 */ -+ "749", /* 749 */ -+ "750", /* 750 */ -+ "751", /* 751 */ -+ "752", /* 752 */ -+ "753", /* 753 */ -+ "754", /* 754 */ -+ "755", /* 755 */ -+ "756", /* 756 */ -+ "757", /* 757 */ -+ "758", /* 758 */ -+ "759", /* 759 */ -+ "760", /* 760 */ -+ "761", /* 761 */ -+ "762", /* 762 */ -+ "763", /* 763 */ -+ "764", /* 764 */ -+ "765", /* 765 */ -+ "766", /* 766 */ -+ "767", /* 767 */ -+ "768", /* 768 */ -+ "769", /* 769 */ -+ "770", /* 770 */ -+ "771", /* 771 */ -+ "772", /* 772 */ -+ "773", /* 773 */ -+ "774", /* 774 */ -+ "775", /* 775 */ -+ "776", /* 776 */ -+ "777", /* 777 */ -+ "778", /* 778 */ -+ "779", /* 779 */ -+ "780", /* 780 */ -+ "781", /* 781 */ -+ "782", /* 782 */ -+ "783", /* 783 */ -+ "784", /* 784 */ -+ "785", /* 785 */ -+ "786", /* 786 */ -+ "787", /* 787 */ -+ "788", /* 788 */ -+ "789", /* 789 */ -+ "790", /* 790 */ -+ "791", /* 791 */ -+ "792", /* 792 */ -+ "793", /* 793 */ -+ "794", /* 794 */ -+ "795", /* 795 */ -+ "796", /* 796 */ -+ "797", /* 797 */ -+ "798", /* 798 */ -+ "799", /* 799 */ -+ "800", /* 800 */ -+ "801", /* 801 */ -+ "802", /* 802 */ -+ "803", /* 803 */ -+ "804", /* 804 */ -+ "805", /* 805 */ -+ "806", /* 806 */ -+ "807", /* 807 */ -+ "808", /* 808 */ -+ "809", /* 809 */ -+ "810", /* 810 */ -+ "811", /* 811 */ -+ "812", /* 812 */ -+ "813", /* 813 */ -+ "814", /* 814 */ -+ "815", /* 815 */ -+ "816", /* 816 */ -+ "817", /* 817 */ -+ "818", /* 818 */ -+ "819", /* 819 */ -+ "820", /* 820 */ -+ "821", /* 821 */ -+ "822", /* 822 */ -+ "823", /* 823 */ -+ "824", /* 824 */ -+ "825", /* 825 */ -+ "826", /* 826 */ -+ "827", /* 827 */ -+ "828", /* 828 */ -+ "829", /* 829 */ -+ "830", /* 830 */ -+ "831", /* 831 */ -+ "832", /* 832 */ -+ "833", /* 833 */ -+ "834", /* 834 */ -+ "835", /* 835 */ -+ "836", /* 836 */ -+ "837", /* 837 */ -+ "838", /* 838 */ -+ "839", /* 839 */ -+ "840", /* 840 */ -+ "841", /* 841 */ -+ "842", /* 842 */ -+ "843", /* 843 */ -+ "844", /* 844 */ -+ "845", /* 845 */ -+ "846", /* 846 */ -+ "847", /* 847 */ -+ "848", /* 848 */ -+ "849", /* 849 */ -+ "850", /* 850 */ -+ "851", /* 851 */ -+ "852", /* 852 */ -+ "853", /* 853 */ -+ "854", /* 854 */ -+ "855", /* 855 */ -+ "856", /* 856 */ -+ "857", /* 857 */ -+ "858", /* 858 */ -+ "859", /* 859 */ -+ "860", /* 860 */ -+ "861", /* 861 */ -+ "862", /* 862 */ -+ "863", /* 863 */ -+ "864", /* 864 */ -+ "865", /* 865 */ -+ "866", /* 866 */ -+ "867", /* 867 */ -+ "868", /* 868 */ -+ "869", /* 869 */ -+ "870", /* 870 */ -+ "871", /* 871 */ -+ "872", /* 872 */ -+ "873", /* 873 */ -+ "874", /* 874 */ -+ "875", /* 875 */ -+ "876", /* 876 */ -+ "877", /* 877 */ -+ "878", /* 878 */ -+ "879", /* 879 */ -+ "880", /* 880 */ -+ "881", /* 881 */ -+ "882", /* 882 */ -+ "883", /* 883 */ -+ "884", /* 884 */ -+ "885", /* 885 */ -+ "886", /* 886 */ -+ "887", /* 887 */ -+ "888", /* 888 */ -+ "889", /* 889 */ -+ "890", /* 890 */ -+ "891", /* 891 */ -+ "892", /* 892 */ -+ "893", /* 893 */ -+ "894", /* 894 */ -+ "895", /* 895 */ -+ "896", /* 896 */ -+ "897", /* 897 */ -+ "898", /* 898 */ -+ "899", /* 899 */ -+ "900", /* 900 */ -+ "901", /* 901 */ -+ "902", /* 902 */ -+ "903", /* 903 */ -+ "904", /* 904 */ -+ "905", /* 905 */ -+ "906", /* 906 */ -+ "907", /* 907 */ -+ "908", /* 908 */ -+ "909", /* 909 */ -+ "910", /* 910 */ -+ "911", /* 911 */ -+ "912", /* 912 */ -+ "913", /* 913 */ -+ "914", /* 914 */ -+ "915", /* 915 */ -+ "916", /* 916 */ -+ "917", /* 917 */ -+ "918", /* 918 */ -+ "919", /* 919 */ -+ "920", /* 920 */ -+ "921", /* 921 */ -+ "922", /* 922 */ -+ "923", /* 923 */ -+ "924", /* 924 */ -+ "925", /* 925 */ -+ "926", /* 926 */ -+ "927", /* 927 */ -+ "928", /* 928 */ -+ "929", /* 929 */ -+ "930", /* 930 */ -+ "931", /* 931 */ -+ "932", /* 932 */ -+ "933", /* 933 */ -+ "934", /* 934 */ -+ "935", /* 935 */ -+ "936", /* 936 */ -+ "937", /* 937 */ -+ "938", /* 938 */ -+ "939", /* 939 */ -+ "940", /* 940 */ -+ "941", /* 941 */ -+ "942", /* 942 */ -+ "943", /* 943 */ -+ "944", /* 944 */ -+ "945", /* 945 */ -+ "946", /* 946 */ -+ "947", /* 947 */ -+ "948", /* 948 */ -+ "949", /* 949 */ -+ "950", /* 950 */ -+ "951", /* 951 */ -+ "952", /* 952 */ -+ "953", /* 953 */ -+ "954", /* 954 */ -+ "955", /* 955 */ -+ "956", /* 956 */ -+ "957", /* 957 */ -+ "958", /* 958 */ -+ "959", /* 959 */ -+ "960", /* 960 */ -+ "961", /* 961 */ -+ "962", /* 962 */ -+ "963", /* 963 */ -+ "964", /* 964 */ -+ "965", /* 965 */ -+ "966", /* 966 */ -+ "967", /* 967 */ -+ "968", /* 968 */ -+ "969", /* 969 */ -+ "970", /* 970 */ -+ "971", /* 971 */ -+ "972", /* 972 */ -+ "973", /* 973 */ -+ "974", /* 974 */ -+ "975", /* 975 */ -+ "976", /* 976 */ -+ "977", /* 977 */ -+ "978", /* 978 */ -+ "979", /* 979 */ -+ "980", /* 980 */ -+ "981", /* 981 */ -+ "982", /* 982 */ -+ "983", /* 983 */ -+ "984", /* 984 */ -+ "985", /* 985 */ -+ "986", /* 986 */ -+ "987", /* 987 */ -+ "988", /* 988 */ -+ "989", /* 989 */ -+ "990", /* 990 */ -+ "991", /* 991 */ -+ "992", /* 992 */ -+ "993", /* 993 */ -+ "994", /* 994 */ -+ "995", /* 995 */ -+ "996", /* 996 */ -+ "997", /* 997 */ -+ "998", /* 998 */ -+ "999", /* 999 */ -+ "1000", /* 1000 */ -+ "1001", /* 1001 */ -+ "1002", /* 1002 */ -+ "1003", /* 1003 */ -+ "1004", /* 1004 */ -+ "1005", /* 1005 */ -+ "1006", /* 1006 */ -+ "1007", /* 1007 */ -+ "1008", /* 1008 */ -+ "1009", /* 1009 */ -+ "1010", /* 1010 */ -+ "1011", /* 1011 */ -+ "1012", /* 1012 */ -+ "1013", /* 1013 */ -+ "1014", /* 1014 */ -+ "1015", /* 1015 */ -+ "1016", /* 1016 */ -+ "1017", /* 1017 */ -+ "1018", /* 1018 */ -+ "1019", /* 1019 */ -+ "1020", /* 1020 */ -+ "1021", /* 1021 */ -+ "1022", /* 1022 */ -+ "1023", /* 1023 */ -+ "open", /* 1024 */ -+ "link", /* 1025 */ -+ "unlink", /* 1026 */ -+ "mknod", /* 1027 */ -+ "chmod", /* 1028 */ -+ "chown", /* 1029 */ -+ "mkdir", /* 1030 */ -+ "rmdir", /* 1031 */ -+ "lchown", /* 1032 */ -+ "access", /* 1033 */ -+ "rename", /* 1034 */ -+ "readlink", /* 1035 */ -+ "symlink", /* 1036 */ -+ "utimes", /* 1037 */ -+ "stat", /* 1038 */ -+ "lstat", /* 1039 */ -+ "pipe", /* 1040 */ -+ "dup2", /* 1041 */ -+ "epoll_create", /* 1042 */ -+ "inotify_init", /* 1043 */ -+ "eventfd", /* 1044 */ -+ "signalfd", /* 1045 */ -+ "sendfile", /* 1046 */ -+ "ftruncate", /* 1047 */ -+ "truncate", /* 1048 */ -+ "stat", /* 1049 */ -+ "lstat", /* 1050 */ -+ "fstat", /* 1051 */ -+ "fcntl", /* 1052 */ -+ "fadvise64", /* 1053 */ -+ "newfstatat", /* 1054 */ -+ "fstatfs", /* 1055 */ -+ "statfs", /* 1056 */ -+ "lseek", /* 1057 */ -+ "mmap", /* 1058 */ -+ "alarm", /* 1059 */ -+ "getpgrp", /* 1060 */ -+ "pause", /* 1061 */ -+ "time", /* 1062 */ -+ "utime", /* 1063 */ -+ "creat", /* 1064 */ -+ "getdents", /* 1065 */ -+ "futimesat", /* 1066 */ -+ "select", /* 1067 */ -+ "poll", /* 1068 */ -+ "epoll_wait", /* 1069 */ -+ "ustat", /* 1070 */ -+ "vfork", /* 1071 */ -+ "oldwait4", /* 1072 */ -+ "recv", /* 1073 */ -+ "send", /* 1074 */ -+ "bdflush", /* 1075 */ -+ "umount", /* 1076 */ -+ "uselib", /* 1077 */ -+ "_sysctl", /* 1078 */ -+ "fork", /* 1079 */ -diff --git a/sysdeps/linux-gnu/aarch64/trace.c b/sysdeps/linux-gnu/aarch64/trace.c -new file mode 100644 -index 0000000..5544b51 ---- /dev/null -+++ b/sysdeps/linux-gnu/aarch64/trace.c -@@ -0,0 +1,83 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2014 Petr Machata, Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "backend.h" -+#include "proc.h" -+ -+void -+get_arch_dep(struct process *proc) -+{ -+} -+ -+int aarch64_read_gregs(struct process *proc, struct user_pt_regs *regs); -+ -+/* The syscall instruction is: -+ * | 31 21 | 20 5 | 4 0 | -+ * | 1 1 0 1 0 1 0 0 | 0 0 0 | imm16 | 0 0 0 0 1 | */ -+#define SVC_MASK 0xffe0001f -+#define SVC_VALUE 0xd4000001 -+ -+int -+syscall_p(struct process *proc, int status, int *sysnum) -+{ -+ if (WIFSTOPPED(status) -+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { -+ -+ struct user_pt_regs regs; -+ if (aarch64_read_gregs(proc, ®s) < 0) { -+ fprintf(stderr, "syscall_p: " -+ "Couldn't read registers of %d.\n", proc->pid); -+ return -1; -+ } -+ -+ errno = 0; -+ unsigned long insn = (unsigned long) ptrace(PTRACE_PEEKTEXT, -+ proc->pid, -+ regs.pc - 4, 0); -+ if (insn == -1UL && errno != 0) { -+ fprintf(stderr, "syscall_p: " -+ "Couldn't peek into %d: %s\n", proc->pid, -+ strerror(errno)); -+ return -1; -+ } -+ -+ insn &= 0xffffffffUL; -+ if ((insn & SVC_MASK) == SVC_VALUE) { -+ *sysnum = regs.regs[8]; -+ -+ size_t d1 = proc->callstack_depth - 1; -+ if (proc->callstack_depth > 0 -+ && proc->callstack[d1].is_syscall -+ && proc->callstack[d1].c_un.syscall == *sysnum) -+ return 2; -+ -+ return 1; -+ } -+ } -+ -+ return 0; -+} -diff --git a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp -index 787e342..2ccf840 100644 ---- a/testsuite/ltrace.main/system_call_params.exp -+++ b/testsuite/ltrace.main/system_call_params.exp -@@ -1,5 +1,5 @@ - # This file is part of ltrace. --# Copyright (C) 2013 Petr Machata, Red Hat Inc. -+# Copyright (C) 2013, 2014 Petr Machata, Red Hat Inc. - # - # This program is free software; you can redistribute it and/or - # modify it under the terms of the GNU General Public License as -@@ -17,11 +17,25 @@ - # 02110-1301 USA - - set bin [ltraceCompile {} [ltraceSource c { -+ #define _GNU_SOURCE - #include - #include - #include -+ #include -+ #include /* For SYS_xxx definitions */ -+ -+ #ifndef SYS_open -+ # if defined(__aarch64__) -+ # /* Linux doesn't actually implement SYS_open on AArch64, but for merely -+ # * recording the syscall, it's fine. */ -+ # define SYS_open 1024 -+ # else -+ # error SYS_open not available. -+ # endif -+ #endif -+ - int main(void) { -- open("/some/path", O_RDONLY); -+ syscall(SYS_open, "/some/path", O_RDONLY); - write(1, "something", 10); - mount("source", "target", "filesystemtype", 0, 0); - } -diff --git a/testsuite/ltrace.main/system_calls.c b/testsuite/ltrace.main/system_calls.c -deleted file mode 100644 -index 7be3d04..0000000 ---- a/testsuite/ltrace.main/system_calls.c -+++ /dev/null -@@ -1,68 +0,0 @@ --/* Ltrace Test : system_calls.c. -- Objectives : Verify that Ltrace can trace all the system calls in -- execution. -- -- You can add new system calls in it and add its verification in -- system_calls correspondingly. -- -- This file was written by Yao Qi . */ -- --#include --#include --#include --#include --#include -- --void exit (int); -- --#define BUF_SIZE 100 -- --int --main () --{ -- FILE* fp; -- char s[]="system_calls"; -- char buffer[BUF_SIZE]; -- struct stat state; -- -- /* SYS_open. */ -- fp = fopen ("system_calls.tmp", "w"); -- if (fp == NULL) -- { -- printf("Can not create system_calls.tmp\n"); -- exit (0); -- } -- /* SYS_write. */ -- fwrite(s, sizeof(s), 1, fp); -- /* SYS_lseek. */ -- fseek (fp, 0, SEEK_CUR); -- /* SYS_read. */ -- fread(buffer, sizeof(s), 1, fp); -- /* SYS_close. */ -- fclose(fp); -- -- /* SYS_getcwd. */ -- getcwd (buffer, BUF_SIZE); -- /* SYS_chdir. */ -- chdir ("."); -- /* SYS_symlink. */ -- symlink ("system_calls.tmp", "system_calls.link"); -- /* SYS_unlink. */ -- remove("system_calls.link"); -- /* SYS_rename. */ -- rename ("system_calls.tmp", "system_calls.tmp1"); -- /* SYS_stat. */ -- stat ("system_calls.tmp", &state); -- /* SYS_access. */ -- access ("system_calls.tmp", R_OK); -- remove("system_calls.tmp1"); -- -- /* SYS_mkdir. */ -- mkdir ("system_call_mkdir", 0777); -- /* SYS_rmdir. */ -- rmdir ("system_call_mkdir"); -- -- return 0; --} -- -- -diff --git a/testsuite/ltrace.main/system_calls.exp b/testsuite/ltrace.main/system_calls.exp -index a74fa04..f60e319 100644 ---- a/testsuite/ltrace.main/system_calls.exp -+++ b/testsuite/ltrace.main/system_calls.exp -@@ -1,67 +1,146 @@ --# This file was written by Yao Qi . -+# This file is part of ltrace. -+# Copyright (C) 2014 Petr Machata, Red Hat Inc. -+# Copyright (C) 2006 Yao Qi , IBM Corporation -+# -+# This program is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public License as -+# published by the Free Software Foundation; either version 2 of the -+# License, or (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+# 02110-1301 USA - --set testfile "system_calls" --set srcfile ${testfile}.c --set binfile ${testfile} -+# Objectives: Verify that Ltrace can trace all the system calls in -+# execution. Note that this test is necessarily noisy. Dynamic -+# linker adds a bunch of system calls of its own. - -+set empty [ltraceCompile {} [ltraceSource c { -+ int main (void) { return 0; } -+}]] - --verbose "compiling source file now....." --# Build the shared libraries this test case needs. --if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { -- send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" -+set bin [ltraceCompile {} [ltraceSource c { -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ int -+ main () -+ { -+ FILE* fp; -+ char s[]="system_calls"; -+ char buffer[1024]; -+ struct stat state; -+ -+ fp = fopen ("system_calls.tmp", "w"); -+ if (fp == NULL) -+ { -+ printf("Can not create system_calls.tmp\n"); -+ exit (0); -+ } -+ fwrite(s, sizeof(s), 1, fp); -+ fseek (fp, 0, SEEK_CUR); -+ fread(buffer, sizeof(s), 1, fp); -+ fclose(fp); -+ -+ getcwd (buffer, sizeof buffer); -+ chdir ("."); -+ symlink ("system_calls.tmp", "system_calls.link"); -+ remove("system_calls.link"); -+ rename ("system_calls.tmp", "system_calls.tmp1"); -+ stat ("system_calls.tmp", &state); -+ access ("system_calls.tmp", R_OK); -+ remove("system_calls.tmp1"); -+ -+ mkdir ("system_call_mkdir", 0777); -+ rmdir ("system_call_mkdir"); -+ -+ return 0; -+ } -+}]] -+ -+proc Calls {logfile} { -+ set fp [open $logfile] -+ set ret {} -+ -+ while {[gets $fp line] >= 0} { -+ if [regexp -- {^[a-zA-Z0-9]*@SYS} $line] { -+ set call [lindex [split $line @] 0] -+ dict incr ret $call -+ } -+ } -+ -+ close $fp -+ return $ret -+} -+ -+proc GetDefault {d key def} { -+ if {[dict exists $d $key]} { -+ return [dict get $d $key] -+ } else { -+ return $def -+ } - } - --# set options for ltrace. --ltrace_options "-S" -+proc Diff {d1 d2} { -+ set keys [lsort -unique [concat [dict keys $d1] [dict keys $d2]]] -+ set ret {} -+ foreach key $keys { -+ set n1 [GetDefault $d1 $key 0] -+ set n2 [GetDefault $d2 $key 0] -+ set sum [expr $n1 - $n2] -+ if {[expr $sum != 0]} { -+ dict set ret $key $sum -+ } -+ } -+ return $ret -+} -+ -+proc Match {d patterns} { -+ foreach line $patterns { -+ set pattern [lindex $line 0] -+ set op [lindex $line 1] -+ set expect [lindex $line 2] - --#Run PUT for ltarce. --set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] -+ set count 0 -+ foreach key [dict keys $d] { -+ if [regexp -- $pattern $key] { -+ incr count [dict get $d $key] -+ } -+ } - --#check the output of this program. --verbose "ltrace runtest output: $exec_output\n" -+ set msgMain "$pattern was recorded $count times" - --if [regexp {ELF from incompatible architecture} $exec_output] { -- fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" -- return --} elseif [ regexp {Couldn't get .hash data} $exec_output ] { -- fail "Couldn't get .hash data!" -- return -+ if {[eval expr $count $op $expect]} { -+ pass $msgMain -+ } else { -+ fail "$msgMain, expected $op $expect" -+ } -+ } - } - -+Match [Diff [Calls [ltraceRun -L -S -- $bin]] \ -+ [Calls [ltraceRun -L -S -- $empty]]] { -+ { {^write$} == 1 } -+ { {^unlink(at)?$} >= 2 } -+ { {^open(at)?$} == 1 } -+ { {^(new|f)?stat(64)?$} == 1 } -+ { {^close$} == 1 } -+ { {^getcwd$} == 1 } -+ { {^chdir$} == 1 } -+ { {^symlink(at)?$} == 1 } -+ { {^f?access(at)?$} == 1 } -+ { {^rename(at)?$} == 1 } -+ { {^mkdir(at)?$} == 1 } -+} - --set pattern "^munmap@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 2 --set pattern "^write@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^unlink@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -- --set pattern "^brk@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^open@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^(new)?fstat(64)?@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep --set pattern "^(old_)?mmap2?@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep --set pattern "^close@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -- --set pattern "^getcwd@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^chdir@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^symlink@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^unlink@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^(new)?stat(64)?@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep --set pattern "^access@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^rename@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^mkdir@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 --set pattern "^rmdir@SYS" --ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -+ltraceDone -diff --git a/testsuite/ltrace.minor/trace-clone.c b/testsuite/ltrace.minor/trace-clone.c -index db1936d..ded930c 100644 ---- a/testsuite/ltrace.minor/trace-clone.c -+++ b/testsuite/ltrace.minor/trace-clone.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - int child () - { -@@ -22,7 +23,8 @@ typedef int (* myfunc)(); - int main () - { - pid_t pid; -- static char stack[STACK_SIZE]; -+ static __attribute__ ((aligned (16))) char stack[STACK_SIZE]; -+ - #ifdef __ia64__ - pid = __clone2((myfunc)&child, stack, STACK_SIZE, CLONE_FS, NULL); - #else diff --git a/ltrace-0.7.91-account_execl.patch b/ltrace-0.7.91-account_execl.patch deleted file mode 100644 index 2aa4ba0..0000000 --- a/ltrace-0.7.91-account_execl.patch +++ /dev/null @@ -1,834 +0,0 @@ -From 0cf4ab66e9927e101a51dd9fa9adc6c8dc56b5e7 Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Thu, 21 Nov 2013 20:25:53 +0100 -Subject: [PATCH] Consider exec and exit events an end of outstanding calls - -- This cleans up a lot of stuff. The actual substance is addition of - account_current_callstack in handle_event.c (which however uses - those cleaned-up interfaces). - -- trace-exec.exp was extended to check that the exec syscall can be - seen in -c output. That's one of the symptoms of what this fixes. ---- - Makefile.am | 8 +- - common.h | 2 - - forward.h | 1 + - handle_event.c | 225 ++++++++++++++++++++------------- - libltrace.c | 5 +- - options.h | 8 +- - output.c | 86 +++---------- - output.h | 5 +- - proc.h | 2 +- - summary.c | 89 +++++++++++++- - summary.h | 35 +++++ - testsuite/ltrace.minor/trace-exec.exp | 16 ++- - 12 files changed, 299 insertions(+), 183 deletions(-) - create mode 100644 summary.h - -diff --git a/Makefile.am b/Makefile.am -index d711aec..efcf18a 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -54,10 +54,10 @@ ltrace_LDADD = \ - - noinst_HEADERS = bits.h backend.h breakpoint.h common.h debug.h \ - defs.h demangle.h dict.h forward.h ltrace-elf.h ltrace.h \ -- options.h output.h proc.h read_config_file.h library.h \ -- filter.h glob.h vect.h type.h value.h value_dict.h callback.h \ -- expr.h fetch.h vect.h param.h printf.h zero.h lens.h \ -- lens_default.h lens_enum.h memstream.h prototype.h -+ options.h output.h proc.h read_config_file.h summary.h \ -+ library.h filter.h glob.h vect.h type.h value.h value_dict.h \ -+ callback.h expr.h fetch.h vect.h param.h printf.h zero.h \ -+ lens.h lens_default.h lens_enum.h memstream.h prototype.h - - dist_man1_MANS = ltrace.1 - dist_man5_MANS = ltrace.conf.5 -diff --git a/common.h b/common.h -index a53c5db..7259ba4 100644 ---- a/common.h -+++ b/common.h -@@ -54,8 +54,6 @@ extern void handle_event(Event * event); - - extern pid_t execute_program(const char * command, char ** argv); - --extern void show_summary(void); -- - struct breakpoint; - struct library_symbol; - -diff --git a/forward.h b/forward.h -index 8641213..58d8f05 100644 ---- a/forward.h -+++ b/forward.h -@@ -34,6 +34,7 @@ struct param_enum; - struct process; - struct protolib; - struct prototype; -+struct timedelta; - struct value; - struct value_dict; - struct vect; -diff --git a/handle_event.c b/handle_event.c -index 9ed62a2..6fa7e98 100644 ---- a/handle_event.c -+++ b/handle_event.c -@@ -32,7 +32,6 @@ - #include - #include - #include --#include - #include - - #include "backend.h" -@@ -41,8 +40,9 @@ - #include "fetch.h" - #include "library.h" - #include "proc.h" --#include "value_dict.h" - #include "prototype.h" -+#include "summary.h" -+#include "value_dict.h" - - static void handle_signal(Event *event); - static void handle_exit(Event *event); -@@ -419,32 +419,11 @@ handle_signal(Event *event) { - continue_after_signal(event->proc->pid, event->e_un.signum); - } - --static void --handle_exit(Event *event) { -- debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val); -- if (event->proc->state != STATE_IGNORED) { -- output_line(event->proc, "+++ exited (status %d) +++", -- event->e_un.ret_val); -- } -- remove_process(event->proc); --} -- --static void --handle_exit_signal(Event *event) { -- debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum); -- if (event->proc->state != STATE_IGNORED) { -- output_line(event->proc, "+++ killed by %s +++", -- shortsignal(event->proc, event->e_un.signum)); -- } -- remove_process(event->proc); --} -- --static void --output_syscall(struct process *proc, const char *name, enum tof tof, -- void (*output)(enum tof, struct process *, -- struct library_symbol *)) -+static int -+init_syscall_symbol(struct library_symbol *libsym, const char *name) - { - static struct library syscall_lib; -+ - if (syscall_lib.protolib == NULL) { - struct protolib *protolib - = protolib_cache_load(&g_protocache, "syscalls", 0, 1); -@@ -475,10 +454,91 @@ output_syscall(struct process *proc, const char *name, enum tof tof, - syscall_lib.protolib = protolib; - } - -+ if (library_symbol_init(libsym, 0, name, 0, LS_TOPLT_NONE) < 0) -+ return -1; -+ -+ libsym->lib = &syscall_lib; -+ return 0; -+} -+ -+/* Account the unfinished functions on the call stack. */ -+static void -+account_current_callstack(struct process *proc) -+{ -+ if (! options.summary) -+ return; -+ -+ struct timedelta spent[proc->callstack_depth]; -+ -+ size_t i; -+ for (i = 0; i < proc->callstack_depth; ++i) { -+ struct callstack_element *elem = &proc->callstack[i]; -+ spent[i] = calc_time_spent(elem->enter_time); -+ } -+ -+ for (i = 0; i < proc->callstack_depth; ++i) { -+ struct callstack_element *elem = &proc->callstack[i]; -+ struct library_symbol syscall, *libsym = NULL; -+ if (elem->is_syscall) { -+ const char *name = sysname(proc, elem->c_un.syscall); -+ if (init_syscall_symbol(&syscall, name) >= 0) -+ libsym = &syscall; -+ -+ } else { -+ libsym = elem->c_un.libfunc; -+ } -+ -+ if (libsym != NULL) { -+ summary_account_call(libsym, spent[i]); -+ -+ if (elem->is_syscall) -+ library_symbol_destroy(&syscall); -+ } -+ } -+} -+ -+static void -+handle_exit(Event *event) { -+ debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val); -+ if (event->proc->state != STATE_IGNORED) { -+ output_line(event->proc, "+++ exited (status %d) +++", -+ event->e_un.ret_val); -+ } -+ -+ account_current_callstack(event->proc); -+ remove_process(event->proc); -+} -+ -+static void -+handle_exit_signal(Event *event) { -+ debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum); -+ if (event->proc->state != STATE_IGNORED) { -+ output_line(event->proc, "+++ killed by %s +++", -+ shortsignal(event->proc, event->e_un.signum)); -+ } -+ -+ account_current_callstack(event->proc); -+ remove_process(event->proc); -+} -+ -+static void -+output_syscall(struct process *proc, const char *name, enum tof tof, -+ bool left, struct timedelta *spent) -+{ -+ if (left) -+ assert(spent == NULL); -+ - struct library_symbol syscall; -- if (library_symbol_init(&syscall, 0, name, 0, LS_TOPLT_NONE) >= 0) { -- syscall.lib = &syscall_lib; -- (*output)(tof, proc, &syscall); -+ if (init_syscall_symbol(&syscall, name) >= 0) { -+ if (left) { -+ if (! options.summary) -+ output_left(tof, proc, &syscall); -+ } else if (options.summary) { -+ summary_account_call(&syscall, *spent); -+ } else { -+ output_right(tof, proc, &syscall, spent); -+ } -+ - library_symbol_destroy(&syscall); - } - } -@@ -486,17 +546,19 @@ output_syscall(struct process *proc, const char *name, enum tof tof, - static void - output_syscall_left(struct process *proc, const char *name) - { -- output_syscall(proc, name, LT_TOF_SYSCALL, &output_left); -+ output_syscall(proc, name, LT_TOF_SYSCALL, true, NULL); - } - - static void --output_syscall_right(struct process *proc, const char *name) -+output_syscall_right(struct process *proc, const char *name, -+ struct timedelta *spent) - { -- output_syscall(proc, name, LT_TOF_SYSCALLR, &output_right); -+ output_syscall(proc, name, LT_TOF_SYSCALLR, false, spent); - } - - static void --handle_syscall(Event *event) { -+handle_syscall(Event *event) -+{ - debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); - if (event->proc->state != STATE_IGNORED) { - callstack_push_syscall(event->proc, event->e_un.sysnum); -@@ -526,6 +588,8 @@ handle_exec(Event *event) - } - output_line(proc, "--- Called exec() ---"); - -+ account_current_callstack(proc); -+ - if (process_exec(proc) < 0) { - fprintf(stderr, - "couldn't reinitialize process %d after exec\n", pid); -@@ -549,74 +613,58 @@ handle_arch_syscall(Event *event) { - continue_process(event->proc->pid); - } - --struct timeval current_time_spent; -- - static void --calc_time_spent(struct process *proc) -+handle_x_sysret(Event *event, char *(*name_cb)(struct process *, int)) - { -- struct timeval tv; -- struct timezone tz; -- struct timeval diff; -- struct callstack_element *elem; -- -- debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid); -- elem = &proc->callstack[proc->callstack_depth - 1]; -- -- gettimeofday(&tv, &tz); -+ debug(DEBUG_FUNCTION, "handle_x_sysret(pid=%d, sysnum=%d)", -+ event->proc->pid, event->e_un.sysnum); - -- diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec; -- if (tv.tv_usec >= elem->time_spent.tv_usec) { -- diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec; -- } else { -- diff.tv_sec--; -- diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec; -- } -- current_time_spent = diff; --} -+ unsigned d = event->proc->callstack_depth; -+ assert(d > 0); -+ struct callstack_element *elem = &event->proc->callstack[d - 1]; -+ assert(elem->is_syscall); - --static void --handle_sysret(Event *event) { -- debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); - if (event->proc->state != STATE_IGNORED) { -- if (opt_T || options.summary) { -- calc_time_spent(event->proc); -- } -+ struct timedelta spent = calc_time_spent(elem->enter_time); - if (options.syscalls) - output_syscall_right(event->proc, -- sysname(event->proc, -- event->e_un.sysnum)); -+ name_cb(event->proc, -+ event->e_un.sysnum), -+ &spent); - -- assert(event->proc->callstack_depth > 0); -- unsigned d = event->proc->callstack_depth - 1; -- assert(event->proc->callstack[d].is_syscall); - callstack_pop(event->proc); - } - continue_after_syscall(event->proc, event->e_un.sysnum, 1); - } - - static void --handle_arch_sysret(Event *event) { -- debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); -- if (event->proc->state != STATE_IGNORED) { -- if (opt_T || options.summary) { -- calc_time_spent(event->proc); -- } -- if (options.syscalls) -- output_syscall_right(event->proc, -- arch_sysname(event->proc, -- event->e_un.sysnum)); -- callstack_pop(event->proc); -- } -- continue_process(event->proc->pid); -+handle_sysret(Event *event) -+{ -+ handle_x_sysret(event, &sysname); -+} -+ -+static void -+handle_arch_sysret(Event *event) -+{ -+ handle_x_sysret(event, &arch_sysname); - } - - static void - output_right_tos(struct process *proc) - { - size_t d = proc->callstack_depth; -+ assert(d > 0); - struct callstack_element *elem = &proc->callstack[d - 1]; -- if (proc->state != STATE_IGNORED) -- output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc); -+ assert(! elem->is_syscall); -+ -+ if (proc->state != STATE_IGNORED) { -+ struct timedelta spent = calc_time_spent(elem->enter_time); -+ if (options.summary) -+ summary_account_call(elem->c_un.libfunc, spent); -+ else -+ output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc, -+ &spent); -+ } - } - - #ifndef ARCH_HAVE_SYMBOL_RET -@@ -645,14 +693,8 @@ handle_breakpoint(Event *event) - - for (i = event->proc->callstack_depth - 1; i >= 0; i--) { - if (brk_addr == event->proc->callstack[i].return_addr) { -- for (j = event->proc->callstack_depth - 1; j > i; j--) { -+ for (j = event->proc->callstack_depth - 1; j > i; j--) - callstack_pop(event->proc); -- } -- if (event->proc->state != STATE_IGNORED) { -- if (opt_T || options.summary) { -- calc_time_spent(event->proc); -- } -- } - - struct library_symbol *libsym = - event->proc->callstack[i].c_un.libfunc; -@@ -705,11 +747,14 @@ handle_breakpoint(Event *event) - /* breakpoint_on_hit may delete its own breakpoint, so we have - * to look it up again. */ - if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) { -+ - if (event->proc->state != STATE_IGNORED - && sbp->libsym != NULL) { - event->proc->stack_pointer = get_stack_pointer(event->proc); - callstack_push_symfunc(event->proc, sbp); -- output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym); -+ if (! options.summary) -+ output_left(LT_TOF_FUNCTION, event->proc, -+ sbp->libsym); - } - - breakpoint_on_continue(sbp, event->proc); -@@ -743,7 +788,7 @@ callstack_push_syscall(struct process *proc, int sysnum) - proc->callstack_depth++; - if (opt_T || options.summary) { - struct timezone tz; -- gettimeofday(&elem->time_spent, &tz); -+ gettimeofday(&elem->enter_time, &tz); - } - } - -@@ -781,7 +826,7 @@ callstack_push_symfunc(struct process *proc, struct breakpoint *bp) - - if (opt_T || options.summary) { - struct timezone tz; -- gettimeofday(&elem->time_spent, &tz); -+ gettimeofday(&elem->enter_time, &tz); - } - } - -diff --git a/libltrace.c b/libltrace.c -index 2d910a1..0112c9f 100644 ---- a/libltrace.c -+++ b/libltrace.c -@@ -32,11 +32,12 @@ - #include - #include - -+#include "backend.h" - #include "common.h" - #include "proc.h" --#include "read_config_file.h" --#include "backend.h" - #include "prototype.h" -+#include "read_config_file.h" -+#include "summary.h" - - char *command = NULL; - -diff --git a/options.h b/options.h -index 6c28ed9..d0df3a7 100644 ---- a/options.h -+++ b/options.h -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2012 Petr Machata, Red Hat Inc. -+ * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. - * Copyright (C) 2009,2010 Joe Damato - * Copyright (C) 1998,2002,2008 Juan Cespedes - * Copyright (C) 2006 Ian Wienand -@@ -103,12 +103,6 @@ int parse_colon_separated_list(const char *paths, struct vect *vec); - /* Vector of struct opt_F_t. */ - extern struct vect opt_F; - --struct opt_c_struct { -- int count; -- struct timeval tv; --}; --extern struct dict *dict_opt_c; -- - extern char **process_options(int argc, char **argv); - - #endif /* _OPTIONS_H_ */ -diff --git a/output.c b/output.c -index edf4522..82b6a5e 100644 ---- a/output.c -+++ b/output.c -@@ -44,16 +44,12 @@ - #include "param.h" - #include "proc.h" - #include "prototype.h" -+#include "summary.h" - #include "type.h" - #include "value.h" - #include "value_dict.h" - --/* TODO FIXME XXX: include in common.h: */ --extern struct timeval current_time_spent; -- --struct dict *dict_opt_c = NULL; -- --static struct process *current_proc = 0; -+static struct process *current_proc = NULL; - static size_t current_depth = 0; - static int current_column = 0; - -@@ -498,9 +494,8 @@ void - output_left(enum tof type, struct process *proc, - struct library_symbol *libsym) - { -- if (options.summary) { -- return; -- } -+ assert(! options.summary); -+ - if (current_proc) { - fprintf(options.output, " \n"); - current_column = 0; -@@ -572,70 +567,21 @@ output_left(enum tof type, struct process *proc, - stel->out.need_delim = need_delim; - } - --static void --free_stringp_cb(const char **stringp, void *data) --{ -- free((char *)*stringp); --} -- - void --output_right(enum tof type, struct process *proc, struct library_symbol *libsym) -+output_right(enum tof type, struct process *proc, struct library_symbol *libsym, -+ struct timedelta *spent) - { -+ assert(! options.summary); -+ - struct prototype *func = lookup_symbol_prototype(proc, libsym); - if (func == NULL) - return; - --again: -- if (options.summary) { -- if (dict_opt_c == NULL) { -- dict_opt_c = malloc(sizeof(*dict_opt_c)); -- if (dict_opt_c == NULL) { -- oom: -- fprintf(stderr, -- "Can't allocate memory for " -- "keeping track of -c.\n"); -- free(dict_opt_c); -- options.summary = 0; -- goto again; -- } -- DICT_INIT(dict_opt_c, char *, struct opt_c_struct, -- dict_hash_string, dict_eq_string, NULL); -- } -- -- struct opt_c_struct *st -- = DICT_FIND_REF(dict_opt_c, &libsym->name, -- struct opt_c_struct); -- if (st == NULL) { -- const char *na = strdup(libsym->name); -- struct opt_c_struct new_st = {.count = 0, .tv = {0, 0}}; -- if (na == NULL -- || DICT_INSERT(dict_opt_c, &na, &new_st) < 0) { -- free((char *)na); -- DICT_DESTROY(dict_opt_c, const char *, -- struct opt_c_struct, -- free_stringp_cb, NULL, NULL); -- goto oom; -- } -- st = DICT_FIND_REF(dict_opt_c, &libsym->name, -- struct opt_c_struct); -- assert(st != NULL); -- } -- -- if (st->tv.tv_usec + current_time_spent.tv_usec > 1000000) { -- st->tv.tv_usec += current_time_spent.tv_usec - 1000000; -- st->tv.tv_sec++; -- } else { -- st->tv.tv_usec += current_time_spent.tv_usec; -- } -- st->count++; -- st->tv.tv_sec += current_time_spent.tv_sec; -- return; -- } -- -- if (current_proc && (current_proc != proc || -- current_depth != proc->callstack_depth)) { -+ if (current_proc != NULL -+ && (current_proc != proc -+ || current_depth != proc->callstack_depth)) { - fprintf(options.output, " \n"); -- current_proc = 0; -+ current_proc = NULL; - } - if (current_proc != proc) { - begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1); -@@ -689,10 +635,12 @@ again: - value_destroy(&retval); - - if (opt_T) { -+ assert(spent != NULL); - fprintf(options.output, " <%lu.%06d>", -- (unsigned long)current_time_spent.tv_sec, -- (int)current_time_spent.tv_usec); -+ (unsigned long) spent->tm.tv_sec, -+ (int) spent->tm.tv_usec); - } -+ - fprintf(options.output, "\n"); - - #if defined(HAVE_LIBUNWIND) -@@ -746,7 +694,7 @@ again: - } - #endif /* defined(HAVE_LIBUNWIND) */ - -- current_proc = 0; -+ current_proc = NULL; - current_column = 0; - } - -diff --git a/output.h b/output.h -index b9f0518..2e74d61 100644 ---- a/output.h -+++ b/output.h -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc. -+ * Copyright (C) 2011, 2012, 2013 Petr Machata, Red Hat Inc. - * Copyright (C) 2009 Juan Cespedes - * - * This program is free software; you can redistribute it and/or -@@ -28,7 +28,8 @@ void output_line(struct process *proc, const char *fmt, ...); - void output_left(enum tof type, struct process *proc, - struct library_symbol *libsym); - void output_right(enum tof type, struct process *proc, -- struct library_symbol *libsym); -+ struct library_symbol *libsym, -+ struct timedelta *spent); - - /* This function is for emitting lists of comma-separated strings. - * -diff --git a/proc.h b/proc.h -index e8032fa..64f8fe2 100644 ---- a/proc.h -+++ b/proc.h -@@ -66,7 +66,7 @@ struct callstack_element { - } c_un; - int is_syscall; - arch_addr_t return_addr; -- struct timeval time_spent; -+ struct timeval enter_time; - struct fetch_context *fetch_context; - struct value_dict *arguments; - struct output_state out; -diff --git a/summary.c b/summary.c -index 9e22086..9103f71 100644 ---- a/summary.c -+++ b/summary.c -@@ -22,11 +22,15 @@ - - #include "config.h" - -+#include - #include - #include --#include -+#include - --#include "common.h" -+#include "summary.h" -+#include "dict.h" -+#include "library.h" -+#include "options.h" - - struct entry_st { - const char *name; -@@ -40,6 +44,32 @@ struct fill_struct_data { - unsigned long tot_usecs; - }; - -+struct opt_c_struct { -+ int count; -+ struct timeval tv; -+}; -+ -+static struct dict *dict_opt_c; -+ -+struct timedelta -+calc_time_spent(struct timeval start) -+{ -+ struct timeval tv; -+ gettimeofday(&tv, NULL); -+ -+ struct timeval diff; -+ diff.tv_sec = tv.tv_sec - start.tv_sec; -+ if (tv.tv_usec >= start.tv_usec) { -+ diff.tv_usec = tv.tv_usec - start.tv_usec; -+ } else { -+ diff.tv_sec--; -+ diff.tv_usec = 1000000 + tv.tv_usec - start.tv_usec; -+ } -+ -+ struct timedelta ret = { diff }; -+ return ret; -+} -+ - static enum callback_status - fill_struct(const char **namep, struct opt_c_struct *st, void *u) - { -@@ -114,3 +144,58 @@ show_summary(void) - - vect_destroy(&cdata.entries, NULL, NULL); - } -+ -+static void -+free_stringp_cb(const char **stringp, void *data) -+{ -+ free((char *)*stringp); -+} -+ -+void -+summary_account_call(struct library_symbol *libsym, struct timedelta spent) -+{ -+ assert(options.summary); -+ -+ if (dict_opt_c == NULL) { -+ dict_opt_c = malloc(sizeof(*dict_opt_c)); -+ if (dict_opt_c == NULL) { -+ oom: -+ fprintf(stderr, -+ "Can't allocate memory for " -+ "keeping track of -c.\n"); -+ free(dict_opt_c); -+ options.summary = 0; -+ return; -+ } -+ DICT_INIT(dict_opt_c, char *, struct opt_c_struct, -+ dict_hash_string, dict_eq_string, NULL); -+ } -+ -+ struct opt_c_struct *st = DICT_FIND_REF(dict_opt_c, &libsym->name, -+ struct opt_c_struct); -+ if (st == NULL) { -+ const char *na = strdup(libsym->name); -+ struct opt_c_struct new_st = {.count = 0, .tv = {0, 0}}; -+ if (na == NULL -+ || DICT_INSERT(dict_opt_c, &na, &new_st) < 0) { -+ free((char *) na); -+ DICT_DESTROY(dict_opt_c, const char *, -+ struct opt_c_struct, -+ free_stringp_cb, NULL, NULL); -+ goto oom; -+ } -+ st = DICT_FIND_REF(dict_opt_c, &libsym->name, -+ struct opt_c_struct); -+ assert(st != NULL); -+ } -+ -+ if (st->tv.tv_usec + spent.tm.tv_usec > 1000000) { -+ st->tv.tv_usec += spent.tm.tv_usec - 1000000; -+ st->tv.tv_sec++; -+ } else { -+ st->tv.tv_usec += spent.tm.tv_usec; -+ } -+ st->count++; -+ st->tv.tv_sec += spent.tm.tv_sec; -+ return; -+} -diff --git a/summary.h b/summary.h -new file mode 100644 -index 0000000..f680ef9 ---- /dev/null -+++ b/summary.h -@@ -0,0 +1,35 @@ -+/* -+ * This file is part of ltrace. -+ * Copyright (C) 2013 Petr Machata, Red Hat Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#ifndef _SUMMARY_H_ -+#define _SUMMARY_H_ -+ -+#include "forward.h" -+ -+struct timedelta { -+ struct timeval tm; -+}; -+ -+struct timedelta calc_time_spent(struct timeval start); -+void summary_account_call(struct library_symbol *libsym, -+ struct timedelta spent); -+void show_summary(void); -+ -+#endif /* _SUMMARY_H_ */ -diff --git a/testsuite/ltrace.minor/trace-exec.exp b/testsuite/ltrace.minor/trace-exec.exp -index 7a953de..57260f8 100644 ---- a/testsuite/ltrace.minor/trace-exec.exp -+++ b/testsuite/ltrace.minor/trace-exec.exp -@@ -1,5 +1,5 @@ - # This file is part of ltrace. --# Copyright (C) 2012 Petr Machata, Red Hat Inc. -+# Copyright (C) 2012, 2013 Petr Machata, Red Hat Inc. - # - # This program is free software; you can redistribute it and/or - # modify it under the terms of the GNU General Public License as -@@ -16,22 +16,30 @@ - # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - # 02110-1301 USA - --ltraceMatch [ltraceRun -xmain -- [ltraceCompile {} [ltraceSource c { -+set bin1 [ltraceCompile {} [ltraceSource c { - #include - #include - int main(int argc, char ** argv) { - execl(argv[1], argv[1], NULL); - abort(); - } --}]] [ltraceCompile {} [ltraceSource c { -+}]] -+ -+set bin2 [ltraceCompile {} [ltraceSource c { - #include - int main(void) { - return puts("Hello, World."); - } --}]]] { -+}]] -+ -+ltraceMatch [ltraceRun -xmain -- $bin1 $bin2] { - {{^execl\(} == 1} - {{^puts\(.*\) .*= 14} == 1} - {{^main\(} == 2} - } - -+ltraceMatch [ltraceRun -c -- $bin1 $bin2] { -+ {{exec} > 0} -+} -+ - ltraceDone --- -1.7.6.5 - diff --git a/ltrace-0.7.91-arm.patch b/ltrace-0.7.91-arm.patch deleted file mode 100644 index 84c7d0d..0000000 --- a/ltrace-0.7.91-arm.patch +++ /dev/null @@ -1,610 +0,0 @@ -diff --git a/ltrace-elf.c b/ltrace-elf.c -index 92b642b..6f86d56 100644 ---- a/ltrace-elf.c -+++ b/ltrace-elf.c -@@ -531,6 +531,38 @@ elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr, - return 0; - } - -+int -+elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep) -+{ -+ Elf_Scn *scn; -+ GElf_Shdr shdr; -+ if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 -+ || scn == NULL) { -+ fail: -+ fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n", -+ elf_errmsg(-1)); -+ return -1; -+ } -+ -+ Elf_Data *data = elf_loaddata(scn, &shdr); -+ if (data == NULL) -+ goto fail; -+ -+ size_t j; -+ for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { -+ GElf_Dyn dyn; -+ if (gelf_getdyn(data, j, &dyn) == NULL) -+ goto fail; -+ -+ if(dyn.d_tag == tag) { -+ *valuep = dyn.d_un.d_ptr; -+ return 0; -+ } -+ } -+ -+ return -1; -+} -+ - static int - ltelf_read_elf(struct ltelf *lte, const char *filename) - { -diff --git a/ltrace-elf.h b/ltrace-elf.h -index ea14512..db4ffe9 100644 ---- a/ltrace-elf.h -+++ b/ltrace-elf.h -@@ -139,6 +139,10 @@ struct elf_each_symbol_t { - int elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr, - struct vect *rela_vec); - -+/* Read a given DT_ TAG from LTE. Value is returned in *VALUEP. -+ * Returns 0 on success or a negative value on failure. */ -+int elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep); -+ - /* Read, respectively, 1, 2, 4, or 8 bytes from Elf data at given - * OFFSET, and store it in *RETP. Returns 0 on success or a negative - * value if there's not enough data. */ -diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h -index 58a7fdf..6d0d902 100644 ---- a/sysdeps/linux-gnu/arm/arch.h -+++ b/sysdeps/linux-gnu/arm/arch.h -@@ -22,6 +22,8 @@ - #ifndef LTRACE_ARM_ARCH_H - #define LTRACE_ARM_ARCH_H - -+#include -+ - #define ARCH_HAVE_ENABLE_BREAKPOINT 1 - #define ARCH_HAVE_DISABLE_BREAKPOINT 1 - -@@ -47,7 +49,7 @@ struct arch_breakpoint_data { - - #define ARCH_HAVE_LTELF_DATA - struct arch_ltelf_data { -- /* We have this only for the hooks. */ -+ Elf_Data *jmprel_data; - }; - - #define ARCH_HAVE_LIBRARY_DATA -diff --git a/sysdeps/linux-gnu/arm/fetch.c b/sysdeps/linux-gnu/arm/fetch.c -index 5081d78..b500448 100644 ---- a/sysdeps/linux-gnu/arm/fetch.c -+++ b/sysdeps/linux-gnu/arm/fetch.c -@@ -32,200 +32,12 @@ - #include "backend.h" - #include "fetch.h" - #include "library.h" --#include "ltrace-elf.h" - #include "proc.h" - #include "ptrace.h" - #include "regs.h" - #include "type.h" - #include "value.h" - --static int --get_hardfp(uint64_t abi_vfp_args) --{ -- if (abi_vfp_args == 2) -- fprintf(stderr, -- "Tag_ABI_VFP_args value 2 (tool chain-specific " -- "conventions) not supported.\n"); -- return abi_vfp_args == 1; --} -- --int --arch_elf_init(struct ltelf *lte, struct library *lib) --{ -- /* Nothing in this section is strictly critical. It's not -- * that much of a deal if we fail to guess right whether the -- * ABI is softfp or hardfp. */ -- unsigned hardfp = 0; -- -- Elf_Scn *scn; -- Elf_Data *data; -- GElf_Shdr shdr; -- if (elf_get_section_type(lte, SHT_ARM_ATTRIBUTES, &scn, &shdr) < 0 -- || (scn != NULL && (data = elf_loaddata(scn, &shdr)) == NULL)) { -- fprintf(stderr, -- "Error when obtaining ARM attribute section: %s\n", -- elf_errmsg(-1)); -- goto done; -- -- } else if (scn != NULL && data != NULL) { -- GElf_Xword offset = 0; -- uint8_t version; -- if (elf_read_next_u8(data, &offset, &version) < 0) { -- goto done; -- } else if (version != 'A') { -- fprintf(stderr, "Unsupported ARM attribute section " -- "version %d ('%c').\n", version, version); -- goto done; -- } -- -- do { -- const char signature[] = "aeabi"; -- /* N.B. LEN is including the length field -- * itself. */ -- uint32_t sec_len; -- if (elf_read_u32(data, offset, &sec_len) < 0 -- || !elf_can_read_next(data, offset, sec_len)) { -- goto done; -- } -- const GElf_Xword next_offset = offset + sec_len; -- offset += 4; -- -- if (sec_len < 4 + sizeof signature -- || strcmp(signature, data->d_buf + offset) != 0) -- goto skip; -- offset += sizeof signature; -- -- const GElf_Xword offset0 = offset; -- uint64_t tag; -- uint32_t sub_len; -- if (elf_read_next_uleb128(data, &offset, &tag) < 0 -- || elf_read_next_u32(data, &offset, &sub_len) < 0 -- || !elf_can_read_next(data, offset0, sub_len)) -- goto done; -- -- if (tag != 1) -- /* IHI0045D_ABI_addenda: "section and -- * symbol attributes are deprecated -- * [...] consumers are permitted to -- * ignore them." */ -- goto skip; -- -- while (offset < offset0 + sub_len) { -- if (elf_read_next_uleb128(data, -- &offset, &tag) < 0) -- goto done; -- -- switch (tag) { -- uint64_t v; -- case 6: /* Tag_CPU_arch */ -- case 7: /* Tag_CPU_arch_profile */ -- case 8: /* Tag_ARM_ISA_use */ -- case 9: /* Tag_THUMB_ISA_use */ -- case 10: /* Tag_FP_arch */ -- case 11: /* Tag_WMMX_arch */ -- case 12: /* Tag_Advanced_SIMD_arch */ -- case 13: /* Tag_PCS_config */ -- case 14: /* Tag_ABI_PCS_R9_use */ -- case 15: /* Tag_ABI_PCS_RW_data */ -- case 16: /* Tag_ABI_PCS_RO_data */ -- case 17: /* Tag_ABI_PCS_GOT_use */ -- case 18: /* Tag_ABI_PCS_wchar_t */ -- case 19: /* Tag_ABI_FP_rounding */ -- case 20: /* Tag_ABI_FP_denormal */ -- case 21: /* Tag_ABI_FP_exceptions */ -- case 22: /* Tag_ABI_FP_user_exceptions */ -- case 23: /* Tag_ABI_FP_number_model */ -- case 24: /* Tag_ABI_align_needed */ -- case 25: /* Tag_ABI_align_preserved */ -- case 26: /* Tag_ABI_enum_size */ -- case 27: /* Tag_ABI_HardFP_use */ -- case 28: /* Tag_ABI_VFP_args */ -- case 29: /* Tag_ABI_WMMX_args */ -- case 30: /* Tag_ABI_optimization_goals */ -- case 31: /* Tag_ABI_FP_optimization_goals */ -- case 32: /* Tag_compatibility */ -- case 34: /* Tag_CPU_unaligned_access */ -- case 36: /* Tag_FP_HP_extension */ -- case 38: /* Tag_ABI_FP_16bit_format */ -- case 42: /* Tag_MPextension_use */ -- case 70: /* Tag_MPextension_use as well */ -- case 44: /* Tag_DIV_use */ -- case 64: /* Tag_nodefaults */ -- case 66: /* Tag_T2EE_use */ -- case 68: /* Tag_Virtualization_use */ -- uleb128: -- if (elf_read_next_uleb128 -- (data, &offset, &v) < 0) -- goto done; -- if (tag == 28) -- hardfp = get_hardfp(v); -- if (tag != 32) -- continue; -- -- /* Tag 32 has two arguments, -- * fall through. */ -- -- case 4: /* Tag_CPU_raw_name */ -- case 5: /* Tag_CPU_name */ -- case 65: /* Tag_also_compatible_with */ -- case 67: /* Tag_conformance */ -- ntbs: -- offset += strlen(data->d_buf -- + offset) + 1; -- continue; -- } -- -- /* Handle unknown tags in a generic -- * manner, if possible. */ -- if (tag <= 32) { -- fprintf(stderr, -- "Unknown tag %lld " -- "at offset %#llx " -- "of ARM attribute section.", -- tag, offset); -- goto skip; -- } else if (tag % 2 == 0) { -- goto uleb128; -- } else { -- goto ntbs; -- } -- } -- -- skip: -- offset = next_offset; -- -- } while (elf_can_read_next(data, offset, 1)); -- -- } -- --done: -- lib->arch.hardfp = hardfp; -- return 0; --} -- --void --arch_elf_destroy(struct ltelf *lte) --{ --} -- --int --arch_library_init(struct library *lib) --{ -- return 0; --} -- --void --arch_library_destroy(struct library *lib) --{ --} -- --int --arch_library_clone(struct library *retp, struct library *lib) --{ -- retp->arch = lib->arch; -- return 0; --} -- - enum { - /* How many (double) VFP registers the AAPCS uses for - * parameter passing. */ -diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c -index d1bf7ca..9e9e37f 100644 ---- a/sysdeps/linux-gnu/arm/plt.c -+++ b/sysdeps/linux-gnu/arm/plt.c -@@ -1,5 +1,6 @@ - /* - * This file is part of ltrace. -+ * Copyright (C) 2013 Petr Machata, Red Hat Inc. - * Copyright (C) 2010 Zach Welch, CodeSourcery - * Copyright (C) 2004,2008,2009 Juan Cespedes - * -@@ -20,20 +21,205 @@ - */ - - #include -+#include -+#include - - #include "proc.h" - #include "library.h" - #include "ltrace-elf.h" - - static int -+get_hardfp(uint64_t abi_vfp_args) -+{ -+ if (abi_vfp_args == 2) -+ fprintf(stderr, -+ "Tag_ABI_VFP_args value 2 (tool chain-specific " -+ "conventions) not supported.\n"); -+ return abi_vfp_args == 1; -+} -+ -+int -+arch_elf_init(struct ltelf *lte, struct library *lib) -+{ -+ GElf_Addr jmprel_addr; -+ Elf_Scn *jmprel_sec; -+ GElf_Shdr jmprel_shdr; -+ if (elf_load_dynamic_entry(lte, DT_JMPREL, &jmprel_addr) < 0 -+ || elf_get_section_covering(lte, jmprel_addr, -+ &jmprel_sec, &jmprel_shdr) < 0 -+ || jmprel_sec == NULL) -+ return -1; -+ -+ lte->arch.jmprel_data = elf_loaddata(jmprel_sec, &jmprel_shdr); -+ if (lte->arch.jmprel_data == NULL) -+ return -1; -+ -+ /* Nothing in this section is strictly critical. It's not -+ * that much of a deal if we fail to guess right whether the -+ * ABI is softfp or hardfp. */ -+ unsigned hardfp = 0; -+ -+ Elf_Scn *scn; -+ Elf_Data *data; -+ GElf_Shdr shdr; -+ if (elf_get_section_type(lte, SHT_ARM_ATTRIBUTES, &scn, &shdr) < 0 -+ || (scn != NULL && (data = elf_loaddata(scn, &shdr)) == NULL)) { -+ fprintf(stderr, -+ "Error when obtaining ARM attribute section: %s\n", -+ elf_errmsg(-1)); -+ goto done; -+ -+ } else if (scn != NULL && data != NULL) { -+ GElf_Xword offset = 0; -+ uint8_t version; -+ if (elf_read_next_u8(data, &offset, &version) < 0) { -+ goto done; -+ } else if (version != 'A') { -+ fprintf(stderr, "Unsupported ARM attribute section " -+ "version %d ('%c').\n", version, version); -+ goto done; -+ } -+ -+ do { -+ const char signature[] = "aeabi"; -+ /* N.B. LEN is including the length field -+ * itself. */ -+ uint32_t sec_len; -+ if (elf_read_u32(data, offset, &sec_len) < 0 -+ || !elf_can_read_next(data, offset, sec_len)) { -+ goto done; -+ } -+ const GElf_Xword next_offset = offset + sec_len; -+ offset += 4; -+ -+ if (sec_len < 4 + sizeof signature -+ || strcmp(signature, data->d_buf + offset) != 0) -+ goto skip; -+ offset += sizeof signature; -+ -+ const GElf_Xword offset0 = offset; -+ uint64_t tag; -+ uint32_t sub_len; -+ if (elf_read_next_uleb128(data, &offset, &tag) < 0 -+ || elf_read_next_u32(data, &offset, &sub_len) < 0 -+ || !elf_can_read_next(data, offset0, sub_len)) -+ goto done; -+ -+ if (tag != 1) -+ /* IHI0045D_ABI_addenda: "section and -+ * symbol attributes are deprecated -+ * [...] consumers are permitted to -+ * ignore them." */ -+ goto skip; -+ -+ while (offset < offset0 + sub_len) { -+ if (elf_read_next_uleb128(data, -+ &offset, &tag) < 0) -+ goto done; -+ -+ switch (tag) { -+ uint64_t v; -+ case 6: /* Tag_CPU_arch */ -+ case 7: /* Tag_CPU_arch_profile */ -+ case 8: /* Tag_ARM_ISA_use */ -+ case 9: /* Tag_THUMB_ISA_use */ -+ case 10: /* Tag_FP_arch */ -+ case 11: /* Tag_WMMX_arch */ -+ case 12: /* Tag_Advanced_SIMD_arch */ -+ case 13: /* Tag_PCS_config */ -+ case 14: /* Tag_ABI_PCS_R9_use */ -+ case 15: /* Tag_ABI_PCS_RW_data */ -+ case 16: /* Tag_ABI_PCS_RO_data */ -+ case 17: /* Tag_ABI_PCS_GOT_use */ -+ case 18: /* Tag_ABI_PCS_wchar_t */ -+ case 19: /* Tag_ABI_FP_rounding */ -+ case 20: /* Tag_ABI_FP_denormal */ -+ case 21: /* Tag_ABI_FP_exceptions */ -+ case 22: /* Tag_ABI_FP_user_exceptions */ -+ case 23: /* Tag_ABI_FP_number_model */ -+ case 24: /* Tag_ABI_align_needed */ -+ case 25: /* Tag_ABI_align_preserved */ -+ case 26: /* Tag_ABI_enum_size */ -+ case 27: /* Tag_ABI_HardFP_use */ -+ case 28: /* Tag_ABI_VFP_args */ -+ case 29: /* Tag_ABI_WMMX_args */ -+ case 30: /* Tag_ABI_optimization_goals */ -+ case 31: /* Tag_ABI_FP_optimization_goals */ -+ case 32: /* Tag_compatibility */ -+ case 34: /* Tag_CPU_unaligned_access */ -+ case 36: /* Tag_FP_HP_extension */ -+ case 38: /* Tag_ABI_FP_16bit_format */ -+ case 42: /* Tag_MPextension_use */ -+ case 70: /* Tag_MPextension_use as well */ -+ case 44: /* Tag_DIV_use */ -+ case 64: /* Tag_nodefaults */ -+ case 66: /* Tag_T2EE_use */ -+ case 68: /* Tag_Virtualization_use */ -+ uleb128: -+ if (elf_read_next_uleb128 -+ (data, &offset, &v) < 0) -+ goto done; -+ if (tag == 28) -+ hardfp = get_hardfp(v); -+ if (tag != 32) -+ continue; -+ -+ /* Tag 32 has two arguments, -+ * fall through. */ -+ -+ case 4: /* Tag_CPU_raw_name */ -+ case 5: /* Tag_CPU_name */ -+ case 65: /* Tag_also_compatible_with */ -+ case 67: /* Tag_conformance */ -+ ntbs: -+ offset += strlen(data->d_buf -+ + offset) + 1; -+ continue; -+ } -+ -+ /* Handle unknown tags in a generic -+ * manner, if possible. */ -+ if (tag <= 32) { -+ fprintf(stderr, -+ "Unknown tag %lld " -+ "at offset %#llx " -+ "of ARM attribute section.", -+ tag, offset); -+ goto skip; -+ } else if (tag % 2 == 0) { -+ goto uleb128; -+ } else { -+ goto ntbs; -+ } -+ } -+ -+ skip: -+ offset = next_offset; -+ -+ } while (elf_can_read_next(data, offset, 1)); -+ -+ } -+ -+done: -+ lib->arch.hardfp = hardfp; -+ return 0; -+} -+ -+void -+arch_elf_destroy(struct ltelf *lte) -+{ -+} -+ -+static int - arch_plt_entry_has_stub(struct ltelf *lte, size_t off) { -- uint16_t op = *(uint16_t *)((char *)lte->relplt->d_buf + off); -+ char *buf = (char *) lte->arch.jmprel_data->d_buf; -+ uint16_t op = *(uint16_t *) (buf + off); - return op == 0x4778; - } - - GElf_Addr - arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { -- size_t start = lte->relplt->d_size + 12; -+ size_t start = lte->arch.jmprel_data->d_size + 12; - size_t off = start + 20, i; - for (i = 0; i < ndx; i++) - off += arch_plt_entry_has_stub(lte, off) ? 16 : 12; -@@ -47,3 +233,21 @@ sym2addr(struct process *proc, struct library_symbol *sym) - { - return sym->enter_addr; - } -+ -+int -+arch_library_init(struct library *lib) -+{ -+ return 0; -+} -+ -+void -+arch_library_destroy(struct library *lib) -+{ -+} -+ -+int -+arch_library_clone(struct library *retp, struct library *lib) -+{ -+ retp->arch = lib->arch; -+ return 0; -+} -diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c -index 5e3ffe1..3ec1397 100644 ---- a/sysdeps/linux-gnu/ppc/plt.c -+++ b/sysdeps/linux-gnu/ppc/plt.c -@@ -402,38 +402,6 @@ get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data) - } - - static int --load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep) --{ -- Elf_Scn *scn; -- GElf_Shdr shdr; -- if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 -- || scn == NULL) { -- fail: -- fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n", -- elf_errmsg(-1)); -- return -1; -- } -- -- Elf_Data *data = elf_loaddata(scn, &shdr); -- if (data == NULL) -- goto fail; -- -- size_t j; -- for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { -- GElf_Dyn dyn; -- if (gelf_getdyn(data, j, &dyn) == NULL) -- goto fail; -- -- if(dyn.d_tag == tag) { -- *valuep = dyn.d_un.d_ptr; -- return 0; -- } -- } -- -- return -1; --} -- --static int - nonzero_data(Elf_Data *data) - { - /* We are not supposed to get here if there's no PLT. */ -@@ -488,8 +456,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib) - Elf_Scn *rela_sec; - GElf_Shdr rela_shdr; - if ((lte->ehdr.e_machine == EM_PPC64 || lte->arch.secure_plt) -- && load_dynamic_entry(lte, DT_RELA, &rela) == 0 -- && load_dynamic_entry(lte, DT_RELASZ, &relasz) == 0 -+ && elf_load_dynamic_entry(lte, DT_RELA, &rela) == 0 -+ && elf_load_dynamic_entry(lte, DT_RELASZ, &relasz) == 0 - && elf_get_section_covering(lte, rela, &rela_sec, &rela_shdr) == 0 - && rela_sec != NULL) { - -@@ -509,7 +477,7 @@ arch_elf_init(struct ltelf *lte, struct library *lib) - - if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { - GElf_Addr ppcgot; -- if (load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) { -+ if (elf_load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) { - fprintf(stderr, "couldn't find DT_PPC_GOT\n"); - return -1; - } -@@ -522,7 +490,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib) - - } else if (lte->ehdr.e_machine == EM_PPC64) { - GElf_Addr glink_vma; -- if (load_dynamic_entry(lte, DT_PPC64_GLINK, &glink_vma) < 0) { -+ if (elf_load_dynamic_entry(lte, DT_PPC64_GLINK, -+ &glink_vma) < 0) { - fprintf(stderr, "couldn't find DT_PPC64_GLINK\n"); - return -1; - } -@@ -532,8 +501,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib) - - } else { - /* By exhaustion--PPC32 BSS. */ -- if (load_dynamic_entry(lte, DT_PLTGOT, -- &lib->arch.pltgot_addr) < 0) { -+ if (elf_load_dynamic_entry(lte, DT_PLTGOT, -+ &lib->arch.pltgot_addr) < 0) { - fprintf(stderr, "couldn't find DT_PLTGOT\n"); - return -1; - } diff --git a/ltrace-0.7.91-breakpoint-on_install.patch b/ltrace-0.7.91-breakpoint-on_install.patch deleted file mode 100644 index 15959a3..0000000 --- a/ltrace-0.7.91-breakpoint-on_install.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 56134ff5442bee4e128b189bb86cfc97dcb6f60a Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Fri, 10 Jan 2014 20:05:15 +0100 -Subject: [PATCH 1/2] Add a new per-breakpoint callback on_install - ---- - breakpoint.h | 9 ++++++++- - breakpoints.c | 11 ++++++++++- - 2 files changed, 18 insertions(+), 2 deletions(-) - -diff --git a/breakpoint.h b/breakpoint.h -index 95964a8..c36f673 100644 ---- a/breakpoint.h -+++ b/breakpoint.h -@@ -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) 2009 Juan Cespedes - * - * This program is free software; you can redistribute it and/or -@@ -46,6 +46,7 @@ - struct bp_callbacks { - void (*on_hit)(struct breakpoint *bp, struct process *proc); - void (*on_continue)(struct breakpoint *bp, struct process *proc); -+ void (*on_install)(struct breakpoint *bp, struct process *proc); - void (*on_retract)(struct breakpoint *bp, struct process *proc); - - /* Create a new breakpoint that should handle return from the -@@ -84,6 +85,12 @@ void breakpoint_on_continue(struct breakpoint *bp, struct process *proc); - * the instruction underneath it). */ - void breakpoint_on_retract(struct breakpoint *bp, struct process *proc); - -+/* Call ON_INSTALL handler of BP, if any is set. This should be -+ * called after the breakpoint is enabled for the first time, not -+ * every time it's enabled (such as after stepping over a site of a -+ * temporarily disabled breakpoint). */ -+void breakpoint_on_install(struct breakpoint *bp, struct process *proc); -+ - /* Call GET_RETURN_BP handler of BP, if any is set. If none is set, - * call CREATE_DEFAULT_RETURN_BP to obtain one. */ - int breakpoint_get_return_bp(struct breakpoint **ret, -diff --git a/breakpoints.c b/breakpoints.c -index 947cb71..c3fa275 100644 ---- a/breakpoints.c -+++ b/breakpoints.c -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2006,2007,2011,2012,2013 Petr Machata, Red Hat Inc. -+ * Copyright (C) 2006,2007,2011,2012,2013,2014 Petr Machata, Red Hat Inc. - * Copyright (C) 2009 Juan Cespedes - * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes - * Copyright (C) 2006 Ian Wienand -@@ -85,6 +85,14 @@ breakpoint_on_retract(struct breakpoint *bp, struct process *proc) - (bp->cbs->on_retract)(bp, proc); - } - -+void -+breakpoint_on_install(struct breakpoint *bp, struct process *proc) -+{ -+ assert(bp != NULL); -+ if (bp->cbs != NULL && bp->cbs->on_install != NULL) -+ (bp->cbs->on_install)(bp, proc); -+} -+ - int - breakpoint_get_return_bp(struct breakpoint **ret, - struct breakpoint *bp, struct process *proc) -@@ -229,6 +237,7 @@ breakpoint_turn_on(struct breakpoint *bp, struct process *proc) - if (bp->enabled == 1) { - assert(proc->pid != 0); - enable_breakpoint(proc, bp); -+ breakpoint_on_install(bp, proc); - } - return 0; - } --- -1.7.6.5 - diff --git a/ltrace-0.7.91-cant_open.patch b/ltrace-0.7.91-cant_open.patch deleted file mode 100644 index 4d3a0d4..0000000 --- a/ltrace-0.7.91-cant_open.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -urp ltrace-0.7.91/libltrace.c master/libltrace.c ---- ltrace-0.7.91/libltrace.c 2014-01-14 16:31:37.696174464 +0100 -+++ master/libltrace.c 2013-11-21 14:06:38.623701688 +0100 -@@ -113,9 +117,13 @@ ltrace_init(int argc, char **argv) { - if (command) { - /* Check that the binary ABI is supported before - * calling execute_program. */ -- struct ltelf lte; -- ltelf_init(<e, command); -- ltelf_destroy(<e); -+ { -+ struct ltelf lte; -+ if (ltelf_init(<e, command) == 0) -+ ltelf_destroy(<e); -+ else -+ exit(EXIT_FAILURE); -+ } - - pid_t pid = execute_program(command, argv); - struct process *proc = open_program(command, pid); -diff -urp ltrace-0.7.91/ltrace-elf.c master/ltrace-elf.c ---- ltrace-0.7.91/ltrace-elf.c 2014-01-14 16:31:37.688174420 +0100 -+++ master/ltrace-elf.c 2013-11-22 18:17:11.767721609 +0100 -@@ -361,8 +361,11 @@ ltelf_init(struct ltelf *lte, const char - { - memset(lte, 0, sizeof *lte); - lte->fd = open(filename, O_RDONLY); -- if (lte->fd == -1) -+ if (lte->fd == -1) { -+ fprintf(stderr, "Can't open %s: %s\n", filename, -+ strerror(errno)); - return 1; -+ } - - elf_version(EV_CURRENT); - diff --git a/ltrace-0.7.91-cet.patch b/ltrace-0.7.91-cet.patch deleted file mode 100644 index a320682..0000000 --- a/ltrace-0.7.91-cet.patch +++ /dev/null @@ -1,121 +0,0 @@ -diff -rup a/ltrace-elf.c b/ltrace-elf.c ---- a/ltrace-elf.c 2019-02-28 17:32:49.873659818 -0500 -+++ b/ltrace-elf.c 2019-02-28 17:36:32.426779439 -0500 -@@ -639,7 +639,21 @@ ltelf_read_elf(struct ltelf *lte, const - } - } else if (shdr.sh_type == SHT_PROGBITS - || shdr.sh_type == SHT_NOBITS) { -- if (strcmp(name, ".plt") == 0) { -+ if (strcmp(name, ".plt") == 0 -+ && lte->second_plt_seen == 0) { -+ lte->plt_addr = shdr.sh_addr; -+ lte->plt_size = shdr.sh_size; -+ lte->plt_data = elf_loaddata(scn, &shdr); -+ if (lte->plt_data == NULL) -+ fprintf(stderr, -+ "Can't load .plt data\n"); -+ lte->plt_flags = shdr.sh_flags; -+ } -+ /* An Intel CET binary has two PLTs; the -+ initial PLTGOT points to the second -+ one. */ -+ else if (strcmp(name, ".plt.sec") == 0) { -+ lte->second_plt_seen = 1; - lte->plt_addr = shdr.sh_addr; - lte->plt_size = shdr.sh_size; - lte->plt_data = elf_loaddata(scn, &shdr); -diff -rup a/ltrace-elf.h b/ltrace-elf.h ---- a/ltrace-elf.h 2019-02-28 17:32:49.874660328 -0500 -+++ b/ltrace-elf.h 2019-02-28 17:36:32.428779868 -0500 -@@ -45,6 +45,7 @@ struct ltelf { - Elf_Data *dynsym; - size_t dynsym_count; - const char *dynstr; -+ int second_plt_seen; - GElf_Addr plt_addr; - GElf_Word plt_flags; - size_t plt_size; -diff -rup a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c ---- a/sysdeps/linux-gnu/x86/plt.c 2019-02-28 17:32:49.991720041 -0500 -+++ b/sysdeps/linux-gnu/x86/plt.c 2019-02-28 17:36:32.429780083 -0500 -@@ -28,18 +28,18 @@ - #include "trace.h" - - static GElf_Addr --x86_plt_offset(uint32_t i) -+x86_plt_offset(struct ltelf *lte, uint32_t i) - { - /* Skip the first PLT entry, which contains a stub to call the - * resolver. */ -- return (i + 1) * 16; -+ return (i + (lte->second_plt_seen ? 0 : 1)) * 16; - } - - GElf_Addr - arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) - { - uint32_t i = *VECT_ELEMENT(<e->arch.plt_map, uint32_t, ndx); -- return x86_plt_offset(i) + lte->plt_addr; -+ return x86_plt_offset(lte, i) + lte->plt_addr; - } - - void * -@@ -116,6 +116,13 @@ arch_elf_init(struct ltelf *lte, struct - * 400426: 68 00 00 00 00 pushq $0x0 - * 40042b: e9 e0 ff ff ff jmpq 400410 <_init+0x18> - * -+ * For CET binaries it is the following: -+ * -+ * 13d0: f3 0f 1e fa endbr64 -+ * 13d4: 68 27 00 00 00 pushq $0x27 <-- index -+ * 13d9: f2 e9 71 fd ff ff bnd jmpq 1150 <.plt> -+ * 13df: 90 nop -+ * - * On i386, the argument to push is an offset of relocation to - * use. The first PLT slot has an offset of 0x0, the second - * 0x8, etc. On x86_64, it's directly the index that we are -@@ -128,11 +135,33 @@ arch_elf_init(struct ltelf *lte, struct - unsigned int i, sz = vect_size(<e->plt_relocs); - for (i = 0; i < sz; ++i) { - -- GElf_Addr offset = x86_plt_offset(i); -+ GElf_Addr offset = x86_plt_offset(lte, i); -+ uint32_t reloc_arg; - - uint8_t byte; -- if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0 -- || byte != 0xff -+ if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0) -+ continue; -+ -+ -+ if (byte == 0xf3 -+ && elf_read_next_u8(lte->plt_data, &offset, &byte) >= 0 -+ && byte == 0x0f -+ && elf_read_next_u8(lte->plt_data, &offset, &byte) >= 0 -+ && byte == 0x1e -+ && elf_read_next_u8(lte->plt_data, &offset, &byte) >= 0 -+ && byte == 0xfa -+ && elf_read_next_u8(lte->plt_data, &offset, &byte) >= 0 -+ && byte == 0x68 -+ && elf_read_next_u32(lte->plt_data, -+ &offset, &reloc_arg) >= 0) -+ { -+ /* CET */ -+ fprintf(stderr, "%d: reloc_arg is %lx\n", i, (long)reloc_arg); -+ *VECT_ELEMENT(<e->arch.plt_map, unsigned int, reloc_arg) = i; -+ continue; -+ } -+ -+ if (byte != 0xff - || elf_read_next_u8(lte->plt_data, &offset, &byte) < 0 - || (byte != 0xa3 && byte != 0x25)) - continue; -@@ -140,7 +169,6 @@ arch_elf_init(struct ltelf *lte, struct - /* Skip immediate argument in the instruction. */ - offset += 4; - -- uint32_t reloc_arg; - if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0 - || byte != 0x68 - || elf_read_next_u32(lte->plt_data, diff --git a/ltrace-0.7.91-man.patch b/ltrace-0.7.91-man.patch deleted file mode 100644 index d7a7dbf..0000000 --- a/ltrace-0.7.91-man.patch +++ /dev/null @@ -1,45 +0,0 @@ -diff -up ltrace-0.7.91/options.c\~ ltrace-0.7.91/options.c ---- ltrace-0.7.91/options.c~ 2013-10-22 11:54:21.000000000 +0200 -+++ ltrace-0.7.91/options.c 2014-01-13 15:38:51.362221740 +0100 -@@ -128,6 +128,8 @@ usage_debug(void) { - "\n" - "Debugging options are mixed using bitwise-or.\n" - "Note that the meanings and values are subject to change.\n" -+ "Also note that these values are used inconsistently in ltrace, and the\n" -+ "only debuglevel that you can rely on is -D77 that will show everything.\n" - ); - } - -diff -up ltrace-0.7.91/ltrace.1\~ ltrace-0.7.91/ltrace.1 ---- ltrace-0.7.91/ltrace.1~ 2013-10-23 17:44:13.000000000 +0200 -+++ ltrace-0.7.91/ltrace.1 2014-01-13 15:51:24.236730677 +0100 -@@ -1,5 +1,5 @@ - .\" -*-nroff-*- --.\" Copyright (c) 2012, 2013 Petr Machata, Red Hat Inc. -+.\" Copyright (c) 2012,2013,2014 Petr Machata, Red Hat Inc. - .\" Copyright (c) 1997-2005 Juan Cespedes - .\" - .\" This program is free software; you can redistribute it and/or -@@ -118,9 +118,9 @@ Besides removing any initial underscore - this makes C++ function names readable. - .IP "\-D, \-\-debug \fRmask\fI" - Show debugging output of \fBltrace\fR itself. \fImask\fR is a number --with internal meaning that's not really well defined at all. --\fImask\fR of 77 shows all debug messages, which is what you usually --need. -+describing which debug messages should be displayed. Use the option -+\-Dh to see what can be used, but note that currently the only -+reliable debugmask is 77, which shows all debug messages. - .IP "\-e \fIfilter" - A qualifying expression which modifies which library calls to trace. - The format of the filter expression is described in the section -@@ -156,7 +156,8 @@ dependency ordering. If you want to mak - library are actually called, use \fB-x @\fIlibrary_pattern\fR instead. - .IP \-L - When no -e option is given, don't assume the default action of --\fB@MAIN\fR. -+\fB@MAIN\fR. In practice this means that library calls will not be -+traced. - .IP "\-n, \-\-indent \fInr" - Indent trace output by \fInr\fR spaces for each level of call - nesting. Using this option makes the program flow visualization easy diff --git a/ltrace-0.7.91-multithread-no-f-1.patch b/ltrace-0.7.91-multithread-no-f-1.patch deleted file mode 100644 index 0589f5e..0000000 --- a/ltrace-0.7.91-multithread-no-f-1.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 4724bd5a4a19db117a1d280b9d1a3508fd4e03fa Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Wed, 8 Apr 2015 07:11:52 -0400 -Subject: [PATCH 1/2] Convert main-threaded test case to new style - ---- - testsuite/ltrace.main/Makefile.am | 4 +- - testsuite/ltrace.main/main-threaded.c | 30 ---------- - testsuite/ltrace.main/main-threaded.exp | 103 ++++++++++++++++++++------------ - 3 files changed, 66 insertions(+), 71 deletions(-) - delete mode 100644 testsuite/ltrace.main/main-threaded.c - -diff --git a/testsuite/ltrace.main/Makefile.am b/testsuite/ltrace.main/Makefile.am -index 23ab8ab..06ad613 100644 ---- a/testsuite/ltrace.main/Makefile.am -+++ b/testsuite/ltrace.main/Makefile.am -@@ -1,4 +1,4 @@ --# Copyright (C) 1992 - 2001, 2012, 2013 Free Software Foundation, Inc. -+# Copyright (C) 1992 - 2001, 2012, 2013, 2015 Free Software Foundation, Inc. - # - # This program is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -17,7 +17,7 @@ - - EXTRA_DIST = branch_func.c branch_func.exp filters.exp hello-vfork.c \ - hello-vfork.exp main.c main.exp main-internal.exp main-lib.c \ -- main-threaded.c main-threaded.exp main-vfork.c main-vfork.exp \ -+ main-threaded.exp main-vfork.c main-vfork.exp \ - parameters.c parameters.conf parameters.exp parameters-lib.c \ - parameters2.exp parameters3.exp signals.c signals.exp \ - system_calls.c system_calls.exp system_call_params.exp -diff --git a/testsuite/ltrace.main/main-threaded.c b/testsuite/ltrace.main/main-threaded.c -deleted file mode 100644 -index 2992d1e..0000000 ---- a/testsuite/ltrace.main/main-threaded.c -+++ /dev/null -@@ -1,29 +0,0 @@ --#include -- --extern void print (char *); -- --#define PRINT_LOOP 10 -- --void * --th_main (void *arg) --{ -- int i; -- for (i=0; i. -+# This file is part of ltrace. -+# Copyright (C) 2011, 2015 Petr Machata, Red Hat Inc. -+# Copyright (C) 2006 Yao Qi . -+# -+# This program is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public License as -+# published by the Free Software Foundation; either version 2 of the -+# License, or (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+# 02110-1301 USA -+ -+set libprint [ltraceCompile libprint.so [ltraceSource c { -+ #include -+ -+ void -+ print(char* s) -+ { -+ printf("%s\n",s); -+ } -+}]] -+ -+set bin [ltraceCompile {} $libprint -lpthread [ltraceSource c { -+ #include -+ -+ extern void print (char *); -+ -+ #define PRINT_LOOP 10 -+ -+ void * -+ th_main (void *arg) -+ { -+ int i; -+ for (i=0; i -Date: Wed, 8 Apr 2015 07:14:10 -0400 -Subject: [PATCH 2/2] Fix tracing multi-threaded processes without -f - -- In handle_syscall, we avoid touching stack of ignored processes. - But in handle_sysret, we require a sysret-like stack entry even - for ignored processes, even though we then go ahead to not act - on that stack entry. Instead, for ignored processes, avoid looking - at stack trace at all. ---- - handle_event.c | 10 +++++----- - testsuite/ltrace.main/main-threaded.exp | 1 + - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/handle_event.c b/handle_event.c -index 6fa7e98..c2550ad 100644 ---- a/handle_event.c -+++ b/handle_event.c -@@ -619,12 +619,12 @@ handle_x_sysret(Event *event, char *(*name_cb)(struct process *, int)) - debug(DEBUG_FUNCTION, "handle_x_sysret(pid=%d, sysnum=%d)", - event->proc->pid, event->e_un.sysnum); - -- unsigned d = event->proc->callstack_depth; -- assert(d > 0); -- struct callstack_element *elem = &event->proc->callstack[d - 1]; -- assert(elem->is_syscall); -- - if (event->proc->state != STATE_IGNORED) { -+ unsigned d = event->proc->callstack_depth; -+ assert(d > 0); -+ struct callstack_element *elem = &event->proc->callstack[d - 1]; -+ assert(elem->is_syscall); -+ - struct timedelta spent = calc_time_spent(elem->enter_time); - if (options.syscalls) - output_syscall_right(event->proc, -diff --git a/testsuite/ltrace.main/main-threaded.exp b/testsuite/ltrace.main/main-threaded.exp -index cead82d..aca7afd 100644 ---- a/testsuite/ltrace.main/main-threaded.exp -+++ b/testsuite/ltrace.main/main-threaded.exp -@@ -60,5 +60,6 @@ set bin [ltraceCompile {} $libprint -lpthread [ltraceSource c { - }]] - - ltraceMatch1 [ltraceRun -f -l libprint.so -- $bin] {print\(} == 30 -+ltraceMatch1 [ltraceRun -L -- $bin] exited == 1 - - ltraceDone --- -2.1.0 diff --git a/ltrace-0.7.91-null.patch b/ltrace-0.7.91-null.patch deleted file mode 100644 index 4ff7e6a..0000000 --- a/ltrace-0.7.91-null.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/output.c b/output.c -index 7cab383..18f9cf0 100644 ---- a/output.c -+++ b/output.c -@@ -598,6 +598,9 @@ frame_callback (Dwfl_Frame *state, void *arg) - NULL, NULL, NULL); - symname = dwfl_module_addrinfo(mod, pc, &off, &sym, - NULL, NULL, NULL); -+ } else { -+ modname = "unknown"; -+ symname = "unknown"; - } - - /* This mimics the output produced by libunwind below. */ diff --git a/ltrace-0.7.91-parser-ws_after_id.patch b/ltrace-0.7.91-parser-ws_after_id.patch deleted file mode 100644 index bc6e96e..0000000 --- a/ltrace-0.7.91-parser-ws_after_id.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 2e9f9f1f5d0fb223b109429b9c904504b7f638e2 Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Fri, 8 Aug 2014 16:53:41 +0200 -Subject: [PATCH] In config files, allow whitespace between identifier and - opening paren - ---- - read_config_file.c | 61 ++++++-------------------------- - testsuite/ltrace.main/parameters2.exp | 14 +++++++- - 2 files changed, 25 insertions(+), 50 deletions(-) - -diff --git a/read_config_file.c b/read_config_file.c -index ea3ab88..05ff283 100644 ---- a/read_config_file.c -+++ b/read_config_file.c -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. -+ * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc. - * Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes - * Copyright (C) 2006 Ian Wienand - * Copyright (C) 2006 Steve Fink -@@ -168,38 +168,6 @@ parse_ident(struct locus *loc, char **str) - return xstrndup(ident, *str - ident); - } - --/* -- Returns position in string at the left parenthesis which starts the -- function's argument signature. Returns NULL on error. --*/ --static char * --start_of_arg_sig(char *str) { -- char *pos; -- int stacked = 0; -- -- if (!strlen(str)) -- return NULL; -- -- pos = &str[strlen(str)]; -- do { -- pos--; -- if (pos < str) -- return NULL; -- while ((pos > str) && (*pos != ')') && (*pos != '(')) -- pos--; -- -- if (*pos == ')') -- stacked++; -- else if (*pos == '(') -- stacked--; -- else -- return NULL; -- -- } while (stacked > 0); -- -- return (stacked == 0) ? pos : NULL; --} -- - static int - parse_int(struct locus *loc, char **str, long *ret) - { -@@ -1110,7 +1078,6 @@ static int - process_line(struct protolib *plib, struct locus *loc, char *buf) - { - char *str = buf; -- char *tmp; - - debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename); - eat_spaces(&str); -@@ -1148,22 +1115,13 @@ process_line(struct protolib *plib, struct locus *loc, char *buf) - debug(4, " return_type = %d", fun.return_info->type); - - eat_spaces(&str); -- tmp = start_of_arg_sig(str); -- if (tmp == NULL) { -- report_error(loc->filename, loc->line_no, "syntax error"); -+ proto_name = parse_ident(loc, &str); -+ if (proto_name == NULL) - goto err; -- } -- *tmp = '\0'; - -- proto_name = strdup(str); -- if (proto_name == NULL) { -- oom: -- report_error(loc->filename, loc->line_no, -- "%s", strerror(errno)); -+ eat_spaces(&str); -+ if (parse_char(loc, &str, '(') < 0) - goto err; -- } -- -- str = tmp + 1; - debug(3, " name = %s", proto_name); - - struct param *extra_param = NULL; -@@ -1177,8 +1135,13 @@ process_line(struct protolib *plib, struct locus *loc, char *buf) - if (have_stop == 0) { - struct param param; - param_init_stop(¶m); -- if (prototype_push_param(&fun, ¶m) < 0) -- goto oom; -+ if (prototype_push_param(&fun, ¶m) < 0) { -+ oom: -+ report_error(loc->filename, -+ loc->line_no, -+ "%s", strerror(errno)); -+ goto err; -+ } - have_stop = 1; - } - str++; -diff --git a/testsuite/ltrace.main/parameters2.exp b/testsuite/ltrace.main/parameters2.exp -index 6318fc5..9850079 100644 ---- a/testsuite/ltrace.main/parameters2.exp -+++ b/testsuite/ltrace.main/parameters2.exp -@@ -1,5 +1,5 @@ - # 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. - # - # This program is free software; you can redistribute it and/or - # modify it under the terms of the GNU General Public License as -@@ -259,4 +259,16 @@ ltraceMatch1 [ltraceLibTest { - somefunc(); - }] {somefunc\(\) *= nil} == 1 - -+# Test that spaces in function name make no difference. -+ -+ltraceMatch1 [ltraceLibTest { -+ void somefunc (); -+} { -+ void somefunc(void); -+} { -+ void somefunc(void) {} -+} { -+ somefunc(); -+}] {somefunc\(\)} == 1 -+ - ltraceDone --- -1.7.6.5 - diff --git a/ltrace-0.7.91-ppc-bias.patch b/ltrace-0.7.91-ppc-bias.patch deleted file mode 100644 index c0c0abd..0000000 --- a/ltrace-0.7.91-ppc-bias.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c -index 45ed7fb..5f81889 100644 ---- a/sysdeps/linux-gnu/ppc/plt.c -+++ b/sysdeps/linux-gnu/ppc/plt.c -@@ -274,14 +274,15 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) - - assert(rela->r_addend != 0); - /* XXX double cast */ -- arch_addr_t res_addr = (arch_addr_t) (uintptr_t) rela->r_addend; -+ arch_addr_t res_addr -+ = (arch_addr_t) (uintptr_t) (rela->r_addend + lte->bias); - if (arch_translate_address(lte, res_addr, &res_addr) < 0) { - fprintf(stderr, "Couldn't OPD-translate IRELATIVE " - "resolver address.\n"); - return 0; - } - /* XXX double cast */ -- return (GElf_Addr) (uintptr_t) res_addr; -+ return (GElf_Addr) (uintptr_t) (res_addr - lte->bias); - - } else { - /* We put brakpoints to PLT entries the same as the -@@ -453,7 +454,7 @@ arch_elf_init(struct ltelf *lte, struct library *lib) - #ifndef EF_PPC64_ABI - assert (! (lte->ehdr.e_flags & 3 ) == 2) - #else -- lte->arch.elfv2_abi=((lte->ehdr.e_flags & EF_PPC64_ABI) == 2) ; -+ lte->arch.elfv2_abi = ((lte->ehdr.e_flags & EF_PPC64_ABI) == 2); - #endif - - if (lte->ehdr.e_machine == EM_PPC64 -@@ -827,15 +828,15 @@ arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, - assert(plt_slot_addr >= lte->plt_addr - || plt_slot_addr < lte->plt_addr + lte->plt_size); - -+ plt_entry_addr += lte->bias; -+ plt_slot_addr += lte->bias; -+ - /* Should avoid to do read if dynamic linker hasn't run yet - * or allow -1 a valid return code. */ - GElf_Addr plt_slot_value; -- if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0) { -- if (!lte->arch.elfv2_abi) -- goto fail; -- else -- return PPC_PLT_UNRESOLVED; -- } -+ int rc = read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value); -+ if (rc < 0 && !lte->arch.elfv2_abi) -+ goto fail; - - struct library_symbol *libsym = malloc(sizeof(*libsym)); - if (libsym == NULL) { -@@ -854,8 +855,9 @@ arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, - goto fail2; - libsym->arch.plt_slot_addr = plt_slot_addr; - -- if (! is_irelative -- && (plt_slot_value == plt_entry_addr || plt_slot_value == 0)) { -+ if (rc < 0 || (! is_irelative -+ && (plt_slot_value == plt_entry_addr -+ || plt_slot_value == 0))) { - libsym->arch.type = PPC_PLT_UNRESOLVED; - libsym->arch.resolved_value = plt_entry_addr; - } else { -@@ -1166,8 +1168,8 @@ ppc_plt_bp_install(struct breakpoint *bp, struct process *proc) - libsym->arch.resolved_value = plt_entry_addr; - } - } else { -- fprintf(stderr, "Couldn't unresolve %s@%p. Not tracing" -- " this symbol.\n", -+ fprintf(stderr, "Couldn't unresolve %s@%p. Will not" -+ " trace this symbol.\n", - breakpoint_name(bp), bp->addr); - proc_remove_breakpoint(proc, bp); - } -@@ -1222,6 +1224,14 @@ arch_library_symbol_clone(struct library_symbol *retp, - struct library_symbol *libsym) - { - retp->arch = libsym->arch; -+ if (libsym->arch.type == PPC_PLT_NEED_UNRESOLVE) { -+ assert(libsym->arch.data->self == libsym->arch.data); -+ retp->arch.data = malloc(sizeof *retp->arch.data); -+ if (retp->arch.data == NULL) -+ return -1; -+ *retp->arch.data = *libsym->arch.data; -+ retp->arch.data->self = retp->arch.data; -+ } - return 0; - } - diff --git a/ltrace-0.7.91-ppc64-fork.patch b/ltrace-0.7.91-ppc64-fork.patch deleted file mode 100644 index 53c66fd..0000000 --- a/ltrace-0.7.91-ppc64-fork.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 35742523e3daa0e59de0c1c3fdd8e5ff52891967 Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Thu, 9 Jan 2014 23:41:50 +0100 -Subject: [PATCH] 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. ---- - sysdeps/linux-gnu/ppc/plt.c | 14 +++++++++++++- - 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; - } - --- -1.7.6.5 - diff --git a/ltrace-0.7.91-ppc64-unprelink.patch b/ltrace-0.7.91-ppc64-unprelink.patch deleted file mode 100644 index a5929e3..0000000 --- a/ltrace-0.7.91-ppc64-unprelink.patch +++ /dev/null @@ -1,221 +0,0 @@ -From a0093ca43cf40d7e5f6cebeb64156062d2de46d9 Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Fri, 10 Jan 2014 20:06:51 +0100 -Subject: [PATCH 2/2] Don't crash untraced calls via PLT in prelinked PPC64 - binaries - -In prelinked binaries, ltrace has to unprelinks PLT slots in order to -catch calls done through PLT. This makes the calls done through these -slots invalid, because the special first PLT slot is not initialized, -and dynamic linker SIGSEGVs because of this. Ltrace relies on -arranging breakpoints such that the dynamic linker is not actually -entered, and moves PC around itself to simulate the effects of a call -through PLT. - -Originally, arch_elf_add_plt_entry was called only for symbols that -were actually traced. Later this was changed and it's now called for -all PLT entries, and the resulting candidate list is filtered -afterwards. This gives backends a chance to rename the symbol, as is -useful with IRELATIVE PLT calls, where symbol name may not be -available at all. But the PPC backend was never updated to reflect -this, and unresolved all symbols for which arch_elf_add_plt_entry was -called, thus rendering _all_ PLT slots invalid, even those that -weren't later procted by breakpoints. Thus calls done through any -untraced slots failed. - -This patch fixes this problem by deferring the unprelinking of PLT -slots into the on_install hook of breakpoints. ---- - sysdeps/linux-gnu/ppc/arch.h | 21 ++++++++- - sysdeps/linux-gnu/ppc/plt.c | 94 +++++++++++++++++++++++++++++++++-------- - 2 files changed, 94 insertions(+), 21 deletions(-) - -diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h -index 2add3b8..bf9b5dc 100644 ---- a/sysdeps/linux-gnu/ppc/arch.h -+++ b/sysdeps/linux-gnu/ppc/arch.h -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2012,2013 Petr Machata -+ * Copyright (C) 2012,2013,2014 Petr Machata - * Copyright (C) 2006 Paul Gilliam - * Copyright (C) 2002,2004 Juan Cespedes - * -@@ -87,12 +87,29 @@ enum ppc64_plt_type { - /* Very similar to PPC_PLT_UNRESOLVED, but for JMP_IREL - * slots. */ - PPC_PLT_IRELATIVE, -+ -+ /* Transitional state before the breakpoint is enabled. */ -+ PPC_PLT_NEED_UNRESOLVE, - }; - - #define ARCH_HAVE_LIBRARY_SYMBOL_DATA -+struct ppc_unresolve_data; - struct arch_library_symbol_data { - enum ppc64_plt_type type; -- GElf_Addr resolved_value; -+ -+ /* State Contents -+ * -+ * PPC_DEFAULT N/A -+ * PPC64_PLT_STUB N/A -+ * PPC_PLT_UNRESOLVED PLT entry address. -+ * PPC_PLT_IRELATIVE Likewise. -+ * PPC_PLT_RESOLVED The original value the slot was resolved to. -+ * PPC_PLT_NEED_UNRESOLVE DATA. -+ */ -+ union { -+ GElf_Addr resolved_value; -+ struct ppc_unresolve_data *data; -+ }; - - /* Address of corresponding slot in .plt. */ - GElf_Addr plt_slot_addr; -diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c -index 8715da6..332daa8 100644 ---- a/sysdeps/linux-gnu/ppc/plt.c -+++ b/sysdeps/linux-gnu/ppc/plt.c -@@ -679,6 +679,14 @@ arch_elf_add_func_entry(struct process *proc, struct ltelf *lte, - return PLT_OK; - } - -+struct ppc_unresolve_data { -+ struct ppc_unresolve_data *self; /* A canary. */ -+ GElf_Addr plt_entry_addr; -+ GElf_Addr plt_slot_addr; -+ GElf_Addr plt_slot_value; -+ bool is_irelative; -+}; -+ - enum plt_status - arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, - const char *a_name, GElf_Rela *rela, size_t ndx, -@@ -778,28 +786,23 @@ arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, - && (plt_slot_value == plt_entry_addr || plt_slot_value == 0)) { - libsym->arch.type = PPC_PLT_UNRESOLVED; - libsym->arch.resolved_value = plt_entry_addr; -- - } else { -- /* Unresolve the .plt slot. If the binary was -- * prelinked, this makes the code invalid, because in -- * case of prelinked binary, the dynamic linker -- * doesn't update .plt[0] and .plt[1] with addresses -- * of the resover. But we don't care, we will never -- * need to enter the resolver. That just means that -- * we have to un-un-resolve this back before we -- * detach. */ -- -- if (unresolve_plt_slot(proc, plt_slot_addr, plt_entry_addr) < 0) { -- library_symbol_destroy(libsym); -+ /* Mark the symbol for later unresolving. We may not -+ * do this right away, as this is called by ltrace -+ * core for all symbols, and only later filtered. We -+ * only unresolve the symbol before the breakpoint is -+ * enabled. */ -+ -+ libsym->arch.type = PPC_PLT_NEED_UNRESOLVE; -+ libsym->arch.data = malloc(sizeof *libsym->arch.data); -+ if (libsym->arch.data == NULL) - goto fail2; -- } - -- if (! is_irelative) { -- mark_as_resolved(libsym, plt_slot_value); -- } else { -- libsym->arch.type = PPC_PLT_IRELATIVE; -- libsym->arch.resolved_value = plt_entry_addr; -- } -+ libsym->arch.data->self = libsym->arch.data; -+ libsym->arch.data->plt_entry_addr = plt_entry_addr; -+ libsym->arch.data->plt_slot_addr = plt_slot_addr; -+ libsym->arch.data->plt_slot_value = plt_slot_value; -+ libsym->arch.data->is_irelative = is_irelative; - } - - *ret = libsym; -@@ -999,6 +1002,7 @@ ppc_plt_bp_continue(struct breakpoint *bp, struct process *proc) - return; - - case PPC64_PLT_STUB: -+ case PPC_PLT_NEED_UNRESOLVE: - /* These should never hit here. */ - break; - } -@@ -1050,6 +1054,52 @@ ppc_plt_bp_retract(struct breakpoint *bp, struct process *proc) - } - } - -+static void -+ppc_plt_bp_install(struct breakpoint *bp, struct process *proc) -+{ -+ /* This should not be an artificial breakpoint. */ -+ struct library_symbol *libsym = bp->libsym; -+ if (libsym == NULL) -+ libsym = bp->arch.irel_libsym; -+ assert(libsym != NULL); -+ -+ if (libsym->arch.type == PPC_PLT_NEED_UNRESOLVE) { -+ /* Unresolve the .plt slot. If the binary was -+ * prelinked, this makes the code invalid, because in -+ * case of prelinked binary, the dynamic linker -+ * doesn't update .plt[0] and .plt[1] with addresses -+ * of the resover. But we don't care, we will never -+ * need to enter the resolver. That just means that -+ * we have to un-un-resolve this back before we -+ * detach. */ -+ -+ struct ppc_unresolve_data *data = libsym->arch.data; -+ libsym->arch.data = NULL; -+ assert(data->self == data); -+ -+ GElf_Addr plt_slot_addr = data->plt_slot_addr; -+ GElf_Addr plt_slot_value = data->plt_slot_value; -+ GElf_Addr plt_entry_addr = data->plt_entry_addr; -+ -+ if (unresolve_plt_slot(proc, plt_slot_addr, -+ plt_entry_addr) == 0) { -+ if (! data->is_irelative) { -+ mark_as_resolved(libsym, plt_slot_value); -+ } else { -+ libsym->arch.type = PPC_PLT_IRELATIVE; -+ libsym->arch.resolved_value = plt_entry_addr; -+ } -+ } else { -+ fprintf(stderr, "Couldn't unresolve %s@%p. Not tracing" -+ " this symbol.\n", -+ breakpoint_name(bp), bp->addr); -+ proc_remove_breakpoint(proc, bp); -+ } -+ -+ free(data); -+ } -+} -+ - int - arch_library_init(struct library *lib) - { -@@ -1080,6 +1130,11 @@ arch_library_symbol_init(struct library_symbol *libsym) - void - arch_library_symbol_destroy(struct library_symbol *libsym) - { -+ if (libsym->arch.type == PPC_PLT_NEED_UNRESOLVE) { -+ assert(libsym->arch.data->self == libsym->arch.data); -+ free(libsym->arch.data); -+ libsym->arch.data = NULL; -+ } - } - - int -@@ -1115,6 +1170,7 @@ arch_breakpoint_init(struct process *proc, struct breakpoint *bp) - static struct bp_callbacks cbs = { - .on_continue = ppc_plt_bp_continue, - .on_retract = ppc_plt_bp_retract, -+ .on_install = ppc_plt_bp_install, - }; - breakpoint_set_callbacks(bp, &cbs); - --- -1.7.6.5 - diff --git a/ltrace-0.7.91-ppc64le-configure.patch b/ltrace-0.7.91-ppc64le-configure.patch deleted file mode 100644 index 74f0987..0000000 --- a/ltrace-0.7.91-ppc64le-configure.patch +++ /dev/null @@ -1,44 +0,0 @@ -From eea6091f8672b01f7f022b0fc367e0f568225ffc Mon Sep 17 00:00:00 2001 -From: Petr Machata -Date: Fri, 8 Aug 2014 17:09:58 +0200 -Subject: [PATCH] Recognize powerpc64le in configure - ---- - configure.ac | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 4f360c8..6fe5e3b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -43,7 +43,7 @@ case "${host_cpu}" in - arm*|sa110) HOST_CPU="arm" ;; - cris*) HOST_CPU="cris" ;; - mips*) HOST_CPU="mips" ;; -- powerpc|powerpc64) HOST_CPU="ppc" ;; -+ powerpc|powerpc64|powerpc64le) HOST_CPU="ppc" ;; - sun4u|sparc64) HOST_CPU="sparc" ;; - s390x) HOST_CPU="s390" ;; - i?86|x86_64) HOST_CPU="x86" ;; -@@ -210,12 +210,12 @@ AC_MSG_RESULT([$enable_libunwind]) - - if test x"$enable_libunwind" = xyes; then - case "${host_cpu}" in -- arm*|sa110) UNWIND_ARCH="arm" ;; -- i?86) UNWIND_ARCH="x86" ;; -- powerpc) UNWIND_ARCH="ppc32" ;; -- powerpc64) UNWIND_ARCH="ppc64" ;; -- mips*) UNWIND_ARCH="mips" ;; -- *) UNWIND_ARCH="${host_cpu}" ;; -+ arm*|sa110) UNWIND_ARCH="arm" ;; -+ i?86) UNWIND_ARCH="x86" ;; -+ powerpc) UNWIND_ARCH="ppc32" ;; -+ powerpc64|powerpc64le) UNWIND_ARCH="ppc64" ;; -+ mips*) UNWIND_ARCH="mips" ;; -+ *) UNWIND_ARCH="${host_cpu}" ;; - esac - - saved_LDFLAGS="${LDFLAGS}" --- -2.1.0 - diff --git a/ltrace-0.7.91-ppc64le-fixes.patch b/ltrace-0.7.91-ppc64le-fixes.patch deleted file mode 100644 index 82fb474..0000000 --- a/ltrace-0.7.91-ppc64le-fixes.patch +++ /dev/null @@ -1,421 +0,0 @@ -diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h -index d5ad759..a8b67bb 100644 ---- a/sysdeps/linux-gnu/ppc/arch.h -+++ b/sysdeps/linux-gnu/ppc/arch.h -@@ -32,36 +32,45 @@ - #define LT_ELF_MACHINE EM_PPC - - #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target. --#define LT_ELFCLASS2 ELFCLASS64 --#define LT_ELF_MACHINE2 EM_PPC64 -+# define LT_ELFCLASS2 ELFCLASS64 -+# define LT_ELF_MACHINE2 EM_PPC64 - - # ifdef __LITTLE_ENDIAN__ --# define BREAKPOINT_VALUE { 0x08, 0x00, 0xe0, 0x7f } --# define ARCH_ENDIAN_LITTLE -+# define BREAKPOINT_VALUE { 0x08, 0x00, 0xe0, 0x7f } -+# define ARCH_ENDIAN_LITTLE - # else --# define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } --# define ARCH_SUPPORTS_OPD --# define ARCH_ENDIAN_BIG -+# define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } -+# define ARCH_SUPPORTS_OPD -+# define ARCH_ENDIAN_BIG - # endif - --# if _CALL_ELF != 2 --# define ARCH_SUPPORTS_OPD --# define STACK_FRAME_OVERHEAD 112 -+# if !defined(_CALL_ELF) || _CALL_ELF < 2 -+# define ARCH_SUPPORTS_OPD -+# define STACK_FRAME_OVERHEAD 112 - # ifndef EF_PPC64_ABI --# define EF_PPC64_ABI 3 -+# define EF_PPC64_ABI 3 - # endif --# else /* _CALL_ELF == 2 ABIv2 */ --# define STACK_FRAME_OVERHEAD 32 -+# elif _CALL_ELF == 2 /* ELFv2 ABI */ -+# define STACK_FRAME_OVERHEAD 32 -+# else -+# error Unsupported PowerPC64 ABI. - # endif /* CALL_ELF */ - - #else --#define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } --#define ARCH_ENDIAN_BIG -+# define STACK_FRAME_OVERHEAD 112 -+# define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } -+# define ARCH_ENDIAN_BIG - # ifndef EF_PPC64_ABI --# define EF_PPC64_ABI 3 -+# define EF_PPC64_ABI 3 - # endif - #endif /* __powerpc64__ */ - -+#ifdef _CALL_ELF -+enum { ppc64_call_elf_abi = _CALL_ELF }; -+#else -+enum { ppc64_call_elf_abi = 0 }; -+#endif -+ - #define ARCH_HAVE_SW_SINGLESTEP - #define ARCH_HAVE_ADD_PLT_ENTRY - #define ARCH_HAVE_ADD_FUNC_ENTRY -diff --git a/sysdeps/linux-gnu/ppc/fetch.c b/sysdeps/linux-gnu/ppc/fetch.c -index c9381c3..c6cbd71 100644 ---- a/sysdeps/linux-gnu/ppc/fetch.c -+++ b/sysdeps/linux-gnu/ppc/fetch.c -@@ -1,6 +1,6 @@ - /* - * This file is part of ltrace. -- * Copyright (C) 2012 Petr Machata, Red Hat Inc. -+ * Copyright (C) 2012, 2014 Petr Machata, Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "backend.h" - #include "fetch.h" -@@ -57,7 +58,7 @@ struct fetch_context { - arch_addr_t stack_pointer; - int greg; - int freg; -- int ret_struct; -+ bool ret_struct; - - union { - gregs32_t r32; -@@ -65,11 +66,29 @@ struct fetch_context { - } regs; - struct fpregs_t fpregs; - int vgreg; -- int struct_size; -- int struct_hfa_size; -- int struct_hfa_count; - }; - -+static bool -+is_eligible_hfa(struct arg_type_info *info, -+ struct arg_type_info **hfa_infop, size_t *hfa_countp) -+{ -+ size_t hfa_count; -+ struct arg_type_info *hfa_info = type_get_hfa_type(info, &hfa_count); -+ -+ if (hfa_info != NULL && hfa_count <= 8 -+ && (hfa_info->type == ARGTYPE_FLOAT -+ || hfa_info->type == ARGTYPE_DOUBLE)) { -+ -+ if (hfa_infop != NULL) -+ *hfa_infop = hfa_info; -+ if (hfa_countp != NULL) -+ *hfa_countp = hfa_count; -+ return true; -+ } -+ -+ return false; -+} -+ - static int - fetch_context_init(struct process *proc, struct fetch_context *context) - { -@@ -125,30 +144,37 @@ arch_fetch_arg_init(enum tof type, struct process *proc, - } - - context->vgreg = context->greg; -- context->struct_size = 0; -- context->struct_hfa_size = 0; -- context->struct_hfa_count = 0; - - /* Aggregates or unions of any length, and character strings - * of length longer than 8 bytes, will be returned in a - * storage buffer allocated by the caller. The caller will - * pass the address of this buffer as a hidden first argument - * in r3, causing the first explicit argument to be passed in -- * r4. */ -- context->ret_struct = ret_info->type == ARGTYPE_STRUCT; -- if (context->ret_struct) { --#if _CALL_ELF == 2 -- /* if R3 points to stack, parameters will be in R4. */ -- uint64_t pstack_end = ptrace(PTRACE_PEEKTEXT, proc->pid, -- proc->stack_pointer, 0); -- if (((arch_addr_t)context->regs.r64[3] > proc->stack_pointer) -- && (context->regs.r64[3] < pstack_end)) { -+ * r4. -+ */ -+ -+ context->ret_struct = false; -+ -+ if (ppc64_call_elf_abi == 2) { -+ /* With ELFv2 ABI, aggregates that consist -+ * (recursively) only of members of the same -+ * floating-point or vector type, are passed in a -+ * series of floating-point resp. vector registers. -+ * Additionally, when returning any aggregate of up to -+ * 16 bytes, general-purpose registers are used. */ -+ -+ if (ret_info->type == ARGTYPE_STRUCT -+ && ! is_eligible_hfa(ret_info, NULL, NULL) -+ && type_sizeof(proc, ret_info) > 16) { -+ -+ context->ret_struct = true; - context->greg++; - context->stack_pointer += 8; - } --#else -+ -+ } else if (ret_info->type == ARGTYPE_STRUCT) { -+ context->ret_struct = true; - context->greg++; --#endif - } - - return context; -@@ -176,17 +202,16 @@ allocate_stack_slot(struct fetch_context *ctx, struct process *proc, - - size_t a = type_alignof(proc, info); - size_t off = 0; -- if (proc->e_machine == EM_PPC && a < 4) -- a = 4; --#if _CALL_ELF == 2 -- else if (proc->e_machine == EM_PPC64 && sz == 4 && is_hfa_type) -+ if (proc->e_machine == EM_PPC && a < 4) { - a = 4; -- else -- a = 8; --#else -- else if (proc->e_machine == EM_PPC64 && a < 8) --#endif -+ } else if (ppc64_call_elf_abi == 2) { -+ if (proc->e_machine == EM_PPC64 && sz == 4 && is_hfa_type) { -+ a = 4; -+ } else -+ a = 8; -+ } else if (proc->e_machine == EM_PPC64 && a < 8) { - a = 8; -+ } - - /* XXX Remove the two double casts when arch_addr_t - * becomes integral type. */ -@@ -259,18 +284,19 @@ allocate_gpr(struct fetch_context *ctx, struct process *proc, - if (sz == (size_t)-1) - return -1; - assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); --#if _CALL_ELF == 2 -- /* Consume the stack slot corresponding to this arg. */ -- if ((sz + off) >= 8) -- ctx->greg++; - -- if (is_hfa_type) -- ctx->stack_pointer += sz; -- else -- ctx->stack_pointer += 8; --#else -- ctx->greg++; --#endif -+ if (ppc64_call_elf_abi == 2) { -+ /* Consume the stack slot corresponding to this arg. */ -+ if ((sz + off) >= 8) -+ ctx->greg++; -+ -+ if (is_hfa_type) -+ ctx->stack_pointer += sz; -+ else -+ ctx->stack_pointer += 8; -+ } else { -+ ctx->greg++; -+ } - - if (valuep == NULL) - return 0; -@@ -326,7 +352,6 @@ allocate_float(struct fetch_context *ctx, struct process *proc, - return allocate_stack_slot(ctx, proc, info, valuep, is_hfa_type); - } - --#if _CALL_ELF == 2 - static int - allocate_hfa(struct fetch_context *ctx, struct process *proc, - struct arg_type_info *info, struct value *valuep, -@@ -336,27 +361,27 @@ allocate_hfa(struct fetch_context *ctx, struct process *proc, - if (sz == (size_t)-1) - return -1; - -- ctx->struct_hfa_size += sz; -- - /* There are two changes regarding structure return types: -- * * heterogeneous float/vector structs are returned -- * in (multiple) FP/vector registers, -- * instead of via implicit reference. -- * * small structs (up to 16 bytes) are return -- * in one or two GPRs, instead of via implicit reference. -+ * * heterogeneous float/vector structs are returned in -+ * (multiple) FP/vector registers, instead of via implicit -+ * reference. -+ * * small structs (up to 16 bytes) are return in one or two -+ * GPRs, instead of via implicit reference. - * - * Other structures (larger than 16 bytes, not heterogeneous) - * are still returned via implicit reference (i.e. a pointer - * to memory where to return the struct being passed in r3). -- * Of course, whether or not an implicit reference pointer -- * is present will shift the remaining arguments, -- * so you need to get this right for ELFv2 in order -- * to get the arguments correct. -+ * Of course, whether or not an implicit reference pointer is -+ * present will shift the remaining arguments, so you need to -+ * get this right for ELFv2 in order to get the arguments -+ * correct. -+ * - * If an actual parameter is known to correspond to an HFA - * formal parameter, each element is passed in the next - * available floating-point argument register starting at fp1 - * until the fp13. The remaining elements of the aggregate are -- * passed on the stack. */ -+ * passed on the stack. -+ */ - size_t slot_off = 0; - - unsigned char *buf = value_reserve(valuep, sz); -@@ -366,26 +391,17 @@ allocate_hfa(struct fetch_context *ctx, struct process *proc, - struct arg_type_info *hfa_info = type_get_simple(hfa_type); - size_t hfa_sz = type_sizeof(proc, hfa_info); - -- if (hfa_count > 8) -- ctx->struct_hfa_count += hfa_count; -- - while (hfa_count > 0 && ctx->freg <= 13) { -- int rc; - struct value tmp; -- - value_init(&tmp, proc, NULL, hfa_info, 0); -+ int rc = allocate_float(ctx, proc, hfa_info, -+ &tmp, slot_off, true); -+ if (rc == 0) -+ memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); -+ value_destroy(&tmp); - -- /* Hetereogeneous struct - get value on GPR or stack. */ -- if (((hfa_type == ARGTYPE_FLOAT -- || hfa_type == ARGTYPE_DOUBLE) -- && hfa_count <= 8)) -- rc = allocate_float(ctx, proc, hfa_info, &tmp, -- slot_off, true); -- else -- rc = allocate_gpr(ctx, proc, hfa_info, &tmp, -- slot_off, true); -- -- memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); -+ if (rc < 0) -+ return -1; - - slot_off += hfa_sz; - buf += hfa_sz; -@@ -394,17 +410,13 @@ allocate_hfa(struct fetch_context *ctx, struct process *proc, - slot_off = 0; - ctx->vgreg++; - } -- -- value_destroy(&tmp); -- if (rc < 0) -- return -1; - } - if (hfa_count == 0) - return 0; - - /* if no remaining FP, GPR corresponding to slot is used -- * Mostly it is in part of r10. */ -- if (ctx->struct_hfa_size <= 64 && ctx->vgreg == 10) { -+ * Mostly it is in part of r10. */ -+ if (ctx->vgreg == 10) { - while (ctx->vgreg <= 10) { - struct value tmp; - value_init(&tmp, proc, NULL, hfa_info, 0); -@@ -428,11 +440,8 @@ allocate_hfa(struct fetch_context *ctx, struct process *proc, - } - } - -- if (hfa_count == 0) -- return 0; -- - /* Remaining values are on stack */ -- while (hfa_count) { -+ while (hfa_count > 0) { - struct value tmp; - value_init(&tmp, proc, NULL, hfa_info, 0); - -@@ -444,7 +453,6 @@ allocate_hfa(struct fetch_context *ctx, struct process *proc, - } - return 0; - } --#endif - - static int - allocate_argument(struct fetch_context *ctx, struct process *proc, -@@ -459,24 +467,20 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - case ARGTYPE_FLOAT: - case ARGTYPE_DOUBLE: - return allocate_float(ctx, proc, info, valuep, -- 8 - type_sizeof(proc,info), false); -+ 8 - type_sizeof(proc,info), false); - - case ARGTYPE_STRUCT: - if (proc->e_machine == EM_PPC) { - if (value_pass_by_reference(valuep) < 0) - return -1; -- } else { --#if _CALL_ELF == 2 -+ } else if (ppc64_call_elf_abi == 2) { - struct arg_type_info *hfa_info; -- size_t hfa_size; -- hfa_info = type_get_hfa_type(info, &hfa_size); -- if (hfa_info != NULL ) { -- size_t sz = type_sizeof(proc, info); -- ctx->struct_size += sz; -+ size_t hfa_count; -+ if (is_eligible_hfa(info, &hfa_info, &hfa_count)) { - return allocate_hfa(ctx, proc, info, valuep, -- hfa_info->type, hfa_size); -+ hfa_info->type, hfa_count); - } --#endif -+ } else { - /* PPC64: Fixed size aggregates and unions passed by - * value are mapped to as many doublewords of the - * parameter save area as the value uses in memory. -@@ -510,9 +514,6 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - if (sz == (size_t)-1) - return -1; - -- if (ctx->ret_struct) -- ctx->struct_size += sz; -- - size_t slots = (sz + width - 1) / width; /* Round up. */ - unsigned char *buf = value_reserve(valuep, slots * width); - if (buf == NULL) -@@ -605,19 +606,7 @@ arch_fetch_retval(struct fetch_context *ctx, enum tof type, - if (fetch_context_init(proc, ctx) < 0) - return -1; - --#if _CALL_ELF == 2 -- void *ptr = (void *)(ctx->regs.r64[1]+32); -- uint64_t val = ptrace(PTRACE_PEEKTEXT, proc->pid, ptr, 0); -- -- if (ctx->ret_struct -- && ((ctx->struct_size > 64 -- || ctx->struct_hfa_count > 8 -- || (ctx->struct_hfa_size == 0 && ctx->struct_size > 56) -- || (ctx->regs.r64[3] == ctx->regs.r64[1]+32) -- || (ctx->regs.r64[3] == val )))) { --#else - if (ctx->ret_struct) { --#endif - assert(info->type == ARGTYPE_STRUCT); - - uint64_t addr = read_gpr(ctx, proc, 3); diff --git a/ltrace-0.7.91-ppc64le-support.patch b/ltrace-0.7.91-ppc64le-support.patch deleted file mode 100644 index e2d8daa..0000000 --- a/ltrace-0.7.91-ppc64le-support.patch +++ /dev/null @@ -1,786 +0,0 @@ -From eea4ad2cce289753aaa35b4e0258a76d8f8f367c Mon Sep 17 00:00:00 2001 -From: Thierry Fauck -Date: Tue, 13 May 2014 07:48:24 -0400 -Subject: [PATCH] Support for powerpc64 arch ppc64el - -Signed-off-by: Thierry Fauck - - Add support for ppc64le proc and ELF ABIv2. - Provides support for irelative and wchar ---- - ltrace-elf.c | 2 +- - ltrace-elf.h | 1 + - sysdeps/linux-gnu/ppc/arch.h | 35 ++++- - sysdeps/linux-gnu/ppc/fetch.c | 244 +++++++++++++++++++++++++++++--- - sysdeps/linux-gnu/ppc/plt.c | 98 ++++++++++++-- - sysdeps/linux-gnu/ppc/trace.c | 10 ++ - testsuite/ltrace.main/system_calls.exp | 2 +- - 7 files changed, 356 insertions(+), 36 deletions(-) - -diff --git a/ltrace-elf.c b/ltrace-elf.c -index 8997518..f638342 100644 ---- a/ltrace-elf.c -+++ b/ltrace-elf.c -@@ -859,7 +859,7 @@ populate_plt(struct process *proc, const char *filename, - return 0; - } - --static void -+void - delete_symbol_chain(struct library_symbol *libsym) - { - while (libsym != NULL) { -diff --git a/ltrace-elf.h b/ltrace-elf.h -index db4ffe9..4a824c4 100644 ---- a/ltrace-elf.h -+++ b/ltrace-elf.h -@@ -166,6 +166,7 @@ int elf_read_next_uleb128(Elf_Data *data, GElf_Xword *offset, uint64_t *retp); - /* Return whether there's AMOUNT more bytes after OFFSET in DATA. */ - int elf_can_read_next(Elf_Data *data, GElf_Xword offset, GElf_Xword amount); - -+void delete_symbol_chain(struct library_symbol *); - #if __WORDSIZE == 32 - #define PRI_ELF_ADDR PRIx32 - #define GELF_ADDR_CAST(x) (void *)(uint32_t)(x) -diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h -index bf9b5dc..7918a13 100644 ---- a/sysdeps/linux-gnu/ppc/arch.h -+++ b/sysdeps/linux-gnu/ppc/arch.h -@@ -23,8 +23,8 @@ - #define LTRACE_PPC_ARCH_H - - #include -+#include - --#define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } - #define BREAKPOINT_LENGTH 4 - #define DECR_PC_AFTER_BREAK 0 - -@@ -34,8 +34,33 @@ - #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target. - #define LT_ELFCLASS2 ELFCLASS64 - #define LT_ELF_MACHINE2 EM_PPC64 --#define ARCH_SUPPORTS_OPD --#endif -+ -+# ifdef __LITTLE_ENDIAN__ -+# define BREAKPOINT_VALUE { 0x08, 0x00, 0xe0, 0x7f } -+# define ARCH_ENDIAN_LITTLE -+# else -+# define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } -+# define ARCH_SUPPORTS_OPD -+# define ARCH_ENDIAN_BIG -+# endif -+ -+# if _CALL_ELF != 2 -+# define ARCH_SUPPORTS_OPD -+# define STACK_FRAME_OVERHEAD 112 -+# ifndef EF_PPC64_ABI -+# define EF_PPC64_ABI 3 -+# endif -+# else /* _CALL_ELF == 2 ABIv2 */ -+# define STACK_FRAME_OVERHEAD 32 -+# endif /* CALL_ELF */ -+ -+#else -+#define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } -+#define ARCH_ENDIAN_BIG -+# ifndef EF_PPC64_ABI -+# define EF_PPC64_ABI 3 -+# endif -+#endif /* __powerpc64__ */ - - #define ARCH_HAVE_SW_SINGLESTEP - #define ARCH_HAVE_ADD_PLT_ENTRY -@@ -43,7 +68,6 @@ - #define ARCH_HAVE_TRANSLATE_ADDRESS - #define ARCH_HAVE_DYNLINK_DONE - #define ARCH_HAVE_FETCH_ARG --#define ARCH_ENDIAN_BIG - #define ARCH_HAVE_SIZEOF - #define ARCH_HAVE_ALIGNOF - -@@ -56,7 +80,8 @@ struct arch_ltelf_data { - Elf_Data *opd_data; - GElf_Addr opd_base; - GElf_Xword opd_size; -- int secure_plt; -+ bool secure_plt : 1; -+ bool elfv2_abi : 1; - - Elf_Data *reladyn; - size_t reladyn_count; -diff --git a/sysdeps/linux-gnu/ppc/fetch.c b/sysdeps/linux-gnu/ppc/fetch.c -index ed38336..c9381c3 100644 ---- a/sysdeps/linux-gnu/ppc/fetch.c -+++ b/sysdeps/linux-gnu/ppc/fetch.c -@@ -30,9 +30,11 @@ - #include "ptrace.h" - #include "proc.h" - #include "value.h" -+#include "ltrace-elf.h" - - static int allocate_gpr(struct fetch_context *ctx, struct process *proc, -- struct arg_type_info *info, struct value *valuep); -+ struct arg_type_info *info, struct value *valuep, -+ size_t off, bool is_hfa_type); - - /* Floating point registers have the same width on 32-bit as well as - * 64-bit PPC, but presents a different API depending on -@@ -62,7 +64,10 @@ struct fetch_context { - gregs64_t r64; - } regs; - struct fpregs_t fpregs; -- -+ int vgreg; -+ int struct_size; -+ int struct_hfa_size; -+ int struct_hfa_count; - }; - - static int -@@ -74,7 +79,8 @@ fetch_context_init(struct process *proc, struct fetch_context *context) - if (proc->e_machine == EM_PPC) - context->stack_pointer = proc->stack_pointer + 8; - else -- context->stack_pointer = proc->stack_pointer + 112; -+ context->stack_pointer = proc->stack_pointer -+ + STACK_FRAME_OVERHEAD; - - /* When ltrace is 64-bit, we might use PTRACE_GETREGS to - * obtain 64-bit as well as 32-bit registers. But if we do it -@@ -118,6 +124,11 @@ arch_fetch_arg_init(enum tof type, struct process *proc, - return NULL; - } - -+ context->vgreg = context->greg; -+ context->struct_size = 0; -+ context->struct_hfa_size = 0; -+ context->struct_hfa_count = 0; -+ - /* Aggregates or unions of any length, and character strings - * of length longer than 8 bytes, will be returned in a - * storage buffer allocated by the caller. The caller will -@@ -125,8 +136,20 @@ arch_fetch_arg_init(enum tof type, struct process *proc, - * in r3, causing the first explicit argument to be passed in - * r4. */ - context->ret_struct = ret_info->type == ARGTYPE_STRUCT; -- if (context->ret_struct) -+ if (context->ret_struct) { -+#if _CALL_ELF == 2 -+ /* if R3 points to stack, parameters will be in R4. */ -+ uint64_t pstack_end = ptrace(PTRACE_PEEKTEXT, proc->pid, -+ proc->stack_pointer, 0); -+ if (((arch_addr_t)context->regs.r64[3] > proc->stack_pointer) -+ && (context->regs.r64[3] < pstack_end)) { -+ context->greg++; -+ context->stack_pointer += 8; -+ } -+#else - context->greg++; -+#endif -+ } - - return context; - } -@@ -144,7 +167,8 @@ arch_fetch_arg_clone(struct process *proc, - - static int - allocate_stack_slot(struct fetch_context *ctx, struct process *proc, -- struct arg_type_info *info, struct value *valuep) -+ struct arg_type_info *info, struct value *valuep, -+ bool is_hfa_type) - { - size_t sz = type_sizeof(proc, info); - if (sz == (size_t)-1) -@@ -154,7 +178,14 @@ allocate_stack_slot(struct fetch_context *ctx, struct process *proc, - size_t off = 0; - if (proc->e_machine == EM_PPC && a < 4) - a = 4; -+#if _CALL_ELF == 2 -+ else if (proc->e_machine == EM_PPC64 && sz == 4 && is_hfa_type) -+ a = 4; -+ else -+ a = 8; -+#else - else if (proc->e_machine == EM_PPC64 && a < 8) -+#endif - a = 8; - - /* XXX Remove the two double casts when arch_addr_t -@@ -164,7 +195,7 @@ allocate_stack_slot(struct fetch_context *ctx, struct process *proc, - - if (valuep != NULL) - value_in_inferior(valuep, ctx->stack_pointer + off); -- ctx->stack_pointer += sz; -+ ctx->stack_pointer += a; - - return 0; - } -@@ -216,19 +247,34 @@ align_small_int(unsigned char *buf, size_t w, size_t sz) - - static int - allocate_gpr(struct fetch_context *ctx, struct process *proc, -- struct arg_type_info *info, struct value *valuep) -+ struct arg_type_info *info, struct value *valuep, -+ size_t off, bool is_hfa_type) - { - if (ctx->greg > 10) -- return allocate_stack_slot(ctx, proc, info, valuep); -+ return allocate_stack_slot(ctx, proc, info, valuep, is_hfa_type); - -- int reg_num = ctx->greg++; -- if (valuep == NULL) -- return 0; -+ int reg_num = ctx->greg; - - size_t sz = type_sizeof(proc, info); - if (sz == (size_t)-1) - return -1; - assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); -+#if _CALL_ELF == 2 -+ /* Consume the stack slot corresponding to this arg. */ -+ if ((sz + off) >= 8) -+ ctx->greg++; -+ -+ if (is_hfa_type) -+ ctx->stack_pointer += sz; -+ else -+ ctx->stack_pointer += 8; -+#else -+ ctx->greg++; -+#endif -+ -+ if (valuep == NULL) -+ return 0; -+ - if (value_reserve(valuep, sz) == NULL) - return -1; - -@@ -240,13 +286,14 @@ allocate_gpr(struct fetch_context *ctx, struct process *proc, - u.i64 = read_gpr(ctx, proc, reg_num); - if (proc->e_machine == EM_PPC) - align_small_int(u.buf, 8, sz); -- memcpy(value_get_raw_data(valuep), u.buf, sz); -+ memcpy(value_get_raw_data(valuep), u.buf + off, sz); - return 0; - } - - static int - allocate_float(struct fetch_context *ctx, struct process *proc, -- struct arg_type_info *info, struct value *valuep) -+ struct arg_type_info *info, struct value *valuep, -+ size_t off, bool is_hfa_type) - { - int pool = proc->e_machine == EM_PPC64 ? 13 : 8; - if (ctx->freg <= pool) { -@@ -257,8 +304,12 @@ allocate_float(struct fetch_context *ctx, struct process *proc, - } u = { .d = ctx->fpregs.fpregs[ctx->freg] }; - - ctx->freg++; -+ -+ if (!is_hfa_type) -+ ctx->vgreg++; -+ - if (proc->e_machine == EM_PPC64) -- allocate_gpr(ctx, proc, info, NULL); -+ allocate_gpr(ctx, proc, info, NULL, off, is_hfa_type); - - size_t sz = sizeof(double); - if (info->type == ARGTYPE_FLOAT) { -@@ -272,8 +323,128 @@ allocate_float(struct fetch_context *ctx, struct process *proc, - memcpy(value_get_raw_data(valuep), u.buf, sz); - return 0; - } -- return allocate_stack_slot(ctx, proc, info, valuep); -+ return allocate_stack_slot(ctx, proc, info, valuep, is_hfa_type); -+} -+ -+#if _CALL_ELF == 2 -+static int -+allocate_hfa(struct fetch_context *ctx, struct process *proc, -+ struct arg_type_info *info, struct value *valuep, -+ enum arg_type hfa_type, size_t hfa_count) -+{ -+ size_t sz = type_sizeof(proc, info); -+ if (sz == (size_t)-1) -+ return -1; -+ -+ ctx->struct_hfa_size += sz; -+ -+ /* There are two changes regarding structure return types: -+ * * heterogeneous float/vector structs are returned -+ * in (multiple) FP/vector registers, -+ * instead of via implicit reference. -+ * * small structs (up to 16 bytes) are return -+ * in one or two GPRs, instead of via implicit reference. -+ * -+ * Other structures (larger than 16 bytes, not heterogeneous) -+ * are still returned via implicit reference (i.e. a pointer -+ * to memory where to return the struct being passed in r3). -+ * Of course, whether or not an implicit reference pointer -+ * is present will shift the remaining arguments, -+ * so you need to get this right for ELFv2 in order -+ * to get the arguments correct. -+ * If an actual parameter is known to correspond to an HFA -+ * formal parameter, each element is passed in the next -+ * available floating-point argument register starting at fp1 -+ * until the fp13. The remaining elements of the aggregate are -+ * passed on the stack. */ -+ size_t slot_off = 0; -+ -+ unsigned char *buf = value_reserve(valuep, sz); -+ if (buf == NULL) -+ return -1; -+ -+ struct arg_type_info *hfa_info = type_get_simple(hfa_type); -+ size_t hfa_sz = type_sizeof(proc, hfa_info); -+ -+ if (hfa_count > 8) -+ ctx->struct_hfa_count += hfa_count; -+ -+ while (hfa_count > 0 && ctx->freg <= 13) { -+ int rc; -+ struct value tmp; -+ -+ value_init(&tmp, proc, NULL, hfa_info, 0); -+ -+ /* Hetereogeneous struct - get value on GPR or stack. */ -+ if (((hfa_type == ARGTYPE_FLOAT -+ || hfa_type == ARGTYPE_DOUBLE) -+ && hfa_count <= 8)) -+ rc = allocate_float(ctx, proc, hfa_info, &tmp, -+ slot_off, true); -+ else -+ rc = allocate_gpr(ctx, proc, hfa_info, &tmp, -+ slot_off, true); -+ -+ memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); -+ -+ slot_off += hfa_sz; -+ buf += hfa_sz; -+ hfa_count--; -+ if (slot_off == 8) { -+ slot_off = 0; -+ ctx->vgreg++; -+ } -+ -+ value_destroy(&tmp); -+ if (rc < 0) -+ return -1; -+ } -+ if (hfa_count == 0) -+ return 0; -+ -+ /* if no remaining FP, GPR corresponding to slot is used -+ * Mostly it is in part of r10. */ -+ if (ctx->struct_hfa_size <= 64 && ctx->vgreg == 10) { -+ while (ctx->vgreg <= 10) { -+ struct value tmp; -+ value_init(&tmp, proc, NULL, hfa_info, 0); -+ union { -+ uint64_t i64; -+ unsigned char buf[0]; -+ } u; -+ -+ u.i64 = read_gpr(ctx, proc, ctx->vgreg); -+ -+ memcpy(buf, u.buf + slot_off, hfa_sz); -+ slot_off += hfa_sz; -+ buf += hfa_sz; -+ hfa_count--; -+ ctx->stack_pointer += hfa_sz; -+ if (slot_off >= 8 ) { -+ slot_off = 0; -+ ctx->vgreg++; -+ } -+ value_destroy(&tmp); -+ } -+ } -+ -+ if (hfa_count == 0) -+ return 0; -+ -+ /* Remaining values are on stack */ -+ while (hfa_count) { -+ struct value tmp; -+ value_init(&tmp, proc, NULL, hfa_info, 0); -+ -+ value_in_inferior(&tmp, ctx->stack_pointer); -+ memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); -+ ctx->stack_pointer += hfa_sz; -+ buf += hfa_sz; -+ hfa_count--; -+ } -+ return 0; - } -+#endif - - static int - allocate_argument(struct fetch_context *ctx, struct process *proc, -@@ -287,13 +458,25 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - - case ARGTYPE_FLOAT: - case ARGTYPE_DOUBLE: -- return allocate_float(ctx, proc, info, valuep); -+ return allocate_float(ctx, proc, info, valuep, -+ 8 - type_sizeof(proc,info), false); - - case ARGTYPE_STRUCT: - if (proc->e_machine == EM_PPC) { - if (value_pass_by_reference(valuep) < 0) - return -1; - } else { -+#if _CALL_ELF == 2 -+ struct arg_type_info *hfa_info; -+ size_t hfa_size; -+ hfa_info = type_get_hfa_type(info, &hfa_size); -+ if (hfa_info != NULL ) { -+ size_t sz = type_sizeof(proc, info); -+ ctx->struct_size += sz; -+ return allocate_hfa(ctx, proc, info, valuep, -+ hfa_info->type, hfa_size); -+ } -+#endif - /* PPC64: Fixed size aggregates and unions passed by - * value are mapped to as many doublewords of the - * parameter save area as the value uses in memory. -@@ -326,6 +509,10 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - size_t sz = type_sizeof(proc, valuep->type); - if (sz == (size_t)-1) - return -1; -+ -+ if (ctx->ret_struct) -+ ctx->struct_size += sz; -+ - size_t slots = (sz + width - 1) / width; /* Round up. */ - unsigned char *buf = value_reserve(valuep, slots * width); - if (buf == NULL) -@@ -346,9 +533,11 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - struct arg_type_info *fp_info - = type_get_fp_equivalent(valuep->type); - if (fp_info != NULL) -- rc = allocate_float(ctx, proc, fp_info, &val); -+ rc = allocate_float(ctx, proc, fp_info, &val, -+ 8-type_sizeof(proc,info), false); - else -- rc = allocate_gpr(ctx, proc, long_info, &val); -+ rc = allocate_gpr(ctx, proc, long_info, &val, -+ 0, false); - - if (rc >= 0) { - memcpy(ptr, value_get_data(&val, NULL), width); -@@ -363,6 +552,7 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - return rc; - } - -+#ifndef __LITTLE_ENDIAN__ - /* Small values need post-processing. */ - if (sz < width) { - switch (info->type) { -@@ -394,6 +584,7 @@ allocate_argument(struct fetch_context *ctx, struct process *proc, - break; - } - } -+#endif - - return 0; - } -@@ -411,7 +602,22 @@ arch_fetch_retval(struct fetch_context *ctx, enum tof type, - struct process *proc, struct arg_type_info *info, - struct value *valuep) - { -+ if (fetch_context_init(proc, ctx) < 0) -+ return -1; -+ -+#if _CALL_ELF == 2 -+ void *ptr = (void *)(ctx->regs.r64[1]+32); -+ uint64_t val = ptrace(PTRACE_PEEKTEXT, proc->pid, ptr, 0); -+ -+ if (ctx->ret_struct -+ && ((ctx->struct_size > 64 -+ || ctx->struct_hfa_count > 8 -+ || (ctx->struct_hfa_size == 0 && ctx->struct_size > 56) -+ || (ctx->regs.r64[3] == ctx->regs.r64[1]+32) -+ || (ctx->regs.r64[3] == val )))) { -+#else - if (ctx->ret_struct) { -+#endif - assert(info->type == ARGTYPE_STRUCT); - - uint64_t addr = read_gpr(ctx, proc, 3); -@@ -424,8 +630,6 @@ arch_fetch_retval(struct fetch_context *ctx, enum tof type, - return 0; - } - -- if (fetch_context_init(proc, ctx) < 0) -- return -1; - return allocate_argument(ctx, proc, info, valuep); - } - -diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c -index 332daa8..45ed7fb 100644 ---- a/sysdeps/linux-gnu/ppc/plt.c -+++ b/sysdeps/linux-gnu/ppc/plt.c -@@ -136,7 +136,11 @@ - */ - - #define PPC_PLT_STUB_SIZE 16 --#define PPC64_PLT_STUB_SIZE 8 //xxx -+#if _CALL_ELF != 2 -+#define PPC64_PLT_STUB_SIZE 8 -+#else -+#define PPC64_PLT_STUB_SIZE 4 -+#endif - - static inline int - host_powerpc64() -@@ -186,8 +190,13 @@ ppc32_delayed_symbol(struct library_symbol *libsym) - if ((insn1 & BRANCH_MASK) == B_INSN - || ((insn2 & BRANCH_MASK) == B_INSN - /* XXX double cast */ -+#ifdef __LITTLE_ENDIAN__ -+ && (ppc_branch_dest(libsym->enter_addr + 4, insn1) -+ == (arch_addr_t) (long) libsym->lib->arch.pltgot_addr))) -+#else - && (ppc_branch_dest(libsym->enter_addr + 4, insn2) - == (arch_addr_t) (long) libsym->lib->arch.pltgot_addr))) -+#endif - { - mark_as_resolved(libsym, libsym->arch.resolved_value); - } -@@ -206,7 +215,7 @@ arch_dynlink_done(struct process *proc) - "couldn't read PLT value for %s(%p): %s\n", - libsym->name, libsym->enter_addr, - strerror(errno)); -- return; -+ return; - } - - if (proc->e_machine == EM_PPC) -@@ -227,8 +236,14 @@ reloc_is_irelative(int machine, GElf_Rela *rela) - { - bool irelative = false; - if (machine == EM_PPC64) { --#ifdef R_PPC64_JMP_IREL -+#ifdef __LITTLE_ENDIAN__ -+# ifdef R_PPC64_IRELATIVE -+ irelative = GELF_R_TYPE(rela->r_info) == R_PPC64_IRELATIVE; -+# endif -+#else -+# ifdef R_PPC64_JMP_IREL - irelative = GELF_R_TYPE(rela->r_info) == R_PPC64_JMP_IREL; -+# endif - #endif - } else { - assert(machine == EM_PPC); -@@ -285,6 +300,7 @@ arch_translate_address_dyn(struct process *proc, - arch_addr_t addr, arch_addr_t *ret) - { - if (proc->e_machine == EM_PPC64) { -+#if _CALL_ELF != 2 - uint64_t value; - if (proc_read_64(proc, addr, &value) < 0) { - fprintf(stderr, -@@ -296,6 +312,7 @@ arch_translate_address_dyn(struct process *proc, - * arch_addr_t becomes integral type. */ - *ret = (arch_addr_t)(uintptr_t)value; - return 0; -+#endif - } - - *ret = addr; -@@ -306,7 +323,8 @@ int - arch_translate_address(struct ltelf *lte, - arch_addr_t addr, arch_addr_t *ret) - { -- if (lte->ehdr.e_machine == EM_PPC64) { -+ if (lte->ehdr.e_machine == EM_PPC64 -+ && !lte->arch.elfv2_abi) { - /* XXX The double cast should be removed when - * arch_addr_t becomes integral type. */ - GElf_Xword offset -@@ -430,7 +448,16 @@ reloc_copy_if_irelative(GElf_Rela *rela, void *data) - int - arch_elf_init(struct ltelf *lte, struct library *lib) - { -+ -+ /* Check for ABIv2 in ELF header processor specific flag. */ -+#ifndef EF_PPC64_ABI -+ assert (! (lte->ehdr.e_flags & 3 ) == 2) -+#else -+ lte->arch.elfv2_abi=((lte->ehdr.e_flags & EF_PPC64_ABI) == 2) ; -+#endif -+ - if (lte->ehdr.e_machine == EM_PPC64 -+ && !lte->arch.elfv2_abi - && load_opd_data(lte, lib) < 0) - return -1; - -@@ -599,7 +626,7 @@ read_plt_slot_value(struct process *proc, GElf_Addr addr, GElf_Addr *valp) - uint64_t l; - /* XXX double cast. */ - if (proc_read_64(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) { -- fprintf(stderr, "ptrace .plt slot value @%#" PRIx64": %s\n", -+ debug(DEBUG_EVENT, "ptrace .plt slot value @%#" PRIx64": %s", - addr, strerror(errno)); - return -1; - } -@@ -616,7 +643,7 @@ unresolve_plt_slot(struct process *proc, GElf_Addr addr, GElf_Addr value) - * pointers intact. Hence the only adjustment that we need to - * do is to IP. */ - if (ptrace(PTRACE_POKETEXT, proc->pid, addr, value) < 0) { -- fprintf(stderr, "failed to unresolve .plt slot: %s\n", -+ debug(DEBUG_EVENT, "failed to unresolve .plt slot: %s", - strerror(errno)); - return -1; - } -@@ -629,9 +656,48 @@ arch_elf_add_func_entry(struct process *proc, struct ltelf *lte, - arch_addr_t addr, const char *name, - struct library_symbol **ret) - { -- if (lte->ehdr.e_machine != EM_PPC || lte->ehdr.e_type == ET_DYN) -+#ifndef PPC64_LOCAL_ENTRY_OFFSET -+ assert(! lte->arch.elfv2_abi); -+#else -+ /* With ABIv2 st_other field contains an offset. */ -+ if (lte->arch.elfv2_abi) -+ addr += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); -+#endif -+ -+ int st_info = GELF_ST_TYPE(sym->st_info); -+ -+ if ((lte->ehdr.e_machine != EM_PPC && sym->st_other == 0) -+ || lte->ehdr.e_type == ET_DYN -+ || (st_info == STT_FUNC && ! sym->st_other)) - return PLT_DEFAULT; - -+ if (st_info == STT_FUNC) { -+ /* Put the default symbol to the chain. -+ * The addr has already been updated with -+ * symbol offset */ -+ char *full_name = strdup(name); -+ if (full_name == NULL) { -+ fprintf(stderr, "couldn't copy name of %s: %s\n", -+ name, strerror(errno)); -+ free(full_name); -+ return PLT_FAIL; -+ } -+ struct library_symbol *libsym = malloc(sizeof *libsym); -+ if (libsym == NULL -+ || library_symbol_init(libsym, addr, full_name, 1, -+ LS_TOPLT_NONE) < 0) { -+ free(libsym); -+ delete_symbol_chain(libsym); -+ libsym = NULL; -+ fprintf(stderr, "Couldn't add symbol %s" -+ "for tracing.\n", name); -+ } -+ full_name = NULL; -+ libsym->next = *ret; -+ *ret = libsym; -+ return PLT_OK; -+ } -+ - bool ifunc = false; - #ifdef STT_GNU_IFUNC - ifunc = GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC; -@@ -761,9 +827,15 @@ arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, - assert(plt_slot_addr >= lte->plt_addr - || plt_slot_addr < lte->plt_addr + lte->plt_size); - -+ /* Should avoid to do read if dynamic linker hasn't run yet -+ * or allow -1 a valid return code. */ - GElf_Addr plt_slot_value; -- if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0) -- goto fail; -+ if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0) { -+ if (!lte->arch.elfv2_abi) -+ goto fail; -+ else -+ return PPC_PLT_UNRESOLVED; -+ } - - struct library_symbol *libsym = malloc(sizeof(*libsym)); - if (libsym == NULL) { -@@ -997,8 +1069,12 @@ ppc_plt_bp_continue(struct breakpoint *bp, struct process *proc) - return; - } - -+#if _CALL_ELF == 2 -+ continue_after_breakpoint(proc, bp); -+#else - jump_to_entry_point(proc, bp); - continue_process(proc->pid); -+#endif - return; - - case PPC64_PLT_STUB: -@@ -1123,7 +1199,11 @@ arch_library_symbol_init(struct library_symbol *libsym) - /* We set type explicitly in the code above, where we have the - * necessary context. This is for calls from ltrace-elf.c and - * such. */ -+#if _CALL_ELF == 2 -+ libsym->arch.type = PPC_PLT_UNRESOLVED; -+#else - libsym->arch.type = PPC_DEFAULT; -+#endif - return 0; - } - -diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c -index ee9a6b5..5aab538 100644 ---- a/sysdeps/linux-gnu/ppc/trace.c -+++ b/sysdeps/linux-gnu/ppc/trace.c -@@ -65,9 +65,15 @@ syscall_p(struct process *proc, int status, int *sysnum) - if (WIFSTOPPED(status) - && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { - long pc = (long)get_instruction_pointer(proc); -+#ifndef __LITTLE_ENDIAN__ - int insn = - (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(long), - 0); -+#else -+ int insn = -+ (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(int), -+ 0); -+#endif - - if (insn == SYSCALL_INSN) { - *sysnum = -diff -up ltrace-0.7.91/sysdeps/linux-gnu/ppc/trace.c\~ ltrace-0.7.91/sysdeps/linux-gnu/ppc/trace.c ---- ltrace-0.7.91/sysdeps/linux-gnu/ppc/trace.c~ 2014-08-08 14:05:58.000000000 +0200 -+++ ltrace-0.7.91/sysdeps/linux-gnu/ppc/trace.c 2014-08-08 14:07:55.000000000 +0200 -@@ -133,7 +133,11 @@ arch_sw_singlestep(struct process *proc, - return SWS_FAIL; - uint32_t insn; - #ifdef __powerpc64__ -+# ifdef __LITTLE_ENDIAN__ -+ insn = (uint32_t) l; -+# else - insn = l >> 32; -+# endif - #else - insn = l; - #endif -diff -up ltrace-0.7.91/configure\~ ltrace-0.7.91/configure ---- ltrace-0.7.91/configure~ 2014-08-08 14:09:12.000000000 +0200 -+++ ltrace-0.7.91/configure 2014-08-08 14:18:30.000000000 +0200 -@@ -2555,7 +2555,7 @@ case "${host_cpu}" in - arm*|sa110) HOST_CPU="arm" ;; - cris*) HOST_CPU="cris" ;; - mips*) HOST_CPU="mips" ;; -- powerpc|powerpc64) HOST_CPU="ppc" ;; -+ powerpc|powerpc64|powerpc64le) HOST_CPU="ppc" ;; - sun4u|sparc64) HOST_CPU="sparc" ;; - s390x) HOST_CPU="s390" ;; - i?86|x86_64) HOST_CPU="x86" ;; -@@ -12094,7 +12094,7 @@ if test x"$enable_libunwind" = xyes; the - arm*|sa110) UNWIND_ARCH="arm" ;; - i?86) UNWIND_ARCH="x86" ;; - powerpc) UNWIND_ARCH="ppc32" ;; -- powerpc64) UNWIND_ARCH="ppc64" ;; -+ powerpc64|powerpc64le) UNWIND_ARCH="ppc64" ;; - mips*) UNWIND_ARCH="mips" ;; - *) UNWIND_ARCH="${host_cpu}" ;; - esac