aboutsummaryrefslogtreecommitdiff
path: root/libop
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitcc2ee177dbb3befca43e36cfc56778b006c3d050 (patch)
treec561d5191fe681fc92caf07156a5b2f5fe6642ba /libop
downloadoprofile-cc2ee177dbb3befca43e36cfc56778b006c3d050.tar.gz
external/oprofile 0.9.1upstream/0.9.1
Diffstat (limited to 'libop')
-rw-r--r--libop/Makefile.am23
-rw-r--r--libop/Makefile.in570
-rw-r--r--libop/op_alloc_counter.c169
-rw-r--r--libop/op_alloc_counter.h43
-rw-r--r--libop/op_config.h33
-rw-r--r--libop/op_config_24.h73
-rw-r--r--libop/op_cpu_type.c139
-rw-r--r--libop/op_cpu_type.h118
-rw-r--r--libop/op_events.c827
-rw-r--r--libop/op_events.h125
-rw-r--r--libop/op_get_interface.c32
-rw-r--r--libop/op_hw_config.h30
-rw-r--r--libop/op_interface.h87
-rw-r--r--libop/op_mangle.c97
-rw-r--r--libop/op_mangle.h65
-rw-r--r--libop/op_parse_event.c120
-rw-r--r--libop/op_parse_event.h42
-rw-r--r--libop/op_sample_file.h38
-rw-r--r--libop/tests/Makefile.am33
-rw-r--r--libop/tests/Makefile.in554
-rw-r--r--libop/tests/alloc_counter_tests.c207
-rw-r--r--libop/tests/cpu_type_tests.c79
-rw-r--r--libop/tests/load_events_files_tests.c31
-rw-r--r--libop/tests/mangle_tests.c67
-rw-r--r--libop/tests/parse_event_tests.c60
25 files changed, 3662 insertions, 0 deletions
diff --git a/libop/Makefile.am b/libop/Makefile.am
new file mode 100644
index 0000000..1caebb8
--- /dev/null
+++ b/libop/Makefile.am
@@ -0,0 +1,23 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS=-I${top_srcdir}/libutil
+AM_CFLAGS = @OP_CFLAGS@
+
+noinst_LIBRARIES = libop.a
+libop_a_SOURCES = \
+ op_events.c \
+ op_events.h \
+ op_parse_event.c \
+ op_parse_event.h \
+ op_cpu_type.c \
+ op_cpu_type.h \
+ op_mangle.c \
+ op_mangle.h \
+ op_get_interface.c \
+ op_interface.h \
+ op_alloc_counter.c \
+ op_alloc_counter.h \
+ op_hw_config.h \
+ op_config.h \
+ op_config_24.h \
+ op_sample_file.h
diff --git a/libop/Makefile.in b/libop/Makefile.in
new file mode 100644
index 0000000..07e2240
--- /dev/null
+++ b/libop/Makefile.in
@@ -0,0 +1,570 @@
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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@
+
+SOURCES = $(libop_a_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+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 = :
+subdir = libop
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/binutils.m4 \
+ $(top_srcdir)/m4/builtinexpect.m4 \
+ $(top_srcdir)/m4/compileroption.m4 \
+ $(top_srcdir)/m4/configmodule.m4 \
+ $(top_srcdir)/m4/copyifchange.m4 $(top_srcdir)/m4/docbook.m4 \
+ $(top_srcdir)/m4/extradirs.m4 $(top_srcdir)/m4/findkernel.m4 \
+ $(top_srcdir)/m4/kerneloption.m4 \
+ $(top_srcdir)/m4/kernelversion.m4 \
+ $(top_srcdir)/m4/mallocattribute.m4 \
+ $(top_srcdir)/m4/poptconst.m4 \
+ $(top_srcdir)/m4/precompiledheader.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/m4/resultyn.m4 $(top_srcdir)/m4/sstream.m4 \
+ $(top_srcdir)/m4/typedef.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libop_a_AR = $(AR) $(ARFLAGS)
+libop_a_LIBADD =
+am_libop_a_OBJECTS = op_events.$(OBJEXT) op_parse_event.$(OBJEXT) \
+ op_cpu_type.$(OBJEXT) op_mangle.$(OBJEXT) \
+ op_get_interface.$(OBJEXT) op_alloc_counter.$(OBJEXT)
+libop_a_OBJECTS = $(am_libop_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libop_a_SOURCES)
+DIST_SOURCES = $(libop_a_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFD_LIBS = @BFD_LIBS@
+CAT_ENTRY_END = @CAT_ENTRY_END@
+CAT_ENTRY_START = @CAT_ENTRY_START@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATE = @DATE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOCBOOK_ROOT = @DOCBOOK_ROOT@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_CFLAGS_MODULE = @EXTRA_CFLAGS_MODULE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KINC = @KINC@
+KSRC = @KSRC@
+KVERS = @KVERS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBERTY_LIBS = @LIBERTY_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MOC = @MOC@
+MODINSTALLDIR = @MODINSTALLDIR@
+OBJEXT = @OBJEXT@
+OPROFILE_DIR = @OPROFILE_DIR@
+OPROFILE_MODULE_ARCH = @OPROFILE_MODULE_ARCH@
+OP_CFLAGS = @OP_CFLAGS@
+OP_CXXFLAGS = @OP_CXXFLAGS@
+OP_DOCDIR = @OP_DOCDIR@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POPT_LIBS = @POPT_LIBS@
+PTRDIFF_T_TYPE = @PTRDIFF_T_TYPE@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+QT_LIB = @QT_LIB@
+QT_VERSION = @QT_VERSION@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIZE_T_TYPE = @SIZE_T_TYPE@
+STRIP = @STRIP@
+UIC = @UIC@
+VERSION = @VERSION@
+XML_CATALOG = @XML_CATALOG@
+XSLTPROC = @XSLTPROC@
+XSLTPROC_FLAGS = @XSLTPROC_FLAGS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+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_alias = @build_alias@
+datadir = @datadir@
+enable_abi_FALSE = @enable_abi_FALSE@
+enable_abi_TRUE = @enable_abi_TRUE@
+exec_prefix = @exec_prefix@
+have_qt_FALSE = @have_qt_FALSE@
+have_qt_TRUE = @have_qt_TRUE@
+have_xsltproc_FALSE = @have_xsltproc_FALSE@
+have_xsltproc_TRUE = @have_xsltproc_TRUE@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kernel_support_FALSE = @kernel_support_FALSE@
+kernel_support_TRUE = @kernel_support_TRUE@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+topdir = @topdir@
+SUBDIRS = . tests
+AM_CPPFLAGS = -I${top_srcdir}/libutil
+AM_CFLAGS = @OP_CFLAGS@
+noinst_LIBRARIES = libop.a
+libop_a_SOURCES = \
+ op_events.c \
+ op_events.h \
+ op_parse_event.c \
+ op_parse_event.h \
+ op_cpu_type.c \
+ op_cpu_type.h \
+ op_mangle.c \
+ op_mangle.h \
+ op_get_interface.c \
+ op_interface.h \
+ op_alloc_counter.c \
+ op_alloc_counter.h \
+ op_hw_config.h \
+ op_config.h \
+ op_config_24.h \
+ op_sample_file.h
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libop/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign libop/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: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libop.a: $(libop_a_OBJECTS) $(libop_a_DEPENDENCIES)
+ -rm -f libop.a
+ $(libop_a_AR) libop.a $(libop_a_OBJECTS) $(libop_a_LIBADD)
+ $(RANLIB) libop.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_alloc_counter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_cpu_type.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_events.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_get_interface.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_mangle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_parse_event.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@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) '$<'`
+uninstall-info-am:
+
+# 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):
+ @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; \
+ (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"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @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; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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 || \
+ tags="$$tags $$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; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LIBRARIES)
+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)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-noinstLIBRARIES 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
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+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
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
+ clean clean-generic clean-noinstLIBRARIES clean-recursive \
+ ctags ctags-recursive distclean distclean-compile \
+ distclean-generic distclean-recursive distclean-tags distdir \
+ dvi dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am uninstall-info-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/libop/op_alloc_counter.c b/libop/op_alloc_counter.c
new file mode 100644
index 0000000..8d20134
--- /dev/null
+++ b/libop/op_alloc_counter.c
@@ -0,0 +1,169 @@
+/**
+ * @file op_alloc_counter.c
+ * hardware counter allocation
+ *
+ * You can have silliness here.
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdlib.h>
+
+#include "op_events.h"
+#include "op_libiberty.h"
+
+
+typedef struct counter_arc_head {
+ /** the head of allowed counter for this event */
+ struct list_head next;
+} counter_arc_head;
+
+
+typedef struct counter_arc {
+ /** counter nr */
+ int counter;
+ /** the next counter allowed for this event */
+ struct list_head next;
+} counter_arc;
+
+
+/**
+ * @param pev an array of event
+ * @param nr_events number of entry in pev
+ *
+ * build an array of counter list allowed for each events
+ * counter_arc_head[i] is the list of allowed counter for pev[i] events
+ * The returned pointer is an array of nr_events entry
+ */
+static counter_arc_head *
+build_counter_arc(struct op_event const * pev[], int nr_events)
+{
+ counter_arc_head * ctr_arc;
+ int i;
+
+ ctr_arc = xmalloc(nr_events * sizeof(*ctr_arc));
+
+ for (i = 0; i < nr_events; ++i) {
+ int j;
+ u32 mask = pev[i]->counter_mask;
+
+ list_init(&ctr_arc[i].next);
+ for (j = 0; mask; ++j) {
+ if (mask & (1 << j)) {
+ counter_arc * arc =
+ xmalloc(sizeof(counter_arc));
+ arc->counter = j;
+ /* we are looping by increasing counter number,
+ * allocation use a left to right tree walking
+ * so we add at end to ensure counter will
+ * be allocated by increasing number: it's not
+ * required but a bit less surprising when
+ * debugging code
+ */
+ list_add_tail(&arc->next, &ctr_arc[i].next);
+ mask &= ~(1 << j);
+ }
+ }
+ }
+
+ return ctr_arc;
+}
+
+
+/**
+ * @param ctr_arc the array to deallocate
+ * @param nr_events number of entry in array
+ *
+ * deallocate all previously allocated resource by build_counter_arc()
+ */
+static void delete_counter_arc(counter_arc_head * ctr_arc, int nr_events)
+{
+ int i;
+ for (i = 0; i < nr_events; ++i) {
+ struct list_head * pos, * pos2;
+ list_for_each_safe(pos, pos2, &ctr_arc[i].next) {
+ counter_arc * arc = list_entry(pos, counter_arc, next);
+ list_del(&arc->next);
+ free(arc);
+ }
+ }
+ free(ctr_arc);
+}
+
+
+/**
+ * @param ctr_arc tree description, ctr_arc[i] is the i-th level of tree.
+ * @param max_depth number of entry in array ctr_arc == depth of tree
+ * @param depth current level we are exploring
+ * @param allocated_mask current counter already allocated mask
+ * @param counter_map array of counter number mapping, returned results go
+ * here
+ *
+ * return non zero on succees, in this case counter_map is set to the counter
+ * mapping number.
+ *
+ * Solution is searched through a simple backtracking exploring recursively all
+ * possible solution until one is found, prunning is done in O(1) by tracking
+ * a bitmask of already allocated counter. Walking through node is done in
+ * preorder left to right.
+ *
+ * Possible improvment if neccessary: partition counters in class of counter,
+ * two counter belong to the same class if they allow exactly the same set of
+ * event. Now using a variant of the backtrack algo can works on class of
+ * counter rather on counter (this is not an improvment if each counter goes
+ * in it's own class)
+ */
+static int
+allocate_counter(counter_arc_head const * ctr_arc, int max_depth, int depth,
+ u32 allocated_mask, size_t * counter_map)
+{
+ struct list_head * pos;
+
+ if (depth == max_depth)
+ return 1;
+
+ list_for_each(pos, &ctr_arc[depth].next) {
+ counter_arc const * arc = list_entry(pos, counter_arc, next);
+
+ if (allocated_mask & (1 << arc->counter))
+ return 0;
+
+ counter_map[depth] = arc->counter;
+
+ if (allocate_counter(ctr_arc, max_depth, depth + 1,
+ allocated_mask | (1 << arc->counter),
+ counter_map))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+size_t * map_event_to_counter(struct op_event const * pev[], int nr_events,
+ op_cpu cpu_type)
+{
+ counter_arc_head * ctr_arc;
+ size_t * counter_map;
+ int nr_counters;
+
+ nr_counters = op_get_nr_counters(cpu_type);
+ if (nr_counters < nr_events)
+ return 0;
+
+ ctr_arc = build_counter_arc(pev, nr_events);
+
+ counter_map = xmalloc(nr_counters * sizeof(size_t));
+
+ if (!allocate_counter(ctr_arc, nr_events, 0, 0, counter_map)) {
+ free(counter_map);
+ counter_map = 0;
+ }
+
+ delete_counter_arc(ctr_arc, nr_events);
+ return counter_map;
+}
diff --git a/libop/op_alloc_counter.h b/libop/op_alloc_counter.h
new file mode 100644
index 0000000..40b4ebf
--- /dev/null
+++ b/libop/op_alloc_counter.h
@@ -0,0 +1,43 @@
+/**
+ * @file op_alloc_counter.h
+ * hardware counter allocation
+ *
+ * You can have silliness here.
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_ALLOC_COUNTER_H
+#define OP_ALLOC_COUNTER_H
+
+#include <stddef.h>
+
+#include "op_cpu_type.h"
+
+struct op_event;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @param pev array of selected event we want to bind to counter
+ * @param nr_events size of pev array
+ * @param cpu_type cpu type
+ *
+ * Try to calculate a binding between passed event in pev and counter number.
+ * The binding is returned in a size_t * where returned ptr[i] is the counter
+ * number bound to pev[i]
+ */
+size_t * map_event_to_counter(struct op_event const * pev[], int nr_events,
+ op_cpu cpu_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !OP_ALLOC_COUNTER_H */
diff --git a/libop/op_config.h b/libop/op_config.h
new file mode 100644
index 0000000..6b4cfbc
--- /dev/null
+++ b/libop/op_config.h
@@ -0,0 +1,33 @@
+/**
+ * @file op_config.h
+ *
+ * Parameters a user may want to change. See
+ * also op_config_24.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_CONFIG_H
+#define OP_CONFIG_H
+
+/* various paths, duplicated in opcontrol */
+#define OP_BASE_DIR "/var/lib/oprofile/"
+#define OP_SAMPLES_DIR OP_BASE_DIR "samples/"
+#define OP_SAMPLES_CURRENT_DIR OP_SAMPLES_DIR "current/"
+#define OP_LOCK_FILE OP_BASE_DIR "lock"
+#define OP_LOG_FILE OP_BASE_DIR "oprofiled.log"
+#define OP_DUMP_STATUS OP_BASE_DIR "complete_dump"
+
+/* Global directory that stores debug files */
+#ifndef DEBUGDIR
+#define DEBUGDIR "/usr/lib/debug"
+#endif
+
+#define OPD_MAGIC "DAE\n"
+#define OPD_VERSION 0x10
+
+#endif /* OP_CONFIG_H */
diff --git a/libop/op_config_24.h b/libop/op_config_24.h
new file mode 100644
index 0000000..8767244
--- /dev/null
+++ b/libop/op_config_24.h
@@ -0,0 +1,73 @@
+/**
+ * @file op_config_24.h
+ *
+ * Parameters a user may want to change
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_CONFIG_24_H
+#define OP_CONFIG_24_H
+
+#define OP_MOUNT "/proc/sys/dev/oprofile/"
+
+#define OP_DEVICE OP_BASE_DIR "opdev"
+#define OP_NOTE_DEVICE OP_BASE_DIR "opnotedev"
+#define OP_HASH_DEVICE OP_BASE_DIR "ophashmapdev"
+
+/*@{\name module default/min/max settings */
+
+/** 65536 * sizeof(op_sample) */
+#define OP_DEFAULT_BUF_SIZE 65536
+/** we don't try to wake-up daemon until it remains more than this free entry
+ * in eviction buffer */
+#define OP_PRE_WATERMARK(buffer_size) \
+ (((buffer_size) / 8) < OP_MIN_PRE_WATERMARK \
+ ? OP_MIN_PRE_WATERMARK \
+ : (buffer_size) / 8)
+/* minimal buffer water mark before we try to wakeup daemon */
+#define OP_MIN_PRE_WATERMARK 8192
+/** maximum number of entry in samples eviction buffer */
+#define OP_MAX_BUF_SIZE 1048576
+/** minimum number of entry in samples eviction buffer */
+#define OP_MIN_BUF_SIZE (32768 + OP_PRE_WATERMARK(32768))
+
+/** 16384 * sizeof(op_note) = 273680 bytes default */
+#define OP_DEFAULT_NOTE_SIZE 16384
+/** we don't try to wake-up daemon until it remains more than this free entry
+ * in note buffer */
+#define OP_PRE_NOTE_WATERMARK(note_size) \
+ (((note_size) / 32) < OP_MIN_NOTE_PRE_WATERMARK \
+ ? OP_MIN_NOTE_PRE_WATERMARK \
+ : (note_size) / 32)
+/* minimal note buffer water mark before we try to wakeup daemon */
+#define OP_MIN_NOTE_PRE_WATERMARK 512
+/** maximum number of entry in note buffer */
+#define OP_MAX_NOTE_TABLE_SIZE 1048576
+/** minimum number of entry in note buffer */
+#define OP_MIN_NOTE_TABLE_SIZE (1024 + OP_PRE_NOTE_WATERMARK(1024))
+
+/** maximum sampling rate when using RTC */
+#define OP_MAX_RTC_COUNT 4096
+/** minimum sampling rate when using RTC */
+#define OP_MIN_RTC_COUNT 2
+
+/*@}*/
+
+/** nr entries in hash map. This is the maximum number of name components
+ * allowed. Must be a prime number */
+#define OP_HASH_MAP_NR 4093
+
+/** size of string pool in bytes */
+#define POOL_SIZE 65536
+
+#ifndef NR_CPUS
+/** maximum number of cpus present in the box */
+#define NR_CPUS 32
+#endif
+
+#endif /* OP_CONFIG_24_H */
diff --git a/libop/op_cpu_type.c b/libop/op_cpu_type.c
new file mode 100644
index 0000000..a2574a0
--- /dev/null
+++ b/libop/op_cpu_type.c
@@ -0,0 +1,139 @@
+/**
+ * @file op_cpu_type.c
+ * CPU type determination
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "op_cpu_type.h"
+
+struct cpu_descr {
+ char const * pretty;
+ char const * name;
+ op_cpu cpu;
+ unsigned int nr_counters;
+};
+
+static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = {
+ { "Pentium Pro", "i386/ppro", CPU_PPRO, 2 },
+ { "PII", "i386/pii", CPU_PII, 2 },
+ { "PIII", "i386/piii", CPU_PIII, 2 },
+ { "Athlon", "i386/athlon", CPU_ATHLON, 4 },
+ { "CPU with timer interrupt", "timer", CPU_TIMER_INT, 1 },
+ { "CPU with RTC device", "rtc", CPU_RTC, 1 },
+ { "P4 / Xeon", "i386/p4", CPU_P4, 8 },
+ { "IA64", "ia64/ia64", CPU_IA64, 4 },
+ { "Itanium", "ia64/itanium", CPU_IA64_1, 4 },
+ { "Itanium 2", "ia64/itanium2", CPU_IA64_2, 4 },
+ { "AMD64 processors", "x86-64/hammer", CPU_HAMMER, 4 },
+ { "P4 / Xeon with 2 hyper-threads", "i386/p4-ht", CPU_P4_HT2, 4 },
+ { "Alpha EV4", "alpha/ev4", CPU_AXP_EV4, 2 },
+ { "Alpha EV5", "alpha/ev5", CPU_AXP_EV5, 3 },
+ { "Alpha PCA56", "alpha/pca56", CPU_AXP_PCA56, 3 },
+ { "Alpha EV6", "alpha/ev6", CPU_AXP_EV6, 2 },
+ { "Alpha EV67", "alpha/ev67", CPU_AXP_EV67, 20 },
+ { "Pentium M (P6 core)", "i386/p6_mobile", CPU_P6_MOBILE, 2 },
+ { "ARM/XScale PMU1", "arm/xscale1", CPU_ARM_XSCALE1, 3 },
+ { "ARM/XScale PMU2", "arm/xscale2", CPU_ARM_XSCALE2, 5 },
+ { "ppc64 POWER4", "ppc64/power4", CPU_PPC64_POWER4, 8 },
+ { "ppc64 POWER5", "ppc64/power5", CPU_PPC64_POWER5, 6 },
+ { "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 },
+ { "MIPS 24K", "mips/24K", CPU_MIPS_24K, 2},
+ { "MIPS R10000", "mips/r10000", CPU_MIPS_R10000, 2 },
+ { "MIPS R12000", "mips/r12000", CPU_MIPS_R12000, 4 },
+ { "QED RM7000", "mips/rm7000", CPU_MIPS_RM7000, 1 },
+ { "PMC-Sierra RM9000", "mips/rm9000", CPU_MIPS_RM9000, 2 },
+ { "Sibyte SB1", "mips/sb1", CPU_MIPS_SB1, 4 },
+ { "NEC VR5432", "mips/vr5432", CPU_MIPS_VR5432, 2 },
+ { "NEC VR5500", "mips/vr5500", CPU_MIPS_VR5500, 2 },
+ { "e500", "ppc/e500", CPU_PPC_E500, 4 },
+};
+
+static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr);
+
+op_cpu op_get_cpu_type(void)
+{
+ int cpu_type = CPU_NO_GOOD;
+ char str[100];
+ FILE * fp;
+
+ fp = fopen("/proc/sys/dev/oprofile/cpu_type", "r");
+ if (!fp) {
+ /* Try 2.6's oprofilefs one instead. */
+ fp = fopen("/dev/oprofile/cpu_type", "r");
+ if (!fp) {
+ fprintf(stderr, "Unable to open cpu_type file for reading\n");
+ fprintf(stderr, "Make sure you have done opcontrol --init\n");
+ return cpu_type;
+ }
+ }
+
+ if (!fgets(str, 99, fp)) {
+ fprintf(stderr, "Could not read cpu type.\n");
+ return CPU_NO_GOOD;
+ }
+
+ cpu_type = op_get_cpu_number(str);
+
+ fclose(fp);
+
+ return cpu_type;
+}
+
+
+op_cpu op_get_cpu_number(char const * cpu_string)
+{
+ int cpu_type = CPU_NO_GOOD;
+ size_t i;
+
+ for (i = 0; i < nr_cpu_descrs; ++i) {
+ if (!strcmp(cpu_descrs[i].name, cpu_string)) {
+ cpu_type = cpu_descrs[i].cpu;
+ break;
+ }
+ }
+
+ /* Attempt to convert into a number */
+ if (cpu_type == CPU_NO_GOOD)
+ sscanf(cpu_string, "%d\n", &cpu_type);
+
+ if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
+ cpu_type = CPU_NO_GOOD;
+
+ return cpu_type;
+}
+
+
+char const * op_get_cpu_type_str(op_cpu cpu_type)
+{
+ if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
+ return "invalid cpu type";
+
+ return cpu_descrs[cpu_type].pretty;
+}
+
+
+char const * op_get_cpu_name(op_cpu cpu_type)
+{
+ if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
+ return "invalid cpu type";
+
+ return cpu_descrs[cpu_type].name;
+}
+
+
+int op_get_nr_counters(op_cpu cpu_type)
+{
+ if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
+ return 0;
+
+ return cpu_descrs[cpu_type].nr_counters;
+}
diff --git a/libop/op_cpu_type.h b/libop/op_cpu_type.h
new file mode 100644
index 0000000..9def1d7
--- /dev/null
+++ b/libop/op_cpu_type.h
@@ -0,0 +1,118 @@
+/**
+ * @file op_cpu_type.h
+ * CPU type determination
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_CPU_TYPE_H
+#define OP_CPU_TYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** supported cpu type */
+typedef enum {
+ CPU_NO_GOOD = -1, /**< unsupported CPU type */
+ CPU_PPRO, /**< Pentium Pro */
+ CPU_PII, /**< Pentium II series */
+ CPU_PIII, /**< Pentium III series */
+ CPU_ATHLON, /**< AMD P6 series */
+ CPU_TIMER_INT, /**< CPU using the timer interrupt */
+ CPU_RTC, /**< other CPU to use the RTC */
+ CPU_P4, /**< Pentium 4 / Xeon series */
+ CPU_IA64, /**< Generic IA64 */
+ CPU_IA64_1, /**< IA64 Merced */
+ CPU_IA64_2, /**< IA64 McKinley */
+ CPU_HAMMER, /**< AMD Hammer family */
+ CPU_P4_HT2, /**< Pentium 4 / Xeon series with 2 hyper-threads */
+ CPU_AXP_EV4, /**< Alpha EV4 family */
+ CPU_AXP_EV5, /**< Alpha EV5 family */
+ CPU_AXP_PCA56, /**< Alpha PCA56 family */
+ CPU_AXP_EV6, /**< Alpha EV6 family */
+ CPU_AXP_EV67, /**< Alpha EV67 family */
+ CPU_P6_MOBILE, /**< Pentium M series */
+ CPU_ARM_XSCALE1, /**< ARM XScale 1 */
+ CPU_ARM_XSCALE2, /**< ARM XScale 2 */
+ CPU_PPC64_POWER4, /**< ppc64 POWER4 family */
+ CPU_PPC64_POWER5, /**< ppc64 POWER5 family */
+ CPU_PPC64_970, /**< ppc64 970 family */
+ CPU_MIPS_24K, /**< MIPS 24K */
+ CPU_MIPS_R10000, /**< MIPS R10000 */
+ CPU_MIPS_R12000, /**< MIPS R12000 */
+ CPU_MIPS_RM7000, /**< QED RM7000 */
+ CPU_MIPS_RM9000, /**< PMC-Sierra RM9000 */
+ CPU_MIPS_SB1, /**< Broadcom SB1 */
+ CPU_MIPS_VR5432, /**< NEC VR5432 */
+ CPU_MIPS_VR5500, /**< MIPS VR5500, VR5532 and VR7701 */
+ CPU_PPC_E500, /**< e500 */
+ MAX_CPU_TYPE
+} op_cpu;
+
+/**
+ * get the CPU type from the kernel
+ *
+ * returns CPU_NO_GOOD if the CPU could not be identified.
+ * This function can not work if the module is not loaded
+ */
+op_cpu op_get_cpu_type(void);
+
+/**
+ * get the cpu number based on string
+ * @param cpu_string with either the cpu type identifier or cpu type number
+ *
+ * The function returns CPU_NO_GOOD if no matching string was found.
+ */
+op_cpu op_get_cpu_number(char const * cpu_string);
+
+/**
+ * get the cpu string.
+ * @param cpu_type the cpu type identifier
+ *
+ * The function always return a valid char const * the core cpu denomination
+ * or "invalid cpu type" if cpu_type is not valid.
+ */
+char const * op_get_cpu_type_str(op_cpu cpu_type);
+
+/**
+ * op_get_cpu_name - get the cpu name
+ * @param cpu_type the cpu identifier name
+ *
+ * The function always return a valid char const *
+ * Return the OProfile CPU name, e.g. "i386/pii"
+ */
+char const * op_get_cpu_name(op_cpu cpu_type);
+
+/**
+ * compute the number of counters available
+ * @param cpu_type numeric processor type
+ *
+ * returns 0 if the CPU could not be identified
+ */
+int op_get_nr_counters(op_cpu cpu_type);
+
+typedef enum {
+ OP_INTERFACE_NO_GOOD = -1,
+ OP_INTERFACE_24,
+ OP_INTERFACE_26
+} op_interface;
+
+/**
+ * get the INTERFACE used to communicate between daemon and the kernel
+ *
+ * returns OP_INTERFACE_NO_GOOD if the INTERFACE could not be identified.
+ * This function will identify the interface as OP_INTERFACE_NO_GOOD if
+ * the module is not loaded.
+ */
+op_interface op_get_interface(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OP_CPU_TYPE_H */
diff --git a/libop/op_events.c b/libop/op_events.c
new file mode 100644
index 0000000..47bae76
--- /dev/null
+++ b/libop/op_events.c
@@ -0,0 +1,827 @@
+/**
+ * @file op_events.c
+ * Details of PMC profiling events
+ *
+ * You can have silliness here.
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include "op_events.h"
+#include "op_libiberty.h"
+#include "op_fileio.h"
+#include "op_string.h"
+#include "op_cpufreq.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static LIST_HEAD(events_list);
+static LIST_HEAD(um_list);
+
+static char const * filename;
+static unsigned int line_nr;
+
+static void parse_error(char const * context)
+{
+ fprintf(stderr, "oprofile: parse error in %s, line %u\n",
+ filename, line_nr);
+ fprintf(stderr, "%s\n", context);
+ exit(EXIT_FAILURE);
+}
+
+
+static int parse_int(char const * str)
+{
+ int value;
+ if (sscanf(str, "%d", &value) != 1) {
+ parse_error("expected decimal value");
+ }
+
+ return value;
+}
+
+
+static int parse_hex(char const * str)
+{
+ int value;
+ if (sscanf(str, "%x", &value) != 1) {
+ parse_error("expected hexadecimal value");
+ }
+
+ return value;
+}
+
+
+static u64 parse_long_hex(char const * str)
+{
+ u64 value;
+ if (sscanf(str, "%Lx", &value) != 1) {
+ parse_error("expected long hexadecimal value");
+ }
+ fflush(stderr);
+ return value;
+}
+
+
+/* name:MESI type:bitmask default:0x0f */
+static void parse_um(struct op_unit_mask * um, char const * line)
+{
+ int seen_name = 0;
+ int seen_type = 0;
+ int seen_default = 0;
+ char const * valueend = line + 1;
+ char const * tagend = line + 1;
+ char const * start = line;
+
+ while (*valueend) {
+ valueend = skip_nonws(valueend);
+
+ while (*tagend != ':' && *tagend)
+ ++tagend;
+
+ if (valueend == tagend)
+ break;
+
+ if (!*tagend)
+ parse_error("parse_um() expected :value");
+
+ ++tagend;
+
+ if (strisprefix(start, "name")) {
+ if (seen_name)
+ parse_error("duplicate name: tag");
+ seen_name = 1;
+ um->name = op_xstrndup(tagend, valueend - tagend);
+ } else if (strisprefix(start, "type")) {
+ if (seen_type)
+ parse_error("duplicate type: tag");
+ seen_type = 1;
+ if (strisprefix(tagend, "mandatory")) {
+ um->unit_type_mask = utm_mandatory;
+ } else if (strisprefix(tagend, "bitmask")) {
+ um->unit_type_mask = utm_bitmask;
+ } else if (strisprefix(tagend, "exclusive")) {
+ um->unit_type_mask = utm_exclusive;
+ } else {
+ parse_error("invalid unit mask type");
+ }
+ } else if (strisprefix(start, "default")) {
+ if (seen_default)
+ parse_error("duplicate default: tag");
+ seen_default = 1;
+ um->default_mask = parse_hex(tagend);
+ } else {
+ parse_error("invalid unit mask tag");
+ }
+
+ valueend = skip_ws(valueend);
+ tagend = valueend;
+ start = valueend;
+ }
+}
+
+
+/* \t0x08 (M)odified cache state */
+static void parse_um_entry(struct op_described_um * entry, char const * line)
+{
+ char const * c = line;
+
+ c = skip_ws(c);
+ entry->value = parse_hex(c);
+ c = skip_nonws(c);
+
+ if (!*c)
+ parse_error("invalid unit mask entry");
+
+ c = skip_ws(c);
+
+ if (!*c)
+ parse_error("invalid unit mask entry");
+
+ entry->desc = xstrdup(c);
+}
+
+
+static struct op_unit_mask * new_unit_mask(void)
+{
+ struct op_unit_mask * um = xmalloc(sizeof(struct op_unit_mask));
+ memset(um, '\0', sizeof(struct op_unit_mask));
+ list_add_tail(&um->um_next, &um_list);
+
+ return um;
+}
+
+
+/*
+ * name:zero type:mandatory default:0x0
+ * \t0x0 No unit mask
+ */
+static void read_unit_masks(char const * file)
+{
+ struct op_unit_mask * um = NULL;
+ char * line;
+ FILE * fp = fopen(file, "r");
+
+ if (!fp) {
+ fprintf(stderr,
+ "oprofile: could not open unit mask description file %s\n", file);
+ exit(EXIT_FAILURE);
+ }
+
+ filename = file;
+ line_nr = 1;
+
+ line = op_get_line(fp);
+
+ while (line) {
+ if (empty_line(line) || comment_line(line))
+ goto next;
+
+ if (line[0] != '\t') {
+ um = new_unit_mask();
+ parse_um(um, line);
+ } else {
+ if (!um) {
+ parse_error("no unit mask name line");
+ }
+ if (um->num >= MAX_UNIT_MASK) {
+ parse_error("oprofile: maximum unit mask entries exceeded");
+ }
+ parse_um_entry(&um->um[um->num], line);
+ ++(um->num);
+ }
+
+next:
+ free(line);
+ line = op_get_line(fp);
+ ++line_nr;
+ }
+
+ fclose(fp);
+}
+
+
+static u32 parse_counter_mask(char const * str)
+{
+ u32 mask = 0;
+ char const * numstart = str;
+
+ while (*numstart) {
+ mask |= 1 << parse_int(numstart);
+
+ while (*numstart && *numstart != ',')
+ ++numstart;
+ /* skip , unless we reach eos */
+ if (*numstart)
+ ++numstart;
+
+ numstart = skip_ws(numstart);
+ }
+
+ return mask;
+}
+
+
+static struct op_unit_mask * find_um(char const * value)
+{
+ struct list_head * pos;
+
+ list_for_each(pos, &um_list) {
+ struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
+ if (strcmp(value, um->name) == 0)
+ return um;
+ }
+
+ fprintf(stderr, "oprofile: could not find unit mask %s\n", value);
+ exit(EXIT_FAILURE);
+}
+
+
+/* parse either a "tag:value" or a ": trailing description string" */
+static int next_token(char const ** cp, char ** name, char ** value)
+{
+ size_t tag_len;
+ size_t val_len;
+ char const * c = *cp;
+ char const * end;
+ char const * colon;
+
+ c = skip_ws(c);
+ end = colon = c;
+ end = skip_nonws(end);
+
+ colon = strchr(colon, ':');
+
+ if (!colon) {
+ if (*c) {
+ parse_error("next_token(): garbage at end of line");
+ }
+ return 0;
+ }
+
+ if (colon >= end)
+ parse_error("next_token() expected ':'");
+
+ tag_len = colon - c;
+ val_len = end - (colon + 1);
+
+ if (!tag_len) {
+ /* : trailing description */
+ end = skip_ws(end);
+ *name = xstrdup("desc");
+ *value = xstrdup(end);
+ end += strlen(end);
+ } else {
+ /* tag:value */
+ *name = op_xstrndup(c, tag_len);
+ *value = op_xstrndup(colon + 1, val_len);
+ end = skip_ws(end);
+ }
+
+ *cp = end;
+ return 1;
+}
+
+
+static struct op_event * new_event(void)
+{
+ struct op_event * event = xmalloc(sizeof(struct op_event));
+ memset(event, '\0', sizeof(struct op_event));
+ list_add_tail(&event->event_next, &events_list);
+
+ return event;
+}
+
+
+/* event:0x00 counters:0 um:zero minimum:4096 name:ISSUES : Total issues */
+static void read_events(char const * file)
+{
+ struct op_event * event = NULL;
+ char * line;
+ char * name;
+ char * value;
+ char const * c;
+ int seen_event, seen_counters, seen_um, seen_minimum, seen_name;
+ FILE * fp = fopen(file, "r");
+
+ if (!fp) {
+ fprintf(stderr, "oprofile: could not open event description file %s\n", file);
+ exit(EXIT_FAILURE);
+ }
+
+ filename = file;
+ line_nr = 1;
+
+ line = op_get_line(fp);
+
+ while (line) {
+ if (empty_line(line) || comment_line(line))
+ goto next;
+
+ seen_name = 0;
+ seen_event = 0;
+ seen_counters = 0;
+ seen_um = 0;
+ seen_minimum = 0;
+ event = new_event();
+
+ c = line;
+ while (next_token(&c, &name, &value)) {
+ if (strcmp(name, "name") == 0) {
+ if (seen_name)
+ parse_error("duplicate name: tag");
+ seen_name = 1;
+ event->name = value;
+ } else if (strcmp(name, "event") == 0) {
+ if (seen_event)
+ parse_error("duplicate event: tag");
+ seen_event = 1;
+ event->val = parse_hex(value);
+ free(value);
+ } else if (strcmp(name, "counters") == 0) {
+ if (seen_counters)
+ parse_error("duplicate counters: tag");
+ seen_counters = 1;
+ event->counter_mask = parse_counter_mask(value);
+ free(value);
+ } else if (strcmp(name, "um") == 0) {
+ if (seen_um)
+ parse_error("duplicate um: tag");
+ seen_um = 1;
+ event->unit = find_um(value);
+ event->unit->used = 1;
+ free(value);
+ } else if (strcmp(name, "minimum") == 0) {
+ if (seen_minimum)
+ parse_error("duplicate minimum: tag");
+ seen_minimum = 1;
+ event->min_count = parse_int(value);
+ free(value);
+ } else if (strcmp(name, "desc") == 0) {
+ event->desc = value;
+ } else {
+ parse_error("unknown tag");
+ }
+
+ free(name);
+ }
+next:
+ free(line);
+ line = op_get_line(fp);
+ ++line_nr;
+ }
+
+ fclose(fp);
+}
+
+
+/* usefull for make check */
+static void check_unit_mask(struct op_unit_mask const * um,
+ char const * cpu_name)
+{
+ u16 i;
+
+ if (!um->used) {
+ fprintf(stderr, "um %s is not used\n", um->name);
+ exit(EXIT_FAILURE);
+ }
+
+ if (um->unit_type_mask == utm_mandatory && um->num != 1) {
+ fprintf(stderr, "mandatory um %s doesn't contain exactly one "
+ "entry (%s)\n", um->name, cpu_name);
+ exit(EXIT_FAILURE);
+ } else if (um->unit_type_mask == utm_bitmask) {
+ u16 default_mask = um->default_mask;
+ for (i = 0; i < um->num; ++i) {
+ default_mask &= ~um->um[i].value;
+ }
+ if (default_mask) {
+ fprintf(stderr, "um %s default mask is not valid "
+ "(%s)\n", um->name, cpu_name);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ for (i = 0; i < um->num; ++i) {
+ if (um->default_mask == um->um[i].value)
+ break;
+ }
+
+ if (i == um->num) {
+ fprintf(stderr, "exclusive um %s default value is not "
+ "valid (%s)\n", um->name, cpu_name);
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+
+static void load_events(op_cpu cpu_type)
+{
+ char const * cpu_name = op_get_cpu_name(cpu_type);
+ char * event_dir;
+ char * event_file;
+ char * um_file;
+ char * dir;
+ struct list_head * pos;
+
+ if (!list_empty(&events_list))
+ return;
+
+ dir = getenv("OPROFILE_EVENTS_DIR");
+ if (dir == NULL)
+ dir = OP_DATADIR;
+
+ event_dir = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
+ strlen("/") + 1);
+ strcpy(event_dir, dir);
+ strcat(event_dir, "/");
+
+ strcat(event_dir, cpu_name);
+ strcat(event_dir, "/");
+
+ event_file = xmalloc(strlen(event_dir) + strlen("events") + 1);
+ strcpy(event_file, event_dir);
+ strcat(event_file, "events");
+
+ um_file = xmalloc(strlen(event_dir) + strlen("unit_masks") + 1);
+ strcpy(um_file, event_dir);
+ strcat(um_file, "unit_masks");
+
+ read_unit_masks(um_file);
+ read_events(event_file);
+
+ /* sanity check: all unit mask must be used */
+ list_for_each(pos, &um_list) {
+ struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
+
+ check_unit_mask(um, cpu_name);
+ }
+
+ free(um_file);
+ free(event_file);
+ free(event_dir);
+}
+
+
+struct list_head * op_events(op_cpu cpu_type)
+{
+ load_events(cpu_type);
+ return &events_list;
+}
+
+
+static void delete_unit_mask(struct op_unit_mask * unit)
+{
+ u32 cur;
+ for (cur = 0 ; cur < unit->num ; ++cur) {
+ if (unit->um[cur].desc)
+ free(unit->um[cur].desc);
+ }
+
+ if (unit->name)
+ free(unit->name);
+
+ list_del(&unit->um_next);
+ free(unit);
+}
+
+
+static void delete_event(struct op_event * event)
+{
+ if (event->name)
+ free(event->name);
+ if (event->desc)
+ free(event->desc);
+
+ list_del(&event->event_next);
+ free(event);
+}
+
+
+void op_free_events(void)
+{
+ struct list_head * pos, * pos2;
+ list_for_each_safe(pos, pos2, &events_list) {
+ struct op_event * event = list_entry(pos, struct op_event, event_next);
+ delete_event(event);
+ }
+
+ list_for_each_safe(pos, pos2, &um_list) {
+ struct op_unit_mask * unit = list_entry(pos, struct op_unit_mask, um_next);
+ delete_unit_mask(unit);
+ }
+}
+
+
+static struct op_event * find_event(u8 nr)
+{
+ struct list_head * pos;
+
+ list_for_each(pos, &events_list) {
+ struct op_event * event = list_entry(pos, struct op_event, event_next);
+ if (event->val == nr)
+ return event;
+ }
+
+ return NULL;
+}
+
+
+static FILE * open_event_mapping_file(char const * cpu_name)
+{
+ char * ev_map_file;
+ char * dir;
+ dir = getenv("OPROFILE_EVENTS_DIR");
+ if (dir == NULL)
+ dir = OP_DATADIR;
+
+ ev_map_file = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
+ strlen("/") + + strlen("event_mappings") + 1);
+ strcpy(ev_map_file, dir);
+ strcat(ev_map_file, "/");
+
+ strcat(ev_map_file, cpu_name);
+ strcat(ev_map_file, "/");
+ strcat(ev_map_file, "event_mappings");
+ filename = ev_map_file;
+ return (fopen(ev_map_file, "r"));
+}
+
+
+/**
+ * This function is PPC64-specific.
+ */
+static char const * get_mapping(u8 nr, FILE * fp)
+{
+ char * line;
+ char * name;
+ char * value;
+ char const * c;
+ char * map = NULL;
+ int seen_event = 0, seen_mmcr0 = 0, seen_mmcr1 = 0, seen_mmcra = 0;
+ u32 mmcr0 = 0;
+ u64 mmcr1 = 0;
+ u32 mmcra = 0;
+ int event_found = 0;
+
+ line_nr = 1;
+ line = op_get_line(fp);
+ while (line && !event_found) {
+ if (empty_line(line) || comment_line(line))
+ goto next;
+
+ seen_event = 0;
+ seen_mmcr0 = 0;
+ seen_mmcr1 = 0;
+ seen_mmcra = 0;
+ mmcr0 = 0;
+ mmcr1 = 0;
+ mmcra = 0;
+
+ c = line;
+ while (next_token(&c, &name, &value)) {
+ if (strcmp(name, "event") == 0) {
+ u8 evt;
+ if (seen_event)
+ parse_error("duplicate event tag");
+ seen_event = 1;
+ evt = parse_hex(value);
+ if (evt == nr) {
+ event_found = 1;
+ }
+ free(value);
+ } else if (strcmp(name, "mmcr0") == 0) {
+ if (seen_mmcr0)
+ parse_error("duplicate mmcr0 tag");
+ seen_mmcr0 = 1;
+ mmcr0 = parse_hex(value);
+ free(value);
+ } else if (strcmp(name, "mmcr1") == 0) {
+ if (seen_mmcr1)
+ parse_error("duplicate mmcr1: tag");
+ seen_mmcr1 = 1;
+ mmcr1 = parse_long_hex(value);
+ free(value);
+ } else if (strcmp(name, "mmcra") == 0) {
+ if (seen_mmcra)
+ parse_error("duplicate mmcra: tag");
+ seen_mmcra = 1;
+ mmcra = parse_hex(value);
+ free(value);
+ } else {
+ parse_error("unknown tag");
+ }
+
+ free(name);
+ }
+next:
+ free(line);
+ line = op_get_line(fp);
+ ++line_nr;
+ }
+ if (event_found) {
+ if (!seen_mmcr0 || !seen_mmcr1 || !seen_mmcra) {
+ fprintf(stderr, "Error: Missing information in line %d of event mapping file %s\n", line_nr, filename);
+ exit(EXIT_FAILURE);
+ }
+ map = xmalloc(70);
+ snprintf(map, 70, "mmcr0:%u mmcr1:%Lu mmcra:%u",
+ mmcr0, mmcr1, mmcra);
+ }
+
+ return map;
+}
+
+
+char const * find_mapping_for_event(u8 nr, op_cpu cpu_type)
+{
+ char const * cpu_name = op_get_cpu_name(cpu_type);
+ FILE * fp = open_event_mapping_file(cpu_name);
+ char const * map = NULL;
+ switch (cpu_type) {
+ case CPU_PPC64_970:
+ case CPU_PPC64_POWER4:
+ case CPU_PPC64_POWER5:
+ if (!fp) {
+ fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename);
+ exit(EXIT_FAILURE);
+ } else {
+ map = get_mapping(nr, fp);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return map;
+}
+
+
+struct op_event * find_event_by_name(char const * name)
+{
+ struct list_head * pos;
+
+ list_for_each(pos, &events_list) {
+ struct op_event * event = list_entry(pos, struct op_event, event_next);
+ if (strcmp(event->name, name) == 0)
+ return event;
+ }
+
+ return NULL;
+}
+
+
+struct op_event * op_find_event(op_cpu cpu_type, u8 nr)
+{
+ struct op_event * event;
+
+ load_events(cpu_type);
+
+ event = find_event(nr);
+
+ return event;
+}
+
+
+int op_check_events(int ctr, u8 nr, u16 um, op_cpu cpu_type)
+{
+ int ret = OP_OK_EVENT;
+ struct op_event * event;
+ size_t i;
+ u32 ctr_mask = 1 << ctr;
+
+ load_events(cpu_type);
+
+ event = find_event(nr);
+
+ if (!event) {
+ ret |= OP_INVALID_EVENT;
+ return ret;
+ }
+
+ if ((event->counter_mask & ctr_mask) == 0)
+ ret |= OP_INVALID_COUNTER;
+
+ if (event->unit->unit_type_mask == utm_bitmask) {
+ for (i = 0; i < event->unit->num; ++i)
+ um &= ~(event->unit->um[i].value);
+
+ if (um)
+ ret |= OP_INVALID_UM;
+
+ } else {
+ for (i = 0; i < event->unit->num; ++i) {
+ if (event->unit->um[i].value == um)
+ break;
+ }
+
+ if (i == event->unit->num)
+ ret |= OP_INVALID_UM;
+ }
+
+ return ret;
+}
+
+
+void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
+{
+ descr->name = "";
+ descr->um = 0x0;
+ /* A fixed value of CPU cycles; this should ensure good
+ * granulity even on faster CPUs, though it will generate more
+ * interrupts.
+ */
+ descr->count = 100000;
+
+ switch (cpu_type) {
+ case CPU_PPRO:
+ case CPU_PII:
+ case CPU_PIII:
+ case CPU_P6_MOBILE:
+ case CPU_ATHLON:
+ case CPU_HAMMER:
+ descr->name = "CPU_CLK_UNHALTED";
+ break;
+
+ case CPU_RTC:
+ descr->name = "RTC_INTERRUPTS";
+ descr->count = 1024;
+ break;
+
+ case CPU_P4:
+ case CPU_P4_HT2:
+ descr->name = "GLOBAL_POWER_EVENTS";
+ descr->um = 0x1;
+ break;
+
+ case CPU_IA64:
+ case CPU_IA64_1:
+ case CPU_IA64_2:
+ descr->count = 1000000;
+ descr->name = "CPU_CYCLES";
+ break;
+
+ case CPU_AXP_EV4:
+ case CPU_AXP_EV5:
+ case CPU_AXP_PCA56:
+ case CPU_AXP_EV6:
+ case CPU_AXP_EV67:
+ descr->name = "CYCLES";
+ break;
+
+ // we could possibly use the CCNT
+ case CPU_ARM_XSCALE1:
+ case CPU_ARM_XSCALE2:
+ descr->name = "CPU_CYCLES";
+ break;
+
+ case CPU_PPC64_970:
+ case CPU_PPC64_POWER4:
+ case CPU_PPC64_POWER5:
+ descr->name = "CYCLES";
+ break;
+
+ case CPU_MIPS_24K:
+ descr->name = "INSTRUCTIONS";
+ break;
+
+ case CPU_MIPS_R10000:
+ case CPU_MIPS_R12000:
+ descr->name = "INSTRUCTIONS_GRADUATED";
+ break;
+
+ case CPU_MIPS_RM7000:
+ case CPU_MIPS_RM9000:
+ descr->name = "INSTRUCTIONS_ISSUED";
+ break;
+
+ case CPU_MIPS_SB1:
+ descr->name = "INSN_SURVIVED_STAGE7";
+ break;
+
+ case CPU_MIPS_VR5432:
+ case CPU_MIPS_VR5500:
+ descr->name = "INSTRUCTIONS_EXECUTED";
+ break;
+
+ case CPU_PPC_E500:
+ descr->name = "CPU_CLK";
+ break;
+
+ // don't use default, if someone add a cpu he wants a compiler
+ // warning if he forgets to handle it here.
+ case CPU_TIMER_INT:
+ case CPU_NO_GOOD:
+ case MAX_CPU_TYPE:
+ break;
+ }
+}
diff --git a/libop/op_events.h b/libop/op_events.h
new file mode 100644
index 0000000..1796fb9
--- /dev/null
+++ b/libop/op_events.h
@@ -0,0 +1,125 @@
+/**
+ * @file op_events.h
+ * Details of PMC profiling events
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_EVENTS_H
+#define OP_EVENTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "op_cpu_type.h"
+#include "op_types.h"
+#include "op_list.h"
+
+/** Describe an unit mask type. Events can optionally use a filter called
+ * the unit mask. the mask type can be a bitmask or a discrete value */
+enum unit_mask_type {
+ utm_mandatory, /**< useless but required by the hardware */
+ utm_exclusive, /**< only one of the values is allowed */
+ utm_bitmask /**< bitmask */
+};
+
+/** up to sixteen allowed unit masks */
+#define MAX_UNIT_MASK 16
+
+
+/** Describe an unit mask. */
+struct op_unit_mask {
+ char * name; /**< name of unit mask type */
+ u32 num; /**< number of possible unit masks */
+ enum unit_mask_type unit_type_mask;
+ u16 default_mask; /**< only the gui use it */
+ struct op_described_um {
+ u16 value;
+ char * desc;
+ } um[MAX_UNIT_MASK];
+ struct list_head um_next; /**< next um in list */
+ int used; /**< used by events file parser */
+};
+
+
+/** Describe an event. */
+struct op_event {
+ u32 counter_mask; /**< bitmask of allowed counter */
+ u8 val; /**< event number */
+ /** which unit mask if any allowed */
+ struct op_unit_mask * unit;
+ char * name; /**< the event name */
+ char * desc; /**< the event description */
+ int min_count; /**< minimum counter value allowed */
+ struct list_head event_next; /**< next event in list */
+};
+
+/** Return the known events list. Idempotent */
+struct list_head * op_events(op_cpu cpu_type);
+
+/** Find a given event, returns NULL on error */
+struct op_event * op_find_event(op_cpu cpu_type, u8 nr);
+
+/** Find a given event by name */
+struct op_event * find_event_by_name(char const * name);
+
+/**
+ * Find a mapping for a given event ID for architectures requiring additional information
+ * from what is held in the events file.
+ */
+char const * find_mapping_for_event(u8 val, op_cpu cpu_type);
+
+
+/** op_check_events() return code */
+enum op_event_check {
+ OP_OK_EVENT = 0, /**< event is valid and allowed */
+ OP_INVALID_EVENT = 1, /**< event number is invalid */
+ OP_INVALID_UM = 2, /**< unit mask is invalid */
+ OP_INVALID_COUNTER = 4 /**< event is not allowed for the given counter */
+};
+
+/**
+ * sanity check event values
+ * @param ctr counter number
+ * @param event value for counter
+ * @param um unit mask for counter
+ * @param cpu_type processor type
+ *
+ * Check that the counter event and unit mask values are allowed.
+ *
+ * The function returns bitmask of failure cause 0 otherwise
+ *
+ * \sa op_cpu, OP_EVENTS_OK
+ */
+int op_check_events(int ctr, u8 event, u16 um, op_cpu cpu_type);
+
+/**
+ * free memory used by any call to above function. Need to be called only once
+ */
+void op_free_events(void);
+
+struct op_default_event_descr {
+ char * name;
+ unsigned long count;
+ unsigned long um;
+};
+
+/**
+ * op_default_event - return the details of the default event
+ * @param cpu_type cpu type
+ * @param descr filled event description
+ *
+ * Fills in the event description if applicable
+ */
+void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OP_EVENTS_H */
diff --git a/libop/op_get_interface.c b/libop/op_get_interface.c
new file mode 100644
index 0000000..bdf72a5
--- /dev/null
+++ b/libop/op_get_interface.c
@@ -0,0 +1,32 @@
+/**
+ * @file op_get_interface.c
+ * Determine which oprofile kernel interface used
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Will Cohen
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "op_cpu_type.h"
+#include "op_file.h"
+
+op_interface op_get_interface(void)
+{
+ static op_interface current_interface = OP_INTERFACE_NO_GOOD;
+
+ if (current_interface != OP_INTERFACE_NO_GOOD)
+ return current_interface;
+
+ if (op_file_readable("/proc/sys/dev/oprofile/cpu_type")) {
+ current_interface = OP_INTERFACE_24;
+ } else if (op_file_readable("/dev/oprofile/cpu_type")) {
+ current_interface = OP_INTERFACE_26;
+ }
+
+ return current_interface;
+}
diff --git a/libop/op_hw_config.h b/libop/op_hw_config.h
new file mode 100644
index 0000000..169b36b
--- /dev/null
+++ b/libop/op_hw_config.h
@@ -0,0 +1,30 @@
+/**
+ * @file op_hw_config.h
+ * Configuration parameters that are dependent on CPU/architecture
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_HW_CONFIG_H
+#define OP_HW_CONFIG_H
+
+/** maximum number of counters, up to 4 for Athlon (18 for P4). The primary
+ * use of this variable is for static/local array dimension. Never use it in
+ * loop or in array index access/index checking unless you know what you
+ * made. */
+#ifdef __alpha__
+#define OP_MAX_COUNTERS 20
+#else
+#define OP_MAX_COUNTERS 8
+#endif
+
+/** maximum number of events between interrupts. Counters are 40 bits, but
+ * for convenience we only use 32 bits. The top bit is used for overflow
+ * detection, so user can set up to (2^31)-1 */
+#define OP_MAX_PERF_COUNT 2147483647UL
+
+#endif /* OP_HW_CONFIG_H */
diff --git a/libop/op_interface.h b/libop/op_interface.h
new file mode 100644
index 0000000..fa2ecbd
--- /dev/null
+++ b/libop/op_interface.h
@@ -0,0 +1,87 @@
+/**
+ * @file op_interface.h
+ *
+ * Module / user space interface for 2.4
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_INTERFACE_H
+#define OP_INTERFACE_H
+
+#include "op_config.h"
+#include "op_types.h"
+
+/*@{\name notifications types encoded in op_note::type */
+/** fork(),vfork(),clone() */
+#define OP_FORK 1
+/** mapping */
+#define OP_MAP 2
+/** execve() */
+#define OP_EXEC 4
+/** init_module() */
+#define OP_DROP_MODULES 8
+/** exit() */
+#define OP_EXIT 16
+/*@}*/
+
+/** Data type to transfer samples counts from the module to the daemon */
+struct op_sample {
+ unsigned long eip; /**< eip value where occur interrupt */
+ u32 counter; /**< counter nr */
+ u32 pid; /**< 32 bits can hold any pid */
+ u32 tgid; /**< always equal to pid for kernel < 2.4.0 */
+};
+
+/** the current kernel-side profiler state */
+enum oprof_state {
+ STOPPED = 0,
+ STOPPING = 1,
+ RUNNING = 2
+};
+
+/**
+ * The head structure of a kernel sample buffer.
+ */
+struct op_buffer_head {
+ int cpu_nr; /**< the CPU number of this buffer */
+ size_t count; /**< number of samples in this buffer */
+ enum oprof_state state; /**< current profiler state */
+ struct op_sample buffer[0]; /**< the sample buffer */
+} __attribute__((__packed__));
+
+/**
+ * Data type used by the module to notify daemon of fork/exit/mapping etc.
+ * Meanings of fields depend on the type of notification encoded in the type
+ * field.
+ * \sa OP_FORK, OP_EXEC, OP_MAP, OP_DROP_MODULES and OP_EXIT
+ */
+struct op_note {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long offset;
+ unsigned int hash;
+ unsigned int pid;
+ unsigned int tgid;
+ unsigned short type;
+};
+
+/**
+ * A path component. Directory name are stored as a stack of path components.
+ * Note than the name index acts also as an unique identifier
+ */
+struct op_hash_index {
+ /** index inside the string pool */
+ u32 name;
+ /** parent component, zero if this component is the root */
+ u32 parent;
+} __attribute__((__packed__));
+
+/** size of hash map in bytes */
+#define OP_HASH_MAP_SIZE (OP_HASH_MAP_NR * sizeof(struct op_hash_index) + POOL_SIZE)
+
+#endif /* OP_INTERFACE_H */
diff --git a/libop/op_mangle.c b/libop/op_mangle.c
new file mode 100644
index 0000000..a78d87f
--- /dev/null
+++ b/libop/op_mangle.c
@@ -0,0 +1,97 @@
+/**
+ * @file op_mangle.c
+ * Mangling of sample file names
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include "op_mangle.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "op_libiberty.h"
+
+#include "op_sample_file.h"
+#include "op_config.h"
+
+static void append_image(char * dest, int flags, int anon, char const * name)
+{
+ if ((flags & MANGLE_KERNEL) && !strchr(name, '/')) {
+ strcat(dest, "{kern}/");
+ } else if (anon) {
+ strcat(dest, "{anon}/");
+ } else {
+ strcat(dest, "{root}/");
+ }
+
+ strcat(dest, name);
+ strcat(dest, "/");
+}
+
+char * op_mangle_filename(struct mangle_values const * values)
+{
+ char * mangled;
+ size_t len;
+ int anon = values->flags & MANGLE_ANON;
+ int cg_anon = values->flags & MANGLE_CG_ANON;
+ /* if dep_name != image_name we need to invert them (and so revert them
+ * unconditionally because if they are equal it doesn't hurt to invert
+ * them), see P:3, FIXME: this is a bit weirds, we prolly need to
+ * reword pp_interface */
+ char const * image_name = values->dep_name;
+ char const * dep_name = values->image_name;
+ char const * cg_image_name = values->cg_image_name;
+
+ len = strlen(OP_SAMPLES_CURRENT_DIR) + strlen(dep_name) + 1
+ + strlen(values->event_name) + 1 + strlen(image_name) + 1;
+
+ if (values->flags & MANGLE_CALLGRAPH)
+ len += strlen(cg_image_name) + 1;
+
+ /* provision for tgid, tid, unit_mask, cpu and some {root}, {dep},
+ * {kern}, {anon} and {cg} marker */
+ /* FIXME: too ugly */
+ len += 256;
+
+ mangled = xmalloc(len);
+
+ strcpy(mangled, OP_SAMPLES_CURRENT_DIR);
+ append_image(mangled, values->flags, 0, image_name);
+
+ strcat(mangled, "{dep}" "/");
+ append_image(mangled, values->flags, anon, dep_name);
+
+ if (values->flags & MANGLE_CALLGRAPH) {
+ strcat(mangled, "{cg}" "/");
+ append_image(mangled, values->flags, cg_anon, cg_image_name);
+ }
+
+ strcat(mangled, values->event_name);
+ sprintf(mangled + strlen(mangled), ".%d.%d.",
+ values->count, values->unit_mask);
+
+ if (values->flags & MANGLE_TGID) {
+ sprintf(mangled + strlen(mangled), "%d.", values->tgid);
+ } else {
+ sprintf(mangled + strlen(mangled), "%s.", "all");
+ }
+
+ if (values->flags & MANGLE_TID) {
+ sprintf(mangled + strlen(mangled), "%d.", values->tid);
+ } else {
+ sprintf(mangled + strlen(mangled), "%s.", "all");
+ }
+
+ if (values->flags & MANGLE_CPU) {
+ sprintf(mangled + strlen(mangled), "%d", values->cpu);
+ } else {
+ sprintf(mangled + strlen(mangled), "%s", "all");
+ }
+
+ return mangled;
+}
diff --git a/libop/op_mangle.h b/libop/op_mangle.h
new file mode 100644
index 0000000..5d02d94
--- /dev/null
+++ b/libop/op_mangle.h
@@ -0,0 +1,65 @@
+/**
+ * @file op_mangle.h
+ * Mangling of sample file names
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_MANGLE_H
+#define OP_MANGLE_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum mangle_flags {
+ MANGLE_NONE = 0,
+ MANGLE_CPU = (1 << 0),
+ MANGLE_TGID = (1 << 1),
+ MANGLE_TID = (1 << 2),
+ MANGLE_KERNEL = (1 << 3),
+ MANGLE_CALLGRAPH = (1 << 4),
+ MANGLE_ANON = (1 << 5),
+ MANGLE_CG_ANON = (1 << 6),
+};
+
+/**
+ * Temporary structure for passing parameters to
+ * op_mangle_filename.
+ */
+struct mangle_values {
+ int flags;
+
+ char const * image_name;
+ char const * dep_name;
+ char const * cg_image_name;
+ char const * event_name;
+ int count;
+ unsigned int unit_mask;
+ pid_t tgid;
+ pid_t tid;
+ int cpu;
+};
+
+/**
+ * op_mangle_filename - mangle a sample filename
+ * @param values parameters to use as mangling input
+ *
+ * See also PP:3 for the encoding scheme
+ *
+ * Returns a char* pointer to the mangled string. Caller
+ * is responsible for freeing this string.
+ */
+char * op_mangle_filename(struct mangle_values const * values);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OP_MANGLE_H */
diff --git a/libop/op_parse_event.c b/libop/op_parse_event.c
new file mode 100644
index 0000000..920d617
--- /dev/null
+++ b/libop/op_parse_event.c
@@ -0,0 +1,120 @@
+/**
+ * @file op_parse_event.c
+ * event parsing
+ *
+ * You can have silliness here.
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "op_parse_event.h"
+#include "op_string.h"
+
+static char * next_part(char const ** str)
+{
+ char const * c;
+ char * ret;
+
+ if ((*str)[0] == '\0')
+ return NULL;
+
+ if ((*str)[0] == ':')
+ ++(*str);
+
+ c = *str;
+
+ while (*c != '\0' && *c != ':')
+ ++c;
+
+ if (c == *str)
+ return NULL;
+
+ ret = op_xstrndup(*str, c - *str);
+ *str += c - *str;
+ return ret;
+}
+
+
+static int parse_ulong(char const * str)
+{
+ unsigned long value;
+ char * end;
+ value = strtoul(str, &end, 0);
+ if (end && *end) {
+ fprintf(stderr, "Invalid event part %s\n", str);
+ exit(EXIT_FAILURE);
+ }
+
+ return value;
+}
+
+
+size_t parse_events(struct parsed_event * parsed_events, size_t max_events,
+ char const * const * events)
+{
+ size_t i = 0;
+
+ while (events[i]) {
+ char const * cp = events[i];
+ char * part = next_part(&cp);
+
+ if (i >= max_events) {
+ fprintf(stderr, "Too many events specified: CPU "
+ "only has %lu counters.\n",
+ (unsigned long) max_events);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!part) {
+ fprintf(stderr, "Invalid event %s\n", cp);
+ exit(EXIT_FAILURE);
+ }
+
+ parsed_events[i].name = part;
+
+ part = next_part(&cp);
+
+ if (!part) {
+ fprintf(stderr, "Invalid count for event %s\n", events[i]);
+ exit(EXIT_FAILURE);
+ }
+
+ parsed_events[i].count = parse_ulong(part);
+ free(part);
+
+ parsed_events[i].unit_mask = 0;
+ part = next_part(&cp);
+
+ if (part) {
+ parsed_events[i].unit_mask = parse_ulong(part);
+ free(part);
+ }
+
+ parsed_events[i].kernel = 1;
+ part = next_part(&cp);
+
+ if (part) {
+ parsed_events[i].kernel = parse_ulong(part);
+ free(part);
+ }
+
+ parsed_events[i].user = 1;
+ part = next_part(&cp);
+
+ if (part) {
+ parsed_events[i].user = parse_ulong(part);
+ free(part);
+ }
+
+ ++i;
+ }
+
+ return i;
+}
diff --git a/libop/op_parse_event.h b/libop/op_parse_event.h
new file mode 100644
index 0000000..247a355
--- /dev/null
+++ b/libop/op_parse_event.h
@@ -0,0 +1,42 @@
+/**
+ * @file op_parse_event.h
+ * event parsing
+ *
+ * You can have silliness here.
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_PARSE_EVENT_H
+#define OP_PARSE_EVENT_H
+
+#include <stddef.h>
+
+struct parsed_event {
+ char * name;
+ int count;
+ int unit_mask;
+ int kernel;
+ int user;
+};
+
+/**
+ * @param parsed_events array of events to fill in
+ * @param max_events size of parsed_events
+ * @param events null terminated array of events string on the form
+ * event_name:count[:unit_mask:kernel:user]
+ *
+ * parse events given by the nil terminated array events and fill in
+ * parsed_events with results. Events validity are not checked except.
+ * A fatal error occur if number of events is greater than max_events.
+ *
+ * Return the number of events parsed.
+ */
+size_t parse_events(struct parsed_event * parsed_events, size_t max_events,
+ char const * const * events);
+
+#endif /* !OP_PARSE_EVENT_H */
diff --git a/libop/op_sample_file.h b/libop/op_sample_file.h
new file mode 100644
index 0000000..c3121c8
--- /dev/null
+++ b/libop/op_sample_file.h
@@ -0,0 +1,38 @@
+/**
+ * @file op_sample_file.h
+ * Sample file format
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#ifndef OP_SAMPLE_FILE_H
+#define OP_SAMPLE_FILE_H
+
+#include "op_types.h"
+
+#include <time.h>
+
+/* header of the sample files */
+struct opd_header {
+ u8 magic[4];
+ u32 version;
+ u32 cpu_type;
+ u32 ctr_event;
+ u32 ctr_um;
+ u32 ctr_count;
+ // for cg file the from_cg_is_kernel
+ u32 is_kernel;
+ double cpu_speed;
+ time_t mtime;
+ u32 cg_to_is_kernel;
+ u64 anon_start;
+ u64 cg_to_anon_start;
+ /* binary compatibility reserve */
+ u32 reserved1[1];
+};
+
+#endif /* OP_SAMPLE_FILE_H */
diff --git a/libop/tests/Makefile.am b/libop/tests/Makefile.am
new file mode 100644
index 0000000..cf5e8fc
--- /dev/null
+++ b/libop/tests/Makefile.am
@@ -0,0 +1,33 @@
+AM_CPPFLAGS = \
+ -I ${top_srcdir}/libutil \
+ -I ${top_srcdir}/libop
+
+AM_CFLAGS = @OP_CFLAGS@ -DOPROFILE_SRCDIR=\"@top_srcdir@\"
+
+COMMON_LIBS = ../libop.a ../../libutil/libutil.a
+
+LIBS = @LIBERTY_LIBS@
+
+check_PROGRAMS = \
+ cpu_type_tests \
+ parse_event_tests \
+ load_events_files_tests \
+ alloc_counter_tests \
+ mangle_tests
+
+cpu_type_tests_SOURCES = cpu_type_tests.c
+cpu_type_tests_LDADD = ${COMMON_LIBS}
+
+parse_event_tests_SOURCES = parse_event_tests.c
+parse_event_tests_LDADD = ${COMMON_LIBS}
+
+alloc_counter_tests_SOURCES = alloc_counter_tests.c
+alloc_counter_tests_LDADD = ${COMMON_LIBS}
+
+load_events_files_tests_SOURCES = load_events_files_tests.c
+load_events_files_tests_LDADD = ${COMMON_LIBS}
+
+mangle_tests_SOURCES = mangle_tests.c
+mangle_tests_LDADD = ${COMMON_LIBS}
+
+TESTS = ${check_PROGRAMS}
diff --git a/libop/tests/Makefile.in b/libop/tests/Makefile.in
new file mode 100644
index 0000000..4992cec
--- /dev/null
+++ b/libop/tests/Makefile.in
@@ -0,0 +1,554 @@
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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@
+SOURCES = $(alloc_counter_tests_SOURCES) $(cpu_type_tests_SOURCES) $(load_events_files_tests_SOURCES) $(mangle_tests_SOURCES) $(parse_event_tests_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+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 = :
+check_PROGRAMS = cpu_type_tests$(EXEEXT) parse_event_tests$(EXEEXT) \
+ load_events_files_tests$(EXEEXT) alloc_counter_tests$(EXEEXT) \
+ mangle_tests$(EXEEXT)
+subdir = libop/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/binutils.m4 \
+ $(top_srcdir)/m4/builtinexpect.m4 \
+ $(top_srcdir)/m4/compileroption.m4 \
+ $(top_srcdir)/m4/configmodule.m4 \
+ $(top_srcdir)/m4/copyifchange.m4 $(top_srcdir)/m4/docbook.m4 \
+ $(top_srcdir)/m4/extradirs.m4 $(top_srcdir)/m4/findkernel.m4 \
+ $(top_srcdir)/m4/kerneloption.m4 \
+ $(top_srcdir)/m4/kernelversion.m4 \
+ $(top_srcdir)/m4/mallocattribute.m4 \
+ $(top_srcdir)/m4/poptconst.m4 \
+ $(top_srcdir)/m4/precompiledheader.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/m4/resultyn.m4 $(top_srcdir)/m4/sstream.m4 \
+ $(top_srcdir)/m4/typedef.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am_alloc_counter_tests_OBJECTS = alloc_counter_tests.$(OBJEXT)
+alloc_counter_tests_OBJECTS = $(am_alloc_counter_tests_OBJECTS)
+am__DEPENDENCIES_1 = ../libop.a ../../libutil/libutil.a
+alloc_counter_tests_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_cpu_type_tests_OBJECTS = cpu_type_tests.$(OBJEXT)
+cpu_type_tests_OBJECTS = $(am_cpu_type_tests_OBJECTS)
+cpu_type_tests_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_load_events_files_tests_OBJECTS = \
+ load_events_files_tests.$(OBJEXT)
+load_events_files_tests_OBJECTS = \
+ $(am_load_events_files_tests_OBJECTS)
+load_events_files_tests_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_mangle_tests_OBJECTS = mangle_tests.$(OBJEXT)
+mangle_tests_OBJECTS = $(am_mangle_tests_OBJECTS)
+mangle_tests_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_parse_event_tests_OBJECTS = parse_event_tests.$(OBJEXT)
+parse_event_tests_OBJECTS = $(am_parse_event_tests_OBJECTS)
+parse_event_tests_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(alloc_counter_tests_SOURCES) $(cpu_type_tests_SOURCES) \
+ $(load_events_files_tests_SOURCES) $(mangle_tests_SOURCES) \
+ $(parse_event_tests_SOURCES)
+DIST_SOURCES = $(alloc_counter_tests_SOURCES) \
+ $(cpu_type_tests_SOURCES) $(load_events_files_tests_SOURCES) \
+ $(mangle_tests_SOURCES) $(parse_event_tests_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFD_LIBS = @BFD_LIBS@
+CAT_ENTRY_END = @CAT_ENTRY_END@
+CAT_ENTRY_START = @CAT_ENTRY_START@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATE = @DATE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOCBOOK_ROOT = @DOCBOOK_ROOT@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_CFLAGS_MODULE = @EXTRA_CFLAGS_MODULE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KINC = @KINC@
+KSRC = @KSRC@
+KVERS = @KVERS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBERTY_LIBS = @LIBERTY_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBERTY_LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MOC = @MOC@
+MODINSTALLDIR = @MODINSTALLDIR@
+OBJEXT = @OBJEXT@
+OPROFILE_DIR = @OPROFILE_DIR@
+OPROFILE_MODULE_ARCH = @OPROFILE_MODULE_ARCH@
+OP_CFLAGS = @OP_CFLAGS@
+OP_CXXFLAGS = @OP_CXXFLAGS@
+OP_DOCDIR = @OP_DOCDIR@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POPT_LIBS = @POPT_LIBS@
+PTRDIFF_T_TYPE = @PTRDIFF_T_TYPE@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+QT_LIB = @QT_LIB@
+QT_VERSION = @QT_VERSION@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIZE_T_TYPE = @SIZE_T_TYPE@
+STRIP = @STRIP@
+UIC = @UIC@
+VERSION = @VERSION@
+XML_CATALOG = @XML_CATALOG@
+XSLTPROC = @XSLTPROC@
+XSLTPROC_FLAGS = @XSLTPROC_FLAGS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+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_alias = @build_alias@
+datadir = @datadir@
+enable_abi_FALSE = @enable_abi_FALSE@
+enable_abi_TRUE = @enable_abi_TRUE@
+exec_prefix = @exec_prefix@
+have_qt_FALSE = @have_qt_FALSE@
+have_qt_TRUE = @have_qt_TRUE@
+have_xsltproc_FALSE = @have_xsltproc_FALSE@
+have_xsltproc_TRUE = @have_xsltproc_TRUE@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kernel_support_FALSE = @kernel_support_FALSE@
+kernel_support_TRUE = @kernel_support_TRUE@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+topdir = @topdir@
+AM_CPPFLAGS = \
+ -I ${top_srcdir}/libutil \
+ -I ${top_srcdir}/libop
+
+AM_CFLAGS = @OP_CFLAGS@ -DOPROFILE_SRCDIR=\"@top_srcdir@\"
+COMMON_LIBS = ../libop.a ../../libutil/libutil.a
+cpu_type_tests_SOURCES = cpu_type_tests.c
+cpu_type_tests_LDADD = ${COMMON_LIBS}
+parse_event_tests_SOURCES = parse_event_tests.c
+parse_event_tests_LDADD = ${COMMON_LIBS}
+alloc_counter_tests_SOURCES = alloc_counter_tests.c
+alloc_counter_tests_LDADD = ${COMMON_LIBS}
+load_events_files_tests_SOURCES = load_events_files_tests.c
+load_events_files_tests_LDADD = ${COMMON_LIBS}
+mangle_tests_SOURCES = mangle_tests.c
+mangle_tests_LDADD = ${COMMON_LIBS}
+TESTS = ${check_PROGRAMS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libop/tests/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign libop/tests/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: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+alloc_counter_tests$(EXEEXT): $(alloc_counter_tests_OBJECTS) $(alloc_counter_tests_DEPENDENCIES)
+ @rm -f alloc_counter_tests$(EXEEXT)
+ $(LINK) $(alloc_counter_tests_LDFLAGS) $(alloc_counter_tests_OBJECTS) $(alloc_counter_tests_LDADD) $(LIBS)
+cpu_type_tests$(EXEEXT): $(cpu_type_tests_OBJECTS) $(cpu_type_tests_DEPENDENCIES)
+ @rm -f cpu_type_tests$(EXEEXT)
+ $(LINK) $(cpu_type_tests_LDFLAGS) $(cpu_type_tests_OBJECTS) $(cpu_type_tests_LDADD) $(LIBS)
+load_events_files_tests$(EXEEXT): $(load_events_files_tests_OBJECTS) $(load_events_files_tests_DEPENDENCIES)
+ @rm -f load_events_files_tests$(EXEEXT)
+ $(LINK) $(load_events_files_tests_LDFLAGS) $(load_events_files_tests_OBJECTS) $(load_events_files_tests_LDADD) $(LIBS)
+mangle_tests$(EXEEXT): $(mangle_tests_OBJECTS) $(mangle_tests_DEPENDENCIES)
+ @rm -f mangle_tests$(EXEEXT)
+ $(LINK) $(mangle_tests_LDFLAGS) $(mangle_tests_OBJECTS) $(mangle_tests_LDADD) $(LIBS)
+parse_event_tests$(EXEEXT): $(parse_event_tests_OBJECTS) $(parse_event_tests_DEPENDENCIES)
+ @rm -f parse_event_tests$(EXEEXT)
+ $(LINK) $(parse_event_tests_LDFLAGS) $(parse_event_tests_OBJECTS) $(parse_event_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc_counter_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu_type_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_events_files_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mangle_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_event_tests.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@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) '$<'`
+uninstall-info-am:
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list='$(TESTS)'; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *" $$tst "*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *" $$tst "*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ skipped="($$skip tests were not run)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+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)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic 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
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+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
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic ctags distclean \
+ distclean-compile distclean-generic distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-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/libop/tests/alloc_counter_tests.c b/libop/tests/alloc_counter_tests.c
new file mode 100644
index 0000000..8a82974
--- /dev/null
+++ b/libop/tests/alloc_counter_tests.c
@@ -0,0 +1,207 @@
+/**
+ * @file alloc_counter_tests.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "op_parse_event.h"
+#include "op_alloc_counter.h"
+#include "op_events.h"
+#include "op_hw_config.h"
+#include "op_cpu_type.h"
+#include "op_events.h"
+
+/* FIXME: alpha description events need 20 but when running test on x86
+ * OP_MAX_COUNTERS is 8, so we can't use it */
+#define MAX_EVENTS 20
+
+
+/* some test are setup to fail in a known way */
+enum failure_type {
+ no_failure,
+ fail_to_find_event,
+ fail_to_alloc_counter
+};
+
+struct allocated_counter {
+ op_cpu cpu_type;
+ char const * const * events;
+ size_t alloc_map[MAX_EVENTS];
+ /* expected failure for this test */
+ enum failure_type failure;
+};
+
+
+/* not more than MAX_EVENTS string for all these arrays */
+static char const * const events_alpha_ev4_1[] = {
+ "ISSUES:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_alpha_ev4_2[] = {
+ "UNKNOWN_EVENT:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_ppro_1[] = {
+ "CPU_CLK_UNHALTED:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_ppro_2[] = {
+ "CPU_CLK_UNHALTED:4096:0:1:1",
+ "DATA_MEM_REFS:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_ppro_3[] = {
+ /* fail_to_alloc_counter: 2 event to counter 0 */
+ "COMP_FLOP_RET:4096:0:1:1",
+ "FLOPS:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_ppro_4[] = {
+ "FLOPS:4096:0:1:1",
+ "FP_ASSIST:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_ppro_5[] = {
+ "FP_ASSIST:4096:0:1:1",
+ "FLOPS:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_p4_1[] = {
+ "BRANCH_RETIRED:4096:0:1:1",
+ "MISPRED_BRANCH_RETIRED:4096:0:1:1",
+ "BPU_FETCH_REQUEST:4096:0:1:1",
+ "ITLB_REFERENCE:4096:0:1:1",
+ "MEMORY_CANCEL:4096:0:1:1",
+ "MEMORY_COMPLETE:4096:0:1:1",
+ "TC_MS_XFER:4096:0:1:1",
+ "UOP_QUEUE_WRITES:4096:0:1:1",
+ NULL
+};
+
+static char const * const events_p4_2[] = {
+ /* fail_to_alloc_counter: 3 event to counter 3, 7 */
+ "BRANCH_RETIRED:4096:0:1:1",
+ "MISPRED_BRANCH_RETIRED:4096:0:1:1",
+ "INSTR_RETIRED:4096:0:1:1",
+ "BPU_FETCH_REQUEST:4096:0:1:1",
+ "ITLB_REFERENCE:4096:0:1:1",
+ "MEMORY_CANCEL:4096:0:1:1",
+ "MEMORY_COMPLETE:4096:0:1:1",
+ "TC_MS_XFER:4096:0:1:1",
+ NULL
+};
+
+static struct allocated_counter const tests[] = {
+ { CPU_AXP_EV4, events_alpha_ev4_1, { 0 }, no_failure },
+ { CPU_AXP_EV4, events_alpha_ev4_2, { -1 }, fail_to_find_event },
+ { CPU_PPRO, events_ppro_1, { 0 }, no_failure },
+ { CPU_PPRO, events_ppro_2, { 1, 0 }, no_failure },
+ { CPU_PPRO, events_ppro_3, { 1, 0 }, fail_to_alloc_counter },
+ { CPU_PPRO, events_ppro_4, { 0, 1 }, no_failure },
+ { CPU_PPRO, events_ppro_5, { 1, 0 }, no_failure },
+ { CPU_P4, events_p4_1, { 7, 3, 4, 0, 6, 2, 5, 1 }, no_failure },
+ { CPU_P4, events_p4_2, { -1 }, fail_to_alloc_counter },
+ { CPU_NO_GOOD, 0, { 0 }, 0 }
+};
+
+
+static void show_events(char const * const * events)
+{
+ for ( ; *events; ++events)
+ printf("%s\n", *events);
+}
+
+
+static void show_counter_map(size_t const * counter_map, size_t nr_events)
+{
+ size_t i;
+ for (i = 0; i < nr_events; ++i)
+ printf("%lu ", (unsigned long)counter_map[i]);
+ printf("\n");
+}
+
+
+static void do_test(struct allocated_counter const * it)
+{
+ size_t i;
+ size_t * counter_map;
+ size_t nr_events;
+ struct parsed_event parsed[MAX_EVENTS];
+ struct op_event const * event[MAX_EVENTS];
+
+ op_events(it->cpu_type);
+
+ nr_events = parse_events(parsed, MAX_EVENTS, it->events);
+
+ for (i = 0; i < nr_events; ++i) {
+ event[i] = find_event_by_name(parsed[i].name);
+ if (!event[i]) {
+ if (it->failure == fail_to_find_event)
+ goto free_events;
+ printf("Can't find events %s for cpu %s\n",
+ parsed[i].name,
+ op_get_cpu_type_str(it->cpu_type));
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ counter_map = map_event_to_counter(event, nr_events, it->cpu_type);
+ if (!counter_map) {
+ if (it->failure == fail_to_alloc_counter)
+ goto free_events;
+ printf("Can't map this set of events to counter:\n");
+ show_events(it->events);
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < nr_events; ++i) {
+ if (counter_map[i] != it->alloc_map[i]) {
+ printf("Incorrect allocation map for these events:\n");
+ show_events(it->events);
+ printf("(expect, found):\n");
+ show_counter_map(it->alloc_map, nr_events);
+ show_counter_map(counter_map, nr_events);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (it->failure != no_failure) {
+ /* test should fail but success! */
+ printf("test should fail with a failure type %d but succeed "
+ "for events:\n", it->failure);
+ for (i = 0; i < nr_events; ++i)
+ printf("%s\n", it->events[i]);
+ exit(EXIT_FAILURE);
+ }
+
+ free(counter_map);
+free_events:
+ op_free_events();
+}
+
+
+int main(void)
+{
+ struct allocated_counter const * it;
+
+ setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1);
+
+ for (it = tests; it->cpu_type != CPU_NO_GOOD; ++it) {
+ do_test(it);
+ }
+ return 0;
+}
diff --git a/libop/tests/cpu_type_tests.c b/libop/tests/cpu_type_tests.c
new file mode 100644
index 0000000..2b0f6ba
--- /dev/null
+++ b/libop/tests/cpu_type_tests.c
@@ -0,0 +1,79 @@
+/**
+ * @file cpu_type_tests.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "op_cpu_type.h"
+
+static struct cpu_type {
+ char const * name;
+ op_cpu type;
+} cpu_str[] = {
+ { "i386/ppro", CPU_PPRO },
+ { "i386/pii", CPU_PII },
+ { "i386/piii", CPU_PIII },
+ { "i386/athlon", CPU_ATHLON },
+ { "timer", CPU_TIMER_INT },
+ { "rtc", CPU_RTC },
+ { "i386/p4", CPU_P4 },
+ { "ia64/ia64", CPU_IA64 },
+ { "ia64/itanium", CPU_IA64_1 },
+ { "ia64/itanium2", CPU_IA64_2 },
+ { "x86-64/hammer", CPU_HAMMER },
+ { "i386/p4-ht", CPU_P4_HT2 },
+ { "alpha/ev4", CPU_AXP_EV4 },
+ { "alpha/ev5", CPU_AXP_EV5 },
+ { "alpha/pca56", CPU_AXP_PCA56 },
+ { "alpha/ev6", CPU_AXP_EV6 },
+ { "alpha/ev67", CPU_AXP_EV67 },
+ { "foo", CPU_NO_GOOD },
+ { "-3", CPU_NO_GOOD },
+ { "2927", CPU_NO_GOOD },
+ { "", CPU_NO_GOOD },
+ { NULL, CPU_NO_GOOD }
+};
+
+
+static void test(struct cpu_type const * cpu)
+{
+ char const * name;
+ op_cpu type;
+
+ name = op_get_cpu_name(cpu->type);
+ if (cpu->type != CPU_NO_GOOD && strcmp(cpu->name, name)) {
+ printf("for %d expect %s found %s\n", cpu->type, cpu->name,
+ name);
+ exit(EXIT_FAILURE);
+ }
+ if (cpu->type == CPU_NO_GOOD && strcmp("invalid cpu type", name)) {
+ printf("for %d expect %s found %s\n", cpu->type,
+ "invalid cpu type", name);
+ exit(EXIT_FAILURE);
+ }
+
+ type = op_get_cpu_number(cpu->name);
+ if (type != cpu->type) {
+ printf("for %s expect %d found %d\n", cpu->name, cpu->type,
+ type);
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+int main(void)
+{
+ struct cpu_type * cpu;
+ for (cpu = cpu_str; cpu->name; ++cpu)
+ test(cpu);
+ return 0;
+}
diff --git a/libop/tests/load_events_files_tests.c b/libop/tests/load_events_files_tests.c
new file mode 100644
index 0000000..de548e5
--- /dev/null
+++ b/libop/tests/load_events_files_tests.c
@@ -0,0 +1,31 @@
+/**
+ * @file load_events_files_tests.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "op_events.h"
+#include "op_cpu_type.h"
+
+int main(void)
+{
+ op_cpu cpu_type;
+
+ setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1);
+
+ for (cpu_type = CPU_NO_GOOD + 1; cpu_type < MAX_CPU_TYPE; ++cpu_type) {
+ if (cpu_type != CPU_TIMER_INT) {
+ op_events(cpu_type);
+ op_free_events();
+ }
+ }
+
+ return 0;
+}
diff --git a/libop/tests/mangle_tests.c b/libop/tests/mangle_tests.c
new file mode 100644
index 0000000..30607bf
--- /dev/null
+++ b/libop/tests/mangle_tests.c
@@ -0,0 +1,67 @@
+/**
+ * @file mangle_tests.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "op_libiberty.h"
+#include "op_mangle.h"
+#include "op_config.h"
+
+struct test_input {
+ struct mangle_values values;
+ char const * result;
+};
+
+static struct test_input const tests[] = {
+ { { MANGLE_NONE, "foo", "bar", NULL, "EVENT", 0, 0, 0, 0, 0 },
+ "{root}/bar/{dep}/{root}/foo/EVENT.0.0.all.all.all" },
+ { { MANGLE_CPU, "foo", "bar", NULL, "EVENT", 0, 0, 0, 0, 2 },
+ "{root}/bar/{dep}/{root}/foo/EVENT.0.0.all.all.2" },
+ { { MANGLE_TID, "foo", "bar", NULL, "EVENT", 0, 0, 0, 33, 0 },
+ "{root}/bar/{dep}/{root}/foo/EVENT.0.0.all.33.all" },
+ { { MANGLE_TGID, "foo", "bar", NULL, "EVENT", 0, 0, 34, 0, 0 },
+ "{root}/bar/{dep}/{root}/foo/EVENT.0.0.34.all.all" },
+ { { MANGLE_KERNEL, "foo", "bar", NULL, "EVENT", 0, 0, 0, 0, 0 },
+ "{kern}/bar/{dep}/{kern}/foo/EVENT.0.0.all.all.all" },
+ { { MANGLE_CALLGRAPH, "foo-from", "bar-from", "foo-to", "EVENT", 0, 0, 0, 0, 0 },
+ "{root}/bar-from/{dep}/{root}/foo-from/{cg}/{root}/foo-to/EVENT.0.0.all.all.all" },
+ { { MANGLE_CPU|MANGLE_TID|MANGLE_TID|MANGLE_TGID|MANGLE_KERNEL, "foo", "bar", NULL, "EVENT", 1234, 8192, 34, 35, 2 },
+ "{kern}/bar/{dep}/{kern}/foo/EVENT.1234.8192.34.35.2" },
+ { { MANGLE_CPU|MANGLE_TID|MANGLE_TID|MANGLE_TGID|MANGLE_KERNEL, "foo1/foo2", "bar1/bar2", NULL, "EVENT", 1234, 8192, 34, 35, 2 },
+ "{root}/bar1/bar2/{dep}/{root}/foo1/foo2/EVENT.1234.8192.34.35.2" },
+ { { MANGLE_CALLGRAPH|MANGLE_CPU|MANGLE_TID|MANGLE_TID|MANGLE_TGID|MANGLE_KERNEL, "bar1/bar2", "bar1/bar2", "bar1/bar2-to", "EVENT", 1234, 8192, 34, 35, 2 },
+ "{root}/bar1/bar2/{dep}/{root}/bar1/bar2/{cg}/{root}/bar1/bar2-to/EVENT.1234.8192.34.35.2" },
+
+ { { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }, NULL }
+};
+
+
+int main(void)
+{
+ struct test_input const * test;
+ for (test = tests; test->result; ++test) {
+ char * result = op_mangle_filename(&test->values);
+ char * expect = xmalloc(strlen(test->result) +
+ strlen(OP_SAMPLES_CURRENT_DIR) + 1);
+ strcpy(expect, OP_SAMPLES_CURRENT_DIR);
+ strcat(expect, test->result);
+ if (strcmp(result, expect)) {
+ fprintf(stderr, "test %d:\nfound: %s\nexpect: %s\n",
+ (int)(test - tests), result, expect);
+ exit(EXIT_FAILURE);
+ }
+ free(expect);
+ free(result);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/libop/tests/parse_event_tests.c b/libop/tests/parse_event_tests.c
new file mode 100644
index 0000000..b1c3394
--- /dev/null
+++ b/libop/tests/parse_event_tests.c
@@ -0,0 +1,60 @@
+/**
+ * @file parse_event_tests.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author Philippe Elie
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "op_parse_event.h"
+
+struct events_test {
+ /* second pointer is the null terminating array marker */
+ char const * const tests[2];
+ struct parsed_event expected;
+};
+
+static struct events_test const events[] =
+{
+ { { "FOO:3000:0:0:0", 0 }, { "FOO", 3000, 0, 0, 0 } },
+ { { "BAR:3000", 0 }, { "BAR", 3000, 0, 1, 1 } },
+ { { "FOOBAR:3000:1:1:1", 0 }, { "FOOBAR", 3000, 1, 1, 1 } },
+ { { NULL, NULL }, { 0, 0, 0, 0, 0 } }
+};
+
+static void do_test(struct events_test const * ev)
+{
+ struct parsed_event parsed;
+
+ parse_events(&parsed, 1, ev->tests);
+
+ if (strcmp(ev->expected.name, parsed.name) ||
+ ev->expected.count != parsed.count ||
+ ev->expected.unit_mask != parsed.unit_mask ||
+ ev->expected.kernel != parsed.kernel ||
+ ev->expected.user != parsed.user) {
+ printf("for %s expect { %s, %d, %d, %d, %d } found "
+ "{ %s, %d, %d, %d, %d }\n",
+ ev->tests[0], ev->expected.name, ev->expected.count,
+ ev->expected.unit_mask, ev->expected.kernel,
+ ev->expected.user, parsed.name, parsed.count,
+ parsed.unit_mask, parsed.kernel, parsed.user);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(void)
+{
+ struct events_test const * ev;
+ for (ev = events; ev->tests[0]; ++ev) {
+ do_test(ev);
+ }
+
+ return 0;
+}