diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:34:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:34:56 +0900 |
commit | 517f5529d7008eba87b8b2fee5ec9ec0a5075f6e (patch) | |
tree | c71720a9b41309713c089478f921165bd2d63b25 /sysdeps/linux-gnu | |
parent | 689b9dbb8d7f88ab91e7741932ed000b6e49be9a (diff) | |
download | ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.tar.gz ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.tar.bz2 ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.zip |
Imported Upstream version 0.7.91upstream/0.7.91upstream
Diffstat (limited to 'sysdeps/linux-gnu')
78 files changed, 3894 insertions, 6840 deletions
diff --git a/sysdeps/linux-gnu/Makefile.am b/sysdeps/linux-gnu/Makefile.am index bfa67d6..ecee577 100644 --- a/sysdeps/linux-gnu/Makefile.am +++ b/sysdeps/linux-gnu/Makefile.am @@ -16,7 +16,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA -DIST_SUBDIRS = alpha arm cris ia64 m68k mipsel ppc s390 sparc x86 +DIST_SUBDIRS = alpha arm cris ia64 m68k metag mips ppc s390 sparc x86 SUBDIRS = \ $(HOST_CPU) @@ -24,11 +24,7 @@ SUBDIRS = \ noinst_LTLIBRARIES = \ ../libos.la -___libos_la_SOURCES = \ - events.c \ - trace.c \ - proc.c \ - breakpoint.c +___libos_la_SOURCES = events.c trace.c proc.c breakpoint.c hooks.c ___libos_la_LIBADD = \ libcpu.la diff --git a/sysdeps/linux-gnu/Makefile.in b/sysdeps/linux-gnu/Makefile.in deleted file mode 100644 index e00136b..0000000 --- a/sysdeps/linux-gnu/Makefile.in +++ /dev/null @@ -1,692 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010,2012 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu -DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libos_la_DEPENDENCIES = libcpu.la -am____libos_la_OBJECTS = events.lo trace.lo proc.lo breakpoint.lo -___libos_la_OBJECTS = $(am____libos_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libos_la_SOURCES) -DIST_SOURCES = $(___libos_la_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive -HEADERS = $(noinst_HEADERS) -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -DIST_SUBDIRS = alpha arm cris ia64 m68k mipsel ppc s390 sparc x86 -SUBDIRS = \ - $(HOST_CPU) - -noinst_LTLIBRARIES = \ - ../libos.la - -___libos_la_SOURCES = \ - events.c \ - trace.c \ - proc.c \ - breakpoint.c - -___libos_la_LIBADD = \ - libcpu.la - -noinst_HEADERS = arch_syscallent.h signalent1.h syscallent1.h trace.h \ - trace-defs.h events.h os.h - -EXTRA_DIST = \ - arch_mksyscallent \ - mksignalent \ - mksyscallent \ - mksyscallent_s390 - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-recursive - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libos.la: $(___libos_la_OBJECTS) $(___libos_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libos_la_OBJECTS) $(___libos_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-recursive - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-recursive - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic clean-libtool \ - clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/alpha/Makefile.in b/sysdeps/linux-gnu/alpha/Makefile.in deleted file mode 100644 index 99a5886..0000000 --- a/sysdeps/linux-gnu/alpha/Makefile.in +++ /dev/null @@ -1,528 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/alpha -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/alpha/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/alpha/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c index c7ce9fe..1185363 100644 --- a/sysdeps/linux-gnu/alpha/plt.c +++ b/sysdeps/linux-gnu/alpha/plt.c @@ -23,11 +23,13 @@ #include "common.h" GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) +{ return lte->plt_addr + ndx * 12 + 32; } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/alpha/regs.c b/sysdeps/linux-gnu/alpha/regs.c index 0b46afd..9ccd8f2 100644 --- a/sysdeps/linux-gnu/alpha/regs.c +++ b/sysdeps/linux-gnu/alpha/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2004,2008,2009 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -36,26 +37,25 @@ #endif void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 64 /* REG_PC */ , 0); } void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, void *addr) +{ ptrace(PTRACE_POKEUSER, proc->pid, 64 /* REG_PC */ , addr); } void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 30 /* REG_FP */ , 0); } void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 26 /* RA */ , 0); } - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, 26 /* RA */ , addr); -} diff --git a/sysdeps/linux-gnu/alpha/trace.c b/sysdeps/linux-gnu/alpha/trace.c index a7c5e59..c6f7494 100644 --- a/sysdeps/linux-gnu/alpha/trace.c +++ b/sysdeps/linux-gnu/alpha/trace.c @@ -40,13 +40,15 @@ #endif void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ } /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { char *ip = get_instruction_pointer(proc) - 4; @@ -69,7 +71,8 @@ syscall_p(Process *proc, int status, int *sysnum) { } long -gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +gimme_arg(enum tof type, struct process *proc, int arg_num, + struct arg_type_info *info) { if (arg_num == -1) { /* return value */ return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0); diff --git a/sysdeps/linux-gnu/arm/Makefile.am b/sysdeps/linux-gnu/arm/Makefile.am index 385424c..2c180c6 100644 --- a/sysdeps/linux-gnu/arm/Makefile.am +++ b/sysdeps/linux-gnu/arm/Makefile.am @@ -1,4 +1,5 @@ # This file is part of ltrace. +# Copyright (C) 2013 Petr Machata, Red Hat Inc. # Copyright (C) 2010 Marc Kleine-Budde, Pengutronix # # This program is free software; you can redistribute it and/or @@ -16,21 +17,11 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA -noinst_LTLIBRARIES = \ - ../libcpu.la +noinst_LTLIBRARIES = ../libcpu.la -___libcpu_la_SOURCES = \ - breakpoint.c \ - plt.c \ - regs.c \ - trace.c +___libcpu_la_SOURCES = breakpoint.c fetch.c plt.c regs.c trace.c -noinst_HEADERS = \ - arch.h \ - arch_syscallent.h \ - ptrace.h \ - signalent.h \ - syscallent.h +noinst_HEADERS = arch.h arch_syscallent.h ptrace.h regs.h signalent.h \ + syscallent.h -MAINTAINERCLEANFILES = \ - Makefile.in +MAINTAINERCLEANFILES = Makefile.in diff --git a/sysdeps/linux-gnu/arm/Makefile.in b/sysdeps/linux-gnu/arm/Makefile.in deleted file mode 100644 index ad6475d..0000000 --- a/sysdeps/linux-gnu/arm/Makefile.in +++ /dev/null @@ -1,531 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/arm -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = breakpoint.lo plt.lo regs.lo trace.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - breakpoint.c \ - plt.c \ - regs.c \ - trace.c - -noinst_HEADERS = \ - arch.h \ - arch_syscallent.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/arm/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/arm/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h index 291443a..58a7fdf 100644 --- a/sysdeps/linux-gnu/arm/arch.h +++ b/sysdeps/linux-gnu/arm/arch.h @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 1998,2004,2008 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -18,6 +19,9 @@ * 02110-1301 USA */ +#ifndef LTRACE_ARM_ARCH_H +#define LTRACE_ARM_ARCH_H + #define ARCH_HAVE_ENABLE_BREAKPOINT 1 #define ARCH_HAVE_DISABLE_BREAKPOINT 1 @@ -31,7 +35,24 @@ #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_ARM +#define ARCH_HAVE_SW_SINGLESTEP +#define ARCH_HAVE_FETCH_ARG +#define ARCH_HAVE_FETCH_PACK +#define ARCH_HAVE_SIZEOF +#define ARCH_HAVE_ALIGNOF #define ARCH_HAVE_BREAKPOINT_DATA struct arch_breakpoint_data { int thumb_mode; }; + +#define ARCH_HAVE_LTELF_DATA +struct arch_ltelf_data { + /* We have this only for the hooks. */ +}; + +#define ARCH_HAVE_LIBRARY_DATA +struct arch_library_data { + unsigned int hardfp:1; +}; + +#endif /* LTRACE_ARM_ARCH_H */ diff --git a/sysdeps/linux-gnu/arm/breakpoint.c b/sysdeps/linux-gnu/arm/breakpoint.c index 5748401..fcd43a7 100644 --- a/sysdeps/linux-gnu/arm/breakpoint.c +++ b/sysdeps/linux-gnu/arm/breakpoint.c @@ -92,16 +92,13 @@ arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) } int -arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp) +arch_breakpoint_init(struct process *proc, struct breakpoint *sbp) { - /* XXX That uintptr_t cast is there temporarily until - * arch_addr_t becomes integral type. */ - int thumb_mode = ((uintptr_t)sbp->addr) & 1; - if (thumb_mode) - sbp->addr = (void *)((uintptr_t)sbp->addr & ~1); - sbp->arch.thumb_mode = thumb_mode | proc->thumb_mode; - /* XXX This doesn't seem like it belongs here. */ - proc->thumb_mode = 0; + /* XXX double cast */ + sbp->arch.thumb_mode = ((uintptr_t)sbp->addr) & 1; + if (sbp->arch.thumb_mode) + /* XXX double cast */ + sbp->addr = (arch_addr_t)((uintptr_t)sbp->addr & ~1); return 0; } diff --git a/sysdeps/linux-gnu/arm/fetch.c b/sysdeps/linux-gnu/arm/fetch.c new file mode 100644 index 0000000..5081d78 --- /dev/null +++ b/sysdeps/linux-gnu/arm/fetch.c @@ -0,0 +1,531 @@ +/* + * 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 + */ + +#include <sys/ptrace.h> +#include <asm/ptrace.h> +#include <assert.h> +#include <elf.h> +#include <libelf.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#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. */ + NUM_VFP_REGS = 8, +}; + +struct fetch_context { + struct pt_regs regs; + + struct { + union { + double d[32]; + float s[64]; + }; + uint32_t fpscr; + } fpregs; + + /* VFP register allocation. ALLOC.S tracks whether the + * corresponding FPREGS.S register is taken, ALLOC.D the same + * for FPREGS.D. We only track 8 (16) registers, because + * that's what the ABI uses for parameter passing. */ + union { + int16_t d[NUM_VFP_REGS]; + int8_t s[NUM_VFP_REGS * 2]; + } alloc; + + unsigned ncrn; + arch_addr_t sp; + arch_addr_t nsaa; + arch_addr_t ret_struct; + + bool hardfp:1; + bool in_varargs:1; +}; + +static int +fetch_register_banks(struct process *proc, struct fetch_context *context) +{ + if (ptrace(PTRACE_GETREGS, proc->pid, NULL, &context->regs) == -1) + return -1; + + if (context->hardfp + && ptrace(PTRACE_GETVFPREGS, proc->pid, + NULL, &context->fpregs) == -1) + return -1; + + context->ncrn = 0; + context->nsaa = context->sp = get_stack_pointer(proc); + memset(&context->alloc, 0, sizeof(context->alloc)); + + return 0; +} + +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)); + + { + struct process *mainp = proc; + while (mainp->libraries == NULL && mainp->parent != NULL) + mainp = mainp->parent; + context->hardfp = mainp->libraries->arch.hardfp; + } + + if (context == NULL + || fetch_register_banks(proc, context) < 0) { + free(context); + return NULL; + } + + if (ret_info->type == ARGTYPE_STRUCT + || ret_info->type == ARGTYPE_ARRAY) { + size_t sz = type_sizeof(proc, ret_info); + assert(sz != (size_t)-1); + if (sz > 4) { + /* XXX double cast */ + context->ret_struct + = (arch_addr_t)context->regs.uregs[0]; + context->ncrn++; + } + } + + return context; +} + +struct fetch_context * +arch_fetch_arg_clone(struct process *proc, + struct fetch_context *context) +{ + struct fetch_context *clone = malloc(sizeof(*context)); + if (clone == NULL) + return NULL; + *clone = *context; + return clone; +} + +/* 0 is success, 1 is failure, negative value is an error. */ +static int +pass_in_vfp(struct fetch_context *ctx, struct process *proc, + enum arg_type type, size_t count, struct value *valuep) +{ + assert(type == ARGTYPE_FLOAT || type == ARGTYPE_DOUBLE); + unsigned max = type == ARGTYPE_DOUBLE ? NUM_VFP_REGS : 2 * NUM_VFP_REGS; + if (count > max) + return 1; + + size_t i; + size_t j; + for (i = 0; i < max; ++i) { + for (j = i; j < i + count; ++j) + if ((type == ARGTYPE_DOUBLE && ctx->alloc.d[j] != 0) + || (type == ARGTYPE_FLOAT && ctx->alloc.s[j] != 0)) + goto next; + + /* Found COUNT consecutive unallocated registers at I. */ + const size_t sz = (type == ARGTYPE_FLOAT ? 4 : 8) * count; + unsigned char *data = value_reserve(valuep, sz); + if (data == NULL) + return -1; + + for (j = i; j < i + count; ++j) + if (type == ARGTYPE_DOUBLE) + ctx->alloc.d[j] = -1; + else + ctx->alloc.s[j] = -1; + + if (type == ARGTYPE_DOUBLE) + memcpy(data, ctx->fpregs.d + i, sz); + else + memcpy(data, ctx->fpregs.s + i, sz); + + return 0; + + next: + continue; + } + return 1; +} + +/* 0 is success, 1 is failure, negative value is an error. */ +static int +consider_vfp(struct fetch_context *ctx, struct process *proc, + struct arg_type_info *info, struct value *valuep) +{ + struct arg_type_info *float_info = NULL; + size_t hfa_size = 1; + if (info->type == ARGTYPE_FLOAT || info->type == ARGTYPE_DOUBLE) + float_info = info; + else + float_info = type_get_hfa_type(info, &hfa_size); + + if (float_info != NULL && hfa_size <= 4) + return pass_in_vfp(ctx, proc, float_info->type, + hfa_size, valuep); + return 1; +} + +int +arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct process *proc, + struct arg_type_info *info, struct value *valuep) +{ + const size_t sz = type_sizeof(proc, info); + assert(sz != (size_t)-1); + + if (ctx->hardfp && !ctx->in_varargs) { + int rc; + if ((rc = consider_vfp(ctx, proc, info, valuep)) != 1) + return rc; + } + + /* IHI0042E_aapcs: If the argument requires double-word + * alignment (8-byte), the NCRN is rounded up to the next even + * register number. */ + const size_t al = type_alignof(proc, info); + assert(al != (size_t)-1); + if (al == 8) + ctx->ncrn = ((ctx->ncrn + 1) / 2) * 2; + + /* If the size in words of the argument is not more than r4 + * minus NCRN, the argument is copied into core registers, + * starting at the NCRN. */ + /* If the NCRN is less than r4 and the NSAA is equal to the + * SP, the argument is split between core registers and the + * stack. */ + + const size_t words = (sz + 3) / 4; + if (ctx->ncrn < 4 && ctx->nsaa == ctx->sp) { + unsigned char *data = value_reserve(valuep, words * 4); + if (data == NULL) + return -1; + size_t i; + for (i = 0; i < words && ctx->ncrn < 4; ++i) { + memcpy(data, &ctx->regs.uregs[ctx->ncrn++], 4); + data += 4; + } + const size_t rest = (words - i) * 4; + if (rest > 0) { + umovebytes(proc, ctx->nsaa, data, rest); + ctx->nsaa += rest; + } + return 0; + } + + assert(ctx->ncrn == 4); + + /* If the argument required double-word alignment (8-byte), + * then the NSAA is rounded up to the next double-word + * address. */ + if (al == 8) + /* XXX double cast. */ + ctx->nsaa = (arch_addr_t)((((uintptr_t)ctx->nsaa + 7) / 8) * 8); + else + ctx->nsaa = (arch_addr_t)((((uintptr_t)ctx->nsaa + 3) / 4) * 4); + + value_in_inferior(valuep, ctx->nsaa); + ctx->nsaa += sz; + + return 0; +} + +int +arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (fetch_register_banks(proc, ctx) < 0) + return -1; + + if (ctx->hardfp && !ctx->in_varargs) { + int rc; + if ((rc = consider_vfp(ctx, proc, info, valuep)) != 1) + return rc; + } + + size_t sz = type_sizeof(proc, info); + assert(sz != (size_t)-1); + + switch (info->type) { + unsigned char *data; + + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + if (ctx->hardfp && !ctx->in_varargs) { + unsigned char *data = value_reserve(valuep, sz); + if (data == NULL) + return -1; + memmove(data, &ctx->fpregs, sz); + return 0; + } + goto pass_in_registers; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + if (sz > 4) { + value_in_inferior(valuep, ctx->ret_struct); + return 0; + } + /* Fall through. */ + + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + pass_in_registers: + if ((data = value_reserve(valuep, sz)) == NULL) + return -1; + memmove(data, ctx->regs.uregs, sz); + return 0; + } + assert(info->type != info->type); + abort(); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + free(context); +} + +int +arch_fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor) +{ + if (ppflavor == PARAM_PACK_VARARGS) + context->in_varargs = true; + return 0; +} + +void +arch_fetch_param_pack_end(struct fetch_context *context) +{ + context->in_varargs = false; +} diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c index 1b97705..d1bf7ca 100644 --- a/sysdeps/linux-gnu/arm/plt.c +++ b/sysdeps/linux-gnu/arm/plt.c @@ -43,6 +43,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c index 484de7f..e9e825e 100644 --- a/sysdeps/linux-gnu/arm/regs.c +++ b/sysdeps/linux-gnu/arm/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes * Copyright (C) 2009 Juan Cespedes * @@ -24,9 +25,11 @@ #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> +#include <errno.h> #include "proc.h" #include "common.h" +#include "regs.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR @@ -36,45 +39,119 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -#define off_pc ((void *)60) -#define off_lr ((void *)56) -#define off_sp ((void *)52) +int +arm_get_register(struct process *proc, enum arm_register reg, uint32_t *lp) +{ + errno = 0; + long l = ptrace(PTRACE_PEEKUSER, proc->pid, (void *)(reg * 4L), 0); + if (l == -1 && errno != 0) + return -1; + *lp = (uint32_t)l; + return 0; +} -void * -get_instruction_pointer(Process *proc) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); +int +arm_set_register(struct process *proc, enum arm_register reg, uint32_t lp) +{ + return ptrace(PTRACE_PEEKUSER, proc->pid, + (void *)(reg * 4L), (void *)lp); } -void -set_instruction_pointer(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr); +int +arm_get_register_offpc(struct process *proc, enum arm_register reg, + uint32_t *lp) +{ + if (arm_get_register(proc, reg, lp) < 0) + return -1; + if (reg == ARM_REG_PC) + *lp += 8; + return 0; } -void * -get_stack_pointer(Process *proc) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0); +int +arm_get_shifted_register(struct process *proc, uint32_t inst, int carry, + arch_addr_t pc_val, uint32_t *lp) +{ + enum arm_register rm = BITS(inst, 0, 3); + unsigned long shifttype = BITS(inst, 5, 6); + + uint32_t shift; + if (BIT(inst, 4)) { + if (arm_get_register_offpc(proc, BITS(inst, 8, 11), &shift) < 0) + return -1; + shift &= 0xff; + } else { + shift = BITS(inst, 7, 11); + } + + uint32_t res; + if (rm == ARM_REG_PC) + /* xxx double cast */ + res = (uintptr_t)pc_val + (BIT(inst, 4) ? 12 : 8); + else if (arm_get_register(proc, rm, &res) < 0) + return -1; + + switch (shifttype) { + case 0: /* LSL */ + res = shift >= 32 ? 0 : res << shift; + break; + + case 1: /* LSR */ + res = shift >= 32 ? 0 : res >> shift; + break; + + case 2: /* ASR */ + if (shift >= 32) + shift = 31; + res = ((res & 0x80000000L) + ? ~((~res) >> shift) : res >> shift); + break; + + case 3: /* ROR/RRX */ + shift &= 31; + if (shift == 0) + res = (res >> 1) | (carry ? 0x80000000L : 0); + else + res = (res >> shift) | (res << (32 - shift)); + break; + } + + *lp = res & 0xffffffff; + return 0; } -/* really, this is given the *stack_pointer expecting - * a CISC architecture; in our case, we don't need that */ -void * -get_return_addr(Process *proc, void *stack_pointer) { - long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0); - - /* Remember & unset the thumb mode bit. XXX This is really a - * bit of a hack, as we assume that the following - * insert_breakpoint call will be related to this address. - * This interface should really be get_return_breakpoint, or - * maybe install_return_breakpoint. */ - proc->thumb_mode = addr & 1; - if (proc->thumb_mode) - addr &= ~1; - - return (void *)addr; +static arch_addr_t +get_register_nocheck(struct process *proc, enum arm_register r) +{ + uint32_t reg; + if (arm_get_register(proc, r, ®) < 0) + /* XXX double cast. */ + return (arch_addr_t)-1; + /* XXX double cast. */ + return (arch_addr_t)(uintptr_t)reg; +} + +arch_addr_t +get_instruction_pointer(struct process *proc) +{ + return get_register_nocheck(proc, ARM_REG_PC); } void -set_return_addr(Process *proc, void *addr) { - long iaddr = (int)addr | proc->thumb_mode; - ptrace(PTRACE_POKEUSER, proc->pid, off_lr, (void *)iaddr); +set_instruction_pointer(struct process *proc, arch_addr_t addr) +{ + /* XXX double cast. */ + arm_set_register(proc, ARM_REG_PC, (uint32_t)addr); +} + +void * +get_stack_pointer(struct process *proc) +{ + return get_register_nocheck(proc, ARM_REG_SP); +} + +arch_addr_t +get_return_addr(struct process *proc, arch_addr_t stack_pointer) +{ + return get_register_nocheck(proc, ARM_REG_LR); } diff --git a/sysdeps/linux-gnu/arm/regs.h b/sysdeps/linux-gnu/arm/regs.h new file mode 100644 index 0000000..f9a5a86 --- /dev/null +++ b/sysdeps/linux-gnu/arm/regs.h @@ -0,0 +1,47 @@ +/* + * 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 + */ + +#define SUBMASK(x) ((1L << ((x) + 1)) - 1) +#define BIT(obj,st) (((obj) >> (st)) & 1) +#define BITS(obj,st,fn) (((obj) >> (st)) & SUBMASK((fn) - (st))) +#define SBITS(obj,st,fn) \ + ((long) (BITS(obj,st,fn) | ((long) BIT(obj,fn) * ~ SUBMASK(fn - st)))) + +enum arm_register { + ARM_REG_R7 = 7, + ARM_REG_IP = 12, + ARM_REG_SP = 13, + ARM_REG_LR = 14, + ARM_REG_PC = 15, + ARM_REG_CPSR = 16, +}; + +/* Write value of register REG to *LP. Return 0 on success or a + * negative value on failure. */ +int arm_get_register(struct process *proc, enum arm_register reg, uint32_t *lp); + +/* Same as above, but if REG==ARM_REG_PC, it returns the value +8. */ +int arm_get_register_offpc(struct process *proc, enum arm_register reg, + uint32_t *lp); + +/* Same as arm_get_register, but shift is performed depending on + * instruction INST. */ +int arm_get_shifted_register(struct process *proc, uint32_t inst, int carry, + arch_addr_t pc, uint32_t *lp); diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c index c528cfb..5e51e91 100644 --- a/sysdeps/linux-gnu/arm/trace.c +++ b/sysdeps/linux-gnu/arm/trace.c @@ -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) 1998,2004,2008,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -29,10 +29,13 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> -#include "proc.h" +#include "bits.h" #include "common.h" +#include "proc.h" #include "output.h" #include "ptrace.h" +#include "regs.h" +#include "type.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR @@ -42,13 +45,9 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -#define off_r0 ((void *)0) -#define off_r7 ((void *)28) -#define off_ip ((void *)48) -#define off_pc ((void *)60) - void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ proc_archdep *a; if (!proc->arch_ptr) @@ -63,21 +62,28 @@ get_arch_dep(Process *proc) { * -1 on error. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { - /* get the user's pc (plus 8) */ - unsigned pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); + uint32_t pc, ip; + if (arm_get_register(proc, ARM_REG_PC, &pc) < 0 + || arm_get_register(proc, ARM_REG_IP, &ip) < 0) + return -1; + pc = pc - 4; + /* fetch the SWI instruction */ unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid, (void *)pc, 0); - int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0); if (insn == 0xef000000 || insn == 0x0f000000 || (insn & 0xffff0000) == 0xdf000000) { /* EABI syscall */ - *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0); + uint32_t r7; + if (arm_get_register(proc, ARM_REG_R7, &r7) < 0) + return -1; + *sysnum = r7; } else if ((insn & 0xfff00000) == 0xef900000) { /* old ABI syscall */ *sysnum = insn & 0xfffff; @@ -103,46 +109,605 @@ syscall_p(Process *proc, int status, int *sysnum) { return 0; } -long -gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +static arch_addr_t +arm_branch_dest(const arch_addr_t pc, const uint32_t insn) { - proc_archdep *a = (proc_archdep *) proc->arch_ptr; + /* Bits 0-23 are signed immediate value. */ + return pc + ((((insn & 0xffffff) ^ 0x800000) - 0x800000) << 2) + 8; +} - if (arg_num == -1) { /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0); - } +/* Addresses for calling Thumb functions have the bit 0 set. + Here are some macros to test, set, or clear bit 0 of addresses. */ +/* XXX double cast */ +#define IS_THUMB_ADDR(addr) ((uintptr_t)(addr) & 1) +#define MAKE_THUMB_ADDR(addr) ((arch_addr_t)((uintptr_t)(addr) | 1)) +#define UNMAKE_THUMB_ADDR(addr) ((arch_addr_t)((uintptr_t)(addr) & ~1)) - /* deal with the ARM calling conventions */ - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - if (arg_num < 4) { - if (a->valid && type == LT_TOF_FUNCTION) - return a->regs.uregs[arg_num]; - if (a->valid && type == LT_TOF_FUNCTIONR) - return a->func_arg[arg_num]; - return ptrace(PTRACE_PEEKUSER, proc->pid, - (void *)(4 * arg_num), 0); - } else { - return ptrace(PTRACE_PEEKDATA, proc->pid, - proc->stack_pointer + 4 * (arg_num - 4), - 0); +enum { + COND_ALWAYS = 0xe, + COND_NV = 0xf, + FLAG_C = 0x20000000, +}; + +static int +arm_get_next_pcs(struct process *proc, + const arch_addr_t pc, arch_addr_t next_pcs[2]) +{ + uint32_t this_instr; + uint32_t status; + if (proc_read_32(proc, pc, &this_instr) < 0 + || arm_get_register(proc, ARM_REG_CPSR, &status) < 0) + return -1; + + /* In theory, we sometimes don't even need to add any + * breakpoints at all. If the conditional bits of the + * instruction indicate that it should not be taken, then we + * can just skip it altogether without bothering. We could + * also emulate the instruction under the breakpoint. + * + * Here, we make it as simple as possible (though We Accept + * Patches). */ + int nr = 0; + + /* ARM can branch either relatively by using a branch + * instruction, or absolutely, by doing arbitrary arithmetic + * with PC as the destination. */ + const unsigned cond = BITS(this_instr, 28, 31); + const unsigned opcode = BITS(this_instr, 24, 27); + + if (cond == COND_NV) + switch (opcode) { + arch_addr_t addr; + case 0xa: + case 0xb: + /* Branch with Link and change to Thumb. */ + /* XXX double cast. */ + addr = (arch_addr_t) + ((uint32_t)arm_branch_dest(pc, this_instr) + | (((this_instr >> 24) & 0x1) << 1)); + next_pcs[nr++] = MAKE_THUMB_ADDR(addr); + break; } - } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { - if (arg_num < 5) { - if (a->valid && type == LT_TOF_SYSCALL) - return a->regs.uregs[arg_num]; - if (a->valid && type == LT_TOF_SYSCALLR) - return a->sysc_arg[arg_num]; - return ptrace(PTRACE_PEEKUSER, proc->pid, - (void *)(4 * arg_num), 0); - } else { - return ptrace(PTRACE_PEEKDATA, proc->pid, - proc->stack_pointer + 4 * (arg_num - 5), - 0); + else + switch (opcode) { + uint32_t operand1, operand2, result = 0; + case 0x0: + case 0x1: /* data processing */ + case 0x2: + case 0x3: + if (BITS(this_instr, 12, 15) != ARM_REG_PC) + break; + + if (BITS(this_instr, 22, 25) == 0 + && BITS(this_instr, 4, 7) == 9) { /* multiply */ + invalid: + fprintf(stderr, + "Invalid update to pc in instruction.\n"); + break; + } + + /* BX <reg>, BLX <reg> */ + if (BITS(this_instr, 4, 27) == 0x12fff1 + || BITS(this_instr, 4, 27) == 0x12fff3) { + enum arm_register reg = BITS(this_instr, 0, 3); + /* XXX double cast: no need to go + * through tmp. */ + uint32_t tmp; + if (arm_get_register_offpc(proc, reg, &tmp) < 0) + return -1; + next_pcs[nr++] = (arch_addr_t)tmp; + return 0; + } + + /* Multiply into PC. */ + if (arm_get_register_offpc + (proc, BITS(this_instr, 16, 19), &operand1) < 0) + return -1; + + int c = (status & FLAG_C) ? 1 : 0; + if (BIT(this_instr, 25)) { + uint32_t immval = BITS(this_instr, 0, 7); + uint32_t rotate = 2 * BITS(this_instr, 8, 11); + operand2 = (((immval >> rotate) + | (immval << (32 - rotate))) + & 0xffffffff); + } else { + /* operand 2 is a shifted register. */ + if (arm_get_shifted_register + (proc, this_instr, c, pc, &operand2) < 0) + return -1; + } + + switch (BITS(this_instr, 21, 24)) { + case 0x0: /*and */ + result = operand1 & operand2; + break; + + case 0x1: /*eor */ + result = operand1 ^ operand2; + break; + + case 0x2: /*sub */ + result = operand1 - operand2; + break; + + case 0x3: /*rsb */ + result = operand2 - operand1; + break; + + case 0x4: /*add */ + result = operand1 + operand2; + break; + + case 0x5: /*adc */ + result = operand1 + operand2 + c; + break; + + case 0x6: /*sbc */ + result = operand1 - operand2 + c; + break; + + case 0x7: /*rsc */ + result = operand2 - operand1 + c; + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: /* tst, teq, cmp, cmn */ + /* Only take the default branch. */ + result = 0; + break; + + case 0xc: /*orr */ + result = operand1 | operand2; + break; + + case 0xd: /*mov */ + /* Always step into a function. */ + result = operand2; + break; + + case 0xe: /*bic */ + result = operand1 & ~operand2; + break; + + case 0xf: /*mvn */ + result = ~operand2; + break; + } + + /* XXX double cast */ + next_pcs[nr++] = (arch_addr_t)result; + break; + + case 0x4: + case 0x5: /* data transfer */ + case 0x6: + case 0x7: + /* Ignore if insn isn't load or Rn not PC. */ + if (!BIT(this_instr, 20) + || BITS(this_instr, 12, 15) != ARM_REG_PC) + break; + + if (BIT(this_instr, 22)) + goto invalid; + + /* byte write to PC */ + uint32_t base; + if (arm_get_register_offpc + (proc, BITS(this_instr, 16, 19), &base) < 0) + return -1; + + if (BIT(this_instr, 24)) { + /* pre-indexed */ + int c = (status & FLAG_C) ? 1 : 0; + uint32_t offset; + if (BIT(this_instr, 25)) { + if (arm_get_shifted_register + (proc, this_instr, c, + pc, &offset) < 0) + return -1; + } else { + offset = BITS(this_instr, 0, 11); + } + + if (BIT(this_instr, 23)) + base += offset; + else + base -= offset; + } + + /* XXX two double casts. */ + uint32_t next; + if (proc_read_32(proc, (arch_addr_t)base, &next) < 0) + return -1; + next_pcs[nr++] = (arch_addr_t)next; + break; + + case 0x8: + case 0x9: /* block transfer */ + if (!BIT(this_instr, 20)) + break; + /* LDM */ + if (BIT(this_instr, 15)) { + /* Loading pc. */ + int offset = 0; + enum arm_register rn = BITS(this_instr, 16, 19); + uint32_t rn_val; + if (arm_get_register(proc, rn, &rn_val) < 0) + return -1; + + int pre = BIT(this_instr, 24); + if (BIT(this_instr, 23)) { + /* Bit U = up. */ + unsigned reglist + = BITS(this_instr, 0, 14); + offset = bitcount(reglist) * 4; + if (pre) + offset += 4; + } else if (pre) { + offset = -4; + } + + /* XXX double cast. */ + arch_addr_t addr + = (arch_addr_t)(rn_val + offset); + uint32_t next; + if (proc_read_32(proc, addr, &next) < 0) + return -1; + next_pcs[nr++] = (arch_addr_t)next; + } + break; + + case 0xb: /* branch & link */ + case 0xa: /* branch */ + next_pcs[nr++] = arm_branch_dest(pc, this_instr); + break; + + case 0xc: + case 0xd: + case 0xe: /* coproc ops */ + case 0xf: /* SWI */ + break; + } + + /* Otherwise take the next instruction. */ + if (cond != COND_ALWAYS || nr == 0) + next_pcs[nr++] = pc + 4; + return 0; +} + +/* Return the size in bytes of the complete Thumb instruction whose + * first halfword is INST1. */ + +static int +thumb_insn_size (unsigned short inst1) +{ + if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0) + return 4; + else + return 2; +} + +static int +thumb_get_next_pcs(struct process *proc, + const arch_addr_t pc, arch_addr_t next_pcs[2]) +{ + uint16_t inst1; + uint32_t status; + if (proc_read_16(proc, pc, &inst1) < 0 + || arm_get_register(proc, ARM_REG_CPSR, &status) < 0) + return -1; + + int nr = 0; + + /* We currently ignore Thumb-2 conditional execution support + * (the IT instruction). No branches are allowed in IT block, + * and it's not legal to jump in the middle of it, so unless + * we need to singlestep through large swaths of code, which + * we currently don't, we can ignore them. */ + + if ((inst1 & 0xff00) == 0xbd00) { /* pop {rlist, pc} */ + /* Fetch the saved PC from the stack. It's stored + * above all of the other registers. */ + const unsigned offset = bitcount(BITS(inst1, 0, 7)) * 4; + uint32_t sp; + uint32_t next; + /* XXX two double casts */ + if (arm_get_register(proc, ARM_REG_SP, &sp) < 0 + || proc_read_32(proc, (arch_addr_t)(sp + offset), + &next) < 0) + return -1; + next_pcs[nr++] = (arch_addr_t)next; + } else if ((inst1 & 0xf000) == 0xd000) { /* conditional branch */ + const unsigned long cond = BITS(inst1, 8, 11); + if (cond != 0x0f) { /* SWI */ + next_pcs[nr++] = pc + (SBITS(inst1, 0, 7) << 1); + if (cond == COND_ALWAYS) + return 0; + } + } else if ((inst1 & 0xf800) == 0xe000) { /* unconditional branch */ + next_pcs[nr++] = pc + (SBITS(inst1, 0, 10) << 1); + } else if (thumb_insn_size(inst1) == 4) { /* 32-bit instruction */ + unsigned short inst2; + if (proc_read_16(proc, pc + 2, &inst2) < 0) + return -1; + + if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000) { + /* Branches and miscellaneous control instructions. */ + + if ((inst2 & 0x1000) != 0 + || (inst2 & 0xd001) == 0xc000) { + /* B, BL, BLX. */ + + const int imm1 = SBITS(inst1, 0, 10); + const unsigned imm2 = BITS(inst2, 0, 10); + const unsigned j1 = BIT(inst2, 13); + const unsigned j2 = BIT(inst2, 11); + + int32_t offset + = ((imm1 << 12) + (imm2 << 1)); + offset ^= ((!j2) << 22) | ((!j1) << 23); + + /* XXX double cast */ + uint32_t next = (uint32_t)(pc + offset); + /* For BLX make sure to clear the low bits. */ + if (BIT(inst2, 12) == 0) + next = next & 0xfffffffc; + /* XXX double cast */ + next_pcs[nr++] = (arch_addr_t)next; + return 0; + } else if (inst1 == 0xf3de + && (inst2 & 0xff00) == 0x3f00) { + /* SUBS PC, LR, #imm8. */ + uint32_t next; + if (arm_get_register(proc, ARM_REG_LR, + &next) < 0) + return -1; + next -= inst2 & 0x00ff; + /* XXX double cast */ + next_pcs[nr++] = (arch_addr_t)next; + return 0; + } else if ((inst2 & 0xd000) == 0x8000 + && (inst1 & 0x0380) != 0x0380) { + /* Conditional branch. */ + const int sign = SBITS(inst1, 10, 10); + const unsigned imm1 = BITS(inst1, 0, 5); + const unsigned imm2 = BITS(inst2, 0, 10); + const unsigned j1 = BIT(inst2, 13); + const unsigned j2 = BIT(inst2, 11); + + int32_t offset = (sign << 20) + + (j2 << 19) + (j1 << 18); + offset += (imm1 << 12) + (imm2 << 1); + next_pcs[nr++] = pc + offset; + if (BITS(inst1, 6, 9) == COND_ALWAYS) + return 0; + } + } else if ((inst1 & 0xfe50) == 0xe810) { + int load_pc = 1; + int offset; + const enum arm_register rn = BITS(inst1, 0, 3); + + if (BIT(inst1, 7) && !BIT(inst1, 8)) { + /* LDMIA or POP */ + if (!BIT(inst2, 15)) + load_pc = 0; + offset = bitcount(inst2) * 4 - 4; + } else if (!BIT(inst1, 7) && BIT(inst1, 8)) { + /* LDMDB */ + if (!BIT(inst2, 15)) + load_pc = 0; + offset = -4; + } else if (BIT(inst1, 7) && BIT(inst1, 8)) { + /* RFEIA */ + offset = 0; + } else if (!BIT(inst1, 7) && !BIT(inst1, 8)) { + /* RFEDB */ + offset = -8; + } else { + load_pc = 0; + } + + if (load_pc) { + uint32_t addr; + if (arm_get_register(proc, rn, &addr) < 0) + return -1; + arch_addr_t a = (arch_addr_t)(addr + offset); + uint32_t next; + if (proc_read_32(proc, a, &next) < 0) + return -1; + /* XXX double cast */ + next_pcs[nr++] = (arch_addr_t)next; + } + } else if ((inst1 & 0xffef) == 0xea4f + && (inst2 & 0xfff0) == 0x0f00) { + /* MOV PC or MOVS PC. */ + const enum arm_register rn = BITS(inst2, 0, 3); + uint32_t next; + if (arm_get_register(proc, rn, &next) < 0) + return -1; + /* XXX double cast */ + next_pcs[nr++] = (arch_addr_t)next; + } else if ((inst1 & 0xff70) == 0xf850 + && (inst2 & 0xf000) == 0xf000) { + /* LDR PC. */ + const enum arm_register rn = BITS(inst1, 0, 3); + uint32_t base; + if (arm_get_register(proc, rn, &base) < 0) + return -1; + + int load_pc = 1; + if (rn == ARM_REG_PC) { + base = (base + 4) & ~(uint32_t)0x3; + if (BIT(inst1, 7)) + base += BITS(inst2, 0, 11); + else + base -= BITS(inst2, 0, 11); + } else if (BIT(inst1, 7)) { + base += BITS(inst2, 0, 11); + } else if (BIT(inst2, 11)) { + if (BIT(inst2, 10)) { + if (BIT(inst2, 9)) + base += BITS(inst2, 0, 7); + else + base -= BITS(inst2, 0, 7); + } + } else if ((inst2 & 0x0fc0) == 0x0000) { + const int shift = BITS(inst2, 4, 5); + const enum arm_register rm = BITS(inst2, 0, 3); + uint32_t v; + if (arm_get_register(proc, rm, &v) < 0) + return -1; + base += v << shift; + } else { + /* Reserved. */ + load_pc = 0; + } + + if (load_pc) { + /* xxx double casts */ + uint32_t next; + if (proc_read_32(proc, + (arch_addr_t)base, &next) < 0) + return -1; + next_pcs[nr++] = (arch_addr_t)next; + } + } else if ((inst1 & 0xfff0) == 0xe8d0 + && (inst2 & 0xfff0) == 0xf000) { + /* TBB. */ + const enum arm_register tbl_reg = BITS(inst1, 0, 3); + const enum arm_register off_reg = BITS(inst2, 0, 3); + + uint32_t table; + if (tbl_reg == ARM_REG_PC) + /* Regcache copy of PC isn't right yet. */ + /* XXX double cast */ + table = (uint32_t)pc + 4; + else if (arm_get_register(proc, tbl_reg, &table) < 0) + return -1; + + uint32_t offset; + if (arm_get_register(proc, off_reg, &offset) < 0) + return -1; + + table += offset; + uint8_t length; + /* XXX double cast */ + if (proc_read_8(proc, (arch_addr_t)table, &length) < 0) + return -1; + + next_pcs[nr++] = pc + 2 * length; + + } else if ((inst1 & 0xfff0) == 0xe8d0 + && (inst2 & 0xfff0) == 0xf010) { + /* TBH. */ + const enum arm_register tbl_reg = BITS(inst1, 0, 3); + const enum arm_register off_reg = BITS(inst2, 0, 3); + + uint32_t table; + if (tbl_reg == ARM_REG_PC) + /* Regcache copy of PC isn't right yet. */ + /* XXX double cast */ + table = (uint32_t)pc + 4; + else if (arm_get_register(proc, tbl_reg, &table) < 0) + return -1; + + uint32_t offset; + if (arm_get_register(proc, off_reg, &offset) < 0) + return -1; + + table += 2 * offset; + uint16_t length; + /* XXX double cast */ + if (proc_read_16(proc, (arch_addr_t)table, &length) < 0) + return -1; + + next_pcs[nr++] = pc + 2 * length; } - } else { - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); } + + /* Otherwise take the next instruction. */ + if (nr == 0) + next_pcs[nr++] = pc + thumb_insn_size(inst1); return 0; } + +enum sw_singlestep_status +arch_sw_singlestep(struct process *proc, struct breakpoint *sbp, + int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), + struct sw_singlestep_data *add_cb_data) +{ + const arch_addr_t pc = get_instruction_pointer(proc); + + uint32_t cpsr; + if (arm_get_register(proc, ARM_REG_CPSR, &cpsr) < 0) + return SWS_FAIL; + + const unsigned thumb_p = BIT(cpsr, 5); + arch_addr_t next_pcs[2] = {}; + if ((thumb_p ? &thumb_get_next_pcs + : &arm_get_next_pcs)(proc, pc, next_pcs) < 0) + return SWS_FAIL; + + int i; + for (i = 0; i < 2; ++i) { + /* XXX double cast. */ + arch_addr_t target + = (arch_addr_t)(((uintptr_t)next_pcs[i]) | thumb_p); + if (next_pcs[i] != 0 && add_cb(target, add_cb_data) < 0) + return SWS_FAIL; + } + + debug(1, "PTRACE_CONT"); + ptrace(PTRACE_CONT, proc->pid, 0, 0); + return SWS_OK; +} + +size_t +arch_type_sizeof(struct process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return 8; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; + + default: + assert(info->type != info->type); + abort(); + } +} + +size_t +arch_type_alignof(struct process *proc, struct arg_type_info *info) +{ + return arch_type_sizeof(proc, info); +} diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c index fe336b1..c28d745 100644 --- a/sysdeps/linux-gnu/breakpoint.c +++ b/sysdeps/linux-gnu/breakpoint.c @@ -79,7 +79,7 @@ arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp) #endif /* ARCH_HAVE_ENABLE_BREAKPOINT */ void -enable_breakpoint(Process *proc, struct breakpoint *sbp) +enable_breakpoint(struct process *proc, struct breakpoint *sbp) { debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, breakpoint_name(sbp)); @@ -127,7 +127,7 @@ arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) #endif /* ARCH_HAVE_DISABLE_BREAKPOINT */ void -disable_breakpoint(Process *proc, struct breakpoint *sbp) +disable_breakpoint(struct process *proc, struct breakpoint *sbp) { debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, breakpoint_name(sbp)); diff --git a/sysdeps/linux-gnu/cris/Makefile.in b/sysdeps/linux-gnu/cris/Makefile.in deleted file mode 100644 index c978410..0000000 --- a/sysdeps/linux-gnu/cris/Makefile.in +++ /dev/null @@ -1,528 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2012 Edgar E. Iglesias, Axis Communications -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/cris -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/cris/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/cris/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/cris/plt.c b/sysdeps/linux-gnu/cris/plt.c index 427ae93..fcc18d2 100644 --- a/sysdeps/linux-gnu/cris/plt.c +++ b/sysdeps/linux-gnu/cris/plt.c @@ -28,7 +28,7 @@ GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) return lte->plt_addr + 0x20 + (ndx * 26); } -void *sym2addr(Process *proc, struct library_symbol *sym) +void *sym2addr(struct process *proc, struct library_symbol *sym) { return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/cris/regs.c b/sysdeps/linux-gnu/cris/regs.c index 7028b9e..4cf1fbf 100644 --- a/sysdeps/linux-gnu/cris/regs.c +++ b/sysdeps/linux-gnu/cris/regs.c @@ -37,22 +37,22 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -void *get_instruction_pointer(Process *proc) +void *get_instruction_pointer(struct process *proc) { return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PPC, 0); } -void set_instruction_pointer(Process *proc, void *addr) +void set_instruction_pointer(struct process *proc, void *addr) { ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PPC, addr); } -void *get_stack_pointer(Process *proc) +void *get_stack_pointer(struct process *proc) { return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0); } -void *get_return_addr(Process *proc, void *stack_pointer) +void *get_return_addr(struct process *proc, void *stack_pointer) { return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_SRP, 0); } diff --git a/sysdeps/linux-gnu/cris/trace.c b/sysdeps/linux-gnu/cris/trace.c index 98cb7d8..7d8cca6 100644 --- a/sysdeps/linux-gnu/cris/trace.c +++ b/sysdeps/linux-gnu/cris/trace.c @@ -40,14 +40,14 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -void get_arch_dep(Process *proc) +void get_arch_dep(struct process *proc) { } /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ #define SYSCALL_INSN 0xe93d -int syscall_p(Process *proc, int status, int *sysnum) +int syscall_p(struct process *proc, int status, int *sysnum) { if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { @@ -71,7 +71,7 @@ int syscall_p(Process *proc, int status, int *sysnum) return 0; } -long gimme_arg(enum tof type, Process *proc, int arg_num, +long gimme_arg(enum tof type, struct process *proc, int arg_num, struct arg_type_info *info) { int pid = proc->pid; diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c index 077a656..51c2cae 100644 --- a/sysdeps/linux-gnu/events.c +++ b/sysdeps/linux-gnu/events.c @@ -48,7 +48,7 @@ static Event * delayed_events = NULL; static Event * end_delayed_events = NULL; static enum callback_status -first (Process * proc, void * data) +first(struct process *proc, void *data) { return CBS_STOP; } @@ -83,12 +83,12 @@ each_qd_event(enum ecb_status (*pred)(Event *, void *), void * data) Event * event; for (event = prev; event != NULL; ) { switch ((*pred)(event, data)) { - case ecb_cont: + case ECB_CONT: prev = event; event = event->next; continue; - case ecb_deque: + case ECB_DEQUE: debug(DEBUG_FUNCTION, "dequeuing event %d for %d", event->type, event->proc != NULL ? event->proc->pid : -1); @@ -106,7 +106,7 @@ each_qd_event(enum ecb_status (*pred)(Event *, void *), void * data) end_delayed_events = NULL; /* fall-through */ - case ecb_yield: + case ECB_YIELD: return event; } } @@ -120,9 +120,9 @@ event_process_not_reenabling(Event * event, void * data) if (event->proc == NULL || event->proc->leader == NULL || event->proc->leader->event_handler == NULL) - return ecb_deque; + return ECB_DEQUE; else - return ecb_cont; + return ECB_CONT; } static Event * @@ -188,7 +188,7 @@ next_event(void) * now) the pain of figuring this out all over again. * Petr Machata 2011-11-22. */ int i = 0; - for (; i < 100 && process_status(pid) != ps_tracing_stop; ++i) { + for (; i < 100 && process_status(pid) != PS_TRACING_STOP; ++i) { debug(2, "waiting for %d to stop", pid); usleep(10000); } @@ -197,9 +197,10 @@ next_event(void) debug(DEBUG_EVENT, "event: NEW: pid=%d", pid); return &event; } + get_arch_dep(event.proc); debug(3, "event from pid %u", pid); - Process *leader = event.proc->leader; + struct process *leader = event.proc->leader; /* The process should be stopped after the waitpid call. But * when the whole thread group is terminated, we see @@ -313,7 +314,7 @@ next_event(void) actually seen this on an Itanium machine on RHEL 5, I don't remember the exact kernel version anymore. ia64-sigill.s in the test suite tests this. Petr Machata 2011-06-08. */ - void * break_address + arch_addr_t break_address = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; if ((stop_signal == SIGSEGV || stop_signal == SIGILL) && leader != NULL @@ -341,13 +342,13 @@ static enum ecb_status event_for_proc(struct Event *event, void *data) { if (event->proc == data) - return ecb_deque; + return ECB_DEQUE; else - return ecb_cont; + return ECB_CONT; } void -delete_events_for(struct Process *proc) +delete_events_for(struct process *proc) { struct Event *event; while ((event = each_qd_event(&event_for_proc, proc)) != NULL) diff --git a/sysdeps/linux-gnu/events.h b/sysdeps/linux-gnu/events.h index 3802aff..51ef309 100644 --- a/sysdeps/linux-gnu/events.h +++ b/sysdeps/linux-gnu/events.h @@ -26,16 +26,16 @@ /* Declarations for event que functions. */ enum ecb_status { - ecb_cont, /* The iteration should continue. */ - ecb_yield, /* The iteration should stop, yielding this + ECB_CONT, /* The iteration should continue. */ + ECB_YIELD, /* The iteration should stop, yielding this * event. */ - ecb_deque, /* Like ecb_stop, but the event should be removed + ECB_DEQUE, /* Like ECB_STOP, but the event should be removed * from the queue. */ }; struct Event *each_qd_event(enum ecb_status (*cb)(struct Event *event, void *data), void *data); -void delete_events_for(struct Process * proc); +void delete_events_for(struct process *proc); void enque_event(struct Event *event); #endif /* SYSDEPS_LINUX_GNU_EVENTS_H */ diff --git a/sysdeps/linux-gnu/hooks.c b/sysdeps/linux-gnu/hooks.c new file mode 100644 index 0000000..1e375fb --- /dev/null +++ b/sysdeps/linux-gnu/hooks.c @@ -0,0 +1,212 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012, 2013 Petr Machata + * + * 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 + */ + +#define _POSIX_C_SOURCE 200809L +#include <sys/types.h> +#include <alloca.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "backend.h" +#include "dict.h" +#include "options.h" +#include "sysdep.h" +#include "vect.h" + +static char * +append(const char *str1, const char *str2) +{ + char *ret = malloc(strlen(str1) + strlen(str2) + 2); + if (ret == NULL) + return ret; + strcpy(stpcpy(ret, str1), str2); + return ret; +} + +static void +add_dir(struct vect *dirs, const char *str1, const char *str2) +{ + char *dir = append(str1, str2); + if (dir != NULL + && VECT_PUSHBACK(dirs, &dir) < 0) + fprintf(stderr, + "Couldn't store candidate config directory %s%s: %s.\n", + str1, str2, strerror(errno)); +} + +static enum callback_status +add_dir_component_cb(struct opt_F_t *entry, void *data) +{ + struct vect *dirs = data; + if (opt_F_get_kind(entry) == OPT_F_DIR) + add_dir(dirs, entry->pathname, "/ltrace"); + return CBS_CONT; +} + +static void +destroy_opt_F_cb(struct opt_F_t *entry, void *data) +{ + opt_F_destroy(entry); +} + +static char *g_home_dir = NULL; + +int +os_get_config_dirs(int private, const char ***retp) +{ + /* Vector of char *. Contains first pointers to local paths, + * then NULL, then pointers to system paths, then another + * NULL. SYS_START points to the beginning of the second + * part. */ + static struct vect dirs; + static ssize_t sys_start = 0; + +again: + if (sys_start != 0) { + if (sys_start == -1) + return -1; + + if (retp != NULL) { + if (private) + *retp = VECT_ELEMENT(&dirs, const char *, 0); + else + *retp = VECT_ELEMENT(&dirs, const char *, + (size_t)sys_start); + } + + return 0; + } + + VECT_INIT(&dirs, char *); + + char *home = getenv("HOME"); + if (home == NULL) { + struct passwd *pwd = getpwuid(getuid()); + if (pwd != NULL) + home = pwd->pw_dir; + } + + size_t home_len = home != NULL ? strlen(home) : 0; + + /* The values coming from getenv and getpwuid may not be + * persistent. */ + if (home != NULL) { + g_home_dir = strdup(home); + if (g_home_dir != NULL) { + home = g_home_dir; + } else { + char *tmp = alloca(home_len + 1); + strcpy(tmp, home); + home = tmp; + } + } + + char *xdg_home = getenv("XDG_CONFIG_HOME"); + if (xdg_home == NULL && home != NULL) { + xdg_home = alloca(home_len + sizeof "/.config"); + sprintf(xdg_home, "%s/.config", home); + } + if (xdg_home != NULL) + add_dir(&dirs, xdg_home, "/ltrace"); + if (home != NULL) + add_dir(&dirs, home, "/.ltrace"); + + char *delim = NULL; + if (VECT_PUSHBACK(&dirs, &delim) < 0) { + fail: + /* This can't work :( */ + fprintf(stderr, + "Couldn't initialize list of config directories: %s.\n", + strerror(errno)); + VECT_DESTROY(&dirs, const char *, dict_dtor_string, NULL); + sys_start = -1; + return -1; + } + sys_start = vect_size(&dirs); + + /* """preference-ordered set of base directories to search for + * configuration files in addition to the $XDG_CONFIG_HOME + * base directory. The directories in $XDG_CONFIG_DIRS should + * be seperated with a colon ':'.""" */ + char *xdg_sys = getenv("XDG_CONFIG_DIRS"); + if (xdg_sys != NULL) { + struct vect v; + VECT_INIT(&v, struct opt_F_t); + if (parse_colon_separated_list(xdg_sys, &v) < 0 + || VECT_EACH(&v, struct opt_F_t, NULL, + add_dir_component_cb, &dirs) != NULL) + fprintf(stderr, + "Error processing $XDG_CONFIG_DIRS '%s': %s\n", + xdg_sys, strerror(errno)); + VECT_DESTROY(&v, struct opt_F_t, destroy_opt_F_cb, NULL); + } + + /* PKGDATADIR is passed via -D when compiling. */ + const char *pkgdatadir = PKGDATADIR; + if (pkgdatadir != NULL) + add_dir(&dirs, pkgdatadir, ""); + + if (VECT_PUSHBACK(&dirs, &delim) < 0) + goto fail; + + goto again; +} + +int +os_get_ltrace_conf_filenames(struct vect *retp) +{ + char *homepath = NULL; + char *syspath = NULL; + +#define FN ".ltrace.conf" + if (g_home_dir == NULL) + os_get_config_dirs(0, NULL); + + if (g_home_dir != NULL) { + homepath = malloc(strlen(g_home_dir) + 1 + sizeof FN); + if (homepath == NULL + || sprintf(homepath, "%s/%s", g_home_dir, FN) < 0) { + fail: + free(syspath); + free(homepath); + return -1; + } + } + + /* SYSCONFDIR is passed via -D when compiling. */ + const char *sysconfdir = SYSCONFDIR; + if (sysconfdir != NULL && *sysconfdir != '\0') { + /* No +1, we skip the initial period. */ + syspath = malloc(strlen(sysconfdir) + sizeof FN); + if (syspath == NULL + || sprintf(syspath, "%s/%s", sysconfdir, FN + 1) < 0) + goto fail; + } + + if (VECT_PUSHBACK(retp, &homepath) < 0 + || VECT_PUSHBACK(retp, &syspath) < 0) + goto fail; + + return 0; +} diff --git a/sysdeps/linux-gnu/ia64/Makefile.in b/sysdeps/linux-gnu/ia64/Makefile.in deleted file mode 100644 index a4eb305..0000000 --- a/sysdeps/linux-gnu/ia64/Makefile.in +++ /dev/null @@ -1,533 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/ia64 -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = breakpoint.lo plt.lo regs.lo trace.lo \ - fetch.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - breakpoint.c \ - plt.c \ - regs.c \ - trace.c \ - fetch.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/ia64/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/ia64/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/ia64/fetch.c b/sysdeps/linux-gnu/ia64/fetch.c index 54dc5b8..171c7a2 100644 --- a/sysdeps/linux-gnu/ia64/fetch.c +++ b/sysdeps/linux-gnu/ia64/fetch.c @@ -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) 2008,2009 Juan Cespedes * Copyright (C) 2006 Steve Fink * Copyright (C) 2006 Ian Wienand @@ -63,7 +63,7 @@ union cfm_t { }; static int -fetch_context_init(struct Process *proc, struct fetch_context *context) +fetch_context_init(struct process *proc, struct fetch_context *context) { context->slot_n = 0; context->flt = 8; @@ -76,7 +76,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context) } struct fetch_context * -arch_fetch_arg_init(enum tof type, struct Process *proc, +arch_fetch_arg_init(enum tof type, struct process *proc, struct arg_type_info *ret_info) { struct fetch_context *context = malloc(sizeof(*context)); @@ -91,7 +91,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc, } struct fetch_context * -arch_fetch_arg_clone(struct Process *proc, +arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) { struct fetch_context *clone = malloc(sizeof(*context)); @@ -102,7 +102,7 @@ arch_fetch_arg_clone(struct Process *proc, } int -allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, +allocate_stack_slot(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t al = type_alignof(proc, info); @@ -121,7 +121,7 @@ allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, } static int -allocate_reg(struct fetch_context *ctx, struct Process *proc, +allocate_reg(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { if (ctx->slot_n >= 8) @@ -152,7 +152,7 @@ allocate_reg(struct fetch_context *ctx, struct Process *proc, } static int -copy_aggregate_part(struct fetch_context *ctx, struct Process *proc, +copy_aggregate_part(struct fetch_context *ctx, struct process *proc, unsigned char *buf, size_t size) { size_t slots = (size + 7) / 8; @@ -176,7 +176,7 @@ copy_aggregate_part(struct fetch_context *ctx, struct Process *proc, } static int -allocate_arg(struct fetch_context *ctx, struct Process *proc, +allocate_arg(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); @@ -213,7 +213,7 @@ fpreg_to_double (struct ia64_fpreg *fp) { } static int -allocate_float(struct fetch_context *ctx, struct Process *proc, +allocate_float(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep, int take_slot) { @@ -249,39 +249,8 @@ allocate_float(struct fetch_context *ctx, struct Process *proc, return 0; } -static enum arg_type -get_hfa_type(struct arg_type_info *info, size_t *countp) -{ - size_t n = type_aggregate_size(info); - if (n == (size_t)-1) - return ARGTYPE_VOID; - - enum arg_type type = ARGTYPE_VOID; - *countp = 0; - - while (n-- > 0) { - struct arg_type_info *emt = type_element(info, n); - - enum arg_type emt_type = emt->type; - size_t emt_count = 1; - if (emt_type == ARGTYPE_STRUCT || emt_type == ARGTYPE_ARRAY) - emt_type = get_hfa_type(emt, &emt_count); - - if (type == ARGTYPE_VOID) { - if (emt_type != ARGTYPE_FLOAT - && emt_type != ARGTYPE_DOUBLE) - return ARGTYPE_VOID; - type = emt_type; - } - if (emt_type != type) - return ARGTYPE_VOID; - *countp += emt_count; - } - return type; -} - static int -allocate_hfa(struct fetch_context *ctx, struct Process *proc, +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) { @@ -366,7 +335,7 @@ allocate_hfa(struct fetch_context *ctx, struct Process *proc, } static int -allocate_ret(struct fetch_context *ctx, struct Process *proc, +allocate_ret(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); @@ -380,10 +349,11 @@ allocate_ret(struct fetch_context *ctx, struct Process *proc, * floating-point registers, beginning with f8. */ if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) { size_t hfa_size; - enum arg_type hfa_type = get_hfa_type(info, &hfa_size); - if (hfa_type != ARGTYPE_VOID && hfa_size <= 8) + struct arg_type_info *hfa_info + = type_get_hfa_type(info, &hfa_size); + if (hfa_info != NULL && hfa_size <= 8) return allocate_hfa(ctx, proc, info, valuep, - hfa_type, hfa_size); + hfa_info->type, hfa_size); } /* Integers and pointers are passed in r8. 128-bit integers @@ -405,11 +375,11 @@ allocate_ret(struct fetch_context *ctx, struct Process *proc, int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, - struct Process *proc, + struct process *proc, struct arg_type_info *info, struct value *valuep) { switch (info->type) { - enum arg_type hfa_type; + struct arg_type_info *hfa_info; size_t hfa_size; case ARGTYPE_VOID: @@ -421,10 +391,10 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, return allocate_float(ctx, proc, info, valuep, 1); case ARGTYPE_STRUCT: - hfa_type = get_hfa_type(info, &hfa_size); - if (hfa_type != ARGTYPE_VOID) + hfa_info = type_get_hfa_type(info, &hfa_size); + if (hfa_info != NULL) return allocate_hfa(ctx, proc, info, valuep, - hfa_type, hfa_size); + hfa_info->type, hfa_size); /* Fall through. */ case ARGTYPE_CHAR: case ARGTYPE_SHORT: @@ -446,7 +416,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, int arch_fetch_retval(struct fetch_context *ctx, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (fetch_context_init(proc, ctx) < 0) diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c index a29488f..f6bc939 100644 --- a/sysdeps/linux-gnu/ia64/plt.c +++ b/sysdeps/linux-gnu/ia64/plt.c @@ -68,12 +68,13 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } int -arch_translate_address_dyn(struct Process *proc, +arch_translate_address_dyn(struct process *proc, arch_addr_t addr, arch_addr_t *ret) { errno = 0; diff --git a/sysdeps/linux-gnu/ia64/regs.c b/sysdeps/linux-gnu/ia64/regs.c index cbc2744..67873ce 100644 --- a/sysdeps/linux-gnu/ia64/regs.c +++ b/sysdeps/linux-gnu/ia64/regs.c @@ -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) 2008,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -34,7 +34,8 @@ #include "common.h" void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0); unsigned long slot = (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 3; @@ -43,7 +44,8 @@ get_instruction_pointer(Process *proc) { } void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, void *addr) +{ unsigned long newip = (unsigned long)addr; unsigned long slot = (unsigned long)addr & 0xf; @@ -59,7 +61,8 @@ set_instruction_pointer(Process *proc, void *addr) { } void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0); if (l == -1 && errno) return NULL; @@ -67,14 +70,10 @@ get_stack_pointer(Process *proc) { } void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0); if (l == -1 && errno) return NULL; return (void *)l; } - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, PT_B0, addr); -} diff --git a/sysdeps/linux-gnu/ia64/trace.c b/sysdeps/linux-gnu/ia64/trace.c index e608275..9e554ef 100644 --- a/sysdeps/linux-gnu/ia64/trace.c +++ b/sysdeps/linux-gnu/ia64/trace.c @@ -70,7 +70,8 @@ union cfm_t { }; int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0); @@ -141,5 +142,6 @@ syscall_p(Process *proc, int status, int *sysnum) { } void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ } diff --git a/sysdeps/linux-gnu/m68k/Makefile.in b/sysdeps/linux-gnu/m68k/Makefile.in deleted file mode 100644 index 45eebd3..0000000 --- a/sysdeps/linux-gnu/m68k/Makefile.in +++ /dev/null @@ -1,530 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/m68k -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c \ - fetch.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/m68k/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/m68k/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/m68k/fetch.c b/sysdeps/linux-gnu/m68k/fetch.c index f6d8a0b..24bd8f0 100644 --- a/sysdeps/linux-gnu/m68k/fetch.c +++ b/sysdeps/linux-gnu/m68k/fetch.c @@ -43,7 +43,7 @@ struct fetch_context }; static int -fetch_register_banks(struct Process *proc, struct fetch_context *context, +fetch_register_banks(struct process *proc, struct fetch_context *context, int floating) { if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0) @@ -57,7 +57,7 @@ fetch_register_banks(struct Process *proc, struct fetch_context *context, } struct fetch_context * -arch_fetch_arg_init(enum tof type, struct Process *proc, +arch_fetch_arg_init(enum tof type, struct process *proc, struct arg_type_info *ret_info) { struct fetch_context *context = malloc(sizeof(*context)); @@ -92,7 +92,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc, } struct fetch_context * -arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) +arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) { struct fetch_context *ret = malloc(sizeof(*ret)); if (ret == NULL) @@ -103,7 +103,7 @@ arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) int arch_fetch_arg_next(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); @@ -143,7 +143,7 @@ arch_fetch_arg_next(struct fetch_context *context, enum tof type, int arch_fetch_retval(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c index c1b37dd..dcd6878 100644 --- a/sysdeps/linux-gnu/m68k/plt.c +++ b/sysdeps/linux-gnu/m68k/plt.c @@ -30,6 +30,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/m68k/regs.c b/sysdeps/linux-gnu/m68k/regs.c index 4afdfbb..e25aefb 100644 --- a/sysdeps/linux-gnu/m68k/regs.c +++ b/sysdeps/linux-gnu/m68k/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -36,26 +37,25 @@ #endif void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PC, 0); } void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, void *addr) +{ ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PC, addr); } void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0); } void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0); } - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr); -} diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c index 311ffd5..01b5253 100644 --- a/sysdeps/linux-gnu/m68k/trace.c +++ b/sysdeps/linux-gnu/m68k/trace.c @@ -40,13 +40,15 @@ #endif void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ } /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ int depth; if (WIFSTOPPED(status) diff --git a/sysdeps/linux-gnu/metag/Makefile.am b/sysdeps/linux-gnu/metag/Makefile.am new file mode 100644 index 0000000..a79d2f7 --- /dev/null +++ b/sysdeps/linux-gnu/metag/Makefile.am @@ -0,0 +1,16 @@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + 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/metag/arch.h b/sysdeps/linux-gnu/metag/arch.h new file mode 100644 index 0000000..2699c62 --- /dev/null +++ b/sysdeps/linux-gnu/metag/arch.h @@ -0,0 +1,28 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2004,2008 Juan Cespedes + * + * 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 + */ + +#define LT_ELFCLASS ELFCLASS32 +#define LT_ELF_MACHINE EM_METAG + +#define BREAKPOINT_VALUE { 0x01, 0x00, 0x40, 0xAF } +#define BREAKPOINT_LENGTH 4 +#define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_LITTLE +#define ARCH_HAVE_SW_SINGLESTEP diff --git a/sysdeps/linux-gnu/metag/plt.c b/sysdeps/linux-gnu/metag/plt.c new file mode 100644 index 0000000..2d479a4 --- /dev/null +++ b/sysdeps/linux-gnu/metag/plt.c @@ -0,0 +1,38 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 <gelf.h> + +#include "debug.h" +#include "proc.h" +#include "library.h" +#include "ltrace-elf.h" + +GElf_Addr +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) +{ + return lte->plt_addr + ( ndx * 0x14 ) + 0x14; +} + +void +*sym2addr(struct process *proc, struct library_symbol *sym) +{ + return sym->enter_addr; +} diff --git a/sysdeps/linux-gnu/metag/ptrace.h b/sysdeps/linux-gnu/metag/ptrace.h new file mode 100644 index 0000000..7a41e4a --- /dev/null +++ b/sysdeps/linux-gnu/metag/ptrace.h @@ -0,0 +1,21 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/metag/regs.c b/sysdeps/linux-gnu/metag/regs.c new file mode 100644 index 0000000..d4a6f2f --- /dev/null +++ b/sysdeps/linux-gnu/metag/regs.c @@ -0,0 +1,89 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 "config.h" + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <linux/uio.h> +#include <asm/ptrace.h> + +#include "proc.h" +#include "common.h" + +arch_addr_t +get_instruction_pointer(struct process *proc) +{ + struct user_gp_regs regs; + struct iovec iov; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) + return (void *)-1; + + return (void *)regs.pc; /* PC */ +} + +void +set_instruction_pointer(struct process *proc, arch_addr_t addr) +{ + struct user_gp_regs regs; + struct iovec iov; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) + return; + + regs.pc = (unsigned long)addr; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + ptrace(PTRACE_SETREGSET, proc->pid, NT_PRSTATUS, (long)&iov); +} + +arch_addr_t +get_stack_pointer(struct process *proc) +{ + struct user_gp_regs regs; + struct iovec iov; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) + return (void *)-1; + + return (void *)regs.ax[0][0]; /* A0StP (A0.0) */ +} + +arch_addr_t +get_return_addr(struct process *proc, void *stack_pointer) +{ + struct user_gp_regs regs; + struct iovec iov; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) + return (void *)-1; + + return (void *)regs.dx[4][1]; /* D1RtP (D1.4) */ +} diff --git a/sysdeps/linux-gnu/metag/signalent.h b/sysdeps/linux-gnu/metag/signalent.h new file mode 100644 index 0000000..80228b7 --- /dev/null +++ b/sysdeps/linux-gnu/metag/signalent.h @@ -0,0 +1,53 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 */ + "SIGRTMIN", /* 32 */ diff --git a/sysdeps/linux-gnu/metag/syscallent.h b/sysdeps/linux-gnu/metag/syscallent.h new file mode 100644 index 0000000..447c550 --- /dev/null +++ b/sysdeps/linux-gnu/metag/syscallent.h @@ -0,0 +1,293 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 */ + "fcntl64", /* 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 */ + "umount", /* 39 */ + "mount", /* 40 */ + "pivot_root", /* 41 */ + "42", /* 42 */ + "statfs64", /* 43 */ + "fstatfs64", /* 44 */ + "truncate64", /* 45 */ + "ftruncate64", /* 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 */ + "llseek", /* 62 */ + "read", /* 63 */ + "write", /* 64 */ + "readv", /* 65 */ + "writev", /* 66 */ + "pread64", /* 67 */ + "pwrite64", /* 68 */ + "preadv", /* 69 */ + "pwritev", /* 70 */ + "sendfile64", /* 71 */ + "pselect6", /* 72 */ + "ppoll", /* 73 */ + "signalfd4", /* 74 */ + "vmsplice", /* 75 */ + "splice", /* 76 */ + "tee", /* 77 */ + "readlinkat", /* 78 */ + "fstatat64", /* 79 */ + "fstat64", /* 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 */ + "newuname", /* 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 */ + "mmap2", /* 222 */ + "fadvise64_64", /* 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 */ + "244", /* 244 */ + "metag_setglobalbit", /* 245 */ + "metag_set_fpu_flags", /* 246 */ + "metag_set_tls", /* 247 */ + "metag_get_tls", /* 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 */ diff --git a/sysdeps/linux-gnu/metag/trace.c b/sysdeps/linux-gnu/metag/trace.c new file mode 100644 index 0000000..ad5fffe --- /dev/null +++ b/sysdeps/linux-gnu/metag/trace.c @@ -0,0 +1,428 @@ +/* + * This file is part of ltrace. + * + * Copyright (C) 2013 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 "config.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include <sys/ptrace.h> +#include <linux/uio.h> +#include <asm/ptrace.h> +#include <assert.h> + +#include "proc.h" +#include "common.h" + +#define METAG_INSN_SIZE 4 +#define N_UNITS 2 +#define REG_SIZE 4 + +/* unit codes */ +enum metag_unitnum { + METAG_UNIT_CT, /* 0x0 */ + METAG_UNIT_D0, + METAG_UNIT_D1, + METAG_UNIT_A0, + METAG_UNIT_A1, /* 0x4 */ + METAG_UNIT_PC, + METAG_UNIT_RA, + METAG_UNIT_TR, + METAG_UNIT_TT, /* 0x8 */ + METAG_UNIT_FX, + METAG_UNIT_MAX, +}; + +/** + \param proc The process that had an event. + + Called by \c next_event() right after the return from wait. + */ +void +get_arch_dep(struct process *proc) +{ + +} + +/** + \param proc Process that had event. + \param status From \c\ waitpid(). + \param sysnum 0-based syscall number. + \return 1 if syscall, 2 if sysret, 0 otherwise. + + Called by \c next_event() after the call to get_arch_dep(). + + */ +int +syscall_p(struct process *proc, int status, int *sysnum) +{ + if (WIFSTOPPED(status) + && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { + struct user_gp_regs regs; + struct iovec iov; + + /* Get GP registers. */ + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, + (long)&iov)) + return -1; + + /* Fetch the SWITCH instruction. */ + unsigned int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, regs.pc, + 0); + *sysnum = regs.dx[0][1]; + + if (insn != 0xaf440001) { + /* Check if we're returning from the system call. */ + insn = ptrace(PTRACE_PEEKTEXT, proc->pid, regs.pc - 4, + 0); + if (insn == 0xaf440001) + return 2; + + return 0; + } + + if (*sysnum >= 0) + return 1; + } + return 0; +} + +/* 2-bit base unit (BU) mapping. */ +static enum metag_unitnum metag_bu_map[4] = { + METAG_UNIT_A1, + METAG_UNIT_D0, + METAG_UNIT_D1, + METAG_UNIT_A0, +}; + +static int +get_regval_from_unit(enum metag_unitnum unit, unsigned int reg, + struct user_gp_regs *regs) +{ + /* + * Check if reg has a sane value. + * We do have N_UNITS, each one having X registers + * and each register is REG_SIZE bytes. + */ + if ((unit == METAG_UNIT_A0) || (unit == METAG_UNIT_A1)) { + if (reg >= ((sizeof(regs->ax)/N_UNITS/REG_SIZE))) + goto bad_reg; + } else if ((unit == METAG_UNIT_D0) || (unit == METAG_UNIT_D1)) { + if (reg >= ((sizeof(regs->dx)/N_UNITS/REG_SIZE))) + goto bad_reg; + } + + switch(unit) { + case METAG_UNIT_A1: + return regs->ax[reg][1]; + case METAG_UNIT_D0: + return regs->dx[reg][0]; + case METAG_UNIT_D1: + return regs->dx[reg][1]; + case METAG_UNIT_A0: + return regs->ax[reg][0]; + /* We really shouldn't be here. */ + default: + assert(unit != unit); + abort(); + } + return 0; + +bad_reg: + fprintf(stderr, + "Reading from register %d of unit %d is not implemented.", + reg, unit); + return 0; + +} + +static int +metag_next_pcs(struct process *proc, uint32_t pc, uint32_t *newpc) +{ + uint32_t inst; + int nr = 0, imm, reg_val; + unsigned int unit = 0, reg; + struct user_gp_regs regs; + struct iovec iov; + + inst = ptrace(PTRACE_PEEKTEXT, proc->pid, pc, 0); + + if (inst == 0xa0fffffe) { /* NOP (Special branch instruction) */ + newpc[nr++] = pc + 4; + } else if ((inst & 0xff000000) == 0xa0000000) { + /* Matching 0xA 0x0 for opcode for B #S19 or B<cc> #S19. + * + * Potential Targets: + * - pc + #S19 * METAG_INSN_SIZE if R=1 or <CC> true + * - pc + 4 */ + imm = ((inst << 8) >> 13) * METAG_INSN_SIZE; + newpc[nr++] = pc + imm; + newpc[nr++] = pc + 4; + } else if ((inst & 0xff000000) == 0xac000000) { + /* Matching 0xA 0xC for opcode. + * JUMP BBx.r,#X16 or CALL BBx.r,#X16 + * + * pc = reg + #x16 (aligned) */ + imm = (inst >> 3) & 0xffff; + reg = (inst >> 19) & 0x1f; + unit = metag_bu_map[inst & 0x3]; + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, + NT_PRSTATUS, (long)&iov)) + goto ptrace_fail; + + reg_val = get_regval_from_unit(unit, reg, ®s); + newpc[nr++] = (reg_val + imm) & -METAG_INSN_SIZE; + } else if ((inst & 0xff000000) == 0xab000000) { + /* Matching 0xA 0xB for opcode. + * + * CALLR BBx.r,#S19 */ + imm = ((inst << 8) >> 13) * METAG_INSN_SIZE; + newpc[nr++] = pc + imm; + } else if ((inst & 0xff0001e0) == 0xa30000a0) { + /* + * Matching 0xA 0x3 for opcode and then + * Ud (bit 8-5) = 0x5 = METAG_UNIT_PC + * + * Potential MOV PC,.. or SWAP<cc> PC,.. or SWAP<cc> ..,PC + */ + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, + NT_PRSTATUS, (long)&iov)) + goto ptrace_fail; + + /* + * Maybe PC is the source register for a SWAP? + * bit9 = 1 and bit13-10(Us) == METAG_UNIT_PC + */ + if (((inst >> 9 ) & 0x1) && + (((inst >> 10) & 0xf) == METAG_UNIT_PC)) { + /* PC will get its value from the + * destination register. */ + reg = (inst >> 14) & 0x1f; + unit = (inst >> 5) & 0xf; + } else { /* PC is the destination register. + * Find the source register. */ + reg = (inst >> 19) & 0x1f; + unit = (inst >> 10) & 0xf; + } + + switch(unit) { + case METAG_UNIT_D0: + case METAG_UNIT_D1: + case METAG_UNIT_A0: + case METAG_UNIT_A1: + reg_val = get_regval_from_unit(unit, reg, ®s); + break; + case METAG_UNIT_PC: + reg_val = regs.pc; + break; + default: + goto unhandled; + } + newpc[nr++] = reg_val; + /* In case it is a conditional instruction. */ + newpc[nr++] = pc + 4; + } else if ((inst & 0xff00001f) == 0xc600000a){ + /* Matching 0xC 0x{4,6} for opcode + * and UD == 0x5 == METAG_UNIT_PC + * + * GETD PC, [A0.r + #S6] or + * GETD PC, [A0.r + A0.r] */ + unit = metag_bu_map[(inst >> 5) & 0x3]; + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + reg = (inst >> 14) & 0x1f; + imm = (inst << 18) >> 5; /* sign-extend it */ + if (ptrace(PTRACE_GETREGSET, proc->pid, + NT_PRSTATUS, (long)&iov)) + goto ptrace_fail; + reg_val = get_regval_from_unit(unit, reg, ®s) + imm; + /* See where reg_val actually points to. */ + newpc[nr++] = ptrace(PTRACE_PEEKTEXT, proc->pid, reg_val, 0); + } else if (((inst & 0xfe0001e0) == 0x840000a0) || /* ADDcc R, A, R */ + ((inst & 0xfe00003f) == 0x8600002a) || /* ADD R, A, #X8 */ + ((inst & 0xfe0001e0) == 0x8c0000a0) || /* SUBcc R, A, R */ + ((inst & 0xfe00003f) == 0x8e00002a) || /* SUB R, A, #X8 */ + ((inst & 0xf40001e0) == 0x040000a0) || /* ADDcc R, D, D */ + ((inst & 0xfe00003f) == 0x0600002a) || /* ADD R, D, #X8 */ + ((inst & 0xf40001e0) == 0x140000a0) || /* SUBcc R, D, D */ + ((inst & 0xf600003f) == 0x1600002a)) { /* SUB R, D, #X8 */ + + /* bits4-1(Ud) == METAG_UNIT_PC */ + + int src1, src2, pc_src1 = 0, pc_src2 = 0, is_aunit = 0; + int umask = 0, optype = 0; + + /* Look for O2R bit */ + if ((((inst >> 24) & 0x6) == 0x4) && (inst & 0x1)) + goto unhandled; + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, + NT_PRSTATUS, (long)&iov)) + goto ptrace_fail; + + /* Figure out unit for source registers based on the opcode. */ + switch((inst >> 28) & 0xf) { + case 0: /* ADD<cc> Rx.r, Dx.r, De.r|#X8 */ + case 1: /* SUB<cc> Rx.r, Dx.r, De.r|#X8 */ + unit = METAG_UNIT_D0 + ((inst >> 24) & 0x1); + is_aunit = 0; + umask = 0x1f; + optype = (inst >> 28) & 0x1; + break; + case 8: + unit = METAG_UNIT_A0 + ((inst >> 24) & 0x1); + is_aunit = 1; + umask = 0xf; + optype = (inst >> 27) & 0x1; + break; + } + + /* Get pc bits (if any). */ + if (is_aunit) { + pc_src1 = (inst >> 18) & 0x1; + pc_src2 = (inst >> 13) & 0x1; + } + + /* Determine ADD|SUB format. Immediate or register ? */ + if ((inst >> 25) & 0x1) { /* ADD|SUB cc PC, X, #imm8 */ + src2 = (inst >> 6) & 0xff; /* so we can share code. */ + reg = (inst >> 14) & umask; + if (pc_src1) /* This can only be true for AU ops. */ + src1 = regs.pc; + else /* This covers both AU an DU ops. */ + src1 = get_regval_from_unit(unit, reg, ®s); + } else { /* ADD|SUB cc PC, X, X */ + if (pc_src1) + src1 = regs.pc; + else + src1 = get_regval_from_unit(unit, (inst >> 14) + & umask, ®s); + if (pc_src2) + src2 = regs.pc; + else + src2 = get_regval_from_unit(unit, (inst >> 9) + & umask, ®s); + } + + /* Construct the new PC. */ + if (optype) + /* SUB */ + newpc[nr++] = src1 - src2; + else /* ADD */ + newpc[nr++] = src1 + src2; + /* Conditional instruction so PC may not change. */ + newpc[nr++] = pc + 4; + } else { + newpc[nr++] = pc + 4; + } + + if (nr <= 0 || nr > 2) + goto fail; + if (nr == 2 && newpc[1] == 0) + goto fail; + + return nr; + +ptrace_fail: + fprintf(stderr, "Failed to read the registers pid=%d @ pc=0x%08x\n", + proc->pid, pc); + return 0; +unhandled: + fprintf(stderr, "Unhandled instruction: pc=0x%08x, inst=0x%08x\n", + pc, inst); + return 0; +fail: + fprintf(stderr, "nr=%d pc=0x%08x\n", nr, pc); + fprintf(stderr, "newpc=0x%08x 0x%08x\n", newpc[0], newpc[1]); + return 0; + +} + +enum sw_singlestep_status +arch_sw_singlestep(struct process *proc, struct breakpoint *bp, + int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), + struct sw_singlestep_data *add_cb_data) +{ + arch_addr_t pc = get_instruction_pointer(proc); + uint32_t newpcs[2]; + int nr; + + nr = metag_next_pcs(proc, (uint32_t)pc, newpcs); + + while (nr-- > 0) { + arch_addr_t baddr = (arch_addr_t) newpcs[nr]; + if (dict_find(proc->leader->breakpoints, &baddr) != NULL) { + fprintf(stderr, "skip %p %p\n", baddr, add_cb_data); + continue; + } + + if (add_cb(baddr, add_cb_data) < 0) + return SWS_FAIL; + } + + ptrace(PTRACE_SYSCALL, proc->pid, 0, 0); + return SWS_OK; +} + +long +gimme_arg(enum tof type, struct process *proc, int arg_num, + struct arg_type_info *info) +{ + long ret; + struct user_gp_regs regs; + struct iovec iov; + + /* get GP registers */ + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, (long)&iov)) + return 0; + + debug(2, "type %d arg %d arg",type, arg_num); + if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL) { + if (arg_num < 6) { + /* Args go backwards starting from D1Ar1 (D1.3) */ + ret = ((unsigned long *)®s.dx[3][1])[-arg_num]; + debug(2,"ret = %#lx",ret); + return ret; + } else { + return 0; + } + } + if (arg_num >= 0) { + fprintf(stderr,"args on return?"); + } + if (type == LT_TOF_FUNCTIONR || type == LT_TOF_SYSCALLR) { + return regs.dx[0][0]; /* D0Re0 (D0.0) */ + } + + fprintf(stderr, "gimme_arg called with wrong arguments\n"); + + return 0; +} diff --git a/sysdeps/linux-gnu/mipsel/Doxyfile b/sysdeps/linux-gnu/mips/Doxyfile index 165f929..1dda2c1 100644 --- a/sysdeps/linux-gnu/mipsel/Doxyfile +++ b/sysdeps/linux-gnu/mips/Doxyfile @@ -21,9 +21,9 @@ #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = ltrace-mipsel -PROJECT_NUMBER = -OUTPUT_DIRECTORY = +PROJECT_NAME = ltrace-mips +PROJECT_NUMBER = +OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO @@ -43,8 +43,8 @@ ABBREVIATE_BRIEF = "The $name class" \ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO @@ -52,7 +52,7 @@ DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 -ALIASES = +ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO BUILTIN_STL_SUPPORT = NO @@ -82,11 +82,11 @@ GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = +ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -96,7 +96,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- @@ -143,15 +143,15 @@ FILE_PATTERNS = *.c \ *.MM \ *.PY RECURSIVE = NO -EXCLUDE = +EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = +EXCLUDE_PATTERNS = +EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing @@ -169,20 +169,20 @@ VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = +CHM_FILE = +HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO @@ -199,8 +199,8 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = +EXTRA_PACKAGES = +LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO @@ -212,8 +212,8 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- @@ -226,8 +226,8 @@ MAN_LINKS = NO #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = +XML_SCHEMA = +XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output @@ -239,29 +239,29 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = +TAGFILES = +GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES @@ -278,8 +278,8 @@ CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = +DOT_PATH = +DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 1000 @@ -288,6 +288,6 @@ DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = NO #--------------------------------------------------------------------------- -# Configuration::additions related to the search engine +# Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO diff --git a/sysdeps/linux-gnu/mipsel/Makefile.am b/sysdeps/linux-gnu/mips/Makefile.am index 9cf8f19..1fd8c2a 100644 --- a/sysdeps/linux-gnu/mipsel/Makefile.am +++ b/sysdeps/linux-gnu/mips/Makefile.am @@ -26,7 +26,7 @@ ___libcpu_la_SOURCES = \ noinst_HEADERS = \ arch.h \ - mipsel.h \ + mips.h \ ptrace.h \ signalent.h \ syscallent.h diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mips/arch.h index 684b546..14572cd 100644 --- a/sysdeps/linux-gnu/mipsel/arch.h +++ b/sysdeps/linux-gnu/mips/arch.h @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata * Copyright (C) 2006 Eric Vaitl * * This program is free software; you can redistribute it and/or @@ -24,10 +25,18 @@ #include <stddef.h> #include <gelf.h> -#define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 } +#ifdef __MIPSEL__ +# define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 } +# define ARCH_ENDIAN_LITTLE +#elif defined(__MIPSEB__) +# define BREAKPOINT_VALUE { 0x00, 0x00, 0x00, 0x0d } +# define ARCH_ENDIAN_BIG +#else +# error __MIPSEL__ or __MIPSEB__ must be defined +#endif + #define BREAKPOINT_LENGTH 4 #define DECR_PC_AFTER_BREAK 0 -#define ARCH_ENDIAN_LITTLE #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_MIPS @@ -43,7 +52,7 @@ struct arch_ltelf_data { #define ARCH_HAVE_GET_SYMINFO #define ARCH_HAVE_DYNLINK_DONE #define ARCH_HAVE_ADD_PLT_ENTRY -#define ARCH_HAVE_ATOMIC_SINGLESTEP +#define ARCH_HAVE_SW_SINGLESTEP #define ARCH_HAVE_SYMBOL_RET #define ARCH_HAVE_LIBRARY_SYMBOL_DATA diff --git a/sysdeps/linux-gnu/mipsel/mipsel.h b/sysdeps/linux-gnu/mips/mips.h index a2dbda2..0cbc715 100644 --- a/sysdeps/linux-gnu/mipsel/mipsel.h +++ b/sysdeps/linux-gnu/mips/mips.h @@ -19,15 +19,15 @@ * 02110-1301 USA */ -#ifndef MIPSEL_h -#define MIPSEL_h +#ifndef MIPS_h +#define MIPS_h // asm/ptrace.h for these offsets. #define off_v0 2 #define off_pc 64 #define off_a0 4 #define off_a3 7 #define off_lr 31 -#define off_fpr0 32 +#define off_fpr0 32 #define off_sp 29 -#endif // MIPSEL_h +#endif // MIPS_h diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mips/plt.c index b277fbc..3adf2ec 100644 --- a/sysdeps/linux-gnu/mipsel/plt.c +++ b/sysdeps/linux-gnu/mips/plt.c @@ -1,7 +1,7 @@ /* * This file is part of ltrace. + * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications - * Copyright (C) 2012 Petr Machata, Red Hat Inc. * Copyright (C) 2008,2009 Juan Cespedes * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. * @@ -35,7 +35,7 @@ #include "backend.h" /** - \addtogroup mipsel + \addtogroup mips @{ */ @@ -104,7 +104,8 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) breakpoint changes I just add a new breakpoint for the new address. */ void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ long ret; if (sym->arch.pltalways @@ -125,7 +126,7 @@ sym2addr(Process *proc, struct library_symbol *sym) { /* Address of run time loader map, used for debugging. */ #define DT_MIPS_RLD_MAP 0x70000016 int -arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, +arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr, arch_addr_t *ret) { arch_addr_t rld_addr; @@ -156,24 +157,21 @@ int arch_get_sym_info(struct ltelf *lte, const char *filename, size_t sym_index, GElf_Rela *rela, GElf_Sym *sym) { - const char *name; - if (mips_elf_is_cpic(lte->ehdr.e_flags)) { - return elf_get_sym_info(lte, filename, sym_index, rela, sym); + return gelf_getsym(lte->dynsym, ELF64_R_SYM(rela->r_info), + sym) != NULL ? 0 : -1; } /* Fixup the offset. */ sym_index += lte->arch.mips_gotsym; - if (gelf_getsym(lte->dynsym, sym_index, sym) == NULL){ - error(EXIT_FAILURE, 0, - "Couldn't get relocation from \"%s\"", filename); - } + if (gelf_getsym(lte->dynsym, sym_index, sym) == NULL) + return -1; - name = lte->dynstr + sym->st_name; if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC) { + const char *name = lte->dynstr + sym->st_name; debug(2, "sym %s not a function", name); - return -1; + return 1; } return 0; @@ -251,11 +249,11 @@ arch_elf_destroy(struct ltelf *lte) /* When functions return we check if the symbol needs an updated breakpoint with the resolved address. */ -void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym) +void arch_symbol_ret(struct process *proc, struct library_symbol *libsym) { struct breakpoint *bp; arch_addr_t resolved_addr; - struct Process *leader = proc->leader; + struct process *leader = proc->leader; /* Only deal with unresolved symbols. */ if (libsym->arch.type != MIPS_PLT_UNRESOLVED) @@ -302,7 +300,7 @@ err: static enum callback_status cb_enable_breakpoint_sym(struct library_symbol *libsym, void *data) { - struct Process *proc = data; + struct process *proc = data; arch_addr_t bp_addr; if (!libsym->arch.gotonly) @@ -329,19 +327,19 @@ cb_enable_breakpoint_sym(struct library_symbol *libsym, void *data) } static enum callback_status -cb_enable_breakpoint_lib(struct Process *proc, struct library *lib, void *data) +cb_enable_breakpoint_lib(struct process *proc, struct library *lib, void *data) { library_each_symbol(lib, NULL, cb_enable_breakpoint_sym, proc); return CBS_CONT; } -void arch_dynlink_done(struct Process *proc) +void arch_dynlink_done(struct process *proc) { proc_each_library(proc->leader, NULL, cb_enable_breakpoint_lib, NULL); } enum plt_status -arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, +arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, const char *a_name, GElf_Rela *rela, size_t ndx, struct library_symbol **ret) { @@ -350,7 +348,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, struct library_symbol *libsym = malloc(sizeof(*libsym)); if (libsym == NULL) - return plt_fail; + return PLT_FAIL; GElf_Addr addr = arch_plt_sym_val(lte, sym_index, 0); @@ -389,12 +387,12 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, } *ret = libsym; - return plt_ok; + return PLT_OK; fail: free(name); free(libsym); - return plt_fail; + return PLT_FAIL; } int diff --git a/sysdeps/linux-gnu/mipsel/ptrace.h b/sysdeps/linux-gnu/mips/ptrace.h index 00c8673..00c8673 100644 --- a/sysdeps/linux-gnu/mipsel/ptrace.h +++ b/sysdeps/linux-gnu/mips/ptrace.h diff --git a/sysdeps/linux-gnu/mipsel/regs.c b/sysdeps/linux-gnu/mips/regs.c index 8731ac5..b143636 100644 --- a/sysdeps/linux-gnu/mipsel/regs.c +++ b/sysdeps/linux-gnu/mips/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2008,2009 Juan Cespedes * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. * @@ -28,7 +29,7 @@ #include "proc.h" #include "common.h" -#include "mipsel.h" +#include "mips.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR @@ -39,7 +40,7 @@ #endif /** - \addtogroup mipsel + \addtogroup mips @{ */ @@ -49,7 +50,8 @@ \return The current instruction pointer. */ void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); } @@ -63,7 +65,8 @@ get_instruction_pointer(Process *proc) { we \c continue_process() after a breakpoint. Check if this is OK. */ void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, void *addr) +{ ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr); } @@ -72,7 +75,8 @@ set_instruction_pointer(Process *proc, void *addr) { \return The current stack pointer. */ void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0); } @@ -87,11 +91,7 @@ get_stack_pointer(Process *proc) { unused. */ void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0); } - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr); -} diff --git a/sysdeps/linux-gnu/mipsel/signalent.h b/sysdeps/linux-gnu/mips/signalent.h index d779af5..d779af5 100644 --- a/sysdeps/linux-gnu/mipsel/signalent.h +++ b/sysdeps/linux-gnu/mips/signalent.h diff --git a/sysdeps/linux-gnu/mipsel/syscallent.h b/sysdeps/linux-gnu/mips/syscallent.h index c0e5dd6..c0e5dd6 100644 --- a/sysdeps/linux-gnu/mipsel/syscallent.h +++ b/sysdeps/linux-gnu/mips/syscallent.h diff --git a/sysdeps/linux-gnu/mipsel/trace.c b/sysdeps/linux-gnu/mips/trace.c index db9ec21..88e13ac 100644 --- a/sysdeps/linux-gnu/mipsel/trace.c +++ b/sysdeps/linux-gnu/mips/trace.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications * Copyright (C) 2010 Arnaud Patard, Mandriva SA * Copyright (C) 2008,2009 Juan Cespedes @@ -33,7 +34,7 @@ #include "backend.h" #include "common.h" #include "debug.h" -#include "mipsel.h" +#include "mips.h" #include "proc.h" #include "type.h" @@ -47,7 +48,7 @@ /** - \addtogroup mipsel Mipsel specific functions. + \addtogroup mips Mips specific functions. These are the functions that it looks like I need to implement in order to get ltrace to work on our target. @@ -64,7 +65,8 @@ private data area. */ void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ } /** @@ -77,7 +79,7 @@ get_arch_dep(Process *proc) { It seems that the ptrace call trips twice on a system call, once just before the system call and once when it returns. Both times, - the pc points at the instruction just after the mipsel "syscall" + the pc points at the instruction just after the mips "syscall" instruction. There are several possiblities for system call sets, each is offset @@ -85,7 +87,8 @@ get_arch_dep(Process *proc) { for the system calls is 4000. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { /* get the user's pc (plus 8) */ @@ -95,7 +98,7 @@ syscall_p(Process *proc, int status, int *sysnum) { int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0); /* - On a mipsel, syscall looks like: + On a mips, syscall looks like: 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall 0000000c syscall */ @@ -141,7 +144,7 @@ mips32_relative_offset (uint32_t inst) return ((itype_immediate(inst) ^ 0x8000) - 0x8000) << 2; } -int mips_next_pcs(struct Process *proc, uint32_t pc, uint32_t *newpc) +int mips_next_pcs(struct process *proc, uint32_t pc, uint32_t *newpc) { uint32_t inst, rx; int op; @@ -261,10 +264,10 @@ fail: return 0; } -int -arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, - int (*add_cb)(void *addr, void *data), - void *add_cb_data) +enum sw_singlestep_status +arch_sw_singlestep(struct process *proc, struct breakpoint *bp, + int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), + struct sw_singlestep_data *add_cb_data) { uint32_t pc = (uint32_t) get_instruction_pointer(proc); uint32_t newpcs[2]; @@ -275,17 +278,17 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, while (nr-- > 0) { arch_addr_t baddr = (arch_addr_t) newpcs[nr]; /* Not sure what to do here. We've already got a bp? */ - if (dict_find_entry(proc->leader->breakpoints, baddr) != NULL) { + if (DICT_HAS_KEY(proc->leader->breakpoints, &baddr)) { fprintf(stderr, "skip %p %p\n", baddr, add_cb_data); continue; } if (add_cb(baddr, add_cb_data) < 0) - return -1; + return SWS_FAIL; } ptrace(PTRACE_SYSCALL, proc->pid, 0, 0); - return 0; + return SWS_OK; } /** @@ -303,7 +306,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, - I'm only displaying the first 4 args (Registers a0..a3). Good enough for now. - Mipsel conventions seem to be: + Mips conventions seem to be: - syscall parameters: r4...r9 - syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;} - function call: r4..r7. Not sure how to get arg number 5. @@ -317,7 +320,8 @@ I'm not doing any floating point support here. */ long -gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +gimme_arg(enum tof type, struct process *proc, int arg_num, + struct arg_type_info *info) { long ret; long addr; diff --git a/sysdeps/linux-gnu/mipsel/Makefile.in b/sysdeps/linux-gnu/mipsel/Makefile.in deleted file mode 100644 index f0a1b06..0000000 --- a/sysdeps/linux-gnu/mipsel/Makefile.in +++ /dev/null @@ -1,532 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/mipsel -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c - -noinst_HEADERS = \ - arch.h \ - mipsel.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -EXTRA_DIST = \ - Doxyfile - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/mipsel/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/mipsel/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/mksyscallent_mips b/sysdeps/linux-gnu/mksyscallent_mips new file mode 100755 index 0000000..f3961b4 --- /dev/null +++ b/sysdeps/linux-gnu/mksyscallent_mips @@ -0,0 +1,60 @@ +#!/usr/bin/awk -f +# This file is part of ltrace. +# Copyright (C) 2010 Arnaud Patard, Mandriva SA +# +# 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 + +# hack expression to generate arch/syscallent.h from <asm/unistd.h> +# It reads from stdin and writes to stdout +# It should work OK on i386,m68k,arm,ia64 +# It does NOT work in mips, s390 +# It is untested in other architectures + +BEGIN { + max=0; + FS="[ \t\n()+]+"; +} + +{ + #debug + #printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4); + if ($2 ~ /__NR_Linux/ && $3 ~ /4000/) { + syscall=1; + } + if ($2 ~ /__NR_Linux_syscalls/) { + syscall=0; + } + if (syscall && ($1 ~ /^#define$/) && ($2 ~ /^__NR_/)) { + SYSCALL[$4]=substr($2,6); + if ($4 > max) { + max=$4; + } + } +} + +END { + for(i=0; i<=max; i++) { + if (!SYSCALL[i]) { + SYSCALL[i] = i; + } + pad = 32 - length(SYSCALL[i]); + if (pad<1) { + pad=1; + } + printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i); + } +} + diff --git a/sysdeps/linux-gnu/os.h b/sysdeps/linux-gnu/os.h index 62bf38b..60fd604 100644 --- a/sysdeps/linux-gnu/os.h +++ b/sysdeps/linux-gnu/os.h @@ -23,3 +23,17 @@ struct os_process_data { arch_addr_t debug_addr; int debug_state; }; + +#define OS_HAVE_LIBRARY_SYMBOL_DATA +struct os_library_symbol_data { + unsigned is_ifunc : 1; +}; + +#define OS_HAVE_BREAKPOINT_DATA +struct os_breakpoint_data { + /* For breakpoints that track return from IFUNC functions, we + * keep here the IFUNC symbol itself. */ + struct library_symbol *ret_libsym; +}; + +#define OS_HAVE_ADD_FUNC_ENTRY diff --git a/sysdeps/linux-gnu/ppc/Makefile.in b/sysdeps/linux-gnu/ppc/Makefile.in deleted file mode 100644 index bcc9d84..0000000 --- a/sysdeps/linux-gnu/ppc/Makefile.in +++ /dev/null @@ -1,531 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/ppc -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c \ - fetch.c - -noinst_HEADERS = \ - arch.h \ - insn.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/ppc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/ppc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h index fb8768a..2add3b8 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 Petr Machata + * Copyright (C) 2012,2013 Petr Machata * Copyright (C) 2006 Paul Gilliam * Copyright (C) 2002,2004 Juan Cespedes * @@ -37,8 +37,9 @@ #define ARCH_SUPPORTS_OPD #endif -#define ARCH_HAVE_ATOMIC_SINGLESTEP +#define ARCH_HAVE_SW_SINGLESTEP #define ARCH_HAVE_ADD_PLT_ENTRY +#define ARCH_HAVE_ADD_FUNC_ENTRY #define ARCH_HAVE_TRANSLATE_ADDRESS #define ARCH_HAVE_DYNLINK_DONE #define ARCH_HAVE_FETCH_ARG @@ -56,6 +57,9 @@ struct arch_ltelf_data { GElf_Addr opd_base; GElf_Xword opd_size; int secure_plt; + + Elf_Data *reladyn; + size_t reladyn_count; }; #define ARCH_HAVE_LIBRARY_DATA @@ -79,6 +83,10 @@ enum ppc64_plt_type { * corresponding PLT entry. The original is now saved in * RESOLVED_VALUE. */ PPC_PLT_RESOLVED, + + /* Very similar to PPC_PLT_UNRESOLVED, but for JMP_IREL + * slots. */ + PPC_PLT_IRELATIVE, }; #define ARCH_HAVE_LIBRARY_SYMBOL_DATA @@ -92,7 +100,10 @@ struct arch_library_symbol_data { #define ARCH_HAVE_BREAKPOINT_DATA struct arch_breakpoint_data { - /* We need this just for arch_breakpoint_init. */ + /* This is where we hide symbol for IRELATIVE breakpoint for + * the first time that it hits. This is NULL for normal + * breakpoints. */ + struct library_symbol *irel_libsym; }; #define ARCH_HAVE_PROCESS_DATA diff --git a/sysdeps/linux-gnu/ppc/fetch.c b/sysdeps/linux-gnu/ppc/fetch.c index 9963a1e..ed38336 100644 --- a/sysdeps/linux-gnu/ppc/fetch.c +++ b/sysdeps/linux-gnu/ppc/fetch.c @@ -31,7 +31,7 @@ #include "proc.h" #include "value.h" -static int allocate_gpr(struct fetch_context *ctx, struct Process *proc, +static int allocate_gpr(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep); /* Floating point registers have the same width on 32-bit as well as @@ -66,7 +66,7 @@ struct fetch_context { }; static int -fetch_context_init(struct Process *proc, struct fetch_context *context) +fetch_context_init(struct process *proc, struct fetch_context *context) { context->greg = 3; context->freg = 1; @@ -108,7 +108,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context) } struct fetch_context * -arch_fetch_arg_init(enum tof type, struct Process *proc, +arch_fetch_arg_init(enum tof type, struct process *proc, struct arg_type_info *ret_info) { struct fetch_context *context = malloc(sizeof(*context)); @@ -132,7 +132,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc, } struct fetch_context * -arch_fetch_arg_clone(struct Process *proc, +arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) { struct fetch_context *clone = malloc(sizeof(*context)); @@ -143,7 +143,7 @@ arch_fetch_arg_clone(struct Process *proc, } static int -allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, +allocate_stack_slot(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); @@ -170,7 +170,7 @@ allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, } static uint64_t -read_gpr(struct fetch_context *ctx, struct Process *proc, int reg_num) +read_gpr(struct fetch_context *ctx, struct process *proc, int reg_num) { if (proc->e_machine == EM_PPC) return ctx->regs.r32[reg_num]; @@ -215,7 +215,7 @@ align_small_int(unsigned char *buf, size_t w, size_t sz) } static int -allocate_gpr(struct fetch_context *ctx, struct Process *proc, +allocate_gpr(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { if (ctx->greg > 10) @@ -245,7 +245,7 @@ allocate_gpr(struct fetch_context *ctx, struct Process *proc, } static int -allocate_float(struct fetch_context *ctx, struct Process *proc, +allocate_float(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { int pool = proc->e_machine == EM_PPC64 ? 13 : 8; @@ -276,7 +276,7 @@ allocate_float(struct fetch_context *ctx, struct Process *proc, } static int -allocate_argument(struct fetch_context *ctx, struct Process *proc, +allocate_argument(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep) { /* Floating point types and void are handled specially. */ @@ -400,7 +400,7 @@ allocate_argument(struct fetch_context *ctx, struct Process *proc, int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, - struct Process *proc, + struct process *proc, struct arg_type_info *info, struct value *valuep) { return allocate_argument(ctx, proc, info, valuep); @@ -408,7 +408,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, int arch_fetch_retval(struct fetch_context *ctx, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (ctx->ret_struct) { diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c index f83f087..5e3ffe1 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 Petr Machata, Red Hat Inc. + * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2004,2008,2009 Juan Cespedes * Copyright (C) 2006 Paul Gilliam * @@ -25,6 +25,7 @@ #include <errno.h> #include <inttypes.h> #include <assert.h> +#include <stdbool.h> #include <string.h> #include "proc.h" @@ -104,6 +105,28 @@ * through half the dynamic linker, we just let the thread run and hit * this breakpoint. When it hits, we know the PLT entry was resolved. * + * Another twist comes from tracing slots corresponding to + * R_PPC64_JMP_IREL relocations. These have no dedicated PLT entry. + * The calls are done directly from stubs, and the .plt entry + * (actually .iplt entry, these live in a special section) is resolved + * in advance before the binary starts. Because there's no PLT entry, + * we put the PLT breakpoints directly to the IFUNC resolver code, and + * then would like them to behave like ordinary PLT slots, including + * catching the point where these get resolved to unresolve them. So + * for the first call (which is the actual resolver call), we pretend + * that this breakpoint is artificial and has no associated symbol, + * and turn it on fully only after the first hit. Ideally we would + * trace that first call as well, but then the stepper, which tries to + * catch the point where the slot is resolved, would hit the return + * breakpoint and that's not currently handled well. + * + * On PPC32 with secure PLT, the address of IFUNC symbols in main + * binary actually isn't of the resolver, but of a PLT slot. We + * therefore have to locate the corresponding PLT relocation (which is + * of type R_PPC_IRELATIVE) and request that it be traced. The addend + * of that relocation is an address of resolver, and we request + * tracing of the xyz.IFUNC symbol there. + * * XXX TODO If we have hardware watch point, we might put a read watch * on .plt slot, and discover the offenders this way. I don't know * the details, but I assume at most a handful (like, one or two, if @@ -125,51 +148,6 @@ host_powerpc64() #endif } -int -read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp) -{ - unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); - if (l == -1UL && errno) - return -1; -#ifdef __powerpc64__ - l >>= 32; -#endif - *lp = l; - return 0; -} - -static int -read_target_8(struct Process *proc, arch_addr_t addr, uint64_t *lp) -{ - unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); - if (l == -1UL && errno) - return -1; - if (host_powerpc64()) { - *lp = l; - } else { - unsigned long l2 = ptrace(PTRACE_PEEKTEXT, proc->pid, - addr + 4, 0); - if (l2 == -1UL && errno) - return -1; - *lp = ((uint64_t)l << 32) | l2; - } - return 0; -} - -int -read_target_long(struct Process *proc, arch_addr_t addr, uint64_t *lp) -{ - if (proc->e_machine == EM_PPC) { - uint32_t w; - int ret = read_target_4(proc, addr, &w); - if (ret >= 0) - *lp = (uint64_t)w; - return ret; - } else { - return read_target_8(proc, addr, lp); - } -} - static void mark_as_resolved(struct library_symbol *libsym, GElf_Addr value) { @@ -177,15 +155,53 @@ mark_as_resolved(struct library_symbol *libsym, GElf_Addr value) libsym->arch.resolved_value = value; } +static void +ppc32_delayed_symbol(struct library_symbol *libsym) +{ + /* arch_dynlink_done is called on attach as well. In that + * case some slots will have been resolved already. + * Unresolved PLT looks like this: + * + * <sleep@plt>: li r11,0 + * <sleep@plt+4>: b "resolve" + * + * "resolve" is another address in PLTGOT (the same block that + * all the PLT slots are it). When resolved, it looks either + * this way: + * + * <sleep@plt>: b 0xfea88d0 <sleep> + * + * Which is easy to detect. It can also look this way: + * + * <sleep@plt>: li r11,0 + * <sleep@plt+4>: b "dispatch" + * + * The "dispatch" address lies in PLTGOT as well. In current + * GNU toolchain, "dispatch" address is the same as PLTGOT + * address. We rely on this to figure out whether the address + * is resolved or not. */ + + uint32_t insn1 = libsym->arch.resolved_value >> 32; + uint32_t insn2 = (uint32_t) libsym->arch.resolved_value; + if ((insn1 & BRANCH_MASK) == B_INSN + || ((insn2 & BRANCH_MASK) == B_INSN + /* XXX double cast */ + && (ppc_branch_dest(libsym->enter_addr + 4, insn2) + == (arch_addr_t) (long) libsym->lib->arch.pltgot_addr))) + { + mark_as_resolved(libsym, libsym->arch.resolved_value); + } +} + void -arch_dynlink_done(struct Process *proc) +arch_dynlink_done(struct process *proc) { - /* On PPC32 with BSS PLT, we need to enable delayed symbols. */ + /* We may need to activate delayed symbols. */ struct library_symbol *libsym = NULL; while ((libsym = proc_each_symbol(proc, libsym, library_symbol_delayed_cb, NULL))) { - if (read_target_8(proc, libsym->enter_addr, - &libsym->arch.resolved_value) < 0) { + if (proc_read_64(proc, libsym->enter_addr, + &libsym->arch.resolved_value) < 0) { fprintf(stderr, "couldn't read PLT value for %s(%p): %s\n", libsym->name, libsym->enter_addr, @@ -193,45 +209,34 @@ arch_dynlink_done(struct Process *proc) return; } - /* arch_dynlink_done is called on attach as well. In - * that case some slots will have been resolved - * already. Unresolved PLT looks like this: - * - * <sleep@plt>: li r11,0 - * <sleep@plt+4>: b "resolve" - * - * "resolve" is another address in PLTGOT (the same - * block that all the PLT slots are it). When - * resolved, it looks either this way: - * - * <sleep@plt>: b 0xfea88d0 <sleep> - * - * Which is easy to detect. It can also look this - * way: - * - * <sleep@plt>: li r11,0 - * <sleep@plt+4>: b "dispatch" - * - * The "dispatch" address lies in PLTGOT as well. In - * current GNU toolchain, "dispatch" address is the - * same as PLTGOT address. We rely on this to figure - * out whether the address is resolved or not. */ - uint32_t insn1 = libsym->arch.resolved_value >> 32; - uint32_t insn2 = (uint32_t)libsym->arch.resolved_value; - if ((insn1 & BRANCH_MASK) == B_INSN - || ((insn2 & BRANCH_MASK) == B_INSN - /* XXX double cast */ - && (ppc_branch_dest(libsym->enter_addr + 4, insn2) - == (void*)(long)libsym->lib->arch.pltgot_addr))) - mark_as_resolved(libsym, libsym->arch.resolved_value); + if (proc->e_machine == EM_PPC) + ppc32_delayed_symbol(libsym); if (proc_activate_delayed_symbol(proc, libsym) < 0) return; - /* XXX double cast */ - libsym->arch.plt_slot_addr - = (GElf_Addr)(uintptr_t)libsym->enter_addr; + if (proc->e_machine == EM_PPC) + /* XXX double cast */ + libsym->arch.plt_slot_addr + = (GElf_Addr) (uintptr_t) libsym->enter_addr; + } +} + +static bool +reloc_is_irelative(int machine, GElf_Rela *rela) +{ + bool irelative = false; + if (machine == EM_PPC64) { +#ifdef R_PPC64_JMP_IREL + irelative = GELF_R_TYPE(rela->r_info) == R_PPC64_JMP_IREL; +#endif + } else { + assert(machine == EM_PPC); +#ifdef R_PPC_IRELATIVE + irelative = GELF_R_TYPE(rela->r_info) == R_PPC_IRELATIVE; +#endif } + return irelative; } GElf_Addr @@ -244,10 +249,28 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) } else if (lte->ehdr.e_machine == EM_PPC) { return rela->r_offset; + /* Beyond this point, we are on PPC64, but don't have stub + * symbols. */ + + } else if (reloc_is_irelative(lte->ehdr.e_machine, rela)) { + + /* Put JMP_IREL breakpoint to resolver, since there's + * no dedicated PLT entry. */ + + assert(rela->r_addend != 0); + /* XXX double cast */ + arch_addr_t res_addr = (arch_addr_t) (uintptr_t) rela->r_addend; + 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; + } else { - /* If we get here, we don't have stub symbols. In - * that case we put brakpoints to PLT entries the same - * as the PPC32 secure PLT case does. */ + /* We put brakpoints to PLT entries the same as the + * PPC32 secure PLT case does. */ assert(lte->arch.plt_stub_vma != 0); return lte->arch.plt_stub_vma + PPC64_PLT_STUB_SIZE * ndx; } @@ -258,12 +281,12 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) * ourselves with bias, as the values in OPD have been resolved * already. */ int -arch_translate_address_dyn(struct Process *proc, +arch_translate_address_dyn(struct process *proc, arch_addr_t addr, arch_addr_t *ret) { if (proc->e_machine == EM_PPC64) { uint64_t value; - if (read_target_8(proc, addr, &value) < 0) { + if (proc_read_64(proc, addr, &value) < 0) { fprintf(stderr, "dynamic .opd translation of %p: %s\n", addr, strerror(errno)); @@ -307,7 +330,8 @@ load_opd_data(struct ltelf *lte, struct library *lib) { Elf_Scn *sec; GElf_Shdr shdr; - if (elf_get_section_named(lte, ".opd", &sec, &shdr) < 0) { + if (elf_get_section_named(lte, ".opd", &sec, &shdr) < 0 + || sec == NULL) { fail: fprintf(stderr, "couldn't find .opd data\n"); return -1; @@ -324,7 +348,7 @@ load_opd_data(struct ltelf *lte, struct library *lib) } void * -sym2addr(struct Process *proc, struct library_symbol *sym) +sym2addr(struct process *proc, struct library_symbol *sym) { return sym->enter_addr; } @@ -335,8 +359,9 @@ get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data) Elf_Scn *ppcgot_sec = NULL; GElf_Shdr ppcgot_shdr; if (ppcgot != 0 - && elf_get_section_covering(lte, ppcgot, - &ppcgot_sec, &ppcgot_shdr) < 0) + && (elf_get_section_covering(lte, ppcgot, + &ppcgot_sec, &ppcgot_shdr) < 0 + || ppcgot_sec == NULL)) fprintf(stderr, "DT_PPC_GOT=%#"PRIx64", but no such section found\n", ppcgot); @@ -425,6 +450,15 @@ nonzero_data(Elf_Data *data) return 0; } +static enum callback_status +reloc_copy_if_irelative(GElf_Rela *rela, void *data) +{ + struct ltelf *lte = data; + + return CBS_STOP_IF(reloc_is_irelative(lte->ehdr.e_machine, rela) + && VECT_PUSHBACK(<e->plt_relocs, rela) < 0); +} + int arch_elf_init(struct ltelf *lte, struct library *lib) { @@ -445,6 +479,34 @@ arch_elf_init(struct ltelf *lte, struct library *lib) * value to something conspicuous. */ lib->arch.bss_plt_prelinked = -1; + /* On PPC64 and PPC32 secure, IRELATIVE relocations actually + * relocate .iplt section, and as such are stored in .rela.dyn + * (where all non-PLT relocations are stored) instead of + * .rela.plt. Add these to lte->plt_relocs. */ + + GElf_Addr rela, relasz; + 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_get_section_covering(lte, rela, &rela_sec, &rela_shdr) == 0 + && rela_sec != NULL) { + + struct vect v; + VECT_INIT(&v, GElf_Rela); + int ret = elf_read_relocs(lte, rela_sec, &rela_shdr, &v); + if (ret >= 0 + && VECT_EACH(&v, GElf_Rela, NULL, + reloc_copy_if_irelative, lte) != NULL) + ret = -1; + + VECT_DESTROY(&v, GElf_Rela, NULL, NULL); + + if (ret < 0) + return ret; + } + if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { GElf_Addr ppcgot; if (load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) { @@ -453,10 +515,9 @@ arch_elf_init(struct ltelf *lte, struct library *lib) } GElf_Addr glink_vma = get_glink_vma(lte, ppcgot, lte->plt_data); - assert(lte->relplt_size % 12 == 0); - size_t count = lte->relplt_size / 12; // size of RELA entry + size_t count = vect_size(<e->plt_relocs); lte->arch.plt_stub_vma = glink_vma - - (GElf_Addr)count * PPC_PLT_STUB_SIZE; + - (GElf_Addr) count * PPC_PLT_STUB_SIZE; debug(1, "stub_vma is %#" PRIx64, lte->arch.plt_stub_vma); } else if (lte->ehdr.e_machine == EM_PPC64) { @@ -560,7 +621,7 @@ arch_elf_init(struct ltelf *lte, struct library *lib) } static int -read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp) +read_plt_slot_value(struct process *proc, GElf_Addr addr, GElf_Addr *valp) { /* On PPC64, we read from .plt, which contains 8 byte * addresses. On PPC32 we read from .plt, which contains 4 @@ -568,7 +629,7 @@ read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp) * either can change. */ uint64_t l; /* XXX double cast. */ - if (read_target_8(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) { + if (proc_read_64(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) { fprintf(stderr, "ptrace .plt slot value @%#" PRIx64": %s\n", addr, strerror(errno)); return -1; @@ -579,7 +640,7 @@ read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp) } static int -unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value) +unresolve_plt_slot(struct process *proc, GElf_Addr addr, GElf_Addr value) { /* We only modify plt_entry[0], which holds the resolved * address of the routine. We keep the TOC and environment @@ -594,36 +655,109 @@ unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value) } enum plt_status -arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, +arch_elf_add_func_entry(struct process *proc, struct ltelf *lte, + const GElf_Sym *sym, + arch_addr_t addr, const char *name, + struct library_symbol **ret) +{ + if (lte->ehdr.e_machine != EM_PPC || lte->ehdr.e_type == ET_DYN) + return PLT_DEFAULT; + + bool ifunc = false; +#ifdef STT_GNU_IFUNC + ifunc = GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC; +#endif + if (! ifunc) + return PLT_DEFAULT; + + size_t len = vect_size(<e->plt_relocs); + size_t i; + for (i = 0; i < len; ++i) { + GElf_Rela *rela = VECT_ELEMENT(<e->plt_relocs, GElf_Rela, i); + if (sym->st_value == arch_plt_sym_val(lte, i, rela)) { + + char *tmp_name = linux_append_IFUNC_to_name(name); + struct library_symbol *libsym = malloc(sizeof *libsym); + + /* XXX double cast. */ + arch_addr_t resolver_addr + = (arch_addr_t) (uintptr_t) rela->r_addend; + + if (tmp_name == NULL || libsym == NULL + || library_symbol_init(libsym, resolver_addr, + tmp_name, 1, + LS_TOPLT_EXEC) < 0) { + fail: + free(tmp_name); + free(libsym); + return PLT_FAIL; + } + + if (elf_add_plt_entry(proc, lte, name, rela, + i, ret) < 0) { + library_symbol_destroy(libsym); + goto fail; + } + + libsym->proto = linux_IFUNC_prototype(); + libsym->next = *ret; + *ret = libsym; + return PLT_OK; + } + } + + *ret = NULL; + return PLT_OK; +} + +enum plt_status +arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, const char *a_name, GElf_Rela *rela, size_t ndx, struct library_symbol **ret) { - if (lte->ehdr.e_machine == EM_PPC) { - if (lte->arch.secure_plt) - return plt_default; + bool is_irelative = reloc_is_irelative(lte->ehdr.e_machine, rela); + char *name; + if (! is_irelative) { + name = strdup(a_name); + } else { + GElf_Addr addr = lte->ehdr.e_machine == EM_PPC64 + ? (GElf_Addr) rela->r_addend + : arch_plt_sym_val(lte, ndx, rela); + name = linux_elf_find_irelative_name(lte, addr); + } - struct library_symbol *libsym = NULL; - if (default_elf_add_plt_entry(proc, lte, a_name, rela, ndx, - &libsym) < 0) - return plt_fail; + if (name == NULL) { + fail: + free(name); + return PLT_FAIL; + } - /* On PPC32 with BSS PLT, delay the symbol until - * dynamic linker is done. */ - assert(!libsym->delayed); - libsym->delayed = 1; + struct library_symbol *chain = NULL; + if (lte->ehdr.e_machine == EM_PPC) { + if (default_elf_add_plt_entry(proc, lte, name, rela, ndx, + &chain) < 0) + goto fail; - *ret = libsym; - return plt_ok; + if (! lte->arch.secure_plt) { + /* On PPC32 with BSS PLT, delay the symbol + * until dynamic linker is done. */ + assert(!chain->delayed); + chain->delayed = 1; + } + + ok: + *ret = chain; + free(name); + return PLT_OK; } /* PPC64. If we have stubs, we return a chain of breakpoint * sites, one for each stub that corresponds to this PLT * entry. */ - struct library_symbol *chain = NULL; struct library_symbol **symp; for (symp = <e->arch.stubs; *symp != NULL; ) { struct library_symbol *sym = *symp; - if (strcmp(sym->name, a_name) != 0) { + if (strcmp(sym->name, name) != 0) { symp = &(*symp)->next; continue; } @@ -634,10 +768,8 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, chain = sym; } - if (chain != NULL) { - *ret = chain; - return plt_ok; - } + if (chain != NULL) + goto ok; /* We don't have stub symbols. Find corresponding .plt slot, * and check whether it contains the corresponding PLT address @@ -648,33 +780,33 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, GElf_Addr plt_entry_addr = arch_plt_sym_val(lte, ndx, rela); GElf_Addr plt_slot_addr = rela->r_offset; + assert(plt_slot_addr >= lte->plt_addr || plt_slot_addr < lte->plt_addr + lte->plt_size); GElf_Addr plt_slot_value; if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0) - return plt_fail; + goto fail; - char *name = strdup(a_name); struct library_symbol *libsym = malloc(sizeof(*libsym)); - if (name == NULL || libsym == NULL) { + if (libsym == NULL) { fprintf(stderr, "allocation for .plt slot: %s\n", strerror(errno)); - fail: - free(name); + fail2: free(libsym); - return plt_fail; + goto fail; } /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ if (library_symbol_init(libsym, - (arch_addr_t)(uintptr_t)plt_entry_addr, + (arch_addr_t) (uintptr_t) plt_entry_addr, name, 1, LS_TOPLT_EXEC) < 0) - goto fail; + goto fail2; libsym->arch.plt_slot_addr = plt_slot_addr; - if (plt_slot_value == plt_entry_addr || plt_slot_value == 0) { + if (! 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; @@ -690,13 +822,19 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, if (unresolve_plt_slot(proc, plt_slot_addr, plt_entry_addr) < 0) { library_symbol_destroy(libsym); - goto fail; + 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; } - mark_as_resolved(libsym, plt_slot_value); } *ret = libsym; - return plt_ok; + return PLT_OK; } void @@ -712,7 +850,7 @@ arch_elf_destroy(struct ltelf *lte) } static void -dl_plt_update_bp_on_hit(struct breakpoint *bp, struct Process *proc) +dl_plt_update_bp_on_hit(struct breakpoint *bp, struct process *proc) { debug(DEBUG_PROCESS, "pid=%d dl_plt_update_bp_on_hit %s(%p)", proc->pid, breakpoint_name(bp), bp->addr); @@ -752,7 +890,7 @@ cb_on_all_stopped(struct process_stopping_handler *self) static enum callback_status cb_keep_stepping_p(struct process_stopping_handler *self) { - struct Process *proc = self->task_enabling_breakpoint; + struct process *proc = self->task_enabling_breakpoint; struct library_symbol *libsym = self->breakpoint_being_enabled->libsym; GElf_Addr value; @@ -799,7 +937,7 @@ cb_keep_stepping_p(struct process_stopping_handler *self) /* Install breakpoint to the address where the change takes * place. If we fail, then that just means that we'll have to * singlestep the next time around as well. */ - struct Process *leader = proc->leader; + struct process *leader = proc->leader; if (leader == NULL || leader->arch.dl_plt_update_bp != NULL) goto done; @@ -807,7 +945,7 @@ cb_keep_stepping_p(struct process_stopping_handler *self) * a store instruction, so moving the breakpoint one * instruction forward is safe. */ arch_addr_t addr = get_instruction_pointer(proc) + 4; - leader->arch.dl_plt_update_bp = insert_breakpoint(proc, addr, NULL); + leader->arch.dl_plt_update_bp = insert_breakpoint_at(proc, addr, NULL); if (leader->arch.dl_plt_update_bp == NULL) goto done; @@ -827,7 +965,7 @@ done: } static void -jump_to_entry_point(struct Process *proc, struct breakpoint *bp) +jump_to_entry_point(struct process *proc, struct breakpoint *bp) { /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ @@ -837,10 +975,19 @@ jump_to_entry_point(struct Process *proc, struct breakpoint *bp) } static void -ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc) +ppc_plt_bp_continue(struct breakpoint *bp, struct process *proc) { + /* If this is a first call through IREL breakpoint, enable the + * symbol so that it doesn't look like an artificial + * breakpoint anymore. */ + if (bp->libsym == NULL) { + assert(bp->arch.irel_libsym != NULL); + bp->libsym = bp->arch.irel_libsym; + bp->arch.irel_libsym = NULL; + } + switch (bp->libsym->arch.type) { - struct Process *leader; + struct process *leader; void (*on_all_stopped)(struct process_stopping_handler *); enum callback_status (*keep_stepping_p) (struct process_stopping_handler *); @@ -851,6 +998,7 @@ ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc) assert(bp->libsym->lib->arch.bss_plt_prelinked == 0); /* Fall through. */ + case PPC_PLT_IRELATIVE: case PPC_PLT_UNRESOLVED: on_all_stopped = NULL; keep_stepping_p = NULL; @@ -899,7 +1047,7 @@ ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc) * detect both cases and do any fix-ups necessary to mend this * situation. */ static enum callback_status -detach_task_cb(struct Process *task, void *data) +detach_task_cb(struct process *task, void *data) { struct breakpoint *bp = data; @@ -919,7 +1067,7 @@ detach_task_cb(struct Process *task, void *data) } static void -ppc_plt_bp_retract(struct breakpoint *bp, struct Process *proc) +ppc_plt_bp_retract(struct breakpoint *bp, struct process *proc) { /* On PPC64, we rewrite .plt with PLT entry addresses. This * needs to be undone. Unfortunately, the program may have @@ -933,9 +1081,10 @@ ppc_plt_bp_retract(struct breakpoint *bp, struct Process *proc) } } -void +int arch_library_init(struct library *lib) { + return 0; } void @@ -943,9 +1092,10 @@ arch_library_destroy(struct library *lib) { } -void +int arch_library_clone(struct library *retp, struct library *lib) { + return 0; } int @@ -975,8 +1125,10 @@ arch_library_symbol_clone(struct library_symbol *retp, * don't need PROC here, we can store the data in BP if it is of * interest to us. */ int -arch_breakpoint_init(struct Process *proc, struct breakpoint *bp) +arch_breakpoint_init(struct process *proc, struct breakpoint *bp) { + bp->arch.irel_libsym = NULL; + /* Artificial and entry-point breakpoints are plain. */ if (bp->libsym == NULL || bp->libsym->plt_type != LS_TOPLT_EXEC) return 0; @@ -996,6 +1148,14 @@ arch_breakpoint_init(struct Process *proc, struct breakpoint *bp) .on_retract = ppc_plt_bp_retract, }; breakpoint_set_callbacks(bp, &cbs); + + /* For JMP_IREL breakpoints, make the breakpoint look + * artificial by hiding the symbol. */ + if (bp->libsym->arch.type == PPC_PLT_IRELATIVE) { + bp->arch.irel_libsym = bp->libsym; + bp->libsym = NULL; + } + return 0; } @@ -1012,7 +1172,7 @@ arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) } int -arch_process_init(struct Process *proc) +arch_process_init(struct process *proc) { proc->arch.dl_plt_update_bp = NULL; proc->arch.handler = NULL; @@ -1020,19 +1180,19 @@ arch_process_init(struct Process *proc) } void -arch_process_destroy(struct Process *proc) +arch_process_destroy(struct process *proc) { } int -arch_process_clone(struct Process *retp, struct Process *proc) +arch_process_clone(struct process *retp, struct process *proc) { retp->arch = proc->arch; return 0; } int -arch_process_exec(struct Process *proc) +arch_process_exec(struct process *proc) { return arch_process_init(proc); } diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c index 37f89a4..40d7e7a 100644 --- a/sysdeps/linux-gnu/ppc/regs.c +++ b/sysdeps/linux-gnu/ppc/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2002,2008,2009 Juan Cespedes * Copyright (C) 2009 Juan Cespedes * Copyright (C) 2008 Luis Machado, IBM Corporation @@ -40,35 +41,26 @@ #endif void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0); } void -set_instruction_pointer(Process *proc, void *addr) +set_instruction_pointer(struct process *proc, void *addr) { if (ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr) != 0) error(0, errno, "set_instruction_pointer"); } void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0); } void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_LNK, 0); } - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_LNK, addr); -} - -/* Grab the value of CTR registers. */ -void * -get_count_register (Process *proc) { - return (void *) ptrace (PTRACE_PEEKUSER, proc->pid, - sizeof (long) * PT_CTR, 0); -} diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c index 4357a1e..ee9a6b5 100644 --- a/sysdeps/linux-gnu/ppc/trace.c +++ b/sysdeps/linux-gnu/ppc/trace.c @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2010,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2011 Andreas Schwab * Copyright (C) 2002,2004,2008,2009 Juan Cespedes * Copyright (C) 2008 Luis Machado, IBM Corporation @@ -49,7 +49,8 @@ #endif void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ #ifdef __powerpc64__ proc->mask_32bit = (proc->e_machine == EM_PPC); #endif @@ -59,7 +60,8 @@ get_arch_dep(Process *proc) { /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { long pc = (long)get_instruction_pointer(proc); @@ -84,18 +86,15 @@ syscall_p(Process *proc, int status, int *sysnum) { /* The atomic skip code is mostly taken from GDB. */ -/* In plt.h. XXX make this official interface. */ -int read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp); - -int -arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, - int (*add_cb)(void *addr, void *data), - void *add_cb_data) +enum sw_singlestep_status +arch_sw_singlestep(struct process *proc, struct breakpoint *sbp, + int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), + struct sw_singlestep_data *add_cb_data) { arch_addr_t ip = get_instruction_pointer(proc); struct breakpoint *other = address2bpstruct(proc->leader, ip); - debug(1, "arch_atomic_singlestep pid=%d addr=%p %s(%p)", + debug(1, "arch_sw_singlestep pid=%d addr=%p %s(%p)", proc->pid, ip, breakpoint_name(sbp), sbp->addr); /* If the original instruction was lwarx/ldarx, we can't @@ -107,15 +106,15 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, } u; if (other != NULL) { memcpy(u.buf, sbp->orig_value, BREAKPOINT_LENGTH); - } else if (read_target_4(proc, ip, &u.insn) < 0) { + } else if (proc_read_32(proc, ip, &u.insn) < 0) { fprintf(stderr, "couldn't read instruction at IP %p\n", ip); /* Do the normal singlestep. */ - return 1; + return SWS_HW; } if ((u.insn & LWARX_MASK) != LWARX_INSTRUCTION && (u.insn & LWARX_MASK) != LDARX_INSTRUCTION) - return 1; + return SWS_HW; debug(1, "singlestep over atomic block at %p", ip); @@ -125,7 +124,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, addr += 4; unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); if (l == (unsigned long)-1 && errno) - return -1; + return SWS_FAIL; uint32_t insn; #ifdef __powerpc64__ insn = l >> 32; @@ -140,7 +139,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, debug(1, "pid=%d, branch in atomic block from %p to %p", proc->pid, addr, branch_addr); if (add_cb(branch_addr, add_cb_data) < 0) - return -1; + return SWS_FAIL; } /* Assume that the atomic sequence ends with a @@ -157,22 +156,22 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, if (insn_count > 16) { fprintf(stderr, "[%d] couldn't find end of atomic block" " at %p\n", proc->pid, ip); - return -1; + return SWS_FAIL; } } /* Put the breakpoint to the next instruction. */ addr += 4; if (add_cb(addr, add_cb_data) < 0) - return -1; + return SWS_FAIL; debug(1, "PTRACE_CONT"); ptrace(PTRACE_CONT, proc->pid, 0, 0); - return 0; + return SWS_OK; } size_t -arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +arch_type_sizeof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; @@ -215,7 +214,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info) } size_t -arch_type_alignof(struct Process *proc, struct arg_type_info *info) +arch_type_alignof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c index 5adfb16..953fd86 100644 --- a/sysdeps/linux-gnu/proc.c +++ b/sysdeps/linux-gnu/proc.c @@ -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) 2010 Zachary T Welch, CodeSourcery * Copyright (C) 2010 Joe Damato * Copyright (C) 1998,2008,2009 Juan Cespedes @@ -177,44 +177,46 @@ process_status_cb(const char *line, const char *prefix, void *data) } while (0) switch (c) { - case 'Z': RETURN(ps_zombie); - case 't': RETURN(ps_tracing_stop); + case 'Z': RETURN(PS_ZOMBIE); + case 't': RETURN(PS_TRACING_STOP); case 'T': /* This can be either "T (stopped)" or, for older * kernels, "T (tracing stop)". */ if (!strcmp(status, "T (stopped)\n")) - RETURN(ps_stop); + RETURN(PS_STOP); else if (!strcmp(status, "T (tracing stop)\n")) - RETURN(ps_tracing_stop); + RETURN(PS_TRACING_STOP); else { fprintf(stderr, "Unknown process status: %s", status); - RETURN(ps_stop); /* Some sort of stop + RETURN(PS_STOP); /* Some sort of stop * anyway. */ } case 'D': - case 'S': RETURN(ps_sleeping); + case 'S': RETURN(PS_SLEEPING); } - RETURN(ps_other); + RETURN(PS_OTHER); #undef RETURN } enum process_status process_status(pid_t pid) { - enum process_status ret = ps_invalid; + enum process_status ret = PS_INVALID; FILE * file = open_status_file(pid); if (file != NULL) { each_line_starting(file, "State:\t", &process_status_cb, &ret); fclose(file); - if (ret == ps_invalid) - fprintf(stderr, "process_status %d: %s", pid, - strerror(errno)); - } else + if (ret == PS_INVALID) + fprintf(stderr, + "Couldn't determine status of process %d: %s\n", + pid, strerror(errno)); + } else { /* If the file is not present, the process presumably * exited already. */ - ret = ps_zombie; + ret = PS_ZOMBIE; + } return ret; } @@ -231,7 +233,7 @@ int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) { PROC_PID_FILE(fn, "/proc/%d/task", pid); - DIR * d = opendir(fn); + DIR *d = opendir(fn); if (d == NULL) return -1; @@ -243,7 +245,9 @@ process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) struct dirent entry; struct dirent *result; if (readdir_r(d, &entry, &result) != 0) { + fail: free(tasks); + closedir(d); return -1; } if (result == NULL) @@ -254,14 +258,11 @@ process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) alloc = alloc > 0 ? (2 * alloc) : 8; pid_t *ntasks = realloc(tasks, sizeof(*tasks) * alloc); - if (ntasks == NULL) { - free(tasks); - return -1; - } + if (ntasks == NULL) + goto fail; tasks = ntasks; } - if (n >= alloc) - abort(); + assert(n < alloc); tasks[n++] = npid; } } @@ -279,7 +280,7 @@ process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) * ABI object, as theorized about somewhere on pmachata/revamp * branch. */ static void * -select_32_64(struct Process *proc, void *p32, void *p64) +select_32_64(struct process *proc, void *p32, void *p64) { if (sizeof(long) == 4 || proc->mask_32bit) return p32; @@ -288,7 +289,7 @@ select_32_64(struct Process *proc, void *p32, void *p64) } static int -fetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) +fetch_dyn64(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret) { if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret)) return -1; @@ -297,7 +298,7 @@ fetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) } static int -fetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) +fetch_dyn32(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret) { Elf32_Dyn dyn; if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn)) @@ -311,14 +312,14 @@ fetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) } static int (* -dyn_fetcher(struct Process *proc))(struct Process *, +dyn_fetcher(struct process *proc))(struct process *, arch_addr_t *, Elf64_Dyn *) { return select_32_64(proc, fetch_dyn32, fetch_dyn64); } int -proc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr, +proc_find_dynamic_entry_addr(struct process *proc, arch_addr_t src_addr, int d_tag, arch_addr_t *ret) { debug(DEBUG_FUNCTION, "find_dynamic_entry()"); @@ -364,7 +365,7 @@ struct lt_link_map_32 LT_LINK_MAP(32); struct lt_link_map_64 LT_LINK_MAP(64); static int -fetch_lm64(struct Process *proc, arch_addr_t addr, +fetch_lm64(struct process *proc, arch_addr_t addr, struct lt_link_map_64 *ret) { if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) @@ -373,7 +374,7 @@ fetch_lm64(struct Process *proc, arch_addr_t addr, } static int -fetch_lm32(struct Process *proc, arch_addr_t addr, +fetch_lm32(struct process *proc, arch_addr_t addr, struct lt_link_map_64 *ret) { struct lt_link_map_32 lm; @@ -390,7 +391,7 @@ fetch_lm32(struct Process *proc, arch_addr_t addr, } static int (* -lm_fetcher(struct Process *proc))(struct Process *, +lm_fetcher(struct process *proc))(struct process *, arch_addr_t, struct lt_link_map_64 *) { return select_32_64(proc, fetch_lm32, fetch_lm64); @@ -410,7 +411,7 @@ struct lt_r_debug_32 LT_R_DEBUG(32); struct lt_r_debug_64 LT_R_DEBUG(64); static int -fetch_rd64(struct Process *proc, arch_addr_t addr, +fetch_rd64(struct process *proc, arch_addr_t addr, struct lt_r_debug_64 *ret) { if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) @@ -419,7 +420,7 @@ fetch_rd64(struct Process *proc, arch_addr_t addr, } static int -fetch_rd32(struct Process *proc, arch_addr_t addr, +fetch_rd32(struct process *proc, arch_addr_t addr, struct lt_r_debug_64 *ret) { struct lt_r_debug_32 rd; @@ -436,7 +437,7 @@ fetch_rd32(struct Process *proc, arch_addr_t addr, } static int (* -rdebug_fetcher(struct Process *proc))(struct Process *, +rdebug_fetcher(struct process *proc))(struct process *, arch_addr_t, struct lt_r_debug_64 *) { return select_32_64(proc, fetch_rd32, fetch_rd64); @@ -463,13 +464,13 @@ fetch_auxv32_entry(int fd, Elf64_auxv_t *ret) } static int (* -auxv_fetcher(struct Process *proc))(int, Elf64_auxv_t *) +auxv_fetcher(struct process *proc))(int, Elf64_auxv_t *) { return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry); } static void -crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) +crawl_linkmap(struct process *proc, struct lt_r_debug_64 *dbg) { debug (DEBUG_FUNCTION, "crawl_linkmap()"); @@ -483,7 +484,7 @@ crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) arch_addr_t addr = (arch_addr_t)(uintptr_t)dbg->r_map; while (addr != 0) { - struct lt_link_map_64 rlm; + struct lt_link_map_64 rlm = {}; if (lm_fetcher(proc)(proc, addr, &rlm) < 0) { debug(2, "Unable to read link map"); return; @@ -533,17 +534,20 @@ crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) struct library *lib = malloc(sizeof(*lib)); if (lib == NULL) { fail: - if (lib != NULL) - library_destroy(lib); + free(lib); fprintf(stderr, "Couldn't load ELF object %s: %s\n", lib_name, strerror(errno)); continue; } - library_init(lib, LT_LIBTYPE_DSO); - if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) + if (library_init(lib, LT_LIBTYPE_DSO) < 0) goto fail; + if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) { + library_destroy(lib); + goto fail; + } + lib->key = key; proc_add_library(proc, lib); } @@ -551,7 +555,7 @@ crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) } static int -load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret) +load_debug_struct(struct process *proc, struct lt_r_debug_64 *ret) { debug(DEBUG_FUNCTION, "load_debug_struct"); @@ -564,7 +568,7 @@ load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret) } static void -rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc) +rdebug_bp_on_hit(struct breakpoint *bp, struct process *proc) { debug(DEBUG_FUNCTION, "arch_check_dbg"); @@ -595,7 +599,7 @@ rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc) #ifndef ARCH_HAVE_FIND_DL_DEBUG int -arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, +arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr, arch_addr_t *ret) { return proc_find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, ret); @@ -603,7 +607,7 @@ arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, #endif int -linkmap_init(struct Process *proc, arch_addr_t dyn_addr) +linkmap_init(struct process *proc, arch_addr_t dyn_addr) { debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr); @@ -619,19 +623,29 @@ linkmap_init(struct Process *proc, arch_addr_t dyn_addr) return status; } + crawl_linkmap(proc, &rdbg); + /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ arch_addr_t addr = (arch_addr_t)(uintptr_t)rdbg.r_brk; if (arch_translate_address_dyn(proc, addr, &addr) < 0) return -1; - struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL); - static struct bp_callbacks rdebug_callbacks = { - .on_hit = rdebug_bp_on_hit, - }; - rdebug_bp->cbs = &rdebug_callbacks; - - crawl_linkmap(proc, &rdbg); + struct breakpoint *rdebug_bp = insert_breakpoint_at(proc, addr, NULL); + if (rdebug_bp == NULL) { + /* This is not fatal, the tracing can continue with + * reduced functionality. */ + fprintf(stderr, + "Couldn't insert _r_debug breakpoint to %d: %s.\n" + "As a result of that, ltrace will not be able to " + "detect and trace\nnewly-loaded libraries.\n", + proc->pid, strerror(errno)); + } else { + static struct bp_callbacks rdebug_callbacks = { + .on_hit = rdebug_bp_on_hit, + }; + rdebug_bp->cbs = &rdebug_callbacks; + } return 0; } @@ -648,13 +662,13 @@ task_kill (pid_t pid, int sig) } void -process_removed(struct Process *proc) +process_removed(struct process *proc) { delete_events_for(proc); } int -process_get_entry(struct Process *proc, +process_get_entry(struct process *proc, arch_addr_t *entryp, arch_addr_t *interp_biasp) { @@ -706,7 +720,7 @@ process_get_entry(struct Process *proc, } int -os_process_init(struct Process *proc) +os_process_init(struct process *proc) { proc->os.debug_addr = 0; proc->os.debug_state = 0; @@ -714,19 +728,19 @@ os_process_init(struct Process *proc) } void -os_process_destroy(struct Process *proc) +os_process_destroy(struct process *proc) { } int -os_process_clone(struct Process *retp, struct Process *proc) +os_process_clone(struct process *retp, struct process *proc) { retp->os = proc->os; return 0; } int -os_process_exec(struct Process *proc) +os_process_exec(struct process *proc) { return 0; } diff --git a/sysdeps/linux-gnu/s390/Makefile.in b/sysdeps/linux-gnu/s390/Makefile.in deleted file mode 100644 index 0f55ef5..0000000 --- a/sysdeps/linux-gnu/s390/Makefile.in +++ /dev/null @@ -1,534 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/s390 -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c \ - fetch.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent1.h \ - signalent.h \ - syscallent1.h \ - syscallent.h \ - syscalls31.h \ - syscalls64.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/s390/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/s390/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/s390/fetch.c b/sysdeps/linux-gnu/s390/fetch.c index fa8f42d..0b68dbc 100644 --- a/sysdeps/linux-gnu/s390/fetch.c +++ b/sysdeps/linux-gnu/s390/fetch.c @@ -61,7 +61,7 @@ s390x(struct fetch_context *ctx) } static int -fetch_register_banks(struct Process *proc, struct fetch_context *ctx) +fetch_register_banks(struct process *proc, struct fetch_context *ctx) { ptrace_area parea; parea.len = sizeof(ctx->regs); @@ -76,7 +76,7 @@ fetch_register_banks(struct Process *proc, struct fetch_context *ctx) } static int -fetch_context_init(struct Process *proc, struct fetch_context *context) +fetch_context_init(struct process *proc, struct fetch_context *context) { context->greg = 2; context->freg = 0; @@ -84,7 +84,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context) } struct fetch_context * -arch_fetch_arg_init(enum tof type, struct Process *proc, +arch_fetch_arg_init(enum tof type, struct process *proc, struct arg_type_info *ret_info) { struct fetch_context *context = malloc(sizeof(*context)); @@ -105,7 +105,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc, } struct fetch_context * -arch_fetch_arg_clone(struct Process *proc, +arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) { struct fetch_context *clone = malloc(sizeof(*context)); @@ -116,7 +116,7 @@ arch_fetch_arg_clone(struct Process *proc, } static int -allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, +allocate_stack_slot(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { @@ -148,7 +148,7 @@ copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) } static int -allocate_gpr(struct fetch_context *ctx, struct Process *proc, +allocate_gpr(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { @@ -160,7 +160,7 @@ allocate_gpr(struct fetch_context *ctx, struct Process *proc, } static int -allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc, +allocate_gpr_pair(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { @@ -191,7 +191,7 @@ allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc, } static int -allocate_fpr(struct fetch_context *ctx, struct Process *proc, +allocate_fpr(struct fetch_context *ctx, struct process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { @@ -212,7 +212,7 @@ allocate_fpr(struct fetch_context *ctx, struct Process *proc, int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, - struct Process *proc, + struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); @@ -267,7 +267,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, int arch_fetch_retval(struct fetch_context *ctx, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (info->type == ARGTYPE_STRUCT) { diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c index 5f612e5..8893d45 100644 --- a/sysdeps/linux-gnu/s390/plt.c +++ b/sysdeps/linux-gnu/s390/plt.c @@ -29,6 +29,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c index 0592ccd..51410d7 100644 --- a/sysdeps/linux-gnu/s390/regs.c +++ b/sysdeps/linux-gnu/s390/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2002,2004,2008,2009 Juan Cespedes * Copyright (C) 2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand @@ -45,50 +46,52 @@ #define PSW_MASK 0x7fffffff #endif -void * -get_instruction_pointer(Process *proc) { +arch_addr_t +get_instruction_pointer(struct process *proc) +{ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) & PSW_MASK; #ifdef __s390x__ if (proc->mask_32bit) ret &= PSW_MASK31; #endif - return (void *)ret; + /* XXX double cast. */ + return (arch_addr_t)ret; } void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, arch_addr_t addr) +{ #ifdef __s390x__ if (proc->mask_32bit) - addr = (void *)((long)addr & PSW_MASK31); + /* XXX double cast. */ + addr = (arch_addr_t)((uintptr_t)addr & PSW_MASK31); +#else + /* XXX double cast. */ + addr = (arch_addr_t)((uintptr_t)addr | ~PSW_MASK); #endif ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, addr); } -void * -get_stack_pointer(Process *proc) { +arch_addr_t +get_stack_pointer(struct process *proc) +{ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0) & PSW_MASK; #ifdef __s390x__ if (proc->mask_32bit) ret &= PSW_MASK31; #endif - return (void *)ret; + /* XXX double cast. */ + return (arch_addr_t)ret; } -void * -get_return_addr(Process *proc, void *stack_pointer) { +arch_addr_t +get_return_addr(struct process *proc, arch_addr_t stack_pointer) +{ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) & PSW_MASK; #ifdef __s390x__ if (proc->mask_32bit) ret &= PSW_MASK31; #endif - return (void *)ret; -} - -void -set_return_addr(Process *proc, void *addr) { -#ifdef __s390x__ - if (proc->mask_32bit) - addr = (void *)((long)addr & PSW_MASK31); -#endif - ptrace(PTRACE_POKEUSER, proc->pid, PT_GPR14, addr); + /* XXX double cast. */ + return (arch_addr_t)ret; } diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c index b9e05ff..78b04c3 100644 --- a/sysdeps/linux-gnu/s390/trace.c +++ b/sysdeps/linux-gnu/s390/trace.c @@ -43,7 +43,8 @@ #endif void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ #ifdef __s390x__ unsigned long psw; @@ -64,7 +65,8 @@ get_arch_dep(Process *proc) { /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ long pc, opcode, offset_reg, scno, tmp; void *svc_addr; int gpr_offset[16] = { PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3, @@ -175,7 +177,7 @@ syscall_p(Process *proc, int status, int *sysnum) { } size_t -arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +arch_type_sizeof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; @@ -217,7 +219,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info) } size_t -arch_type_alignof(struct Process *proc, struct arg_type_info *info) +arch_type_alignof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; diff --git a/sysdeps/linux-gnu/sparc/Makefile.in b/sysdeps/linux-gnu/sparc/Makefile.in deleted file mode 100644 index d94a1d8..0000000 --- a/sysdeps/linux-gnu/sparc/Makefile.in +++ /dev/null @@ -1,528 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/sparc -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - syscallent.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/sparc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/sparc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c index 40bbabc..3d2e589 100644 --- a/sysdeps/linux-gnu/sparc/plt.c +++ b/sysdeps/linux-gnu/sparc/plt.c @@ -28,6 +28,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } diff --git a/sysdeps/linux-gnu/sparc/regs.c b/sysdeps/linux-gnu/sparc/regs.c index 5e5ad20..c474c83 100644 --- a/sysdeps/linux-gnu/sparc/regs.c +++ b/sysdeps/linux-gnu/sparc/regs.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2004,2008,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -27,7 +28,8 @@ #include "common.h" void * -get_instruction_pointer(Process *proc) { +get_instruction_pointer(struct process *proc) +{ proc_archdep *a = (proc_archdep *) (proc->arch_ptr); if (a->valid) return (void *)a->regs.pc; @@ -35,14 +37,16 @@ get_instruction_pointer(Process *proc) { } void -set_instruction_pointer(Process *proc, void *addr) { +set_instruction_pointer(struct process *proc, void *addr) +{ proc_archdep *a = (proc_archdep *) (proc->arch_ptr); if (a->valid) a->regs.pc = (long)addr; } void * -get_stack_pointer(Process *proc) { +get_stack_pointer(struct process *proc) +{ proc_archdep *a = (proc_archdep *) (proc->arch_ptr); if (a->valid) return (void *)a->regs.u_regs[UREG_I5]; @@ -50,7 +54,8 @@ get_stack_pointer(Process *proc) { } void * -get_return_addr(Process *proc, void *stack_pointer) { +get_return_addr(struct process *proc, void *stack_pointer) +{ proc_archdep *a = (proc_archdep *) (proc->arch_ptr); unsigned int t; if (!a->valid) @@ -61,11 +66,3 @@ get_return_addr(Process *proc, void *stack_pointer) { return (void *)a->regs.u_regs[UREG_I6] + 12; return (void *)a->regs.u_regs[UREG_I6] + 8; } - -void -set_return_addr(Process *proc, void *addr) { - proc_archdep *a = (proc_archdep *) (proc->arch_ptr); - if (!a->valid) - return; - ptrace(PTRACE_POKETEXT, proc->pid, a->regs.u_regs[UREG_I6] + 8, addr); -} diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c index e1725ff..078d406 100644 --- a/sysdeps/linux-gnu/sparc/trace.c +++ b/sysdeps/linux-gnu/sparc/trace.c @@ -31,7 +31,8 @@ #include "common.h" void -get_arch_dep(Process *proc) { +get_arch_dep(struct process *proc) +{ proc_archdep *a; if (!proc->arch_ptr) proc->arch_ptr = (void *)malloc(sizeof(proc_archdep)); @@ -43,7 +44,8 @@ get_arch_dep(Process *proc) { * Returns -1 otherwise */ int -syscall_p(Process *proc, int status, int *sysnum) { +syscall_p(struct process *proc, int status, int *sysnum) +{ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { void *ip = get_instruction_pointer(proc); @@ -66,7 +68,8 @@ syscall_p(Process *proc, int status, int *sysnum) { } long -gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +gimme_arg(enum tof type, struct process *proc, int arg_num, + struct arg_type_info *info) { proc_archdep *a = (proc_archdep *) proc->arch_ptr; if (!a->valid) { diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c index e13b761..e648b8f 100644 --- a/sysdeps/linux-gnu/trace.c +++ b/sysdeps/linux-gnu/trace.c @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2007,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2007,2011,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2010 Joe Damato * Copyright (C) 1998,2002,2003,2004,2008,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand @@ -24,29 +24,36 @@ #include "config.h" #include <asm/unistd.h> -#include <sys/types.h> -#include <sys/wait.h> #include <assert.h> #include <errno.h> +#include <gelf.h> +#include <inttypes.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> #ifdef HAVE_LIBSELINUX # include <selinux/selinux.h> #endif -#include "linux-gnu/trace.h" #include "linux-gnu/trace-defs.h" +#include "linux-gnu/trace.h" #include "backend.h" #include "breakpoint.h" #include "debug.h" #include "events.h" +#include "fetch.h" +#include "ltrace-elf.h" #include "options.h" #include "proc.h" +#include "prototype.h" #include "ptrace.h" #include "type.h" +#include "value.h" void trace_fail_warning(pid_t pid) @@ -111,7 +118,7 @@ trace_pid(pid_t pid) } void -trace_set_options(struct Process *proc) +trace_set_options(struct process *proc) { if (proc->tracesysgood & 0x80) return; @@ -148,8 +155,8 @@ static enum ecb_status event_for_pid(Event *event, void *data) { if (event->proc != NULL && event->proc->pid == (pid_t)(uintptr_t)data) - return ecb_yield; - return ecb_cont; + return ECB_YIELD; + return ECB_CONT; } static int @@ -206,7 +213,7 @@ add_task_info(struct pid_set *pids, pid_t pid) } static enum callback_status -task_stopped(struct Process *task, void *data) +task_stopped(struct process *task, void *data) { enum process_status st = process_status(task->pid); if (data != NULL) @@ -217,13 +224,13 @@ task_stopped(struct Process *task, void *data) * the meantime. This can happen when the whole thread group * is terminating. */ switch (st) { - case ps_invalid: - case ps_tracing_stop: - case ps_zombie: + case PS_INVALID: + case PS_TRACING_STOP: + case PS_ZOMBIE: return CBS_CONT; - case ps_sleeping: - case ps_stop: - case ps_other: + case PS_SLEEPING: + case PS_STOP: + case PS_OTHER: return CBS_STOP; } @@ -232,7 +239,7 @@ task_stopped(struct Process *task, void *data) /* Task is blocked if it's stopped, or if it's a vfork parent. */ static enum callback_status -task_blocked(struct Process *task, void *data) +task_blocked(struct process *task, void *data) { struct pid_set *pids = data; struct pid_task *task_info = get_task_info(pids, task->pid); @@ -246,7 +253,7 @@ task_blocked(struct Process *task, void *data) static Event *process_vfork_on_event(struct event_handler *super, Event *event); static enum callback_status -task_vforked(struct Process *task, void *data) +task_vforked(struct process *task, void *data) { if (task->event_handler != NULL && task->event_handler->on_event == &process_vfork_on_event) @@ -255,15 +262,15 @@ task_vforked(struct Process *task, void *data) } static int -is_vfork_parent(struct Process *task) +is_vfork_parent(struct process *task) { return each_task(task->leader, NULL, &task_vforked, NULL) != NULL; } static enum callback_status -send_sigstop(struct Process *task, void *data) +send_sigstop(struct process *task, void *data) { - struct Process *leader = task->leader; + struct process *leader = task->leader; struct pid_set *pids = data; /* Look for pre-existing task record, or add new. */ @@ -299,8 +306,8 @@ send_sigstop(struct Process *task, void *data) * vforked process. We set up event handler specially to hint * us. In that case parent is in D state, which we use to * weed out unnecessary looping. */ - if (st == ps_sleeping - && is_vfork_parent (task)) { + if (st == PS_SLEEPING + && is_vfork_parent(task)) { task_info->vforked = 1; return CBS_CONT; } @@ -321,20 +328,22 @@ send_sigstop(struct Process *task, void *data) breakpoint where IP points and let the process continue. After this the breakpoint can be retracted and the process detached. */ static void -ugly_workaround(struct Process *proc) +ugly_workaround(struct process *proc) { - void *ip = get_instruction_pointer(proc); - struct breakpoint *sbp = dict_find_entry(proc->leader->breakpoints, ip); - if (sbp != NULL) - enable_breakpoint(proc, sbp); - else - insert_breakpoint(proc, ip, NULL); + arch_addr_t ip = get_instruction_pointer(proc); + struct breakpoint *found; + if (DICT_FIND_VAL(proc->leader->breakpoints, &ip, &found) < 0) { + insert_breakpoint_at(proc, ip, NULL); + } else { + assert(found != NULL); + enable_breakpoint(proc, found); + } ptrace(PTRACE_CONT, proc->pid, 0, 0); } static void process_stopping_done(struct process_stopping_handler *self, - struct Process *leader) + struct process *leader) { debug(DEBUG_PROCESS, "process stopping done %d", self->task_enabling_breakpoint->pid); @@ -351,7 +360,7 @@ process_stopping_done(struct process_stopping_handler *self, if (self->exiting) { ugly_workaround: - self->state = psh_ugly_workaround; + self->state = PSH_UGLY_WORKAROUND; ugly_workaround(self->task_enabling_breakpoint); } else { switch ((self->ugly_workaround_p)(self)) { @@ -377,11 +386,11 @@ undo_breakpoint(Event *event, void *data) && event->proc->leader == data && event->type == EVENT_BREAKPOINT) set_instruction_pointer(event->proc, event->e_un.brk_addr); - return ecb_cont; + return ECB_CONT; } static enum callback_status -untrace_task(struct Process *task, void *data) +untrace_task(struct process *task, void *data) { if (task != data) untrace_pid(task->pid); @@ -389,7 +398,7 @@ untrace_task(struct Process *task, void *data) } static enum callback_status -remove_task(struct Process *task, void *data) +remove_task(struct process *task, void *data) { /* Don't untrace leader just yet. */ if (task != data) @@ -398,14 +407,14 @@ remove_task(struct Process *task, void *data) } static enum callback_status -retract_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data) +retract_breakpoint_cb(struct process *proc, struct breakpoint *bp, void *data) { breakpoint_on_retract(bp, proc); return CBS_CONT; } static void -detach_process(struct Process *leader) +detach_process(struct process *leader) { each_qd_event(&undo_breakpoint, leader); disable_all_breakpoints(leader); @@ -414,7 +423,7 @@ detach_process(struct Process *leader) /* Now untrace the process, if it was attached to by -p. */ struct opt_p_t *it; for (it = opt_p; it != NULL; it = it->next) { - struct Process *proc = pid2proc(it->pid); + struct process *proc = pid2proc(it->pid); if (proc == NULL) continue; if (proc->leader == leader) { @@ -540,19 +549,13 @@ all_stops_accountable(struct pid_set *pids) return 1; } -/* The protocol is: 0 for success, negative for failure, positive if - * default singlestep is to be used. */ -int arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, - int (*add_cb)(void *addr, void *data), - void *add_cb_data); - -#ifndef ARCH_HAVE_ATOMIC_SINGLESTEP -int -arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, - int (*add_cb)(void *addr, void *data), - void *add_cb_data) +#ifndef ARCH_HAVE_SW_SINGLESTEP +enum sw_singlestep_status +arch_sw_singlestep(struct process *proc, struct breakpoint *bp, + int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), + struct sw_singlestep_data *data) { - return 1; + return SWS_HW; } #endif @@ -560,74 +563,84 @@ static Event *process_stopping_on_event(struct event_handler *super, Event *event); static void -remove_atomic_breakpoints(struct Process *proc) +remove_sw_breakpoints(struct process *proc) { struct process_stopping_handler *self = (void *)proc->leader->event_handler; assert(self != NULL); assert(self->super.on_event == process_stopping_on_event); - int ct = sizeof(self->atomic_skip_bp_addrs) - / sizeof(*self->atomic_skip_bp_addrs); + int ct = sizeof(self->sws_bps) / sizeof(*self->sws_bps); int i; for (i = 0; i < ct; ++i) - if (self->atomic_skip_bp_addrs[i] != 0) { - delete_breakpoint(proc, self->atomic_skip_bp_addrs[i]); - self->atomic_skip_bp_addrs[i] = 0; + if (self->sws_bps[i] != NULL) { + delete_breakpoint_at(proc, self->sws_bps[i]->addr); + self->sws_bps[i] = NULL; } } static void -atomic_singlestep_bp_on_hit(struct breakpoint *bp, struct Process *proc) +sw_singlestep_bp_on_hit(struct breakpoint *bp, struct process *proc) { - remove_atomic_breakpoints(proc); + remove_sw_breakpoints(proc); } +struct sw_singlestep_data { + struct process_stopping_handler *self; +}; + static int -atomic_singlestep_add_bp(void *addr, void *data) +sw_singlestep_add_bp(arch_addr_t addr, struct sw_singlestep_data *data) { - struct process_stopping_handler *self = data; - struct Process *proc = self->task_enabling_breakpoint; + struct process_stopping_handler *self = data->self; + struct process *proc = self->task_enabling_breakpoint; - int ct = sizeof(self->atomic_skip_bp_addrs) - / sizeof(*self->atomic_skip_bp_addrs); + int ct = sizeof(self->sws_bps) / sizeof(*self->sws_bps); int i; for (i = 0; i < ct; ++i) - if (self->atomic_skip_bp_addrs[i] == 0) { - self->atomic_skip_bp_addrs[i] = addr; + if (self->sws_bps[i] == NULL) { static struct bp_callbacks cbs = { - .on_hit = atomic_singlestep_bp_on_hit, + .on_hit = sw_singlestep_bp_on_hit, }; struct breakpoint *bp - = insert_breakpoint(proc, addr, NULL); + = insert_breakpoint_at(proc, addr, NULL); breakpoint_set_callbacks(bp, &cbs); + self->sws_bps[i] = bp; return 0; } - assert(!"Too many atomic singlestep breakpoints!"); + assert(!"Too many sw singlestep breakpoints!"); abort(); } static int singlestep(struct process_stopping_handler *self) { - struct Process *proc = self->task_enabling_breakpoint; - - int status = arch_atomic_singlestep(self->task_enabling_breakpoint, - self->breakpoint_being_enabled, - &atomic_singlestep_add_bp, self); + size_t i; + for (i = 0; i < sizeof(self->sws_bps) / sizeof(*self->sws_bps); ++i) + self->sws_bps[i] = NULL; + + struct sw_singlestep_data data = { self }; + switch (arch_sw_singlestep(self->task_enabling_breakpoint, + self->breakpoint_being_enabled, + &sw_singlestep_add_bp, &data)) { + case SWS_HW: + /* Otherwise do the default action: singlestep. */ + debug(1, "PTRACE_SINGLESTEP"); + if (ptrace(PTRACE_SINGLESTEP, + self->task_enabling_breakpoint->pid, 0, 0)) { + perror("PTRACE_SINGLESTEP"); + return -1; + } + return 0; - /* Propagate failure and success. */ - if (status <= 0) - return status; + case SWS_OK: + return 0; - /* Otherwise do the default action: singlestep. */ - debug(1, "PTRACE_SINGLESTEP"); - if (ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0)) { - perror("PTRACE_SINGLESTEP"); + case SWS_FAIL: return -1; } - return 0; + abort(); } static void @@ -639,27 +652,27 @@ post_singlestep(struct process_stopping_handler *self, if (*eventp != NULL && (*eventp)->type == EVENT_BREAKPOINT) *eventp = NULL; // handled - struct Process *proc = self->task_enabling_breakpoint; + struct process *proc = self->task_enabling_breakpoint; - remove_atomic_breakpoints(proc); + remove_sw_breakpoints(proc); self->breakpoint_being_enabled = NULL; } static void singlestep_error(struct process_stopping_handler *self) { - struct Process *teb = self->task_enabling_breakpoint; + struct process *teb = self->task_enabling_breakpoint; struct breakpoint *sbp = self->breakpoint_being_enabled; fprintf(stderr, "%d couldn't continue when handling %s (%p) at %p\n", teb->pid, breakpoint_name(sbp), sbp->addr, get_instruction_pointer(teb)); - delete_breakpoint(teb->leader, sbp->addr); + delete_breakpoint_at(teb->leader, sbp->addr); } static void pt_continue(struct process_stopping_handler *self) { - struct Process *teb = self->task_enabling_breakpoint; + struct process *teb = self->task_enabling_breakpoint; debug(1, "PTRACE_CONT"); ptrace(PTRACE_CONT, teb->pid, 0, 0); } @@ -675,12 +688,12 @@ static void disable_and(struct process_stopping_handler *self, void (*do_this)(struct process_stopping_handler *self)) { - struct Process *teb = self->task_enabling_breakpoint; + struct process *teb = self->task_enabling_breakpoint; debug(DEBUG_PROCESS, "all stopped, now singlestep/cont %d", teb->pid); if (self->breakpoint_being_enabled->enabled) disable_breakpoint(teb, self->breakpoint_being_enabled); (do_this)(self); - self->state = psh_singlestep; + self->state = PSH_SINGLESTEP; } void @@ -705,9 +718,9 @@ static Event * process_stopping_on_event(struct event_handler *super, Event *event) { struct process_stopping_handler *self = (void *)super; - struct Process *task = event->proc; - struct Process *leader = task->leader; - struct Process *teb = self->task_enabling_breakpoint; + struct process *task = event->proc; + struct process *leader = task->leader; + struct process *teb = self->task_enabling_breakpoint; debug(DEBUG_PROCESS, "process_stopping_on_event: pid %d; event type %d; state %d", @@ -733,11 +746,12 @@ process_stopping_on_event(struct event_handler *super, Event *event) if (event != NULL && event->type == EVENT_SYSRET) { debug(1, "%d LT_EV_SYSRET", event->proc->pid); event_to_queue = 0; - task_info->sysret = 1; + if (task_info != NULL) + task_info->sysret = 1; } switch (state) { - case psh_stopping: + case PSH_STOPPING: /* If everyone is stopped, singlestep. */ if (each_task(leader, NULL, &task_blocked, &self->pids) == NULL) { @@ -746,7 +760,7 @@ process_stopping_on_event(struct event_handler *super, Event *event) } break; - case psh_singlestep: + case PSH_SINGLESTEP: /* In singlestep state, breakpoint signifies that we * have now stepped, and can re-enable the breakpoint. */ if (event != NULL && task == teb) { @@ -801,13 +815,14 @@ process_stopping_on_event(struct event_handler *super, Event *event) break; psh_sinking: - state = self->state = psh_sinking; - case psh_sinking: + state = self->state = PSH_SINKING; + /* Fall through. */ + case PSH_SINKING: if (await_sigstop_delivery(&self->pids, task_info, event)) process_stopping_done(self, leader); break; - case psh_ugly_workaround: + case PSH_UGLY_WORKAROUND: if (event == NULL) break; if (event->type == EVENT_BREAKPOINT) { @@ -845,7 +860,7 @@ no(struct process_stopping_handler *self) } int -process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp, +process_install_stopping_handler(struct process *proc, struct breakpoint *sbp, void (*as)(struct process_stopping_handler *), enum callback_status (*ks) (struct process_stopping_handler *), @@ -894,7 +909,7 @@ process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp, } void -continue_after_breakpoint(Process *proc, struct breakpoint *sbp) +continue_after_breakpoint(struct process *proc, struct breakpoint *sbp) { debug(DEBUG_PROCESS, "continue_after_breakpoint: pid=%d, addr=%p", @@ -904,18 +919,11 @@ continue_after_breakpoint(Process *proc, struct breakpoint *sbp) if (sbp->enabled == 0) { continue_process(proc->pid); - } else { -#if defined __sparc__ || defined __ia64___ - /* we don't want to singlestep here */ + } else if (process_install_stopping_handler + (proc, sbp, NULL, NULL, NULL) < 0) { + perror("process_stopping_handler_create"); + /* Carry on not bothering to re-enable. */ continue_process(proc->pid); -#else - if (process_install_stopping_handler - (proc, sbp, NULL, NULL, NULL) < 0) { - perror("process_stopping_handler_create"); - /* Carry on not bothering to re-enable. */ - continue_process(proc->pid); - } -#endif } } @@ -937,8 +945,8 @@ static Event * ltrace_exiting_on_event(struct event_handler *super, Event *event) { struct ltrace_exiting_handler *self = (void *)super; - struct Process *task = event->proc; - struct Process *leader = task->leader; + struct process *task = event->proc; + struct process *leader = task->leader; debug(DEBUG_PROCESS, "ltrace_exiting_on_event: pid %d; event type %d", @@ -970,7 +978,7 @@ ltrace_exiting_destroy(struct event_handler *super) } static int -ltrace_exiting_install_handler(struct Process *proc) +ltrace_exiting_install_handler(struct process *proc) { /* Only install to leader. */ if (proc->leader != proc) @@ -1035,7 +1043,7 @@ ltrace_exiting_install_handler(struct Process *proc) struct process_vfork_handler { struct event_handler super; - void *bp_addr; + int vfork_bp_refd:1; }; static Event * @@ -1046,38 +1054,33 @@ process_vfork_on_event(struct event_handler *super, Event *event) event->proc->pid, event->type); struct process_vfork_handler *self = (void *)super; - struct breakpoint *sbp; + struct process *proc = event->proc; assert(self != NULL); switch (event->type) { case EVENT_BREAKPOINT: - /* Remember the vfork return breakpoint. */ - if (self->bp_addr == 0) - self->bp_addr = event->e_un.brk_addr; + /* We turn on the vfork return breakpoint (which + * should be the one that we have tripped over just + * now) one extra time, so that the vfork parent hits + * it as well. */ + if (!self->vfork_bp_refd) { + struct breakpoint *sbp = NULL; + DICT_FIND_VAL(proc->leader->breakpoints, + &event->e_un.brk_addr, &sbp); + assert(sbp != NULL); + breakpoint_turn_on(sbp, proc->leader); + self->vfork_bp_refd = 1; + } break; case EVENT_EXIT: case EVENT_EXIT_SIGNAL: case EVENT_EXEC: - /* Smuggle back in the vfork return breakpoint, so - * that our parent can trip over it once again. */ - if (self->bp_addr != 0) { - sbp = dict_find_entry(event->proc->leader->breakpoints, - self->bp_addr); - if (sbp != NULL) - assert(sbp->libsym == NULL); - /* We don't mind failing that, it's not a big - * deal to not display one extra vfork return. */ - insert_breakpoint(event->proc->parent, - self->bp_addr, NULL); - } - - continue_process(event->proc->parent->pid); - /* Remove the leader that we artificially set up * earlier. */ - change_process_leader(event->proc, event->proc); - destroy_event_handler(event->proc); + change_process_leader(proc, proc); + destroy_event_handler(proc); + continue_process(proc->parent->pid); default: ; @@ -1087,7 +1090,7 @@ process_vfork_on_event(struct event_handler *super, Event *event) } void -continue_after_vfork(struct Process *proc) +continue_after_vfork(struct process *proc) { debug(DEBUG_PROCESS, "continue_after_vfork: pid=%d", proc->pid); struct process_vfork_handler *handler = calloc(sizeof(*handler), 1); @@ -1116,7 +1119,7 @@ continue_after_vfork(struct Process *proc) } static int -is_mid_stopping(Process *proc) +is_mid_stopping(struct process *proc) { return proc != NULL && proc->event_handler != NULL @@ -1124,7 +1127,7 @@ is_mid_stopping(Process *proc) } void -continue_after_syscall(struct Process *proc, int sysnum, int ret_p) +continue_after_syscall(struct process *proc, int sysnum, int ret_p) { /* Don't continue if we are mid-stopping. */ if (ret_p && (is_mid_stopping(proc) || is_mid_stopping(proc->leader))) { @@ -1136,6 +1139,23 @@ continue_after_syscall(struct Process *proc, int sysnum, int ret_p) continue_process(proc->pid); } +void +continue_after_exec(struct process *proc) +{ + continue_process(proc->pid); + + /* After the exec, we expect to hit the first executable + * instruction. + * + * XXX TODO It would be nice to have this removed, but then we + * need to do that also for initial call to wait_for_proc in + * execute_program. In that case we could generate a + * EVENT_FIRST event or something, or maybe this could somehow + * be rolled into EVENT_NEW. */ + wait_for_proc(proc->pid); + continue_process(proc->pid); +} + /* If ltrace gets SIGINT, the processes directly or indirectly run by * ltrace get it too. We just have to wait long enough for the signal * to be delivered and the process terminated, which we notice and @@ -1152,7 +1172,7 @@ os_ltrace_exiting(void) { struct opt_p_t *it; for (it = opt_p; it != NULL; it = it->next) { - struct Process *proc = pid2proc(it->pid); + struct process *proc = pid2proc(it->pid); if (proc == NULL || proc->leader == NULL) continue; if (ltrace_exiting_install_handler(proc->leader) < 0) @@ -1174,7 +1194,8 @@ os_ltrace_exiting_sighandler(void) } size_t -umovebytes(Process *proc, void *addr, void *laddr, size_t len) { +umovebytes(struct process *proc, void *addr, void *laddr, size_t len) +{ union { long a; @@ -1206,3 +1227,292 @@ umovebytes(Process *proc, void *addr, void *laddr, size_t len) { return bytes_read; } + +struct irelative_name_data_t { + GElf_Addr addr; + const char *found_name; +}; + +static enum callback_status +irelative_name_cb(GElf_Sym *symbol, const char *name, void *d) +{ + struct irelative_name_data_t *data = d; + + if (symbol->st_value == data->addr) { + bool is_ifunc = false; +#ifdef STT_GNU_IFUNC + is_ifunc = GELF_ST_TYPE(symbol->st_info) == STT_GNU_IFUNC; +#endif + data->found_name = name; + + /* Keep looking, unless we found the actual IFUNC + * symbol. What we matched may have been a symbol + * denoting the resolver function, which would have + * the same address. */ + return CBS_STOP_IF(is_ifunc); + } + + return CBS_CONT; +} + +char * +linux_elf_find_irelative_name(struct ltelf *lte, GElf_Addr addr) +{ + struct irelative_name_data_t data = { addr, NULL }; + if (addr != 0 + && elf_each_symbol(lte, 0, + irelative_name_cb, &data).status < 0) + return NULL; + + const char *name; + if (data.found_name != NULL) { + name = data.found_name; + } else { +#define NAME "IREL." + /* NAME\0 + 0x + digits. */ + char *tmp_name = alloca(sizeof NAME + 2 + 16); + sprintf(tmp_name, NAME "%#" PRIx64, (uint64_t) addr); + name = tmp_name; +#undef NAME + } + + return strdup(name); +} + +enum plt_status +linux_elf_add_plt_entry_irelative(struct process *proc, struct ltelf *lte, + GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) + +{ + char *name = linux_elf_find_irelative_name(lte, rela->r_addend); + int i = default_elf_add_plt_entry(proc, lte, name, rela, ndx, ret); + free(name); + return i < 0 ? PLT_FAIL : PLT_OK; +} + +struct prototype * +linux_IFUNC_prototype(void) +{ + static struct prototype ret; + if (ret.return_info == NULL) { + prototype_init(&ret); + ret.return_info = type_get_voidptr(); + ret.own_return_info = 0; + } + return &ret; +} + +int +os_library_symbol_init(struct library_symbol *libsym) +{ + libsym->os = (struct os_library_symbol_data){}; + return 0; +} + +void +os_library_symbol_destroy(struct library_symbol *libsym) +{ +} + +int +os_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym) +{ + retp->os = libsym->os; + return 0; +} + +char * +linux_append_IFUNC_to_name(const char *name) +{ +#define S ".IFUNC" + char *tmp_name = malloc(strlen(name) + sizeof S); + if (tmp_name == NULL) + return NULL; + sprintf(tmp_name, "%s%s", name, S); +#undef S + return tmp_name; +} + +enum plt_status +os_elf_add_func_entry(struct process *proc, struct ltelf *lte, + const GElf_Sym *sym, + arch_addr_t addr, const char *name, + struct library_symbol **ret) +{ + if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) + return PLT_DEFAULT; + + bool ifunc = false; +#ifdef STT_GNU_IFUNC + ifunc = GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC; +#endif + + if (ifunc) { + char *tmp_name = linux_append_IFUNC_to_name(name); + struct library_symbol *tmp = malloc(sizeof *tmp); + if (tmp_name == NULL || tmp == NULL) { + fail: + free(tmp_name); + free(tmp); + return PLT_FAIL; + } + + if (library_symbol_init(tmp, addr, tmp_name, 1, + LS_TOPLT_NONE) < 0) + goto fail; + tmp->proto = linux_IFUNC_prototype(); + tmp->os.is_ifunc = 1; + + *ret = tmp; + return PLT_OK; + } + + *ret = NULL; + return PLT_OK; +} + +static enum callback_status +libsym_at_address(struct library_symbol *libsym, void *addrp) +{ + arch_addr_t addr = *(arch_addr_t *)addrp; + return CBS_STOP_IF(addr == libsym->enter_addr); +} + +static void +ifunc_ret_hit(struct breakpoint *bp, struct process *proc) +{ + struct fetch_context *fetch = fetch_arg_init(LT_TOF_FUNCTION, proc, + type_get_voidptr()); + if (fetch == NULL) + return; + + struct breakpoint *nbp = NULL; + int own_libsym = 0; + + struct value value; + value_init(&value, proc, NULL, type_get_voidptr(), 0); + size_t sz = value_size(&value, NULL); + union { + uint64_t u64; + uint32_t u32; + arch_addr_t a; + } u; + + if (fetch_retval(fetch, LT_TOF_FUNCTIONR, proc, + value.type, &value) < 0 + || sz > 8 /* Captures failure as well. */ + || value_extract_buf(&value, (void *) &u, NULL) < 0) { + fail: + fprintf(stderr, + "Couldn't trace the function " + "indicated by IFUNC resolver.\n"); + goto done; + } + + assert(sz == 4 || sz == 8); + /* XXX double casts below: */ + if (sz == 4) + u.a = (arch_addr_t)(uintptr_t)u.u32; + else + u.a = (arch_addr_t)(uintptr_t)u.u64; + if (arch_translate_address_dyn(proc, u.a, &u.a) < 0) { + fprintf(stderr, "Couldn't OPD-translate the address returned" + " by the IFUNC resolver.\n"); + goto done; + } + + assert(bp->os.ret_libsym != NULL); + + struct library *lib = bp->os.ret_libsym->lib; + assert(lib != NULL); + + /* Look if we already have a symbol with this address. + * Otherwise create a new one. */ + struct library_symbol *libsym + = library_each_symbol(lib, NULL, libsym_at_address, &u.a); + if (libsym == NULL) { + libsym = malloc(sizeof *libsym); + char *name = strdup(bp->os.ret_libsym->name); + + if (libsym == NULL + || name == NULL + || library_symbol_init(libsym, u.a, name, 1, + LS_TOPLT_NONE) < 0) { + free(libsym); + free(name); + goto fail; + } + + /* Snip the .IFUNC token. */ + *strrchr(name, '.') = 0; + + own_libsym = 1; + library_add_symbol(lib, libsym); + } + + nbp = malloc(sizeof *bp); + if (nbp == NULL || breakpoint_init(nbp, proc, u.a, libsym) < 0) + goto fail; + + /* If there already is a breakpoint at that address, that is + * suspicious, but whatever. */ + struct breakpoint *pre_bp = insert_breakpoint(proc, nbp); + if (pre_bp == NULL) + goto fail; + if (pre_bp == nbp) { + /* PROC took our breakpoint, so these resources are + * not ours anymore. */ + nbp = NULL; + own_libsym = 0; + } + +done: + free(nbp); + if (own_libsym) { + library_symbol_destroy(libsym); + free(libsym); + } + fetch_arg_done(fetch); +} + +static int +create_ifunc_ret_bp(struct breakpoint **ret, + struct breakpoint *bp, struct process *proc) +{ + *ret = create_default_return_bp(proc); + if (*ret == NULL) + return -1; + static struct bp_callbacks cbs = { + .on_hit = ifunc_ret_hit, + }; + breakpoint_set_callbacks(*ret, &cbs); + + (*ret)->os.ret_libsym = bp->libsym; + + return 0; +} + +int +os_breakpoint_init(struct process *proc, struct breakpoint *bp) +{ + if (bp->libsym != NULL && bp->libsym->os.is_ifunc) { + static struct bp_callbacks cbs = { + .get_return_bp = create_ifunc_ret_bp, + }; + breakpoint_set_callbacks(bp, &cbs); + } + return 0; +} + +void +os_breakpoint_destroy(struct breakpoint *bp) +{ +} + +int +os_breakpoint_clone(struct breakpoint *retp, struct breakpoint *bp) +{ + return 0; +} diff --git a/sysdeps/linux-gnu/trace.h b/sysdeps/linux-gnu/trace.h index 88ac33d..94844dd 100644 --- a/sysdeps/linux-gnu/trace.h +++ b/sysdeps/linux-gnu/trace.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. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -59,13 +59,13 @@ struct process_stopping_handler struct event_handler super; /* The task that is doing the re-enablement. */ - struct Process *task_enabling_breakpoint; + struct process *task_enabling_breakpoint; /* The pointer being re-enabled. */ struct breakpoint *breakpoint_being_enabled; - /* Artificial atomic skip breakpoint, if any needed. */ - void *atomic_skip_bp_addrs[2]; + /* Software singlestep breakpoints, if any needed. */ + struct breakpoint *sws_bps[2]; /* When all tasks are stopped, this callback gets called. */ void (*on_all_stopped)(struct process_stopping_handler *); @@ -84,17 +84,17 @@ struct process_stopping_handler enum { /* We are waiting for everyone to land in t/T. */ - psh_stopping = 0, + PSH_STOPPING = 0, /* We are doing the PTRACE_SINGLESTEP. */ - psh_singlestep, + PSH_SINGLESTEP, /* We are waiting for all the SIGSTOPs to arrive so * that we can sink them. */ - psh_sinking, + PSH_SINKING, /* This is for tracking the ugly workaround. */ - psh_ugly_workaround, + PSH_UGLY_WORKAROUND, } state; int exiting; @@ -108,7 +108,7 @@ struct process_stopping_handler * ON_ALL_STOPPED is LINUX_PTRACE_DISABLE_AND_SINGLESTEP, the default * for KEEP_STEPPING_P and UGLY_WORKAROUND_P is "no". */ int process_install_stopping_handler - (struct Process *proc, struct breakpoint *sbp, + (struct process *proc, struct breakpoint *sbp, void (*on_all_stopped)(struct process_stopping_handler *), enum callback_status (*keep_stepping_p) (struct process_stopping_handler *), @@ -118,4 +118,37 @@ int process_install_stopping_handler void linux_ptrace_disable_and_singlestep(struct process_stopping_handler *self); void linux_ptrace_disable_and_continue(struct process_stopping_handler *self); +/* When main binary needs to call an IFUNC function defined in the + * binary itself, a PLT entry is set up so that dynamic linker can get + * involved and resolve the symbol. But unlike other PLT relocation, + * this one can't rely on symbol table being available. So it doesn't + * reference the symbol by its name, but by its address, and + * correspondingly, has another type. When arch backend wishes to + * support these IRELATIVE relocations, it should override + * arch_elf_add_plt_entry and dispatch to this function for IRELATIVE + * relocations. + * + * This function behaves as arch_elf_add_plt_entry, except that it + * doesn't take name for a parameter, but instead looks up the name in + * symbol tables in LTE. */ +enum plt_status linux_elf_add_plt_entry_irelative(struct process *proc, + struct ltelf *lte, + GElf_Rela *rela, size_t ndx, + struct library_symbol **ret); + +/* Service routine of the above. Determines a name corresponding to + * ADDR, or invents a new one. Returns NULL on failures, otherwise it + * returns a malloc'd pointer that the caller is responsible for + * freeing. */ +char *linux_elf_find_irelative_name(struct ltelf *lte, GElf_Addr addr); + +/* Returns ${NAME}.IFUNC in a newly-malloc'd block, or NULL on + * failures. */ +char *linux_append_IFUNC_to_name(const char *name); + +/* Returns a statically allocated prototype that represents the + * prototype "void *()". Never fails. */ +struct prototype *linux_IFUNC_prototype(void); + + #endif /* _LTRACE_LINUX_TRACE_H_ */ diff --git a/sysdeps/linux-gnu/x86/Makefile.in b/sysdeps/linux-gnu/x86/Makefile.in deleted file mode 100644 index bb7bc9f..0000000 --- a/sysdeps/linux-gnu/x86/Makefile.in +++ /dev/null @@ -1,532 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# This file is part of ltrace. -# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix -# -# 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 - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = sysdeps/linux-gnu/x86 -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ - $(top_srcdir)/config/m4/ltoptions.m4 \ - $(top_srcdir)/config/m4/ltsugar.m4 \ - $(top_srcdir)/config/m4/ltversion.m4 \ - $(top_srcdir)/config/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -___libcpu_la_LIBADD = -am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo -___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) -am__dirstamp = $(am__leading_dot)dirstamp -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(___libcpu_la_SOURCES) -DIST_SOURCES = $(___libcpu_la_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_VALGRIND = @HAVE_VALGRIND@ -HOST_CPU = @HOST_CPU@ -HOST_OS = @HOST_OS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ -liberty_LIBS = @liberty_LIBS@ -libexecdir = @libexecdir@ -libstdcxx_LIBS = @libstdcxx_LIBS@ -libsupcxx_LIBS = @libsupcxx_LIBS@ -libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ -libunwind_LIBS = @libunwind_LIBS@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = \ - ../libcpu.la - -___libcpu_la_SOURCES = \ - plt.c \ - regs.c \ - trace.c \ - fetch.c - -noinst_HEADERS = \ - arch.h \ - ptrace.h \ - signalent.h \ - signalent1.h \ - syscallent.h \ - syscallent1.h - -MAINTAINERCLEANFILES = \ - Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/x86/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign sysdeps/linux-gnu/x86/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -../$(am__dirstamp): - @$(MKDIR_P) .. - @: > ../$(am__dirstamp) -../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) - $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../.libs ../_libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h index 329cfba..da5bd33 100644 --- a/sysdeps/linux-gnu/x86/arch.h +++ b/sysdeps/linux-gnu/x86/arch.h @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011, 2012 Petr Machata + * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2006 Ian Wienand * Copyright (C) 2004 Juan Cespedes * @@ -28,6 +28,8 @@ #define ARCH_HAVE_ALIGNOF #define ARCH_ENDIAN_LITTLE +#define ARCH_HAVE_ADD_PLT_ENTRY + #ifdef __x86_64__ #define LT_ELFCLASS ELFCLASS64 #define LT_ELF_MACHINE EM_X86_64 diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c index 4dab4cc..6868101 100644 --- a/sysdeps/linux-gnu/x86/fetch.c +++ b/sysdeps/linux-gnu/x86/fetch.c @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011,2012 Petr Machata + * Copyright (C) 2011,2012,2013 Petr Machata * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -58,9 +58,10 @@ struct fetch_context struct user_regs_struct iregs; struct user_fpregs_struct fpregs; - void *stack_pointer; + arch_addr_t stack_pointer; size_t ireg; /* Used-up integer registers. */ size_t freg; /* Used-up floating registers. */ + int machine; union { struct { @@ -137,14 +138,14 @@ allocate_stack_slot(struct fetch_context *context, struct value *valuep, size_t sz, size_t offset, size_t archw) { + assert(valuep != NULL); size_t a = type_alignof(valuep->inferior, valuep->type); if (a < archw) a = archw; context->stack_pointer = (void *)align((unsigned long)context->stack_pointer, a); - if (valuep != NULL) - value_in_inferior(valuep, context->stack_pointer); + value_in_inferior(valuep, context->stack_pointer); context->stack_pointer += sz; } @@ -238,21 +239,42 @@ allocate_integer(struct fetch_context *context, struct value *valuep, case POOL_SYSCALL: #ifdef __x86_64__ - switch (context->ireg) { - HANDLE(0, rdi); - HANDLE(1, rsi); - HANDLE(2, rdx); - HANDLE(3, r10); - HANDLE(4, r8); - HANDLE(5, r9); - default: - assert(!"More than six syscall arguments???"); - abort(); + if (context->machine == EM_X86_64) { + switch (context->ireg) { + HANDLE(0, rdi); + HANDLE(1, rsi); + HANDLE(2, rdx); + HANDLE(3, r10); + HANDLE(4, r8); + HANDLE(5, r9); + default: + assert(!"More than six syscall arguments???"); + abort(); + } } +#endif + if (context->machine == EM_386) { + +#ifdef __x86_64__ +# define HANDLE32(NUM, WHICH) HANDLE(NUM, r##WHICH) #else - i386_unreachable(); +# define HANDLE32(NUM, WHICH) HANDLE(NUM, e##WHICH) #endif + switch (context->ireg) { + HANDLE32(0, bx); + HANDLE32(1, cx); + HANDLE32(2, dx); + HANDLE32(3, si); + HANDLE32(4, di); + HANDLE32(5, bp); + default: + assert(!"More than six syscall arguments???"); + abort(); + } +#undef HANDLE32 + } + case POOL_RETVAL: switch (context->ireg) { #ifdef __x86_64__ @@ -323,14 +345,14 @@ allocate_class(enum arg_class cls, struct fetch_context *context, } static ssize_t -classify(struct Process *proc, struct fetch_context *context, - struct arg_type_info *info, struct value *valuep, enum arg_class classes[], +classify(struct process *proc, struct fetch_context *context, + struct arg_type_info *info, enum arg_class classes[], size_t sz, size_t eightbytes); /* This classifies one eightbyte part of an array or struct. */ static ssize_t -classify_eightbyte(struct Process *proc, struct fetch_context *context, - struct arg_type_info *info, struct value *valuep, +classify_eightbyte(struct process *proc, struct fetch_context *context, + struct arg_type_info *info, enum arg_class *classp, size_t start, size_t end, struct arg_type_info *(*getter)(struct arg_type_info *, size_t)) @@ -343,7 +365,7 @@ classify_eightbyte(struct Process *proc, struct fetch_context *context, size_t sz = type_sizeof(proc, info2); if (sz == (size_t)-1) return -1; - if (classify(proc, context, info2, valuep, &cls2, sz, 1) < 0) + if (classify(proc, context, info2, &cls2, sz, 1) < 0) return -1; if (cls == CLASS_NO) @@ -364,8 +386,8 @@ classify_eightbyte(struct Process *proc, struct fetch_context *context, /* This classifies small arrays and structs. */ static ssize_t -classify_eightbytes(struct Process *proc, struct fetch_context *context, - struct arg_type_info *info, struct value *valuep, +classify_eightbytes(struct process *proc, struct fetch_context *context, + struct arg_type_info *info, enum arg_class classes[], size_t elements, size_t eightbytes, struct arg_type_info *(*getter)(struct arg_type_info *, @@ -384,9 +406,9 @@ classify_eightbytes(struct Process *proc, struct fetch_context *context, } enum arg_class cls1, cls2; - if (classify_eightbyte(proc, context, info, valuep, &cls1, + if (classify_eightbyte(proc, context, info, &cls1, 0, start_2nd, getter) < 0 - || classify_eightbyte(proc, context, info, valuep, &cls2, + || classify_eightbyte(proc, context, info, &cls2, start_2nd, elements, getter) < 0) return -1; @@ -400,7 +422,7 @@ classify_eightbytes(struct Process *proc, struct fetch_context *context, return 2; } - return classify_eightbyte(proc, context, info, valuep, classes, + return classify_eightbyte(proc, context, info, classes, 0, elements, getter); } @@ -432,8 +454,8 @@ flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info) } static ssize_t -classify(struct Process *proc, struct fetch_context *context, - struct arg_type_info *info, struct value *valuep, enum arg_class classes[], +classify(struct process *proc, struct fetch_context *context, + struct arg_type_info *info, enum arg_class classes[], size_t sz, size_t eightbytes) { switch (info->type) { @@ -474,7 +496,7 @@ classify(struct Process *proc, struct fetch_context *context, if (expr_eval_constant(info->u.array_info.length, &l) < 0) return -1; - return classify_eightbytes(proc, context, info, valuep, classes, + return classify_eightbytes(proc, context, info, classes, (size_t)l, eightbytes, get_array_field); @@ -492,7 +514,7 @@ classify(struct Process *proc, struct fetch_context *context, goto done; } ret = classify_eightbytes(proc, context, &flattened, - valuep, classes, + classes, type_struct_size(&flattened), eightbytes, type_struct_get); done: @@ -517,7 +539,7 @@ pass_by_reference(struct value *valuep, enum arg_class classes[]) } static ssize_t -classify_argument(struct Process *proc, struct fetch_context *context, +classify_argument(struct process *proc, struct fetch_context *context, struct arg_type_info *info, struct value *valuep, enum arg_class classes[], size_t *sizep) { @@ -541,11 +563,11 @@ classify_argument(struct Process *proc, struct fetch_context *context, return pass_by_reference(valuep, classes); } - return classify(proc, context, info, valuep, classes, sz, eightbytes); + return classify(proc, context, info, classes, sz, eightbytes); } static int -fetch_register_banks(struct Process *proc, struct fetch_context *context, +fetch_register_banks(struct process *proc, struct fetch_context *context, int floating) { if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0) @@ -566,12 +588,21 @@ fetch_register_banks(struct Process *proc, struct fetch_context *context, static int arch_fetch_arg_next_32(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { size_t sz = type_sizeof(proc, info); if (sz == (size_t)-1) return -1; + if (value_reserve(valuep, sz) == NULL) + return -1; + + if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { + int cls = allocate_integer(context, valuep, + sz, 0, POOL_SYSCALL); + assert(cls == CLASS_INTEGER); + return 0; + } allocate_stack_slot(context, valuep, sz, 0, 4); @@ -580,7 +611,7 @@ arch_fetch_arg_next_32(struct fetch_context *context, enum tof type, static int arch_fetch_retval_32(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) @@ -646,7 +677,7 @@ fetch_stack_pointer(struct fetch_context *context) struct fetch_context * arch_fetch_arg_init_32(struct fetch_context *context, - enum tof type, struct Process *proc, + enum tof type, struct process *proc, struct arg_type_info *ret_info) { context->stack_pointer = fetch_stack_pointer(context) + 4; @@ -673,7 +704,7 @@ arch_fetch_arg_init_32(struct fetch_context *context, struct fetch_context * arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type, - struct Process *proc, struct arg_type_info *ret_info) + struct process *proc, struct arg_type_info *ret_info) { /* The first stack slot holds a return address. */ ctx->stack_pointer = fetch_stack_pointer(ctx) + 8; @@ -698,12 +729,13 @@ arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type, } struct fetch_context * -arch_fetch_arg_init(enum tof type, struct Process *proc, +arch_fetch_arg_init(enum tof type, struct process *proc, struct arg_type_info *ret_info) { struct fetch_context *ctx = malloc(sizeof(*ctx)); if (ctx == NULL) return NULL; + ctx->machine = proc->e_machine; assert(type != LT_TOF_FUNCTIONR && type != LT_TOF_SYSCALLR); @@ -724,7 +756,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc, } struct fetch_context * -arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) +arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) { struct fetch_context *ret = malloc(sizeof(*ret)); if (ret == NULL) @@ -734,7 +766,7 @@ arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) static int arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep, enum reg_pool pool) { enum arg_class classes[2]; @@ -776,7 +808,7 @@ arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type, int arch_fetch_fun_retval(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { assert(type != LT_TOF_FUNCTION @@ -808,7 +840,7 @@ arch_fetch_fun_retval(struct fetch_context *context, enum tof type, int arch_fetch_arg_next(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (proc->e_machine == EM_386) @@ -832,7 +864,7 @@ arch_fetch_arg_next(struct fetch_context *context, enum tof type, int arch_fetch_retval(struct fetch_context *context, enum tof type, - struct Process *proc, struct arg_type_info *info, + struct process *proc, struct arg_type_info *info, struct value *valuep) { if (proc->e_machine == EM_386) diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c index dc6f183..6d11987 100644 --- a/sysdeps/linux-gnu/x86/plt.c +++ b/sysdeps/linux-gnu/x86/plt.c @@ -1,5 +1,6 @@ /* * This file is part of ltrace. + * Copyright (C) 2013 Petr Machata, Red Hat Inc. * Copyright (C) 2004,2008,2009 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -19,16 +20,45 @@ */ #include <gelf.h> +#include <stdbool.h> + #include "proc.h" #include "common.h" #include "library.h" +#include "trace.h" GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) +{ return lte->plt_addr + (ndx + 1) * 16; } void * -sym2addr(Process *proc, struct library_symbol *sym) { +sym2addr(struct process *proc, struct library_symbol *sym) +{ return sym->enter_addr; } + +enum plt_status +arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + bool irelative = false; + if (lte->ehdr.e_machine == EM_X86_64) { +#ifdef R_X86_64_IRELATIVE + irelative = GELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE; +#endif + } else { + assert(lte->ehdr.e_machine == EM_386); +#ifdef R_386_IRELATIVE + irelative = GELF_R_TYPE(rela->r_info) == R_386_IRELATIVE; +#endif + } + + if (irelative) + return linux_elf_add_plt_entry_irelative(proc, lte, rela, + ndx, ret); + + return PLT_DEFAULT; +} diff --git a/sysdeps/linux-gnu/x86/regs.c b/sysdeps/linux-gnu/x86/regs.c index ca6470b..0a42c6e 100644 --- a/sysdeps/linux-gnu/x86/regs.c +++ b/sysdeps/linux-gnu/x86/regs.c @@ -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) 1998,2002,2004,2008,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -56,7 +56,7 @@ conv_32(arch_addr_t val) } void * -get_instruction_pointer(struct Process *proc) +get_instruction_pointer(struct process *proc) { long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, XIP, 0); if (proc->e_machine == EM_386) @@ -65,7 +65,7 @@ get_instruction_pointer(struct Process *proc) } void -set_instruction_pointer(struct Process *proc, arch_addr_t addr) +set_instruction_pointer(struct process *proc, arch_addr_t addr) { if (proc->e_machine == EM_386) addr = conv_32(addr); @@ -73,7 +73,7 @@ set_instruction_pointer(struct Process *proc, arch_addr_t addr) } void * -get_stack_pointer(struct Process *proc) +get_stack_pointer(struct process *proc) { long sp = ptrace(PTRACE_PEEKUSER, proc->pid, XSP, 0); if (sp == -1 && errno) { @@ -91,7 +91,7 @@ get_stack_pointer(struct Process *proc) } void * -get_return_addr(struct Process *proc, void *sp) +get_return_addr(struct process *proc, void *sp) { long a = ptrace(PTRACE_PEEKTEXT, proc->pid, sp, 0); if (a == -1 && errno) { @@ -107,10 +107,3 @@ get_return_addr(struct Process *proc, void *sp) ret = conv_32(ret); return ret; } - -void -set_return_addr(Process *proc, void *addr) { - if (proc->e_machine == EM_386) - addr = (void *)((long int)addr & 0xffffffff); - ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr); -} diff --git a/sysdeps/linux-gnu/x86/trace.c b/sysdeps/linux-gnu/x86/trace.c index ed8bdb4..6a1a6a5 100644 --- a/sysdeps/linux-gnu/x86/trace.c +++ b/sysdeps/linux-gnu/x86/trace.c @@ -55,7 +55,7 @@ static const int x86_64 = 0; #endif void -get_arch_dep(struct Process *proc) +get_arch_dep(struct process *proc) { /* Unfortunately there are still remnants of mask_32bit uses * around. */ @@ -75,7 +75,7 @@ get_arch_dep(struct Process *proc) /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int -syscall_p(struct Process *proc, int status, int *sysnum) +syscall_p(struct process *proc, int status, int *sysnum) { if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { @@ -109,7 +109,7 @@ syscall_p(struct Process *proc, int status, int *sysnum) } size_t -arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +arch_type_sizeof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; @@ -151,7 +151,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info) } size_t -arch_type_alignof(struct Process *proc, struct arg_type_info *info) +arch_type_alignof(struct process *proc, struct arg_type_info *info) { if (proc == NULL) return (size_t)-2; |