aboutsummaryrefslogtreecommitdiff
path: root/libpp
diff options
context:
space:
mode:
Diffstat (limited to 'libpp')
-rw-r--r--libpp/Makefile.am52
-rw-r--r--libpp/Makefile.in513
-rw-r--r--libpp/arrange_profiles.cpp776
-rw-r--r--libpp/arrange_profiles.h245
-rw-r--r--libpp/callgraph_container.cpp604
-rw-r--r--libpp/callgraph_container.h172
-rw-r--r--libpp/diff_container.cpp159
-rw-r--r--libpp/diff_container.h50
-rw-r--r--libpp/filename_spec.cpp79
-rw-r--r--libpp/filename_spec.h79
-rw-r--r--libpp/format_flags.h69
-rw-r--r--libpp/format_output.cpp544
-rw-r--r--libpp/format_output.h222
-rw-r--r--libpp/image_errors.cpp81
-rw-r--r--libpp/image_errors.h39
-rw-r--r--libpp/locate_images.cpp135
-rw-r--r--libpp/locate_images.h78
-rw-r--r--libpp/name_storage.cpp65
-rw-r--r--libpp/name_storage.h102
-rw-r--r--libpp/op_header.cpp184
-rw-r--r--libpp/op_header.h54
-rw-r--r--libpp/parse_filename.cpp211
-rw-r--r--libpp/parse_filename.h60
-rw-r--r--libpp/populate.cpp97
-rw-r--r--libpp/populate.h26
-rw-r--r--libpp/profile.cpp165
-rw-r--r--libpp/profile.h176
-rw-r--r--libpp/profile_container.cpp318
-rw-r--r--libpp/profile_container.h175
-rw-r--r--libpp/profile_spec.cpp447
-rw-r--r--libpp/profile_spec.h142
-rw-r--r--libpp/sample_container.cpp140
-rw-r--r--libpp/sample_container.h77
-rw-r--r--libpp/symbol.cpp29
-rw-r--r--libpp/symbol.h133
-rw-r--r--libpp/symbol_container.cpp100
-rw-r--r--libpp/symbol_container.h92
-rw-r--r--libpp/symbol_functors.cpp30
-rw-r--r--libpp/symbol_functors.h38
-rw-r--r--libpp/symbol_sort.cpp207
-rw-r--r--libpp/symbol_sort.h59
41 files changed, 0 insertions, 7024 deletions
diff --git a/libpp/Makefile.am b/libpp/Makefile.am
deleted file mode 100644
index 07a7fdd..0000000
--- a/libpp/Makefile.am
+++ /dev/null
@@ -1,52 +0,0 @@
-AM_CPPFLAGS = \
- -I ${top_srcdir}/libop \
- -I ${top_srcdir}/libutil \
- -I ${top_srcdir}/libdb \
- -I ${top_srcdir}/libopt++ \
- -I ${top_srcdir}/libutil++ \
- -I ${top_srcdir}/libop++ \
- -I ${top_srcdir}/libregex
-
-AM_CXXFLAGS = @OP_CXXFLAGS@
-
-noinst_LIBRARIES = libpp.a
-libpp_a_SOURCES = \
- arrange_profiles.cpp \
- arrange_profiles.h \
- callgraph_container.h \
- callgraph_container.cpp \
- diff_container.cpp \
- diff_container.h \
- filename_spec.cpp \
- filename_spec.h \
- format_flags.h \
- format_output.cpp \
- format_output.h \
- image_errors.h \
- image_errors.cpp \
- locate_images.cpp \
- locate_images.h \
- name_storage.cpp \
- name_storage.h \
- op_header.cpp \
- op_header.h \
- symbol.cpp \
- symbol.h \
- parse_filename.cpp \
- parse_filename.h \
- populate.h \
- populate.cpp \
- profile.cpp \
- profile.h \
- profile_container.cpp \
- profile_container.h \
- profile_spec.cpp \
- profile_spec.h \
- sample_container.cpp \
- sample_container.h \
- symbol_container.cpp \
- symbol_container.h \
- symbol_functors.cpp \
- symbol_functors.h \
- symbol_sort.cpp \
- symbol_sort.h
diff --git a/libpp/Makefile.in b/libpp/Makefile.in
deleted file mode 100644
index ffbb3cf..0000000
--- a/libpp/Makefile.in
+++ /dev/null
@@ -1,513 +0,0 @@
-# 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 = $(libpp_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 = libpp
-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
-libpp_a_AR = $(AR) $(ARFLAGS)
-libpp_a_LIBADD =
-am_libpp_a_OBJECTS = arrange_profiles.$(OBJEXT) \
- callgraph_container.$(OBJEXT) diff_container.$(OBJEXT) \
- filename_spec.$(OBJEXT) format_output.$(OBJEXT) \
- image_errors.$(OBJEXT) locate_images.$(OBJEXT) \
- name_storage.$(OBJEXT) op_header.$(OBJEXT) symbol.$(OBJEXT) \
- parse_filename.$(OBJEXT) populate.$(OBJEXT) profile.$(OBJEXT) \
- profile_container.$(OBJEXT) profile_spec.$(OBJEXT) \
- sample_container.$(OBJEXT) symbol_container.$(OBJEXT) \
- symbol_functors.$(OBJEXT) symbol_sort.$(OBJEXT)
-libpp_a_OBJECTS = $(am_libpp_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
- -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libpp_a_SOURCES)
-DIST_SOURCES = $(libpp_a_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 = @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}/libop \
- -I ${top_srcdir}/libutil \
- -I ${top_srcdir}/libdb \
- -I ${top_srcdir}/libopt++ \
- -I ${top_srcdir}/libutil++ \
- -I ${top_srcdir}/libop++ \
- -I ${top_srcdir}/libregex
-
-AM_CXXFLAGS = @OP_CXXFLAGS@
-noinst_LIBRARIES = libpp.a
-libpp_a_SOURCES = \
- arrange_profiles.cpp \
- arrange_profiles.h \
- callgraph_container.h \
- callgraph_container.cpp \
- diff_container.cpp \
- diff_container.h \
- filename_spec.cpp \
- filename_spec.h \
- format_flags.h \
- format_output.cpp \
- format_output.h \
- image_errors.h \
- image_errors.cpp \
- locate_images.cpp \
- locate_images.h \
- name_storage.cpp \
- name_storage.h \
- op_header.cpp \
- op_header.h \
- symbol.cpp \
- symbol.h \
- parse_filename.cpp \
- parse_filename.h \
- populate.h \
- populate.cpp \
- profile.cpp \
- profile.h \
- profile_container.cpp \
- profile_container.h \
- profile_spec.cpp \
- profile_spec.h \
- sample_container.cpp \
- sample_container.h \
- symbol_container.cpp \
- symbol_container.h \
- symbol_functors.cpp \
- symbol_functors.h \
- symbol_sort.cpp \
- symbol_sort.h
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .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 libpp/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign libpp/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)
-libpp.a: $(libpp_a_OBJECTS) $(libpp_a_DEPENDENCIES)
- -rm -f libpp.a
- $(libpp_a_AR) libpp.a $(libpp_a_OBJECTS) $(libpp_a_LIBADD)
- $(RANLIB) libpp.a
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arrange_profiles.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callgraph_container.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diff_container.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filename_spec.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format_output.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image_errors.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locate_images.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name_storage.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op_header.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_filename.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/populate.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile_container.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile_spec.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample_container.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_container.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_functors.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_sort.Po@am__quote@
-
-.cpp.o:
-@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
-@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(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
-
-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
-check: check-am
-all-am: Makefile $(LIBRARIES)
-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-generic clean-noinstLIBRARIES 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-am clean clean-generic \
- clean-noinstLIBRARIES 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/libpp/arrange_profiles.cpp b/libpp/arrange_profiles.cpp
deleted file mode 100644
index 4b21eb6..0000000
--- a/libpp/arrange_profiles.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/**
- * @file arrange_profiles.cpp
- * Classify and process a list of candidate sample files
- * into merged sets and classes.
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- */
-
-#include <algorithm>
-#include <cstdlib>
-#include <iostream>
-#include <iterator>
-#include <map>
-#include <set>
-
-#include "string_manip.h"
-#include "op_header.h"
-#include "op_exception.h"
-
-#include "arrange_profiles.h"
-#include "parse_filename.h"
-#include "locate_images.h"
-
-using namespace std;
-
-namespace {
-
-int numeric_compare(string const & lhs, string const & rhs)
-{
- if (lhs == "all" && rhs == "all")
- return 0;
- // we choose an order arbitrarily
- if (lhs == "all")
- return 1;
- if (rhs == "all")
- return -1;
- unsigned int lhsval = op_lexical_cast<unsigned int>(lhs);
- unsigned int rhsval = op_lexical_cast<unsigned int>(rhs);
- if (lhsval == rhsval)
- return 0;
- if (lhsval < rhsval)
- return -1;
- return 1;
-}
-
-} // anonymous namespace
-
-
-// global to fix some C++ obscure corner case.
-bool operator<(profile_class const & lhs,
- profile_class const & rhs)
-{
- profile_template const & lt = lhs.ptemplate;
- profile_template const & rt = rhs.ptemplate;
-
- int comp = numeric_compare(lt.cpu, rt.cpu);
- if (comp)
- return comp < 0;
-
- comp = numeric_compare(lt.tgid, rt.tgid);
- if (comp)
- return comp < 0;
-
- comp = numeric_compare(lt.tid, rt.tid);
- if (comp)
- return comp < 0;
-
- comp = numeric_compare(lt.unitmask, rt.unitmask);
- if (comp)
- return comp < 0;
-
- if (lt.event == rt.event)
- return lt.count < rt.count;
- return lt.event < rt.event;
-}
-
-namespace {
-
-struct axis_t {
- string name;
- string suggestion;
-} axes[AXIS_MAX] = {
- { "event", "specify event:, count: or unitmask: (see also --merge=unitmask)" },
- { "tgid", "specify tgid: or --merge tgid" },
- { "tid", "specify tid: or --merge tid" },
- { "cpu", "specify cpu: or --merge cpu" },
-};
-
-
-bool profile_classes::matches(profile_classes const & classes)
-{
- if (v.size() != classes.v.size())
- return false;
-
- axis_types const axis2 = classes.axis;
-
- switch (axis) {
- case AXIS_EVENT:
- break;
- case AXIS_TGID:
- case AXIS_TID:
- return axis2 == AXIS_TID || axis2 == AXIS_TGID;
- case AXIS_CPU:
- return axis2 == AXIS_CPU;
- case AXIS_MAX:
- return false;
- }
-
- // check that the events match (same event, count)
-
- vector<profile_class>::const_iterator it1 = v.begin();
- vector<profile_class>::const_iterator end1 = v.end();
- vector<profile_class>::const_iterator it2 = classes.v.begin();
-
- while (it1 != end1) {
- if (it1->ptemplate.event != it2->ptemplate.event)
- return false;
- if (it1->ptemplate.count != it2->ptemplate.count)
- return false;
- // differing unit mask is considered comparable
- ++it1;
- ++it2;
- }
-
- return true;
-}
-
-
-/// We have more than one axis of classification, tell the user.
-void report_error(profile_classes const & classes, axis_types newaxis)
-{
- string str = "Already displaying results for parameter ";
- str += axes[classes.axis].name;
- str += " with values:\n";
- vector<profile_class>::const_iterator it = classes.v.begin();
- vector<profile_class>::const_iterator const end = classes.v.end();
-
- // We show error for the first conflicting axis but on this
- // axis we can get only a few different it->name, we display only
- // these different name.
- set <string> name_seen;
- size_t i = 5;
- for (; it != end && i; ++it) {
- if (name_seen.find(it->name) == name_seen.end()) {
- name_seen.insert(it->name);
- str += it->name + ",";
- --i;
- }
- }
-
- if (!i) {
- str += " and ";
- str += op_lexical_cast<string>(classes.v.size() - 5);
- str += " more,";
- }
-
- str += "\nwhich conflicts with parameter ";
- str += axes[newaxis].name += ".\n";
- str += "Suggestion: ";
- str += axes[classes.axis].suggestion;
- throw op_fatal_error(str);
-}
-
-
-/**
- * check that two different axes are OK - this is only
- * allowed if they are TGID,TID and for each class,
- * tid == tgid
- */
-bool allow_axes(profile_classes const & classes, axis_types newaxis)
-{
- // No previous axis - OK
- if (classes.axis == AXIS_MAX)
- return true;
-
- if (classes.axis != AXIS_TID && classes.axis != AXIS_TGID)
- return false;
-
- if (newaxis != AXIS_TID && newaxis != AXIS_TGID)
- return false;
-
- vector<profile_class>::const_iterator it = classes.v.begin();
- vector<profile_class>::const_iterator const end = classes.v.end();
-
- for (; it != end; ++it) {
- if (it->ptemplate.tgid != it->ptemplate.tid)
- return false;
- }
-
- return true;
-}
-
-
-/// find the first sample file header in the class
-opd_header const get_first_header(profile_class const & pclass)
-{
- profile_set const & profile = *(pclass.profiles.begin());
-
- string file;
-
- // could be only one main app, with no samples for the main image
- if (profile.files.empty()) {
- profile_dep_set const & dep = *(profile.deps.begin());
- list<profile_sample_files> const & files = dep.files;
- profile_sample_files const & sample_files = *(files.begin());
- if (!sample_files.sample_filename.empty())
- file = sample_files.sample_filename;
- else
- file = *sample_files.cg_files.begin();
- } else {
- profile_sample_files const & sample_files
- = *(profile.files.begin());
- if (!sample_files.sample_filename.empty())
- file = sample_files.sample_filename;
- else
- file = *sample_files.cg_files.begin();
- }
-
- return read_header(file);
-}
-
-/// merge sample file header in the profile_sample_files
-void merge_header(profile_sample_files const & files, opd_header & header)
-{
- if (!files.sample_filename.empty()) {
- opd_header const temp = read_header(files.sample_filename);
- header.ctr_um |= temp.ctr_um;
- }
-
- list<string>::const_iterator it = files.cg_files.begin();
- list<string>::const_iterator const end = files.cg_files.end();
- for ( ; it != end; ++it) {
- opd_header const temp = read_header(*it);
- header.ctr_um |= temp.ctr_um;
- }
-}
-
-/// merge sample file header in the class
-opd_header const get_header(profile_class const & pclass,
- merge_option const & merge_by)
-{
- opd_header header = get_first_header(pclass);
-
- if (!merge_by.unitmask)
- return header;
-
- profile_set const & profile = *(pclass.profiles.begin());
-
- typedef list<profile_sample_files>::const_iterator citerator;
-
- citerator it = profile.files.begin();
- citerator const end = profile.files.end();
- for ( ; it != end; ++it) {
- merge_header(*it, header);
- }
-
- list<profile_dep_set>::const_iterator dep_it = profile.deps.begin();
- list<profile_dep_set>::const_iterator dep_end = profile.deps.end();
- for ( ; dep_it != dep_end; ++dep_it) {
- citerator it = dep_it->files.begin();
- citerator const end = dep_it->files.end();
- for ( ; it != end; ++it) {
- merge_header(*it, header);
- }
- }
-
- return header;
-}
-
-
-/// Give human-readable names to each class.
-void name_classes(profile_classes & classes, merge_option const & merge_by)
-{
- opd_header header = get_header(classes.v[0], merge_by);
-
- classes.event = describe_header(header);
- classes.cpuinfo = describe_cpu(header);
-
- // If we're splitting on event anyway, clear out the
- // global event name
- if (classes.axis == AXIS_EVENT)
- classes.event.erase();
-
- vector<profile_class>::iterator it = classes.v.begin();
- vector<profile_class>::iterator const end = classes.v.end();
-
- for (; it != end; ++it) {
- it->name = axes[classes.axis].name + ":";
- switch (classes.axis) {
- case AXIS_EVENT:
- it->name = it->ptemplate.event
- + ":" + it->ptemplate.count;
- header = get_header(*it, merge_by);
- it->longname = describe_header(header);
- break;
- case AXIS_TGID:
- it->name += it->ptemplate.tgid;
- it->longname = "Processes with a thread group ID of ";
- it->longname += it->ptemplate.tgid;
- break;
- case AXIS_TID:
- it->name += it->ptemplate.tid;
- it->longname = "Processes with a thread ID of ";
- it->longname += it->ptemplate.tid;
- break;
- case AXIS_CPU:
- it->name += it->ptemplate.cpu;
- it->longname = "Samples on CPU " + it->ptemplate.cpu;
- break;
- case AXIS_MAX:;
- }
- }
-}
-
-
-/**
- * Name and verify classes.
- */
-void identify_classes(profile_classes & classes,
- merge_option const & merge_by)
-{
- profile_template & ptemplate = classes.v[0].ptemplate;
- bool changed[AXIS_MAX] = { false, };
-
- vector<profile_class>::iterator it = classes.v.begin();
- ++it;
- vector<profile_class>::iterator end = classes.v.end();
-
- // only one class, name it after the event
- if (it == end) {
- changed[AXIS_EVENT] = true;
- }
-
- for (; it != end; ++it) {
- if (it->ptemplate.event != ptemplate.event
- || it->ptemplate.count != ptemplate.count
- // unit mask are mergeable
- || (!merge_by.unitmask
- && it->ptemplate.unitmask != ptemplate.unitmask))
- changed[AXIS_EVENT] = true;
-
- // we need the merge checks here because each
- // template is filled in from the first non
- // matching profile, so just because they differ
- // doesn't mean it's the axis we care about
- if (!merge_by.tgid && it->ptemplate.tgid != ptemplate.tgid)
- changed[AXIS_TGID] = true;
-
- if (!merge_by.tid && it->ptemplate.tid != ptemplate.tid)
- changed[AXIS_TID] = true;
-
- if (!merge_by.cpu && it->ptemplate.cpu != ptemplate.cpu)
- changed[AXIS_CPU] = true;
- }
-
- classes.axis = AXIS_MAX;
-
- for (size_t i = 0; i < AXIS_MAX; ++i) {
- if (!changed[i])
- continue;
-
- if (!allow_axes(classes, axis_types(i)))
- report_error(classes, axis_types(i));
- classes.axis = axis_types(i);
- /* do this early for report_error */
- name_classes(classes, merge_by);
- }
-
- if (classes.axis == AXIS_MAX) {
- cerr << "Internal error - no equivalence class axis" << endl;
- abort();
- }
-}
-
-
-/// construct a class template from a profile
-profile_template const
-template_from_profile(parsed_filename const & parsed,
- merge_option const & merge_by)
-{
- profile_template ptemplate;
-
- ptemplate.event = parsed.event;
- ptemplate.count = parsed.count;
-
- if (!merge_by.unitmask)
- ptemplate.unitmask = parsed.unitmask;
- if (!merge_by.tgid)
- ptemplate.tgid = parsed.tgid;
- if (!merge_by.tid)
- ptemplate.tid = parsed.tid;
- if (!merge_by.cpu)
- ptemplate.cpu = parsed.cpu;
- return ptemplate;
-}
-
-
-/**
- * Find a matching class the sample file could go in, or generate
- * a new class if needed.
- * This is the heart of the merging and classification process.
- * The returned value is non-const reference but the ptemplate member
- * must be considered as const
- */
-profile_class & find_class(set<profile_class> & classes,
- parsed_filename const & parsed,
- merge_option const & merge_by)
-{
- profile_class cls;
- cls.ptemplate = template_from_profile(parsed, merge_by);
-
- pair<set<profile_class>::iterator, bool> ret = classes.insert(cls);
-
- return const_cast<profile_class &>(*ret.first);
-}
-
-/**
- * Sanity check : we can't overwrite sample_filename, if we abort here it means
- * we fail to detect that parsed sample filename for two distinct samples
- * filename must go in two distinct profile_sample_files. This assumption is
- * false for callgraph samples files so this function is only called for non cg
- * files.
- */
-void sanitize_profile_sample_files(profile_sample_files const & sample_files,
- parsed_filename const & parsed)
-{
- // We can't allow to overwrite sample_filename.
- if (!sample_files.sample_filename.empty()) {
- ostringstream out;
- out << "sanitize_profile_sample_files(): sample file "
- << "parsed twice ?\nsample_filename:\n"
- << sample_files.sample_filename << endl
- << parsed << endl;
- throw op_fatal_error(out.str());
- }
-}
-
-
-/**
- * Add a sample filename (either cg or non cg files) to this profile.
- */
-void
-add_to_profile_sample_files(profile_sample_files & sample_files,
- parsed_filename const & parsed)
-{
- if (parsed.cg_image.empty()) {
- // We can't allow to overwrite sample_filename.
- sanitize_profile_sample_files(sample_files, parsed);
-
- sample_files.sample_filename = parsed.filename;
- } else {
- sample_files.cg_files.push_back(parsed.filename);
- }
-}
-
-
-/**
- * we need to fix cg filename: a callgraph filename can occur before the binary
- * non callgraph samples filename occur so we must search.
- */
-profile_sample_files &
-find_profile_sample_files(list<profile_sample_files> & files,
- parsed_filename const & parsed)
-{
- list<profile_sample_files>::iterator it;
- list<profile_sample_files>::iterator const end = files.end();
- for (it = files.begin(); it != end; ++it) {
- if (!it->sample_filename.empty()) {
- parsed_filename psample_filename =
- parse_filename(it->sample_filename);
- if (psample_filename.lib_image == parsed.lib_image &&
- psample_filename.image == parsed.image &&
- psample_filename.profile_spec_equal(parsed))
- return *it;
- }
-
- list<string>::const_iterator cit;
- list<string>::const_iterator const cend = it->cg_files.end();
- for (cit = it->cg_files.begin(); cit != cend; ++cit) {
- parsed_filename pcg_filename = parse_filename(*cit);
- if (pcg_filename.lib_image == parsed.lib_image &&
- pcg_filename.image == parsed.image &&
- pcg_filename.profile_spec_equal(parsed))
- return *it;
- }
- }
-
- // not found, create a new one
- files.push_back(profile_sample_files());
- return files.back();
-}
-
-
-/**
- * Add a profile to particular profile set. If the new profile is
- * a dependent image, it gets added to the dep list, or just placed
- * on the normal list of profiles otherwise.
- */
-void
-add_to_profile_set(profile_set & set, parsed_filename const & parsed, bool merge_by_lib)
-{
- if (parsed.image == parsed.lib_image && !merge_by_lib) {
- profile_sample_files & sample_files =
- find_profile_sample_files(set.files, parsed);
- add_to_profile_sample_files(sample_files, parsed);
- return;
- }
-
- list<profile_dep_set>::iterator it = set.deps.begin();
- list<profile_dep_set>::iterator const end = set.deps.end();
-
- for (; it != end; ++it) {
- if (it->lib_image == parsed.lib_image && !merge_by_lib) {
- profile_sample_files & sample_files =
- find_profile_sample_files(it->files, parsed);
- add_to_profile_sample_files(sample_files, parsed);
- return;
- }
- }
-
- profile_dep_set depset;
- depset.lib_image = parsed.lib_image;
- profile_sample_files & sample_files =
- find_profile_sample_files(depset.files, parsed);
- add_to_profile_sample_files(sample_files, parsed);
- set.deps.push_back(depset);
-}
-
-
-/**
- * Add a profile to a particular equivalence class. The previous matching
- * will have ensured the profile "fits", so now it's just a matter of
- * finding which sample file list it needs to go on.
- */
-void add_profile(profile_class & pclass, parsed_filename const & parsed, bool merge_by_lib)
-{
- list<profile_set>::iterator it = pclass.profiles.begin();
- list<profile_set>::iterator const end = pclass.profiles.end();
-
- for (; it != end; ++it) {
- if (it->image == parsed.image) {
- add_to_profile_set(*it, parsed, merge_by_lib);
- return;
- }
- }
-
- profile_set set;
- set.image = parsed.image;
- add_to_profile_set(set, parsed, merge_by_lib);
- pclass.profiles.push_back(set);
-}
-
-} // anon namespace
-
-
-profile_classes const
-arrange_profiles(list<string> const & files, merge_option const & merge_by)
-{
- set<profile_class> temp_classes;
-
- list<string>::const_iterator it = files.begin();
- list<string>::const_iterator const end = files.end();
-
- for (; it != end; ++it) {
- parsed_filename parsed = parse_filename(*it);
-
- if (parsed.lib_image.empty())
- parsed.lib_image = parsed.image;
-
- // This simplifies the add of the profile later,
- // if we're lib-merging, then the app_image cannot
- // matter. After this, any non-dependent has
- // image == lib_image
- if (merge_by.lib)
- parsed.image = parsed.lib_image;
-
- profile_class & pclass =
- find_class(temp_classes, parsed, merge_by);
- add_profile(pclass, parsed, merge_by.lib);
- }
-
- profile_classes classes;
- copy(temp_classes.begin(), temp_classes.end(),
- back_inserter(classes.v));
-
- if (classes.v.empty())
- return classes;
-
- // sort by template for nicely ordered columns
- stable_sort(classes.v.begin(), classes.v.end());
-
- // name and check
- identify_classes(classes, merge_by);
-
- return classes;
-}
-
-
-ostream & operator<<(ostream & out, profile_sample_files const & sample_files)
-{
- out << "sample_filename: " << sample_files.sample_filename << endl;
- out << "callgraph filenames:\n";
- copy(sample_files.cg_files.begin(), sample_files.cg_files.end(),
- ostream_iterator<string>(out, "\n"));
- return out;
-}
-
-ostream & operator<<(ostream & out, profile_dep_set const & pdep_set)
-{
- out << "lib_image: " << pdep_set.lib_image << endl;
-
- list<profile_sample_files>::const_iterator it;
- list<profile_sample_files>::const_iterator const end =
- pdep_set.files.end();
- size_t i = 0;
- for (it = pdep_set.files.begin(); it != end; ++it)
- out << "profile_sample_files #" << i++ << ":\n" << *it;
-
- return out;
-}
-
-ostream & operator<<(ostream & out, profile_set const & pset)
-{
- out << "image: " << pset.image << endl;
-
- list<profile_sample_files>::const_iterator it;
- list<profile_sample_files>::const_iterator const end =
- pset.files.end();
- size_t i = 0;
- for (it = pset.files.begin(); it != end; ++it)
- out << "profile_sample_files #" << i++ << ":\n" << *it;
-
- list<profile_dep_set>::const_iterator cit;
- list<profile_dep_set>::const_iterator const cend = pset.deps.end();
- i = 0;
- for (cit = pset.deps.begin(); cit != cend; ++cit)
- out << "profile_dep_set #" << i++ << ":\n" << *cit;
-
- return out;
-}
-
-ostream & operator<<(ostream & out, profile_template const & ptemplate)
-{
- out << "event: " << ptemplate.event << endl
- << "count: " << ptemplate.count << endl
- << "unitmask: " << ptemplate.unitmask << endl
- << "tgid: " << ptemplate.tgid << endl
- << "tid: " << ptemplate.tid << endl
- << "cpu: " << ptemplate.cpu << endl;
- return out;
-}
-
-ostream & operator<<(ostream & out, profile_class const & pclass)
-{
- out << "name: " << pclass.name << endl
- << "longname: " << pclass.longname << endl
- << "ptemplate:\n" << pclass.ptemplate;
-
- size_t i = 0;
- list<profile_set>::const_iterator it;
- list<profile_set>::const_iterator const end = pclass.profiles.end();
- for (it = pclass.profiles.begin(); it != end; ++it)
- out << "profiles_set #" << i++ << ":\n" << *it;
-
- return out;
-}
-
-ostream & operator<<(ostream & out, profile_classes const & pclasses)
-{
- out << "event: " << pclasses.event << endl
- << "cpuinfo: " << pclasses.cpuinfo << endl;
-
- for (size_t i = 0; i < pclasses.v.size(); ++i)
- out << "class #" << i << ":\n" << pclasses.v[i];
-
- return out;
-}
-
-
-namespace {
-
-/// add the files to group of image sets
-void add_to_group(image_group_set & group, string const & app_image,
- list<profile_sample_files> const & files)
-{
- image_set set;
- set.app_image = app_image;
- set.files = files;
- group.push_back(set);
-}
-
-
-typedef map<string, inverted_profile> app_map_t;
-
-
-inverted_profile &
-get_iprofile(app_map_t & app_map, string const & image, size_t nr_classes)
-{
- app_map_t::iterator ait = app_map.find(image);
- if (ait != app_map.end())
- return ait->second;
-
- inverted_profile ip;
- ip.image = image;
- ip.groups.resize(nr_classes);
- app_map[image] = ip;
- return app_map[image];
-}
-
-
-/// Pull out all the images, removing any we can't access.
-void
-verify_and_fill(string archive_path, app_map_t & app_map,
- list<inverted_profile> & plist, extra_images const & extra)
-{
- app_map_t::iterator it = app_map.begin();
- app_map_t::iterator const end = app_map.end();
-
- for (; it != end; ++it) {
- plist.push_back(it->second);
- inverted_profile & ip = plist.back();
- ip.image = find_image_path(archive_path, ip.image, extra,
- ip.error);
- }
-}
-
-} // anon namespace
-
-
-list<inverted_profile> const
-invert_profiles(string archive_path, profile_classes const & classes,
- extra_images const & extra)
-{
- app_map_t app_map;
-
- size_t nr_classes = classes.v.size();
-
- for (size_t i = 0; i < nr_classes; ++i) {
- list<profile_set>::const_iterator pit
- = classes.v[i].profiles.begin();
- list<profile_set>::const_iterator pend
- = classes.v[i].profiles.end();
-
- for (; pit != pend; ++pit) {
- // files can be empty if samples for a lib image
- // but none for the main image. Deal with it here
- // rather than later.
- if (pit->files.size()) {
- inverted_profile & ip = get_iprofile(app_map,
- pit->image, nr_classes);
- add_to_group(ip.groups[i], pit->image, pit->files);
- }
-
- list<profile_dep_set>::const_iterator dit
- = pit->deps.begin();
- list<profile_dep_set>::const_iterator const dend
- = pit->deps.end();
-
- for (; dit != dend; ++dit) {
- inverted_profile & ip = get_iprofile(app_map,
- dit->lib_image, nr_classes);
- add_to_group(ip.groups[i], pit->image,
- dit->files);
- }
- }
- }
-
- list<inverted_profile> inverted_list;
-
- verify_and_fill(archive_path, app_map, inverted_list, extra);
-
- return inverted_list;
-}
diff --git a/libpp/arrange_profiles.h b/libpp/arrange_profiles.h
deleted file mode 100644
index 3f71305..0000000
--- a/libpp/arrange_profiles.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * @file arrange_profiles.h
- * Classify and process a list of candidate sample files
- * into merged sets and classes.
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- */
-
-#ifndef ARRANGE_PROFILES_H
-#define ARRANGE_PROFILES_H
-
-#include <string>
-#include <list>
-#include <vector>
-#include <iosfwd>
-
-#include "image_errors.h"
-
-/**
- * store merging options options used to classify profiles
- */
-struct merge_option {
- bool cpu;
- bool lib;
- bool tid;
- bool tgid;
- bool unitmask;
-};
-
-
-/**
- * This describes which parameters are set for each
- * equivalence class.
- */
-struct profile_template {
- std::string event;
- std::string count;
- std::string unitmask;
- std::string tgid;
- std::string tid;
- std::string cpu;
-};
-
-
-/**
- * A samples filename + its associated callgraph sample filename.
- */
-struct profile_sample_files {
- /**
- * This member can be empty since it is possible to get callgraph
- * w/o any samples to the binary. e.g an application which defer all
- * works to shared library but if arrange_profiles receive a sample
- * file list filtered from cg file sample_filename can't be empty
- */
- std::string sample_filename;
- /**
- * List of callgraph sample filename. If the {dep} part of
- * cg_filename != {cg} part it's a cross binary samples file.
- */
- std::list<std::string> cg_files;
-};
-
-
-/**
- * A number of profiles files that are all dependent on
- * the same main (application) profile, for the same
- * dependent image.
- */
-struct profile_dep_set {
- /// which dependent image is this set for
- std::string lib_image;
-
- /// the actual sample files optionnaly including callgraph sample files
- std::list<profile_sample_files> files;
-};
-
-/**
- * A number of profile files all for the same binary with the same
- * profile specification (after merging). Includes the set of dependent
- * profile files, if any.
- *
- * For example, we could have image == "/bin/bash", where files
- * contains all profiles against /bin/bash, and deps contains
- * the sample file list for /lib/libc.so, /lib/ld.so etc.
- */
-struct profile_set {
- std::string image;
-
- /// the actual sample files for the main image and the asociated
- /// callgraph files
- std::list<profile_sample_files> files;
-
- /// all profile files dependent on the main image
- std::list<profile_dep_set> deps;
-};
-
-
-/**
- * A class collection of profiles. This is an equivalence class and
- * will correspond to columnar output of opreport.
- */
-struct profile_class {
- std::list<profile_set> profiles;
-
- /// human-readable column name
- std::string name;
-
- /// human-readable long name
- std::string longname;
-
- /// merging matches against this
- profile_template ptemplate;
-};
-
-
-/**
- * The "axis" says what we've used to split the sample
- * files into the classes. Only one is allowed.
- */
-enum axis_types {
- AXIS_EVENT,
- AXIS_TGID,
- AXIS_TID,
- AXIS_CPU,
- AXIS_MAX
-};
-
-
-struct profile_classes {
- /**
- * This is only set if we're not classifying on event/count
- * anyway - if we're classifying on event/count, then we'll
- * already output the details of each class's event/count.
- *
- * It's only used when classifying by CPU, tgid etc. so the
- * user can still see what perfctr event was used.
- */
- std::string event;
-
- /// CPU info
- std::string cpuinfo;
-
- /// the actual classes
- std::vector<profile_class> v;
-
- /// the axis of the classes
- axis_types axis;
-
- /// is this class set comparable with another?
- bool matches(profile_classes const & classes);
-};
-
-
-std::ostream & operator<<(std::ostream &, profile_sample_files const &);
-std::ostream & operator<<(std::ostream &, profile_dep_set const &);
-std::ostream & operator<<(std::ostream &, profile_set const &);
-std::ostream & operator<<(std::ostream &, profile_template const &);
-std::ostream & operator<<(std::ostream &, profile_class const &);
-std::ostream & operator<<(std::ostream &, profile_classes const &);
-
-
-/**
- * Take a list of sample filenames, and process them into a set of
- * classes containing profile_sets. Merging is done at this stage
- * as well as attaching dependent profiles to the main image.
- *
- * The classes correspond to the columns you'll get in opreport:
- * this can be a number of events, or different CPUs, etc.
- */
-profile_classes const
-arrange_profiles(std::list<std::string> const & files,
- merge_option const & merge_by);
-
-
-/**
- * A set of sample files where the image binary to open
- * are all the same.
- */
-struct image_set {
- /// this is main app image, *not* necessarily
- /// the one we need to open
- std::string app_image;
-
- /// the sample files
- std::list<profile_sample_files> files;
-};
-
-typedef std::list<image_set> image_group_set;
-
-/**
- * All sample files where the binary image to open is
- * the same.
- *
- * This is the "inverse" to some degree of profile_set.
- * For example, here we might have image = "/lib/libc.so",
- * with groups being the profile classifications
- * tgid:404, tgid:301, etc.
- *
- * Within each group there's a number of image_sets.
- * All the sample files listed within the image_sets
- * are still for /lib/libc.so, but they may have
- * different app_image values, e.g. /bin/bash.
- * We need to keep track of the app_image values to
- * make opreport give the right info in the "app"
- * column.
- */
-struct inverted_profile {
- inverted_profile() : error(image_ok) {}
- /// the image to open
- std::string image;
-
- /// an error found in reading the image
- mutable image_error error;
-
- /// all sample files with data for the above image
- std::vector<image_group_set> groups;
-};
-
-
-class extra_images;
-
-/**
- * Invert the profile set. For opreport -l, opannotate etc.,
- * processing the profile_classes directly is slow, because
- * we end up opening BFDs multiple times (for each class,
- * dependent images etc.). This function returns an inverted
- * set of sample files, where the primary sort is on the binary
- * image to open.
- *
- * Thus each element in the returned list is for exactly one
- * binary file that we're going to bfd_openr(). Attached to that
- * is the actual sample files we need to process for that binary
- * file. In order to get the output right, these have to be
- * marked with the profile class they're from (hence the groups
- * vector), and the app image that owned the sample file, if
- * applicable (hence image_set).
- */
-std::list<inverted_profile> const
-invert_profiles(std::string archive_path, profile_classes const & classes,
- extra_images const & extra);
-
-#endif /* !ARRANGE_PROFILES_H */
diff --git a/libpp/callgraph_container.cpp b/libpp/callgraph_container.cpp
deleted file mode 100644
index b9b1a49..0000000
--- a/libpp/callgraph_container.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/**
- * @file callgraph_container.cpp
- * Container associating symbols and caller/caller symbols
- *
- * @remark Copyright 2004 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <cstdlib>
-
-#include <map>
-#include <set>
-#include <algorithm>
-#include <iterator>
-#include <string>
-#include <iostream>
-#include <numeric>
-
-#include "callgraph_container.h"
-#include "cverb.h"
-#include "parse_filename.h"
-#include "profile_container.h"
-#include "arrange_profiles.h"
-#include "populate.h"
-#include "string_filter.h"
-#include "op_bfd.h"
-#include "op_sample_file.h"
-#include "locate_images.h"
-
-using namespace std;
-
-namespace {
-
-bool operator==(cg_symbol const & lhs, cg_symbol const & rhs)
-{
- less_symbol cmp_symb;
- return !cmp_symb(lhs, rhs) && !cmp_symb(rhs, lhs);
-}
-
-
-// we store {caller,callee} inside a single u64
-odb_key_t caller_to_key(u32 value)
-{
- return odb_key_t(value) << 32;
-}
-
-
-u32 key_to_callee(odb_key_t key)
-{
- return key & 0xffffffff;
-}
-
-
-bool compare_by_callee_vma(pair<odb_key_t, odb_value_t> const & lhs,
- pair<odb_key_t, odb_value_t> const & rhs)
-{
- return (key_to_callee(lhs.first)) < (key_to_callee(rhs.first));
-}
-
-
-/*
- * We need 2 comparators for callgraph to get the desired output:
- *
- * caller_with_few_samples
- * caller_with_many_samples
- * function_with_many_samples
- * callee_with_many_samples
- * callee_with_few_samples
- */
-
-bool
-compare_arc_count(symbol_entry const & lhs, symbol_entry const & rhs)
-{
- return lhs.sample.counts[0] < rhs.sample.counts[0];
-}
-
-
-bool
-compare_arc_count_reverse(symbol_entry const & lhs, symbol_entry const & rhs)
-{
- return rhs.sample.counts[0] < lhs.sample.counts[0];
-}
-
-
-// find the nearest bfd symbol for the given file offset and check it's
-// in range
-op_bfd_symbol const *
-get_symbol_by_filepos(op_bfd const & bfd, u32 bfd_offset,
- vma_t offset, symbol_index_t & i)
-{
- offset += bfd_offset;
- op_bfd_symbol tmpsym(offset, 0, string());
-
- // sorted by filepos so this will find the nearest
- vector<op_bfd_symbol>::const_iterator it =
- upper_bound(bfd.syms.begin(), bfd.syms.end(), tmpsym);
-
- if (it != bfd.syms.begin())
- --it;
-
- if (it == bfd.syms.end()) {
- cerr << "get_symbol_by_filepos: no symbols at all?" << endl;
- abort();
- }
-
- // if the offset is past the end of the symbol, we didn't find one
- u32 const end_offset = it->size() + it->filepos();
-
- if (offset >= end_offset) {
- // let's be verbose for now
- cerr << "warning: dropping hyperspace sample at offset "
- << hex << offset << " >= " << end_offset
- << " for binary " << bfd.get_filename() << dec << endl;
- return NULL;
- }
-
- i = distance(bfd.syms.begin(), it);
- return &(*it);
-}
-
-
-/// temporary caller and callee data held during processing
-class call_data {
-public:
- call_data(profile_container const & p, profile_t const & pr,
- op_bfd const & bfd, u32 boff, image_name_id iid,
- image_name_id aid, bool debug_info)
- : pc(p), profile(pr), b(bfd), boffset(boff), image(iid),
- app(aid), debug(debug_info) {}
-
- /// point to a caller symbol
- void caller_sym(symbol_index_t i) {
- sym = symbol_entry();
-
- unsigned long start;
- unsigned long end;
- b.get_symbol_range(i, start, end);
-
- samples.clear();
-
- // see profile_t::samples_range() for why we need this check
- if (start > boffset) {
- profile_t::iterator_pair p_it = profile.samples_range(
- caller_to_key(start - boffset),
- caller_to_key(end - boffset));
-
- // Our odb_key_t contain (from_eip << 32 | to_eip),
- // the range of keys we selected above contains one
- // caller but different callees, and due to the
- // ordering callee offsets are not consecutive: so
- // we must sort them first.
-
- for (; p_it.first != p_it.second; ++p_it.first) {
- samples.push_back(make_pair(p_it.first.vma(),
- p_it.first.count()));
- }
-
- sort(samples.begin(), samples.end(),
- compare_by_callee_vma);
- }
-
- sym.size = end - start;
- sym.name = symbol_names.create(b.syms[i].name());
- sym.sample.vma = b.sym_offset(i, start) + b.syms[i].vma();
-
- finish_sym(i, start);
-
- if (cverb << vdebug) {
- cverb << vdebug << hex << "Caller sym: "
- << b.syms[i].name() << " filepos " << start
- << "-" << end << dec << endl;
- }
- }
-
- /// point to a callee symbol
- bool callee_sym(u32 off) {
- sym = symbol_entry();
-
- symbol_index_t i;
- op_bfd_symbol const * bfdsym =
- get_symbol_by_filepos(b, boffset, off, i);
-
- if (!bfdsym)
- return false;
-
- callee_end = bfdsym->size() + bfdsym->filepos() - boffset;
-
- sym.size = bfdsym->size();
- sym.name = symbol_names.create(bfdsym->name());
- sym.sample.vma = bfdsym->vma();
-
- finish_sym(i, bfdsym->filepos());
-
- if (cverb << vdebug) {
- cverb << vdebug << hex << "Callee sym: "
- << bfdsym->name() << " filepos "
- << bfdsym->filepos() << "-"
- << (bfdsym->filepos() + bfdsym->size())
- << dec << endl;
- }
- return true;
- }
-
- void verbose_bfd(string const & prefix) const {
- cverb << vdebug << prefix << " " << b.get_filename()
- << " offset " << boffset << " app "
- << image_names.name(app) << endl;
- }
-
- typedef vector<pair<odb_key_t, odb_value_t> > samples_t;
-
- typedef samples_t::const_iterator const_iterator;
-
- samples_t samples;
- symbol_entry sym;
- u32 callee_end;
-
-private:
- /// fill in the rest of the sym
- void finish_sym(symbol_index_t i, unsigned long start) {
- sym.image_name = image;
- sym.app_name = app;
- symbol_entry const * self = pc.find(sym);
- if (self)
- sym.sample.counts = self->sample.counts;
-
- if (debug) {
- string filename;
- file_location & loc = sym.sample.file_loc;
- if (b.get_linenr(i, start, filename, loc.linenr))
- loc.filename = debug_names.create(filename);
- }
- }
-
- profile_container const & pc;
- profile_t const & profile;
- op_bfd const & b;
- u32 boffset;
- image_name_id image;
- image_name_id app;
- bool debug;
-};
-
-
-/// accumulate all samples for a given caller/callee pair
-u32
-accumulate_callee(call_data::const_iterator & it, call_data::const_iterator end,
- u32 callee_end)
-{
- u32 count = 0;
- call_data::const_iterator const start = it;
-
- while (it != end) {
- u32 offset = key_to_callee(it->first);
-
- if (cverb << (vdebug & vlevel1)) {
- cverb << (vdebug & vlevel1) << hex << "offset: "
- << offset << dec << endl;
- }
-
- // stop if we pass the end of the callee
- if (offset >= callee_end)
- break;
-
- count += it->second;
- ++it;
- }
-
- // If we haven't advanced at all, then we'll get
- // an infinite loop, so we must abort.
- if (it == start) {
- cerr << "failure to advance iterator\n";
- abort();
- }
-
- return count;
-}
-
-
-} // anonymous namespace
-
-
-void arc_recorder::
-add(symbol_entry const & caller, symbol_entry const * callee,
- count_array_t const & arc_count)
-{
- cg_data & data = sym_map[caller];
-
- // If we have a callee, add it to the caller's list, then
- // add the caller to the callee's list.
- if (callee) {
- data.callees[*callee] += arc_count;
-
- cg_data & callee_data = sym_map[*callee];
-
- callee_data.callers[caller] += arc_count;
- }
-}
-
-
-void arc_recorder::process_children(cg_symbol & sym, double threshold)
-{
- // generate the synthetic self entry for the symbol
- symbol_entry self = sym;
-
- self.name = symbol_names.create(symbol_names.demangle(self.name)
- + " [self]");
-
- sym.total_callee_count += self.sample.counts;
- sym.callees.push_back(self);
-
- sort(sym.callers.begin(), sym.callers.end(), compare_arc_count);
- sort(sym.callees.begin(), sym.callees.end(), compare_arc_count_reverse);
-
- // FIXME: this relies on sort always being sample count
-
- cg_symbol::children::iterator cit = sym.callers.begin();
- cg_symbol::children::iterator cend = sym.callers.end();
-
- while (cit != cend && op_ratio(cit->sample.counts[0],
- sym.total_caller_count[0]) < threshold)
- ++cit;
-
- if (cit != cend)
- sym.callers.erase(sym.callers.begin(), cit);
-
- cit = sym.callees.begin();
- cend = sym.callees.end();
-
- while (cit != cend && op_ratio(cit->sample.counts[0],
- sym.total_callee_count[0]) >= threshold)
- ++cit;
-
- if (cit != cend)
- sym.callees.erase(cit, sym.callees.end());
-}
-
-
-void arc_recorder::
-process(count_array_t total, double threshold,
- string_filter const & sym_filter)
-{
- map_t::const_iterator it;
- map_t::const_iterator end = sym_map.end();
-
- for (it = sym_map.begin(); it != end; ++it) {
- cg_symbol sym((*it).first);
- cg_data const & data = (*it).second;
-
- // threshold out the main symbol if needed
- if (op_ratio(sym.sample.counts[0], total[0]) < threshold)
- continue;
-
- // FIXME: slow?
- if (!sym_filter.match(symbol_names.demangle(sym.name)))
- continue;
-
- cg_data::children::const_iterator cit;
- cg_data::children::const_iterator cend = data.callers.end();
-
- for (cit = data.callers.begin(); cit != cend; ++cit) {
- symbol_entry csym = cit->first;
- csym.sample.counts = cit->second;
- sym.callers.push_back(csym);
- sym.total_caller_count += cit->second;
- }
-
- cend = data.callees.end();
-
- for (cit = data.callees.begin(); cit != cend; ++cit) {
- symbol_entry csym = cit->first;
- csym.sample.counts = cit->second;
- sym.callees.push_back(csym);
- sym.total_callee_count += cit->second;
- }
-
- process_children(sym, threshold);
-
- cg_syms.push_back(sym);
- }
-}
-
-
-cg_collection arc_recorder::get_symbols() const
-{
- return cg_syms;
-}
-
-
-void callgraph_container::populate(string const & archive_path,
- list<inverted_profile> const & iprofiles,
- extra_images const & extra, bool debug_info, double threshold,
- bool merge_lib, string_filter const & sym_filter)
-{
- // non callgraph samples container, we record sample at symbol level
- // not at vma level.
- profile_container pc(debug_info, false);
-
- list<inverted_profile>::const_iterator it;
- list<inverted_profile>::const_iterator const end = iprofiles.end();
- for (it = iprofiles.begin(); it != end; ++it) {
- // populate_caller_image take care about empty sample filename
- populate_for_image(archive_path, pc, *it, sym_filter, 0);
- }
-
- add_symbols(pc);
-
- total_count = pc.samples_count();
-
- for (it = iprofiles.begin(); it != end; ++it) {
- for (size_t i = 0; i < it->groups.size(); ++i) {
- populate(archive_path, it->groups[i], it->image, extra,
- i, pc, debug_info, merge_lib);
- }
- }
-
- recorder.process(total_count, threshold / 100.0, sym_filter);
-}
-
-
-void callgraph_container::populate(string const & archive_path,
- list<image_set> const & lset,
- string const & app_image, extra_images const & extra, size_t pclass,
- profile_container const & pc, bool debug_info, bool merge_lib)
-{
- list<image_set>::const_iterator lit;
- list<image_set>::const_iterator const lend = lset.end();
- for (lit = lset.begin(); lit != lend; ++lit) {
- list<profile_sample_files>::const_iterator pit;
- list<profile_sample_files>::const_iterator pend
- = lit->files.end();
- for (pit = lit->files.begin(); pit != pend; ++pit) {
- populate(archive_path, pit->cg_files, app_image,
- extra, pclass, pc, debug_info, merge_lib);
- }
- }
-}
-
-
-void callgraph_container::populate(string const & archive_path,
- list<string> const & cg_files,
- string const & app_image, extra_images const & extra, size_t pclass,
- profile_container const & pc, bool debug_info, bool merge_lib)
-{
- list<string>::const_iterator it;
- list<string>::const_iterator const end = cg_files.end();
- for (it = cg_files.begin(); it != end; ++it) {
- cverb << vdebug << "samples file : " << *it << endl;
-
- parsed_filename caller_file = parse_filename(*it);
- string const app_name = caller_file.image;
-
- image_error error;
- string caller_binary =
- find_image_path(archive_path, caller_file.lib_image,
- extra, error);
-
- if (error != image_ok)
- report_image_error(archive_path + caller_file.lib_image,
- error, false);
-
- bool caller_bfd_ok = true;
- op_bfd caller_bfd(archive_path, caller_binary,
- string_filter(), caller_bfd_ok);
- if (!caller_bfd_ok)
- report_image_error(caller_binary,
- image_format_failure, false);
-
- parsed_filename callee_file = parse_filename(*it);
-
- string callee_binary =
- find_image_path(archive_path, callee_file.cg_image,
- extra, error);
- if (error != image_ok)
- report_image_error(callee_file.cg_image, error, false);
-
- bool callee_bfd_ok = true;
- op_bfd callee_bfd(archive_path, callee_binary,
- string_filter(), callee_bfd_ok);
- if (!callee_bfd_ok)
- report_image_error(callee_binary,
- image_format_failure, false);
-
- profile_t profile;
- // We can't use start_offset support in profile_t, give
- // it a zero offset and we will fix that in add()
- profile.add_sample_file(*it);
- add(profile, caller_bfd, caller_bfd_ok, callee_bfd,
- merge_lib ? app_image : app_name, pc,
- debug_info, pclass);
- }
-}
-
-
-void callgraph_container::
-add(profile_t const & profile, op_bfd const & caller_bfd, bool caller_bfd_ok,
- op_bfd const & callee_bfd, string const & app_name,
- profile_container const & pc, bool debug_info, size_t pclass)
-{
- string const image_name = caller_bfd.get_filename();
-
- opd_header const & header = profile.get_header();
-
- // We can't use kernel sample file w/o the binary else we will
- // use it with a zero offset, the code below will abort because
- // we will get incorrect callee sub-range and out of range
- // callee vma. FIXME
- if (header.is_kernel && !caller_bfd_ok)
- return;
-
- // We must handle start_offset, this offset can be different for the
- // caller and the callee: kernel sample traversing the syscall barrier.
- u32 caller_offset = 0;
-
- if (header.is_kernel || header.anon_start) {
- caller_offset = caller_bfd.get_start_offset(header.anon_start);
- }
-
- u32 callee_offset = 0;
-
- if (header.cg_to_is_kernel || header.cg_to_anon_start) {
- callee_offset =
- callee_bfd.get_start_offset(header.cg_to_anon_start);
- }
-
- image_name_id image_id = image_names.create(image_name);
- image_name_id callee_image_id = image_names.create(callee_bfd.get_filename());
- image_name_id app_id = image_names.create(app_name);
-
- call_data caller(pc, profile, caller_bfd, caller_offset, image_id,
- app_id, debug_info);
- call_data callee(pc, profile, callee_bfd, callee_offset,
- callee_image_id, app_id, debug_info);
-
- if (cverb << vdebug) {
- caller.verbose_bfd("Caller:");
- callee.verbose_bfd("Callee:");
- }
-
- // For each symbol in the caller bfd, process all arcs to
- // callee bfd symbols
-
- for (symbol_index_t i = 0; i < caller_bfd.syms.size(); ++i) {
-
- caller.caller_sym(i);
-
- call_data::const_iterator dit = caller.samples.begin();
- call_data::const_iterator dend = caller.samples.end();
- while (dit != dend) {
- // if we can't find the callee, skip an arc
- if (!callee.callee_sym(key_to_callee(dit->first))) {
- ++dit;
- continue;
- }
-
- count_array_t arc_count;
- arc_count[pclass] =
- accumulate_callee(dit, dend, callee.callee_end);
-
- recorder.add(caller.sym, &callee.sym, arc_count);
- }
- }
-}
-
-
-void callgraph_container::add_symbols(profile_container const & pc)
-{
- symbol_container::symbols_t::iterator it;
- symbol_container::symbols_t::iterator const end = pc.end_symbol();
-
- for (it = pc.begin_symbol(); it != end; ++it)
- recorder.add(*it, 0, count_array_t());
-}
-
-
-column_flags callgraph_container::output_hint() const
-{
- column_flags output_hints = cf_none;
-
- // FIXME: costly: must we access directly recorder map ?
- cg_collection syms = recorder.get_symbols();
-
- cg_collection::const_iterator it;
- cg_collection::const_iterator const end = syms.end();
- for (it = syms.begin(); it != end; ++it)
- output_hints = it->output_hint(output_hints);
-
- return output_hints;
-}
-
-
-count_array_t callgraph_container::samples_count() const
-{
- return total_count;
-}
-
-
-cg_collection callgraph_container::get_symbols() const
-{
- return recorder.get_symbols();
-}
diff --git a/libpp/callgraph_container.h b/libpp/callgraph_container.h
deleted file mode 100644
index 7b8ee6e..0000000
--- a/libpp/callgraph_container.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * @file callgraph_container.h
- * Container associating symbols and caller/caller symbols
- *
- * @remark Copyright 2004 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef CALLGRAPH_CONTAINER_H
-#define CALLGRAPH_CONTAINER_H
-
-#include <set>
-#include <vector>
-#include <string>
-
-#include "symbol.h"
-#include "symbol_functors.h"
-#include "string_filter.h"
-
-class profile_container;
-class inverted_profile;
-class profile_t;
-class extra_images;
-class image_set;
-class op_bfd;
-
-
-/**
- * During building a callgraph_container we store all caller/callee
- * relationship in this container.
- *
- * An "arc" is simply a description of a call from one function to
- * another.
- */
-class arc_recorder {
-public:
- ~arc_recorder() {}
-
- /**
- * Add a symbol arc.
- * @param caller The calling symbol
- * @param callee The called symbol
- * @param arc_count profile data for the arcs
- *
- * If the callee is NULL, only the caller is added to the main
- * list. This is used to initially populate the recorder with
- * the symbols.
- */
- void add(symbol_entry const & caller, symbol_entry const * callee,
- count_array_t const & arc_count);
-
- /// return all the cg symbols
- cg_collection get_symbols() const;
-
- /**
- * After population, build the final output, and do
- * thresholding.
- */
- void process(count_array_t total, double threshold,
- string_filter const & filter);
-
-private:
- /**
- * Internal structure used during collation. We use a map to
- * allow quick lookup of children (we'll do this several times
- * if we have more than one profile class). Each child maps from
- * the symbol to the relevant arc data.
- */
- struct cg_data {
- cg_data() {}
-
- typedef std::map<symbol_entry, count_array_t, less_symbol> children;
-
- /// callers of this symbol
- children callers;
- /// callees of this symbol
- children callees;
- };
-
- /**
- * Sort and threshold callers and callees.
- */
- void process_children(cg_symbol & sym, double threshold);
-
- typedef std::map<symbol_entry, cg_data, less_symbol> map_t;
-
- /// all the symbols (used during processing)
- map_t sym_map;
-
- /// final output data
- cg_collection cg_syms;
-};
-
-
-/**
- * Store all callgraph information for the given profiles
- */
-class callgraph_container {
-public:
- /**
- * Populate the container, must be called once only.
- * @param archive_path oparchive prefix path
- * @param iprofiles sample file list including callgraph files.
- * @param extra extra image list to fixup binary name.
- * @param debug_info true if we must record linenr information
- * @param threshold ignore sample percent below this threshold
- * @param merge_lib merge library samples
- * @param sym_filter symbol filter
- *
- * Currently all errors core dump.
- * FIXME: consider if this should be a ctor
- */
- void populate(std::string const & archive_path,
- std::list<inverted_profile> const & iprofiles,
- extra_images const & extra, bool debug_info,
- double threshold, bool merge_lib,
- string_filter const & sym_filter);
-
- /// return hint on how data must be displayed.
- column_flags output_hint() const;
-
- /// return the total number of samples.
- count_array_t samples_count() const;
-
- // return all the cg symbols
- cg_collection get_symbols() const;
-
-private:
- /**
- * Record caller/callee for one cg file
- * @param profile one callgraph file stored in a profile_t
- * @param caller_bfd the caller bfd
- * @param bfd_caller_ok true if we succefully open the binary
- * @param callee_bfd the callee bfd
- * @param app_name the owning application
- * @param pc the profile_container holding all non cg samples.
- * @param debug_info record linenr debug information
- * @param pclass profile class nr
- */
- void add(profile_t const & profile, op_bfd const & caller_bfd,
- bool bfd_caller_ok, op_bfd const & callee_bfd,
- std::string const & app_name,
- profile_container const & pc, bool debug_info,
- size_t pclass);
-
- void populate(std::string const & archive_path,
- std::list<image_set> const & lset,
- std::string const & app_image,
- extra_images const & extra, size_t pclass,
- profile_container const & pc, bool debug_info,
- bool merge_lib);
- void populate(std::string const & archive_path,
- std::list<std::string> const & cg_files,
- std::string const & app_image,
- extra_images const & extra, size_t pclass,
- profile_container const & pc, bool debug_info,
- bool merge_lib);
-
- /// record all main symbols
- void add_symbols(profile_container const & pc);
-
- /// Cached value of samples count.
- count_array_t total_count;
-
- /// A structured representation of the callgraph.
- arc_recorder recorder;
-};
-
-#endif /* !CALLGRAPH_CONTAINER_H */
diff --git a/libpp/diff_container.cpp b/libpp/diff_container.cpp
deleted file mode 100644
index 7762916..0000000
--- a/libpp/diff_container.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * @file diff_container.cpp
- * Container for diffed symbols
- *
- * @remark Copyright 2005 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-/* older glibc has C99 INFINITY in _GNU_SOURCE */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include "diff_container.h"
-
-#include <cmath>
-
-using namespace std;
-
-
-namespace {
-
-
-/// a comparator suitable for diffing symbols
-bool rough_less(symbol_entry const & lhs, symbol_entry const & rhs)
-{
- if (lhs.image_name != rhs.image_name)
- return lhs.image_name < rhs.image_name;
-
- if (lhs.app_name != rhs.app_name)
- return lhs.app_name < rhs.app_name;
-
- if (lhs.name != rhs.name)
- return lhs.name < rhs.name;
-
- return false;
-}
-
-
-/// possibly add a diff sym
-void
-add_sym(diff_collection & syms, diff_symbol const & sym,
- profile_container::symbol_choice & choice)
-{
- if (choice.match_image
- && (image_names.name(sym.image_name) != choice.image_name))
- return;
-
- if (fabs(sym.diffs[0]) < choice.threshold)
- return;
-
- choice.hints = sym.output_hint(choice.hints);
- syms.push_back(sym);
-}
-
-
-/// add a symbol not present in the new profile
-void
-symbol_old(diff_collection & syms, symbol_entry const & sym,
- profile_container::symbol_choice & choice)
-{
- diff_symbol symbol(sym);
- symbol.diffs.fill(sym.sample.counts.size(), -INFINITY);
- add_sym(syms, symbol, choice);
-}
-
-
-/// add a symbol not present in the old profile
-void
-symbol_new(diff_collection & syms, symbol_entry const & sym,
- profile_container::symbol_choice & choice)
-{
- diff_symbol symbol(sym);
- symbol.diffs.fill(sym.sample.counts.size(), INFINITY);
- add_sym(syms, symbol, choice);
-}
-
-
-/// add a diffed symbol
-void symbol_diff(diff_collection & syms,
- symbol_entry const & sym1, count_array_t const & total1,
- symbol_entry const & sym2, count_array_t const & total2,
- profile_container::symbol_choice & choice)
-{
- diff_symbol symbol(sym2);
-
- size_t size = sym2.sample.counts.size();
- for (size_t i = 0; i != size; ++i) {
- double percent1;
- double percent2;
- percent1 = op_ratio(sym1.sample.counts[i], total1[i]);
- percent2 = op_ratio(sym2.sample.counts[i], total2[i]);
- symbol.diffs[i] = op_ratio(percent2 - percent1, percent1);
- symbol.diffs[i] *= 100.0;
- }
-
- add_sym(syms, symbol, choice);
-}
-
-
-}; // namespace anon
-
-
-diff_container::diff_container(profile_container const & c1,
- profile_container const & c2)
- : pc1(c1), pc2(c2),
- total1(pc1.samples_count()), total2(pc2.samples_count())
-{
-}
-
-
-diff_collection const
-diff_container::get_symbols(profile_container::symbol_choice & choice) const
-{
- diff_collection syms;
-
- /*
- * Do a pairwise comparison of the two symbol sets. We're
- * relying here on the symbol container being sorted such
- * that rough_less() is suitable for iterating through the
- * two lists (see less_symbol).
- */
-
- symbol_container::symbols_t::iterator it1 = pc1.begin_symbol();
- symbol_container::symbols_t::iterator end1 = pc1.end_symbol();
- symbol_container::symbols_t::iterator it2 = pc2.begin_symbol();
- symbol_container::symbols_t::iterator end2 = pc2.end_symbol();
-
- while (it1 != end1 && it2 != end2) {
- if (rough_less(*it1, *it2)) {
- symbol_old(syms, *it1, choice);
- ++it1;
- } else if (rough_less(*it2, *it1)) {
- symbol_new(syms, *it2, choice);
- ++it2;
- } else {
- symbol_diff(syms, *it1, total1, *it2, total2, choice);
- ++it1;
- ++it2;
- }
- }
-
- for (; it1 != end1; ++it1)
- symbol_old(syms, *it1, choice);
-
- for (; it2 != end2; ++it2)
- symbol_new(syms, *it2, choice);
-
- return syms;
-}
-
-
-count_array_t const diff_container::samples_count() const
-{
- return total2;
-}
diff --git a/libpp/diff_container.h b/libpp/diff_container.h
deleted file mode 100644
index 14b431d..0000000
--- a/libpp/diff_container.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file diff_container.h
- * Container for diffed symbols
- *
- * @remark Copyright 2005 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef DIFF_CONTAINER_H
-#define DIFF_CONTAINER_H
-
-#include "profile_container.h"
-
-
-/**
- * Store two profiles for diffing.
- */
-class diff_container : noncopyable {
-public:
- /// populate the collection of diffed symbols
- diff_container(profile_container const & pc1,
- profile_container const & pc2);
-
- ~diff_container() {}
-
- /// return a collection of diffed symbols
- diff_collection const
- get_symbols(profile_container::symbol_choice & choice) const;
-
- /// total count for 'new' profile
- count_array_t const samples_count() const;
-
-private:
- /// first profile
- profile_container const & pc1;
-
- /// second profile
- profile_container const & pc2;
-
- /// samples count for pc1
- count_array_t total1;
-
- /// samples count for pc2
- count_array_t total2;
-};
-
-#endif /* !DIFF_CONTAINER_H */
diff --git a/libpp/filename_spec.cpp b/libpp/filename_spec.cpp
deleted file mode 100644
index 9ce7cb4..0000000
--- a/libpp/filename_spec.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file filename_spec.cpp
- * Container holding a sample filename split into its components
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#include <string>
-
-#include "filename_spec.h"
-#include "parse_filename.h"
-#include "generic_spec.h"
-
-
-using namespace std;
-
-
-filename_spec::filename_spec(string const & filename)
-{
- set_sample_filename(filename);
-}
-
-
-filename_spec::filename_spec()
- : image("*"), lib_image("*")
-{
-}
-
-
-bool filename_spec::match(filename_spec const & rhs,
- string const & binary) const
-{
- if (!tid.match(rhs.tid) || !cpu.match(rhs.cpu) ||
- !tgid.match(rhs.tgid) || count != rhs.count ||
- unitmask != rhs.unitmask || event != rhs.event) {
- return false;
- }
-
- if (binary.empty()) {
- return image == rhs.image && lib_image == rhs.lib_image;
- }
-
- // PP:3.3 if binary is not empty we must match either the
- // lib_name if present or the image name
- if (!rhs.lib_image.empty()) {
- // FIXME: use fnmatch ?
- return rhs.lib_image == binary;
- }
-
- // FIXME: use fnmatch ?
- return rhs.image == binary;
-}
-
-
-void filename_spec::set_sample_filename(string const & filename)
-{
- parsed_filename parsed = parse_filename(filename);
-
- image = parsed.image;
- lib_image = parsed.lib_image;
- cg_image = parsed.cg_image;
- event = parsed.event;
- count = op_lexical_cast<int>(parsed.count);
- unitmask = op_lexical_cast<unsigned int>(parsed.unitmask);
- tgid.set(parsed.tgid);
- tid.set(parsed.tid);
- cpu.set(parsed.cpu);
-}
-
-
-bool filename_spec::is_dependent() const
-{
- if (cg_image.empty())
- return image != lib_image;
- return cg_image != image || cg_image != lib_image;
-}
diff --git a/libpp/filename_spec.h b/libpp/filename_spec.h
deleted file mode 100644
index abd7f8a..0000000
--- a/libpp/filename_spec.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file filename_spec.h
- * Container holding a sample filename split into its components
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#ifndef FILENAME_SPEC_H
-#define FILENAME_SPEC_H
-
-#include <unistd.h>
-#include <string>
-
-#include "generic_spec.h"
-
-class profile_spec;
-
-/**
- * A class to split and store components of a sample filename.
- * These derived values are then used to match against a
- * profile_spec as given by the user.
- */
-class filename_spec
-{
- friend class profile_spec;
-
-public:
- /**
- * @param filename the samples filename
- *
- * build a filename_spec from a samples filename
- */
- filename_spec(std::string const & filename);
-
- filename_spec();
-
- /**
- * @param filename a sample filename
- *
- * setup filename spec according to the samples filename. PP:3.19 to
- * 3.25
- */
- void set_sample_filename(std::string const & filename);
-
- /**
- * @param rhs right hand side of the match operator
- * @param binary if binary is non-empty, and matches
- * the binary or lib name, use it rather than the
- * one in rhs.
- *
- * return true if *this match rhs, matching if:
- * - image_name are identical
- * - lib_name are identical
- * - event_spec match
- *
- * This operation is not commutative. First part of PP:3.24
- */
- bool match(filename_spec const & rhs,
- std::string const & binary) const;
-
- bool is_dependent() const;
-
-private:
- std::string image;
- std::string lib_image;
- std::string cg_image;
- std::string event;
- int count;
- unsigned int unitmask;
- generic_spec<pid_t> tgid;
- generic_spec<pid_t> tid;
- generic_spec<int> cpu;
-};
-
-
-#endif /* !FILENAME_SPEC_H */
diff --git a/libpp/format_flags.h b/libpp/format_flags.h
deleted file mode 100644
index 6268ae1..0000000
--- a/libpp/format_flags.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file format_flags.h
- * output options
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- * @author Philippe Elie
- */
-
-#ifndef FORMAT_FLAGS_H
-#define FORMAT_FLAGS_H
-
-/**
- * flags passed to the ctor of an output_symbol object.
- *
- * \sa format_output::formatter
- */
-enum format_flags {
- ff_none = 0,
- /// a formatted memory address
- ff_vma = 1 << 0,
- /// output debug filename and line nr.
- ff_linenr_info = 1 << 1,
- /// output the image name for this line
- ff_image_name = 1 << 3,
- /// output owning application name
- ff_app_name = 1 << 4,
- /// output the (demangled) symbol name
- ff_symb_name = 1 << 5,
-
- /** @name subset of flags used by opreport_formatter */
- //@{
- /// number of samples
- ff_nr_samples = 1 << 6,
- /// number of samples accumulated
- ff_nr_samples_cumulated = 1 << 7,
- /// relative percentage of samples
- ff_percent = 1 << 8,
- /// relative percentage of samples accumulated
- ff_percent_cumulated = 1 << 9,
- /**
- * Output percentage for details, not relative
- * to symbol but relative to the total nr of samples
- */
- ff_percent_details = 1 << 10,
- /**
- * Output percentage for details, not relative
- * to symbol but relative to the total nr of samples,
- * accumulated
- */
- ff_percent_cumulated_details = 1 << 11,
- /// output diff value
- ff_diff = 1 << 12,
- //@}
-};
-
-
-/**
- * General hints about formatting of the columnar output.
- */
-enum column_flags {
- cf_none = 0,
- cf_64bit_vma = 1 << 0,
- cf_image_name = 1 << 1
-};
-
-#endif // FORMAT_FLAGS_H
diff --git a/libpp/format_output.cpp b/libpp/format_output.cpp
deleted file mode 100644
index 700c0d6..0000000
--- a/libpp/format_output.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/**
- * @file format_output.cpp
- * outputting format for symbol lists
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-/* older glibc has C99 INFINITY in _GNU_SOURCE */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <sstream>
-#include <iomanip>
-#include <iostream>
-#include <cmath>
-
-#include "string_manip.h"
-
-#include "format_output.h"
-#include "profile_container.h"
-#include "callgraph_container.h"
-#include "diff_container.h"
-
-using namespace std;
-
-
-namespace {
-
-string const & get_image_name(image_name_id id, bool lf)
-{
- return lf ? image_names.name(id) : image_names.basename(id);
-}
-
-string const get_linenr_info(file_location const floc, bool lf)
-{
- ostringstream out;
-
- string const & filename = lf
- ? debug_names.name(floc.filename)
- : debug_names.basename(floc.filename);
-
- if (!filename.empty()) {
- out << filename << ":" << floc.linenr;
- } else {
- out << "(no location information)";
- }
-
- return out.str();
-}
-
-string get_vma(bfd_vma vma, bool vma_64)
-{
- ostringstream out;
- int width = vma_64 ? 16 : 8;
-
- out << hex << setw(width) << setfill('0') << vma;
-
- return out.str();
-}
-
-string get_percent(size_t dividend, size_t divisor)
-{
- double ratio = op_ratio(dividend, divisor);
-
- return ::format_percent(ratio * 100, percent_int_width,
- percent_fract_width);
-}
-
-} // anonymous namespace
-
-
-namespace format_output {
-
-
-formatter::formatter()
- :
- nr_classes(1),
- flags(ff_none),
- vma_64(false),
- long_filenames(false),
- need_header(true)
-{
- format_map[ff_vma] = field_description(9, "vma", &formatter::format_vma);
- format_map[ff_nr_samples] = field_description(9, "samples", &formatter::format_nr_samples);
- format_map[ff_nr_samples_cumulated] = field_description(14, "cum. samples", &formatter::format_nr_cumulated_samples);
- format_map[ff_percent] = field_description(9, "%", &formatter::format_percent);
- format_map[ff_percent_cumulated] = field_description(11, "cum. %", &formatter::format_cumulated_percent);
- format_map[ff_linenr_info] = field_description(28, "linenr info", &formatter::format_linenr_info);
- format_map[ff_image_name] = field_description(25, "image name", &formatter::format_image_name);
- format_map[ff_app_name] = field_description(25, "app name", &formatter::format_app_name);
- format_map[ff_symb_name] = field_description(30, "symbol name", &formatter::format_symb_name);
- format_map[ff_percent_details] = field_description(9, "%", &formatter::format_percent_details);
- format_map[ff_percent_cumulated_details] = field_description(10, "cum. %", &formatter::format_cumulated_percent_details);
- format_map[ff_diff] = field_description(10, "diff %", &formatter::format_diff);
-}
-
-
-formatter::~formatter()
-{
-}
-
-
-void formatter::set_nr_classes(size_t nr)
-{
- nr_classes = nr;
-}
-
-
-void formatter::add_format(format_flags flag)
-{
- flags = static_cast<format_flags>(flags | flag);
-}
-
-
-void formatter::show_header(bool on_off)
-{
- need_header = on_off;
-}
-
-
-void formatter::vma_format_64bit(bool on_off)
-{
- vma_64 = on_off;
-}
-
-
-void formatter::show_long_filenames(bool on_off)
-{
- long_filenames = on_off;
-}
-
-
-void formatter::show_global_percent(bool on_off)
-{
- global_percent = on_off;
-}
-
-
-void formatter::output_header(ostream & out)
-{
- if (!need_header)
- return;
-
- size_t padding = 0;
-
- // first output the vma field
- if (flags & ff_vma)
- padding = output_header_field(out, ff_vma, padding);
-
- // the field repeated for each profile class
- for (size_t pclass = 0 ; pclass < nr_classes; ++pclass) {
- if (flags & ff_nr_samples)
- padding = output_header_field(out,
- ff_nr_samples, padding);
-
- if (flags & ff_nr_samples_cumulated)
- padding = output_header_field(out,
- ff_nr_samples_cumulated, padding);
-
- if (flags & ff_percent)
- padding = output_header_field(out,
- ff_percent, padding);
-
- if (flags & ff_percent_cumulated)
- padding = output_header_field(out,
- ff_percent_cumulated, padding);
-
- if (flags & ff_diff)
- padding = output_header_field(out,
- ff_diff, padding);
-
- if (flags & ff_percent_details)
- padding = output_header_field(out,
- ff_percent_details, padding);
-
- if (flags & ff_percent_cumulated_details)
- padding = output_header_field(out,
- ff_percent_cumulated_details, padding);
- }
-
- // now the remaining field
- if (flags & ff_linenr_info)
- padding = output_header_field(out, ff_linenr_info, padding);
-
- if (flags & ff_image_name)
- padding = output_header_field(out, ff_image_name, padding);
-
- if (flags & ff_app_name)
- padding = output_header_field(out, ff_app_name, padding);
-
- if (flags & ff_symb_name)
- padding = output_header_field(out, ff_symb_name, padding);
-
- out << "\n";
-}
-
-
-/// describe each possible field of colummned output.
-// FIXME: use % of the screen width here. sum of % equal to 100, then calculate
-// ratio between 100 and the selected % to grow non fixed field use also
-// lib[n?]curses to get the console width (look info source) (so on add a fixed
-// field flags)
-size_t formatter::
-output_field(ostream & out, field_datum const & datum,
- format_flags fl, size_t padding, bool hide_immutable)
-{
- if (!hide_immutable) {
- out << string(padding, ' ');
-
- field_description const & field(format_map[fl]);
- string str = (this->*field.formatter)(datum);
- out << str;
-
- // at least one separator char
- padding = 1;
- if (str.length() < field.width)
- padding = field.width - str.length();
- } else {
- field_description const & field(format_map[fl]);
- padding += field.width;
- }
-
- return padding;
-}
-
-
-size_t formatter::
-output_header_field(ostream & out, format_flags fl, size_t padding)
-{
- out << string(padding, ' ');
-
- field_description const & field(format_map[fl]);
- out << field.header_name;
-
- // at least one separator char
- padding = 1;
- if (field.header_name.length() < field.width)
- padding = field.width - field.header_name.length();
-
- return padding;
-}
-
-
-string formatter::format_vma(field_datum const & f)
-{
- return get_vma(f.sample.vma, vma_64);
-}
-
-
-string formatter::format_symb_name(field_datum const & f)
-{
- return symbol_names.demangle(f.symbol.name);
-}
-
-
-string formatter::format_image_name(field_datum const & f)
-{
- return get_image_name(f.symbol.image_name, long_filenames);
-}
-
-
-string formatter::format_app_name(field_datum const & f)
-{
- return get_image_name(f.symbol.app_name, long_filenames);
-}
-
-
-string formatter::format_linenr_info(field_datum const & f)
-{
- return get_linenr_info(f.sample.file_loc, long_filenames);
-}
-
-
-string formatter::format_nr_samples(field_datum const & f)
-{
- ostringstream out;
- out << f.sample.counts[f.pclass];
- return out.str();
-}
-
-
-string formatter::format_nr_cumulated_samples(field_datum const & f)
-{
- if (f.diff == -INFINITY)
- return "---";
- ostringstream out;
- f.counts.cumulated_samples[f.pclass] += f.sample.counts[f.pclass];
- out << f.counts.cumulated_samples[f.pclass];
- return out.str();
-}
-
-
-string formatter::format_percent(field_datum const & f)
-{
- if (f.diff == -INFINITY)
- return "---";
- return get_percent(f.sample.counts[f.pclass], f.counts.total[f.pclass]);
-}
-
-
-string formatter::format_cumulated_percent(field_datum const & f)
-{
- if (f.diff == -INFINITY)
- return "---";
- f.counts.cumulated_percent[f.pclass] += f.sample.counts[f.pclass];
-
- return get_percent(f.counts.cumulated_percent[f.pclass],
- f.counts.total[f.pclass]);
-}
-
-
-string formatter::format_percent_details(field_datum const & f)
-{
- return get_percent(f.sample.counts[f.pclass],
- f.counts.total[f.pclass]);
-}
-
-
-string formatter::format_cumulated_percent_details(field_datum const & f)
-{
- f.counts.cumulated_percent_details[f.pclass] += f.sample.counts[f.pclass];
-
- return get_percent(f.counts.cumulated_percent_details[f.pclass],
- f.counts.total[f.pclass]);
-}
-
-
-string formatter::format_diff(field_datum const & f)
-{
- if (f.diff == INFINITY) {
- ostringstream out;
- out << "+++";
- return out.str();
- } else if (f.diff == -INFINITY) {
- ostringstream out;
- out << "---";
- return out.str();
- }
-
- return ::format_percent(f.diff, percent_int_width,
- percent_fract_width, true);
-}
-
-
-void formatter::
-do_output(ostream & out, symbol_entry const & symb, sample_entry const & sample,
- counts_t & c, diff_array_t const & diffs, bool hide_immutable)
-{
- size_t padding = 0;
-
- // first output the vma field
- field_datum datum(symb, sample, 0, c);
- if (flags & ff_vma)
- padding = output_field(out, datum, ff_vma, padding, false);
-
- // repeated fields for each profile class
- for (size_t pclass = 0 ; pclass < nr_classes; ++pclass) {
- field_datum datum(symb, sample, pclass, c, diffs[pclass]);
-
- if (flags & ff_nr_samples)
- padding = output_field(out, datum,
- ff_nr_samples, padding, false);
-
- if (flags & ff_nr_samples_cumulated)
- padding = output_field(out, datum,
- ff_nr_samples_cumulated, padding, false);
-
- if (flags & ff_percent)
- padding = output_field(out, datum,
- ff_percent, padding, false);
-
- if (flags & ff_percent_cumulated)
- padding = output_field(out, datum,
- ff_percent_cumulated, padding, false);
-
- if (flags & ff_diff)
- padding = output_field(out, datum,
- ff_diff, padding, false);
-
- if (flags & ff_percent_details)
- padding = output_field(out, datum,
- ff_percent_details, padding, false);
-
- if (flags & ff_percent_cumulated_details)
- padding = output_field(out, datum,
- ff_percent_cumulated_details, padding, false);
- }
-
- // now the remaining field
- if (flags & ff_linenr_info)
- padding = output_field(out, datum, ff_linenr_info,
- padding, false);
-
- if (flags & ff_image_name)
- padding = output_field(out, datum, ff_image_name,
- padding, hide_immutable);
-
- if (flags & ff_app_name)
- padding = output_field(out, datum, ff_app_name,
- padding, hide_immutable);
-
- if (flags & ff_symb_name)
- padding = output_field(out, datum, ff_symb_name,
- padding, hide_immutable);
-
- out << "\n";
-}
-
-
-opreport_formatter::opreport_formatter(profile_container const & p)
- :
- profile(p),
- need_details(false)
-{
- counts.total = profile.samples_count();
-}
-
-
-void opreport_formatter::show_details(bool on_off)
-{
- need_details = on_off;
-}
-
-
-void opreport_formatter::output(ostream & out, symbol_entry const * symb)
-{
- do_output(out, *symb, symb->sample, counts);
-
- if (need_details)
- output_details(out, symb);
-}
-
-
-void opreport_formatter::
-output(ostream & out, symbol_collection const & syms)
-{
- output_header(out);
-
- symbol_collection::const_iterator it = syms.begin();
- symbol_collection::const_iterator end = syms.end();
- for (; it != end; ++it)
- output(out, *it);
-}
-
-
-void opreport_formatter::
-output_details(ostream & out, symbol_entry const * symb)
-{
- counts_t c = counts;
-
- if (!global_percent)
- c.total = symb->sample.counts;
-
- // cumulated percent are relative to current symbol.
- c.cumulated_samples = count_array_t();
- c.cumulated_percent = count_array_t();
-
- sample_container::samples_iterator it = profile.begin(symb);
- sample_container::samples_iterator end = profile.end(symb);
- for (; it != end; ++it) {
- out << " ";
- do_output(out, *symb, it->second, c, diff_array_t(), true);
- }
-}
-
-
-cg_formatter::cg_formatter(callgraph_container const & profile)
-{
- counts.total = profile.samples_count();
-}
-
-
-void cg_formatter::output(ostream & out, cg_collection const & syms)
-{
- // amount of spacing prefixing child and parent lines
- string const child_parent_prefix(" ");
-
- output_header(out);
-
- out << string(79, '-') << endl;
-
- cg_collection::const_iterator it;
- cg_collection::const_iterator end = syms.end();
-
- for (it = syms.begin(); it < end; ++it) {
- cg_symbol const & sym = *it;
-
- cg_symbol::children::const_iterator cit;
- cg_symbol::children::const_iterator cend = sym.callers.end();
-
- counts_t c;
- if (global_percent)
- c.total = counts.total;
- else
- c.total = sym.total_caller_count;
-
- for (cit = sym.callers.begin(); cit != cend; ++cit) {
- out << child_parent_prefix;
- do_output(out, *cit, cit->sample, c);
- }
-
- do_output(out, sym, sym.sample, counts);
-
- c = counts_t();
- if (global_percent)
- c.total = counts.total;
- else
- c.total = sym.total_callee_count;
-
- cend = sym.callees.end();
-
- for (cit = sym.callees.begin(); cit != cend; ++cit) {
- out << child_parent_prefix;
- do_output(out, *cit, cit->sample, c);
- }
-
- out << string(79, '-') << endl;
- }
-}
-
-
-diff_formatter::diff_formatter(diff_container const & profile)
-{
- counts.total = profile.samples_count();
-}
-
-
-void diff_formatter::output(ostream & out, diff_collection const & syms)
-{
- output_header(out);
-
- diff_collection::const_iterator it = syms.begin();
- diff_collection::const_iterator end = syms.end();
- for (; it != end; ++it)
- do_output(out, *it, it->sample, counts, it->diffs);
-}
-
-
-} // namespace format_output
diff --git a/libpp/format_output.h b/libpp/format_output.h
deleted file mode 100644
index 88404d7..0000000
--- a/libpp/format_output.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * @file format_output.h
- * outputting format for symbol lists
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef FORMAT_OUTPUT_H
-#define FORMAT_OUTPUT_H
-
-#include "config.h"
-
-#include <string>
-#include <map>
-#include <iosfwd>
-
-#include "format_flags.h"
-#include "symbol.h"
-
-class symbol_entry;
-class sample_entry;
-class callgraph_container;
-class profile_container;
-class diff_container;
-
-namespace format_output {
-
-/// base class for formatter, handle common options to formatter
-class formatter {
-public:
- formatter();
- virtual ~formatter();
-
- /// add a given column
- void add_format(format_flags flag);
-
- /// set the need_header boolean to false
- void show_header(bool);
- /// format for 64 bit wide VMAs
- void vma_format_64bit(bool);
- /// show long (full path) filenames
- void show_long_filenames(bool);
- /// use global count rather symbol count for details percent
- void show_global_percent(bool);
-
- /**
- * Set the number of collected profile classes. Each class
- * will output sample count and percentage in extra columns.
- *
- * This class assumes that the profile information has been
- * populated with the right number of classes.
- */
- void set_nr_classes(size_t nr_classes);
-
- /// output table header, implemented by calling the virtual function
- /// output_header_field()
- void output_header(std::ostream & out);
-
-protected:
- struct counts_t {
- /// total sample count
- count_array_t total;
- /// samples so far
- count_array_t cumulated_samples;
- /// percentage so far
- count_array_t cumulated_percent;
- /// detailed percentage so far
- count_array_t cumulated_percent_details;
- };
-
- /// data passed for output
- struct field_datum {
- field_datum(symbol_entry const & sym,
- sample_entry const & s,
- size_t pc, counts_t & c, double d = 0.0)
- : symbol(sym), sample(s), pclass(pc),
- counts(c), diff(d) {}
- symbol_entry const & symbol;
- sample_entry const & sample;
- size_t pclass;
- mutable counts_t & counts;
- double diff;
- };
-
- /// format callback type
- typedef std::string (formatter::*fct_format)(field_datum const &);
-
- /** @name format functions.
- * The set of formatting functions, used internally by output().
- */
- //@{
- std::string format_vma(field_datum const &);
- std::string format_symb_name(field_datum const &);
- std::string format_image_name(field_datum const &);
- std::string format_app_name(field_datum const &);
- std::string format_linenr_info(field_datum const &);
- std::string format_nr_samples(field_datum const &);
- std::string format_nr_cumulated_samples(field_datum const &);
- std::string format_percent(field_datum const &);
- std::string format_cumulated_percent(field_datum const &);
- std::string format_percent_details(field_datum const &);
- std::string format_cumulated_percent_details(field_datum const &);
- std::string format_diff(field_datum const &);
- //@}
-
- /// decribe one field of the colummned output.
- struct field_description {
- field_description() {}
- field_description(std::size_t w, std::string h, fct_format f)
- : width(w), header_name(h), formatter(f) {}
-
- std::size_t width;
- std::string header_name;
- fct_format formatter;
- };
-
- typedef std::map<format_flags, field_description> format_map_t;
-
- /// actually do output
- void do_output(std::ostream & out, symbol_entry const & symbol,
- sample_entry const & sample, counts_t & c,
- diff_array_t const & = diff_array_t(),
- bool hide_immutable_field = false);
-
- /// returns the nr of char needed to pad this field
- size_t output_header_field(std::ostream & out, format_flags fl,
- size_t padding);
-
- /// returns the nr of char needed to pad this field
- size_t output_field(std::ostream & out, field_datum const & datum,
- format_flags fl, size_t padding,
- bool hide_immutable);
-
- /// stores functors for doing actual formatting
- format_map_t format_map;
-
- /// number of profile classes
- size_t nr_classes;
-
- /// total counts
- counts_t counts;
-
- /// formatting flags set
- format_flags flags;
- /// true if we need to format as 64 bits quantities
- bool vma_64;
- /// false if we use basename(filename) in output rather filename
- bool long_filenames;
- /// true if we need to show header before the first output
- bool need_header;
- /// bool if details percentage are relative to total count rather to
- /// symbol count
- bool global_percent;
-};
-
-
-/// class to output in a columned format symbols and associated samples
-class opreport_formatter : public formatter {
-public:
- /// build a ready to use formatter
- opreport_formatter(profile_container const & profile);
-
- /** output a vector of symbols to out according to the output format
- * specifier previously set by call(s) to add_format() */
- void output(std::ostream & out, symbol_collection const & syms);
-
- /// set the output_details boolean
- void show_details(bool);
-
-private:
-
- /** output one symbol symb to out according to the output format
- * specifier previously set by call(s) to add_format() */
- void output(std::ostream & out, symbol_entry const * symb);
-
- /// output details for the symbol
- void output_details(std::ostream & out, symbol_entry const * symb);
-
- /// container we work from
- profile_container const & profile;
-
- /// true if we need to show details for each symbols
- bool need_details;
-};
-
-
-/// class to output in a columned format caller/callee and associated samples
-class cg_formatter : public formatter {
-public:
- /// build a ready to use formatter
- cg_formatter(callgraph_container const & profile);
-
- /** output callgraph information according to the previously format
- * specifier set by call(s) to add_format() */
- void output(std::ostream & out, cg_collection const & syms);
-};
-
-/// class to output a columned format symbols plus diff values
-class diff_formatter : public formatter {
-public:
- /// build a ready to use formatter
- diff_formatter(diff_container const & profile);
-
- /**
- * Output a vector of symbols to out according to the output
- * format specifier previously set by call(s) to add_format()
- */
- void output(std::ostream & out, diff_collection const & syms);
-
-private:
- /// output a single symbol
- void output(std::ostream & out, diff_symbol const & sym);
-
-};
-
-} // namespace format_output
-
-#endif /* !FORMAT_OUTPUT_H */
diff --git a/libpp/image_errors.cpp b/libpp/image_errors.cpp
deleted file mode 100644
index 0960be6..0000000
--- a/libpp/image_errors.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file image_errors.cpp
- * Report errors in images
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- */
-
-#include "image_errors.h"
-
-#include "arrange_profiles.h"
-#include "string_manip.h"
-
-#include <iostream>
-#include <set>
-
-using namespace std;
-
-namespace {
-
-set<string> reported_images_error;
-
-}
-
-void report_image_error(string const & image, image_error error, bool fatal)
-{
- if (error == image_ok)
- return;
-
- if (reported_images_error.find(image) == reported_images_error.end()) {
- reported_images_error.insert(image);
-
- // FIXME: hacky
- if (error == image_not_found && is_prefix(image, "anon "))
- return;
-
- cerr << (fatal ? "error: " : "warning: ");
- cerr << image << ' ';
-
- switch (error) {
- case image_not_found:
- cerr << "could not be found.\n";
- break;
-
- case image_unreadable:
- cerr << "could not be read.\n";
- break;
-
- case image_multiple_match:
- cerr << "matches more than one file: "
- "detailed profile will not be provided.\n";
- break;
-
- case image_format_failure:
- cerr << "is not in a usable binary format.\n";
- break;
-
- case image_ok:
- break;
- }
- }
-}
-
-
-void report_image_error(inverted_profile const & profile, bool fatal)
-{
- report_image_error(profile.image, profile.error, fatal);
-}
-
-
-void report_image_errors(list<inverted_profile> const & plist)
-{
- list<inverted_profile>::const_iterator it = plist.begin();
- list<inverted_profile>::const_iterator const end = plist.end();
-
- for (; it != end; ++it) {
- report_image_error(*it, false);
- }
-}
diff --git a/libpp/image_errors.h b/libpp/image_errors.h
deleted file mode 100644
index ec26d90..0000000
--- a/libpp/image_errors.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file image_errors.h
- * Report errors in images
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- */
-
-#ifndef IMAGE_ERRORS_H
-#define IMAGE_ERRORS_H
-
-#include <list>
-#include <string>
-
-class inverted_profile;
-
-/// possible reasons why we can't read a binary image
-enum image_error {
- image_ok = 0,
- image_not_found,
- image_unreadable,
- image_format_failure,
- image_multiple_match
-};
-
-/// output why the image passed can't be read to stderr, we warranty only one
-/// error report by image name.
-void
-report_image_error(std::string const & image, image_error error, bool fatal);
-
-/// output why the image passed can't be read to stderr
-void report_image_error(inverted_profile const & profile, bool fatal);
-
-/// output why any bad images can't be read to stderr
-void report_image_errors(std::list<inverted_profile> const & plist);
-
-#endif /* IMAGE_ERRORS_H */
diff --git a/libpp/locate_images.cpp b/libpp/locate_images.cpp
deleted file mode 100644
index 26b14b3..0000000
--- a/libpp/locate_images.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * @file locate_images.cpp
- * Command-line helper
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include "file_manip.h"
-#include "locate_images.h"
-
-#include <cerrno>
-#include <iostream>
-#include <sstream>
-#include <cstdlib>
-
-using namespace std;
-
-
-void extra_images::populate(vector<string> const & paths)
-{
- vector<string>::const_iterator cit = paths.begin();
- vector<string>::const_iterator end = paths.end();
- for (; cit != end; ++cit) {
- string const path = op_realpath(*cit);
- list<string> file_list;
- create_file_list(file_list, path, "*", true);
- list<string>::const_iterator lit = file_list.begin();
- list<string>::const_iterator lend = file_list.end();
- for (; lit != lend; ++lit) {
- value_type v(op_basename(*lit), op_dirname(*lit));
- images.insert(v);
- }
- }
-}
-
-
-vector<string> const extra_images::find(string const & name) const
-{
- extra_images::matcher match(name);
- return find(match);
-}
-
-
-vector<string> const
-extra_images::find(extra_images::matcher const & match) const
-{
- vector<string> matches;
-
- const_iterator cit = images.begin();
- const_iterator end = images.end();
-
- for (; cit != end; ++cit) {
- if (match(cit->first))
- matches.push_back(cit->second + '/' + cit->first);
- }
-
- return matches;
-}
-
-
-namespace {
-
-/**
- * Function object for matching a module filename, which
- * has its own special mangling rules in 2.6 kernels.
- */
-struct module_matcher : public extra_images::matcher {
-public:
- explicit module_matcher(string const & s)
- : extra_images::matcher(s) {}
-
- virtual bool operator()(string const & candidate) const {
- if (candidate.length() != value.length())
- return false;
-
- for (string::size_type i = 0 ; i < value.length() ; ++i) {
- if (value[i] == candidate[i])
- continue;
- if (value[i] == '_' &&
- (candidate[i] == ',' || candidate[i] == '-'))
- continue;
- return false;
- }
-
- return true;
- }
-};
-
-} // anon namespace
-
-
-string const find_image_path(string const & archive_path,
- string const & image_name,
- extra_images const & extra_images,
- image_error & error)
-{
- error = image_ok;
-
- string const image = op_realpath(archive_path + image_name);
-
- // simplest case
- if (op_file_readable(image)) {
- error = image_ok;
- return image_name;
- }
-
- if (errno == EACCES) {
- error = image_unreadable;
- return image_name;
- }
-
- string const base = op_basename(image);
-
- vector<string> result = extra_images.find(base);
-
- // not found, try a module search
- if (result.empty())
- result = extra_images.find(module_matcher(base + ".ko"));
-
- if (result.empty()) {
- error = image_not_found;
- return image_name;
- }
-
- if (result.size() > 1) {
- error = image_multiple_match;
- return image_name;
- }
-
- return result[0];
-}
diff --git a/libpp/locate_images.h b/libpp/locate_images.h
deleted file mode 100644
index c003f9e..0000000
--- a/libpp/locate_images.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file locate_images.h
- * Location of binary images
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef LOCATE_IMAGES_H
-#define LOCATE_IMAGES_H
-
-#include <string>
-#include <map>
-#include <vector>
-
-#include "image_errors.h"
-
-/**
- * A class containing mappings from an image basename,
- * such as 'floppy.ko', to locations in the paths passed
- * in to populate().
- *
- * The name may exist multiple times; all locations are recorded
- * in this container.
- */
-class extra_images {
-public:
- /// add all filenames found in the given paths, recursively
- void populate(std::vector<std::string> const & paths);
-
- /// base class for matcher functors object
- struct matcher {
- std::string const & value;
- public:
- explicit matcher(std::string const & v) : value(v) {}
- virtual ~matcher() {}
- /// default functor allowing trivial match
- virtual bool operator()(std::string const & str) const {
- return str == value;
- }
- };
-
- /**
- * return a vector of all directories that match the functor
- */
- std::vector<std::string> const find(matcher const & match) const;
-
- /// return a vector of all directories that match the given name
- std::vector<std::string> const find(std::string const & name) const;
-
-private:
- typedef std::multimap<std::string, std::string> images_t;
- typedef images_t::value_type value_type;
- typedef images_t::const_iterator const_iterator;
-
- /// map from image basename to owning directory
- images_t images;
-};
-
-/**
- * @param archive_path archive prefix path
- * @param extra_images container where all extra candidate filenames are stored
- * @param image_name binary image name
- * @param error errors are flagged in this passed enum ref
- *
- * Locate a (number of) matching absolute paths to the given image name.
- * If we fail to find the file we fill in error and return the original string.
- */
-std::string const
-find_image_path(std::string const & archive_path,
- std::string const & image_name,
- extra_images const & extra_images,
- image_error & error);
-
-#endif /* LOCATE_IMAGES_H */
diff --git a/libpp/name_storage.cpp b/libpp/name_storage.cpp
deleted file mode 100644
index 99e0e90..0000000
--- a/libpp/name_storage.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file name_storage.cpp
- * Storage of global names (filenames and symbols)
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <stdexcept>
-
-#include "name_storage.h"
-#include "demangle_symbol.h"
-#include "file_manip.h"
-#include "string_manip.h"
-
-using namespace std;
-
-image_name_storage image_names;
-debug_name_storage debug_names;
-symbol_name_storage symbol_names;
-
-
-string const & image_name_storage::basename(image_name_id id) const
-{
- stored_name const & n = get(id);
- if (n.name_processed.empty()) {
- n.name_processed = op_basename(n.name);
- }
- return n.name_processed;
-}
-
-
-string const & debug_name_storage::basename(debug_name_id id) const
-{
- stored_name const & n = get(id);
- if (n.name_processed.empty()) {
- n.name_processed = op_basename(n.name);
- }
- return n.name_processed;
-}
-
-
-string const & symbol_name_storage::demangle(symbol_name_id id) const
-{
- stored_name const & n = get(id);
- if (!n.name_processed.empty() || n.name.empty())
- return n.name_processed;
-
- if (n.name[0] != '?') {
- n.name_processed = demangle_symbol(n.name);
- return n.name_processed;
- }
-
- if (n.name.length() < 2 || n.name[1] != '?') {
- n.name_processed = "(no symbols)";
- return n.name_processed;
- }
-
- n.name_processed = "anonymous symbol from section ";
- n.name_processed += ltrim(n.name, "?");
- return n.name_processed;
-}
diff --git a/libpp/name_storage.h b/libpp/name_storage.h
deleted file mode 100644
index 0e278cb..0000000
--- a/libpp/name_storage.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * @file name_storage.h
- * Type-safe unique storage of global names (filenames and symbols)
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef NAME_STORAGE_H
-#define NAME_STORAGE_H
-
-#include <string>
-
-#include "unique_storage.h"
-
-/// store original name and processed name
-struct stored_name {
- stored_name(std::string const & n = std::string())
- : name(n) {}
-
- bool operator<(stored_name const & rhs) const {
- return name < rhs.name;
- }
-
- std::string name;
- mutable std::string name_processed;
-};
-
-
-/// partial specialization for unique storage of names
-template <typename I> struct name_storage : unique_storage<I, stored_name> {
-
- typedef typename unique_storage<I, stored_name>::id_value id_value;
-
- std::string const & name(id_value const & id) const {
- return unique_storage<I, stored_name>::get(id).name;
- };
-};
-
-
-class debug_name_tag;
-/// a debug filename
-typedef name_storage<debug_name_tag>::id_value debug_name_id;
-
-/// class storing a set of shared debug name (source filename)
-struct debug_name_storage : name_storage<debug_name_tag> {
- /// return the basename for the given ID
- std::string const & basename(debug_name_id id) const;
-};
-
-
-class image_name_tag;
-/// an image name
-typedef name_storage<image_name_tag>::id_value image_name_id;
-
-/// class storing a set of shared image name
-struct image_name_storage : name_storage<image_name_tag> {
- /// return the basename name for the given ID
- std::string const & basename(image_name_id) const;
-};
-
-
-class symbol_name_tag;
-/// a (demangled) symbol
-typedef name_storage<symbol_name_tag>::id_value symbol_name_id;
-
-/// class storing a set of shared symbol name
-struct symbol_name_storage : name_storage<symbol_name_tag> {
- /// return the demangled name for the given ID
- std::string const & demangle(symbol_name_id id) const;
-};
-
-
-/// for images
-extern image_name_storage image_names;
-
-/// for debug filenames i.e. source filename
-extern debug_name_storage debug_names;
-
-/// for symbols
-extern symbol_name_storage symbol_names;
-
-
-/**
- * debug name specialisation for comparison.
- *
- * We compare by name rather by id since what user will see are
- * filename and when the criteria "samples count" give identical
- * result it's better to obtain result sorted by the user visible
- * property filename rather than by an obscure, invisible from user
- * point of view, file identifier property
- */
-template<> inline bool
-debug_name_id::operator<(debug_name_id const & rhs) const
-{
- return debug_names.name(*this) < debug_names.name(rhs);
-}
-
-#endif /* !NAME_STORAGE_H */
diff --git a/libpp/op_header.cpp b/libpp/op_header.cpp
deleted file mode 100644
index f0bacac..0000000
--- a/libpp/op_header.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * @file op_header.cpp
- * various free function acting on a sample file header
- *
- * @remark Copyright 2004 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- * @author Philippe Elie
- */
-
-#include <iostream>
-#include <cstdlib>
-#include <iomanip>
-#include <set>
-#include <sstream>
-
-#include "op_exception.h"
-#include "odb.h"
-#include "op_cpu_type.h"
-#include "op_file.h"
-#include "op_header.h"
-#include "op_events.h"
-#include "string_manip.h"
-
-using namespace std;
-
-void op_check_header(opd_header const & h1, opd_header const & h2,
- string const & filename)
-{
- if (h1.mtime != h2.mtime) {
- ostringstream os;
- os << "header timestamps are different ("
- << h1.mtime << ", " << h2.mtime << ") for "
- << filename << "\n";
- throw op_fatal_error(os.str());
- }
-
- if (h1.is_kernel != h2.is_kernel) {
- ostringstream os;
- os << "header is_kernel flags are different for "
- << filename << "\n";
- throw op_fatal_error(os.str());
- }
-
- if (h1.anon_start != h2.anon_start) {
- ostringstream os;
- os << "header anon_start flags are different for "
- << filename << "\n";
- throw op_fatal_error(os.str());
- }
-
- // Note that we don't check CPU speed since that can vary
- // freely on the same machine
-}
-
-
-namespace {
-
-set<string> warned_files;
-
-}
-
-
-void check_mtime(string const & file, opd_header const & header)
-{
- time_t const newmtime = op_get_mtime(file.c_str());
-
- if (newmtime == header.mtime)
- return;
-
- if (warned_files.find(file) != warned_files.end())
- return;
-
- warned_files.insert(file);
-
- // Files we couldn't get mtime of have zero mtime
- if (!header.mtime) {
- cerr << "warning: could not check that the binary file "
- << file << " has not been modified since "
- "the profile was taken. Results may be inaccurate.\n";
- } else {
- static bool warned_already = false;
-
- cerr << "warning: the last modified time of the binary file "
- "does not match that of the sample file for " << file
- << "\n";
-
- if (!warned_already) {
- cerr << "Either this is the wrong binary or the binary "
- "has been modified since the sample file was created.\n";
- warned_already = true;
- }
- }
-}
-
-
-opd_header const read_header(string const & sample_filename)
-{
- odb_t samples_db;
-
- int rc = odb_open(&samples_db, sample_filename.c_str(), ODB_RDONLY,
- sizeof(struct opd_header));
-
- if (rc)
- throw op_fatal_error(sample_filename + ": " + strerror(rc));
-
- opd_header head = *static_cast<opd_header *>(samples_db.data->base_memory);
-
- odb_close(&samples_db);
-
- return head;
-}
-
-
-namespace {
-
-string const op_print_event(op_cpu cpu_type, u8 type, u16 um, u32 count)
-{
- string str;
-
- if (cpu_type == CPU_TIMER_INT) {
- str += "Profiling through timer interrupt";
- return str;
- }
-
- struct op_event * event = op_find_event(cpu_type, type);
-
- if (!event) {
- cerr << "Could not locate event " << int(type) << endl;
- return str;
- }
-
- char const * um_desc = 0;
-
- for (size_t i = 0; i < event->unit->num; ++i) {
- if (event->unit->um[i].value == um)
- um_desc = event->unit->um[i].desc;
- }
-
- str += string("Counted ") + event->name;
- str += string(" events (") + event->desc + ")";
-
- if (cpu_type != CPU_RTC) {
- str += " with a unit mask of 0x";
-
- ostringstream ss;
- ss << hex << setw(2) << setfill('0') << unsigned(um);
- str += ss.str();
-
- str += " (";
- str += um_desc ? um_desc : "multiple flags";
- str += ")";
- }
-
- str += " count " + op_lexical_cast<string>(count);
- return str;
-}
-
-}
-
-
-string const describe_header(opd_header const & header)
-{
- op_cpu cpu = static_cast<op_cpu>(header.cpu_type);
-
- return op_print_event(cpu, header.ctr_event,
- header.ctr_um, header.ctr_count);
-}
-
-
-string const describe_cpu(opd_header const & header)
-{
- op_cpu cpu = static_cast<op_cpu>(header.cpu_type);
-
- string str;
- str += string("CPU: ") + op_get_cpu_type_str(cpu);
- str += ", speed ";
-
- ostringstream ss;
- ss << header.cpu_speed;
- str += ss.str() + " MHz (estimated)";
- return str;
-}
diff --git a/libpp/op_header.h b/libpp/op_header.h
deleted file mode 100644
index 0e109bc..0000000
--- a/libpp/op_header.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * @file op_header.h
- * various free function acting on a sample file header
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- * @author Philippe Elie
- */
-
-#ifndef OP_HEADER_H
-#define OP_HEADER_H
-
-#include <iosfwd>
-#include <string>
-
-#include "op_sample_file.h"
-
-/**
- * @param h1 sample file header
- * @param h2 sample file header
- * @param filename sample filename
- *
- * check that the h1 and h2 are coherent (same size, same mtime etc.)
- * all error are fatal
- */
-void op_check_header(opd_header const & h1, opd_header const & h2,
- std::string const & filename);
-
-/**
- * check mtime of samples file header against file
- * all error are fatal
- */
-void check_mtime(std::string const & file, opd_header const & header);
-
-/**
- * @param sample_filename the sample to open
- *
- * Return the header of this sample file. Only the magic number is checked
- * the version number is not checked. All error are fatal
- */
-opd_header const read_header(std::string const & sample_filename);
-
-/**
- * output a readable form of header, this don't include the cpu type
- * and speed
- */
-std::string const describe_header(opd_header const & header);
-
-/// output a readable form of cpu type and speed
-std::string const describe_cpu(opd_header const & header);
-
-#endif // OP_HEADER_H
diff --git a/libpp/parse_filename.cpp b/libpp/parse_filename.cpp
deleted file mode 100644
index 1593b94..0000000
--- a/libpp/parse_filename.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * @file parse_filename.cpp
- * Split a sample filename into its constituent parts
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#include <stdexcept>
-#include <vector>
-#include <string>
-#include <iostream>
-
-#include "parse_filename.h"
-#include "file_manip.h"
-#include "string_manip.h"
-
-using namespace std;
-
-namespace {
-
-// PP:3.19 event_name.count.unitmask.tgid.tid.cpu
-parsed_filename parse_event_spec(string const & event_spec)
-{
- typedef vector<string> parts_type;
- typedef parts_type::size_type size_type;
-
- size_type const nr_parts = 6;
-
- parts_type parts = separate_token(event_spec, '.');
-
- if (parts.size() != nr_parts) {
- throw invalid_argument("parse_event_spec(): bad event specification: " + event_spec);
- }
-
- for (size_type i = 0; i < nr_parts ; ++i) {
- if (parts[i].empty()) {
- throw invalid_argument("parse_event_spec(): bad event specification: " + event_spec);
- }
- }
-
- parsed_filename result;
-
- size_type i = 0;
- result.event = parts[i++];
- result.count = parts[i++];
- result.unitmask = parts[i++];
- result.tgid = parts[i++];
- result.tid = parts[i++];
- result.cpu = parts[i++];
-
- return result;
-}
-
-
-/**
- * @param component path component
- *
- * remove from path_component all directory left to {root}, {kern} or {anon}
- */
-void remove_base_dir(vector<string> & path)
-{
- vector<string>::iterator it;
- for (it = path.begin(); it != path.end(); ++it) {
- if (*it == "{root}" || *it == "{kern}" || *it == "{anon}")
- break;
- }
-
- path.erase(path.begin(), it);
-}
-
-
-/// Handle an anon region. Pretty print the details.
-string const parse_anon(string const & str)
-{
- vector<string> parts = separate_token(str, '.');
- if (parts.size() != 3)
- throw invalid_argument("parse_anon() invalid name: " + str);
-
- string ret = "anon (tgid:";
- ret += parts[0] + " range:" + parts[1] + "-" + parts[2] + ")";
- return ret;
-}
-
-
-} // anonymous namespace
-
-
-/*
- * valid filename are variations on:
- *
- * {kern}/name/event_spec
- * {root}/path/to/bin/{dep}/{root}/path/to/bin/event_spec
- * {root}/path/to/bin/{dep}/{anon}/pid.start.end/event_spec
- * {root}/path/to/bin/{dep}/{kern}/name/event_spec
- * {root}/path/to/bin/{dep}/{root}/path/to/bin/{cg}/{root}/path/to/bin/event_spec
-
- *
- * where /name/ denote a unique path component
- */
-parsed_filename parse_filename(string const & filename)
-{
- string::size_type pos = filename.find_last_of('/');
- if (pos == string::npos) {
- throw invalid_argument("parse_filename() invalid filename: " +
- filename);
- }
- string event_spec = filename.substr(pos + 1);
- string filename_spec = filename.substr(0, pos);
-
- parsed_filename result = parse_event_spec(event_spec);
-
- result.filename = filename;
-
- vector<string> path = separate_token(filename_spec, '/');
-
- remove_base_dir(path);
-
- // pp_interface PP:3.19 to PP:3.23 path must start either with {root}
- // or {kern} and we must found at least 2 component, remove_base_dir()
- // return an empty path if {root} or {kern} are not found
- if (path.size() < 2) {
- throw invalid_argument("parse_filename() invalid filename: " +
- filename);
- }
-
- size_t i;
- for (i = 1 ; i < path.size() ; ++i) {
- if (path[i] == "{dep}")
- break;
-
- result.image += "/" + path[i];
- }
-
- if (i == path.size()) {
- throw invalid_argument("parse_filename() invalid filename: " +
- filename);
- }
-
- // skip "{dep}"
- ++i;
-
- // PP:3.19 {dep}/ must be followed by {kern}/, {root}/ or {anon}/
- if (path[i] != "{kern}" && path[i] != "{root}" && path[i] != "{anon}") {
- throw invalid_argument("parse_filename() invalid filename: " +
- filename);
- }
-
- bool anon = path[i] == "{anon}";
-
- // skip "{root}", "{kern}" or "{anon}"
- ++i;
-
- for (; i < path.size(); ++i) {
- if (path[i] == "{cg}")
- break;
-
- if (anon) {
- result.lib_image = parse_anon(path[i++]);
- break;
- }
- result.lib_image += "/" + path[i];
- }
-
- if (i == path.size())
- return result;
-
- // skip "{cg}"
- ++i;
- if (i == path.size() ||
- (path[i] != "{kern}" && path[i] != "{root}" && path[i] != "{anon}")) {
- throw invalid_argument("parse_filename() invalid filename: "
- + filename);
- }
-
- // skip "{root}", "{kern}" or "{anon}"
- anon = path[i] == "{anon}";
- ++i;
-
- if (anon) {
- result.cg_image = parse_anon(path[i++]);
- } else {
- for (; i < path.size(); ++i)
- result.cg_image += "/" + path[i];
- }
-
- return result;
-}
-
-bool parsed_filename::profile_spec_equal(parsed_filename const & parsed)
-{
- return event == parsed.event &&
- count == parsed.count &&
- unitmask == parsed.unitmask &&
- tgid == parsed.tgid &&
- tid == parsed.tid &&
- cpu == parsed.tid;
-}
-
-ostream & operator<<(ostream & out, parsed_filename const & data)
-{
- out << data.filename << endl;
- out << data.image << " " << data.lib_image << " "
- << data.event << " " << data.count << " "
- << data.unitmask << " " << data.tgid << " "
- << data.tid << " " << data.cpu << endl;
-
- return out;
-}
diff --git a/libpp/parse_filename.h b/libpp/parse_filename.h
deleted file mode 100644
index 79c06aa..0000000
--- a/libpp/parse_filename.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file parse_filename.h
- * Split a sample filename into its constituent parts
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#ifndef PARSE_FILENAME_H
-#define PARSE_FILENAME_H
-
-#include <string>
-
-/**
- * a convenience class to store result of parse_filename()
- */
-struct parsed_filename
-{
- std::string image;
- std::string lib_image;
- /// destination image for call graph file, empty if this sample
- /// file is not a callgraph file.
- std::string cg_image;
- std::string event;
- std::string count;
- std::string unitmask;
- std::string tgid;
- std::string tid;
- std::string cpu;
-
- /// return true if the profile specification are identical.
- bool profile_spec_equal(parsed_filename const & parsed);
-
- /**
- * the original sample filename from which the
- * above components are built
- */
- std::string filename;
-};
-
-
-/// debugging helper
-std::ostream & operator<<(std::ostream &, parsed_filename const &);
-
-
-/**
- * parse a sample filename
- * @param filename in: a sample filename
- *
- * filename is split into constituent parts, the lib_image is optional
- * and can be empty on successfull call. All other error are fatal.
- * Filenames are encoded as according to PP:3.19 to PP:3.25
- *
- * all errors throw an std::invalid_argument exception
- */
-parsed_filename parse_filename(std::string const & filename);
-
-#endif /* !PARSE_FILENAME_H */
diff --git a/libpp/populate.cpp b/libpp/populate.cpp
deleted file mode 100644
index 450673a..0000000
--- a/libpp/populate.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file populate.cpp
- * Fill up a profile_container from inverted profiles
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- * @author Philippe Elie
- */
-
-#include "profile.h"
-#include "profile_container.h"
-#include "arrange_profiles.h"
-#include "op_bfd.h"
-#include "op_header.h"
-#include "populate.h"
-
-#include "image_errors.h"
-
-#include <iostream>
-
-using namespace std;
-
-namespace {
-
-/// load merged files for one set of sample files
-bool
-populate_from_files(profile_t & profile, op_bfd const & abfd,
- list<profile_sample_files> const & files)
-{
- list<profile_sample_files>::const_iterator it = files.begin();
- list<profile_sample_files>::const_iterator const end = files.end();
-
- bool found = false;
- // we can't handle cg files here obviously
- for (; it != end; ++it) {
- // A bit ugly but we must accept silently empty sample filename
- // since we can create a profile_sample_files for cg file only
- // (i.e no sample to the binary)
- if (!it->sample_filename.empty()) {
- profile.add_sample_file(it->sample_filename);
- profile.set_offset(abfd);
- found = true;
- }
- }
-
- return found;
-}
-
-} // anon namespace
-
-
-void
-populate_for_image(string const & archive_path, profile_container & samples,
- inverted_profile const & ip, string_filter const & symbol_filter,
- bool * has_debug_info)
-{
- bool ok = ip.error == image_ok;
-
- op_bfd abfd(archive_path, ip.image, symbol_filter, ok);
- if (!ok && ip.error == image_ok)
- ip.error = image_format_failure;
-
- if (ip.error == image_format_failure)
- report_image_error(ip, false);
-
- opd_header header;
-
- bool found = false;
- for (size_t i = 0; i < ip.groups.size(); ++i) {
- list<image_set>::const_iterator it
- = ip.groups[i].begin();
- list<image_set>::const_iterator const end
- = ip.groups[i].end();
-
- // we can only share a profile_t amongst each
- // image_set's files - this is because it->app_image
- // changes, and the .add() would mis-attribute
- // to the wrong app_image otherwise
- for (; it != end; ++it) {
- profile_t profile;
- if (populate_from_files(profile, abfd, it->files)) {
- header = profile.get_header();
- samples.add(profile, abfd, it->app_image, i);
- found = true;
- }
- }
- }
-
- // we shouldn't check/warn if an archive is used
- if (archive_path.empty() && found == true && ip.error == image_ok)
- check_mtime(abfd.get_filename(), header);
-
- if (has_debug_info)
- *has_debug_info = abfd.has_debug_info();
-}
diff --git a/libpp/populate.h b/libpp/populate.h
deleted file mode 100644
index 082136f..0000000
--- a/libpp/populate.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @file populate.h
- * Fill up a profile_container from inverted profiles
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon
- * @author Philippe Elie
- */
-
-#ifndef POPULATE_H
-#define POPULATE_H
-
-class profile_container;
-class inverted_profile;
-class string_filter;
-
-
-/// Load all sample file information for exactly one binary image.
-void
-populate_for_image(std::string const & archive_path,
- profile_container & samples, inverted_profile const & ip,
- string_filter const & symbol_filter, bool * has_debug_info);
-
-#endif /* POPULATE_H */
diff --git a/libpp/profile.cpp b/libpp/profile.cpp
deleted file mode 100644
index a0007dd..0000000
--- a/libpp/profile.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file profile.cpp
- * Encapsulation for samples files over all profile classes
- * belonging to the same binary image
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <unistd.h>
-
-#include <iostream>
-#include <string>
-#include <sstream>
-
-#include <cerrno>
-
-#include "op_exception.h"
-#include "op_header.h"
-#include "op_config.h"
-#include "op_sample_file.h"
-#include "profile.h"
-#include "op_bfd.h"
-#include "cverb.h"
-
-using namespace std;
-
-profile_t::profile_t()
- : start_offset(0)
-{
-}
-
-
-// static member
-unsigned int profile_t::sample_count(string const & filename)
-{
- odb_t samples_db;
-
- open_sample_file(filename, samples_db);
-
- unsigned int count = 0;
-
- odb_node_nr_t node_nr, pos;
- odb_node_t * node = odb_get_iterator(&samples_db, &node_nr);
- for (pos = 0; pos < node_nr; ++pos) {
- if (node[pos].key)
- count += node[pos].value;
- }
-
- odb_close(&samples_db);
-
- return count;
-}
-
-//static member
-void profile_t::open_sample_file(string const & filename, odb_t & db)
-{
- int rc = odb_open(&db, filename.c_str(), ODB_RDONLY,
- sizeof(struct opd_header));
-
- if (rc)
- throw op_fatal_error(filename + ": " + strerror(rc));
-
- opd_header const & head =
- *static_cast<opd_header *>(odb_get_data(&db));
-
- if (head.version != OPD_VERSION) {
- ostringstream os;
- os << "oprofpp: samples files version mismatch, are you "
- << "running a daemon and post-profile tools with version "
- << "mismatch ?\n";
- throw op_fatal_error(os.str());
- }
-}
-
-void profile_t::add_sample_file(string const & filename)
-{
- odb_t samples_db;
-
- open_sample_file(filename, samples_db);
-
- opd_header const & head =
- *static_cast<opd_header *>(odb_get_data(&samples_db));
-
- // if we already read a sample file header pointer is non null
- if (file_header.get())
- op_check_header(head, *file_header, filename);
-
- file_header.reset(new opd_header(head));
-
- odb_node_nr_t node_nr, pos;
- odb_node_t * node = odb_get_iterator(&samples_db, &node_nr);
-
- for (pos = 0; pos < node_nr; ++pos) {
- if (node[pos].key) {
- ordered_samples_t::iterator it =
- ordered_samples.find(node[pos].key);
- if (it != ordered_samples.end()) {
- it->second += node[pos].value;
- } else {
- ordered_samples_t::value_type
- val(node[pos].key, node[pos].value);
- ordered_samples.insert(val);
- }
- }
- }
-
- odb_close(&samples_db);
-}
-
-
-void profile_t::set_offset(op_bfd const & abfd)
-{
- opd_header const & header = get_header();
- if (header.anon_start || header.is_kernel)
- start_offset = abfd.get_start_offset(header.anon_start);
- cverb << (vdebug) << "start_offset is now " << start_offset << endl;
-}
-
-
-profile_t::iterator_pair
-profile_t::samples_range(odb_key_t start, odb_key_t end) const
-{
- // Check the start position isn't before start_offset:
- // this avoids wrapping/underflowing start/end.
- // This can happen on e.g. ARM kernels, where .init is
- // mapped before .text - we just have to skip any such
- // .init symbols.
- if (start < start_offset) {
- return make_pair(const_iterator(ordered_samples.end(), 0),
- const_iterator(ordered_samples.end(), 0));
- }
-
- start -= start_offset;
- end -= start_offset;
-
- // sanity check if start > end caller will enter into an infinite loop
- if (start > end) {
- throw op_fatal_error("profile_t::samples_range(): start > end"
- " something wrong with kernel or module layout ?\n"
- "please report problem to "
- "oprofile-list@lists.sourceforge.net");
- }
-
- ordered_samples_t::const_iterator first =
- ordered_samples.lower_bound(start);
- ordered_samples_t::const_iterator last =
- ordered_samples.lower_bound(end);
-
- return make_pair(const_iterator(first, start_offset),
- const_iterator(last, start_offset));
-}
-
-
-profile_t::iterator_pair profile_t::samples_range() const
-{
- ordered_samples_t::const_iterator first = ordered_samples.begin();
- ordered_samples_t::const_iterator last = ordered_samples.end();
-
- return make_pair(const_iterator(first, start_offset),
- const_iterator(last, start_offset));
-}
diff --git a/libpp/profile.h b/libpp/profile.h
deleted file mode 100644
index 237e354..0000000
--- a/libpp/profile.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * @file profile.h
- * Encapsulation for samples files over all profile classes
- * belonging to the same binary image
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef PROFILE_H
-#define PROFILE_H
-
-#include <string>
-#include <map>
-#include <iterator>
-
-#include "odb.h"
-#include "op_types.h"
-#include "utility.h"
-
-class opd_header;
-class op_bfd;
-
-/**
- * Class containing a single sample file contents.
- * i.e. set of count values for VMA offsets for
- * a particular binary.
- */
-class profile_t : noncopyable {
-public:
- /**
- * profile_t - construct an empty profile_t object
- */
- profile_t();
-
- /// return true if no sample file has been loaded
- bool empty() const { return !file_header.get(); }
-
- /// return the header of the last opened samples file
- opd_header const & get_header() const {
- return *file_header;
- }
-
- /**
- * count samples count w/o recording them
- * @param filename sample filename
- *
- * convenience interface for raw access to sample count w/o recording
- * them. It's placed here so all access to samples files go through
- * profile_t static or non static member.
- */
- static unsigned int sample_count(std::string const & filename);
-
- /**
- * cumulate sample file to our container of samples
- * @param filename sample file name
- *
- * store samples for one sample file, sample file header is sanitized.
- *
- * all error are fatal
- */
- void add_sample_file(std::string const & filename);
-
- /// Set an appropriate start offset, see comments below.
- void set_offset(op_bfd const & abfd);
-
- class const_iterator;
- typedef std::pair<const_iterator, const_iterator> iterator_pair;
-
- /**
- * @param start start offset
- * @param end end offset
- *
- * return an iterator pair to [start, end) range
- */
- iterator_pair
- samples_range(odb_key_t start, odb_key_t end) const;
-
- /// return a pair of iterator for all samples
- iterator_pair samples_range() const;
-
-private:
- /// helper for sample_count() and add_sample_file(). All error launch
- /// an exception.
- static void
- open_sample_file(std::string const & filename, odb_t &);
-
- /// copy of the samples file header
- scoped_ptr<opd_header> file_header;
-
- /// storage type for samples sorted by eip
- typedef std::map<odb_key_t, odb_value_t> ordered_samples_t;
-
- /**
- * Samples are stored in hash table, iterating over hash table don't
- * provide any ordering, the above count() interface rely on samples
- * ordered by eip. This map is only a temporary storage where samples
- * are ordered by eip.
- */
- ordered_samples_t ordered_samples;
-
- /**
- * For certain profiles, such as kernel/modules, and anon
- * regions with a matching binary, this value is non-zero,
- * and represents the file offset of the relevant section.
- *
- * For kernel profiles, this is done because we use the information
- * provided in /proc/ksyms, which only gives the mapped position of
- * .text, and the symbol _text from vmlinux. This value is used to fix
- * up the sample offsets for kernel code as a result of this difference
- *
- * In user-space samples, the sample offset is from the start of the
- * mapped file, as seen in /proc/pid/maps. This is fine for
- * mappings of permanent files, but with anon mappings, we need
- * to adjust the key values to be a file offset against the
- * *binary* (if there is one). This can obviously be different.
- * So we pass our anon mapping start VMA to op_bfd, which looks
- * for a section with that VMA, then returns the section's
- * filepos. So all is good.
- *
- * Finally, note that for cg we can't use this inside the
- * profile_t, as we're storing two offsets in the key value. So
- * we do it later in that case.
- *
- * Phew.
- */
- u32 start_offset;
-};
-
-
-// It will be easier to derive profile_t::const_iterator from
-// std::iterator<std::input_iterator_tag, unsigned int> but this doesn't
-// work for gcc <= 2.95 so we provide the neccessary typedef in the hard way.
-// See ISO C++ 17.4.3.1 § 1 and 14.7.3 § 9.
-namespace std {
- template <>
- struct iterator_traits<profile_t::const_iterator> {
- typedef ptrdiff_t difference_type;
- typedef unsigned int value_type;
- typedef unsigned int * pointer;
- typedef unsigned int & reference;
- typedef input_iterator_tag iterator_category;
- };
-}
-
-
-class profile_t::const_iterator
-{
- typedef ordered_samples_t::const_iterator iterator_t;
-public:
- const_iterator() : start_offset(0) {}
- const_iterator(iterator_t it_, u32 start_offset_)
- : it(it_), start_offset(start_offset_) {}
-
- unsigned int operator*() const { return it->second; }
- const_iterator & operator++() { ++it; return *this; }
-
- odb_key_t vma() const { return it->first + start_offset; }
- unsigned int count() const { return **this; }
-
- bool operator!=(const_iterator const & rhs) const {
- return it != rhs.it;
- }
- bool operator==(const_iterator const & rhs) const {
- return it == rhs.it;
- }
-
-private:
- iterator_t it;
- u32 start_offset;
-};
-
-#endif /* !PROFILE_H */
diff --git a/libpp/profile_container.cpp b/libpp/profile_container.cpp
deleted file mode 100644
index b0422d1..0000000
--- a/libpp/profile_container.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/**
- * @file profile_container.cpp
- * profile file container
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <set>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <algorithm>
-#include <numeric>
-
-#include "symbol.h"
-#include "op_header.h"
-#include "profile.h"
-#include "symbol_functors.h"
-#include "profile_container.h"
-#include "sample_container.h"
-#include "symbol_container.h"
-
-using namespace std;
-
-namespace {
-
-struct filename_by_samples {
- filename_by_samples(debug_name_id id, double percent_)
- : filename(id), percent(percent_)
- {}
-
- bool operator<(filename_by_samples const & lhs) const {
- if (percent != lhs.percent)
- return percent < lhs.percent;
- return filename < lhs.filename;
- }
-
- debug_name_id filename;
- // ratio of samples which belongs to this filename.
- double percent;
-};
-
-} // anon namespace
-
-
-profile_container::profile_container(bool debug_info_, bool need_details_)
- :
- symbols(new symbol_container),
- samples(new sample_container),
- debug_info(debug_info_),
- need_details(need_details_)
-{
-}
-
-
-profile_container::~profile_container()
-{
-}
-
-
-// Post condition:
-// the symbols/samples are sorted by increasing vma.
-// the range of sample_entry inside each symbol entry are valid
-// the samples_by_file_loc member var is correctly setup.
-void profile_container::add(profile_t const & profile,
- op_bfd const & abfd, string const & app_name,
- size_t pclass)
-{
- string const image_name = abfd.get_filename();
-
- for (symbol_index_t i = 0; i < abfd.syms.size(); ++i) {
-
- unsigned long start, end;
- symbol_entry symb_entry;
-
- abfd.get_symbol_range(i, start, end);
-
- profile_t::iterator_pair p_it =
- profile.samples_range(start, end);
-
- u32 count = accumulate(p_it.first, p_it.second, 0);
-
- // skip entries with no samples
- if (count == 0)
- continue;
-
- symb_entry.sample.counts[pclass] = count;
- total_count[pclass] += count;
-
- symb_entry.size = end - start;
-
- symb_entry.name = symbol_names.create(abfd.syms[i].name());
-
- symb_entry.sample.file_loc.linenr = 0;
- if (debug_info) {
- string filename;
- if (abfd.get_linenr(i, start, filename,
- symb_entry.sample.file_loc.linenr)) {
- symb_entry.sample.file_loc.filename =
- debug_names.create(filename);
- }
- }
-
- symb_entry.image_name = image_names.create(image_name);
- symb_entry.app_name = image_names.create(app_name);
-
- bfd_vma base_vma = abfd.syms[i].vma();
-
- symb_entry.sample.vma = abfd.sym_offset(i, start) + base_vma;
-
- symbol_entry const * symbol = symbols->insert(symb_entry);
-
- if (need_details) {
- add_samples(abfd, i, p_it, symbol, pclass);
- }
- }
-}
-
-
-void
-profile_container::add_samples(op_bfd const & abfd, symbol_index_t sym_index,
- profile_t::iterator_pair const & p_it,
- symbol_entry const * symbol, size_t pclass)
-{
- bfd_vma base_vma = abfd.syms[sym_index].vma();
-
- profile_t::const_iterator it;
- for (it = p_it.first; it != p_it.second ; ++it) {
- sample_entry sample;
-
- sample.counts[pclass] = it.count();
-
- sample.file_loc.linenr = 0;
- if (debug_info) {
- string filename;
- if (abfd.get_linenr(sym_index, it.vma(), filename,
- sample.file_loc.linenr)) {
- sample.file_loc.filename =
- debug_names.create(filename);
- }
- }
-
- sample.vma = abfd.sym_offset(sym_index, it.vma()) + base_vma;
-
- samples->insert(symbol, sample);
- }
-}
-
-
-symbol_collection const
-profile_container::select_symbols(symbol_choice & choice) const
-{
- symbol_collection result;
-
- double const threshold = choice.threshold / 100.0;
-
- symbol_container::symbols_t::iterator it = symbols->begin();
- symbol_container::symbols_t::iterator const end = symbols->end();
-
- for (; it != end; ++it) {
- if (choice.match_image
- && (image_names.name(it->image_name) != choice.image_name))
- continue;
-
- double const percent =
- op_ratio(it->sample.counts[0], total_count[0]);
-
- if (percent >= threshold) {
- result.push_back(&*it);
-
- choice.hints = it->output_hint(choice.hints);
- }
- }
-
- return result;
-}
-
-
-vector<debug_name_id> const
-profile_container::select_filename(double threshold) const
-{
- set<debug_name_id> filename_set;
-
- threshold /= 100.0;
-
- // Trying to iterate on symbols to create the set of filenames which
- // contain sample does not work: a symbol can contain samples and this
- // symbol is in a source file that contain zero sample because only
- // inline function in this source file contains samples.
- sample_container::samples_iterator sit = samples->begin();
- sample_container::samples_iterator const send = samples->end();
-
- for (; sit != send; ++sit) {
- debug_name_id name_id = sit->second.file_loc.filename;
- if (name_id.set()) {
- filename_set.insert(name_id);
- }
- }
-
- // Give a sort order on filename for the selected pclass.
- vector<filename_by_samples> file_by_samples;
-
- set<debug_name_id>::const_iterator it = filename_set.begin();
- set<debug_name_id>::const_iterator const end = filename_set.end();
- for (; it != end; ++it) {
- // FIXME: is samples_count() the right interface now ?
- count_array_t counts = samples_count(*it);
-
- double const ratio = op_ratio(counts[0], total_count[0]);
- filename_by_samples const f(*it, ratio);
-
- file_by_samples.push_back(f);
- }
-
- // now sort the file_by_samples entry.
- sort(file_by_samples.begin(), file_by_samples.end());
-
- // 2.91.66 doesn't like const_reverse_iterator in this context
- vector<filename_by_samples>::reverse_iterator cit
- = file_by_samples.rbegin();
- vector<filename_by_samples>::reverse_iterator const cend
- = file_by_samples.rend();
-
- vector<debug_name_id> result;
- for (; cit != cend; ++cit) {
- if (cit->percent >= threshold)
- result.push_back(cit->filename);
- }
-
- return result;
-}
-
-
-count_array_t profile_container::samples_count() const
-{
- return total_count;
-}
-
-
-// Rest here are delegated to our private implementation.
-
-symbol_entry const *
-profile_container::find_symbol(string const & image_name, bfd_vma vma) const
-{
- return symbols->find_by_vma(image_name, vma);
-}
-
-
-symbol_entry const *
-profile_container::find_symbol(debug_name_id filename, size_t linenr) const
-{
- return symbols->find(filename, linenr);
-}
-
-
-sample_entry const *
-profile_container::find_sample(symbol_entry const * symbol, bfd_vma vma) const
-{
- return samples->find_by_vma(symbol, vma);
-}
-
-
-count_array_t profile_container::samples_count(debug_name_id filename_id) const
-{
- return samples->accumulate_samples(filename_id);
-}
-
-
-count_array_t profile_container::samples_count(debug_name_id filename,
- size_t linenr) const
-{
- return samples->accumulate_samples(filename, linenr);
-}
-
-
-sample_container::samples_iterator
-profile_container::begin(symbol_entry const * symbol) const
-{
- return samples->begin(symbol);
-}
-
-
-sample_container::samples_iterator
-profile_container::end(symbol_entry const * symbol) const
-{
- return samples->end(symbol);
-}
-
-
-sample_container::samples_iterator profile_container::begin() const
-{
- return samples->begin();
-}
-
-
-sample_container::samples_iterator profile_container::end() const
-{
- return samples->end();
-}
-
-symbol_entry const * profile_container::find(symbol_entry const & symbol) const
-{
- return symbols->find(symbol);
-}
-
-symbol_container::symbols_t::iterator profile_container::begin_symbol() const
-{
- return symbols->begin();
-}
-
-symbol_container::symbols_t::iterator profile_container::end_symbol() const
-{
- return symbols->end();
-}
diff --git a/libpp/profile_container.h b/libpp/profile_container.h
deleted file mode 100644
index 153ecfc..0000000
--- a/libpp/profile_container.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @file profile_container.h
- * Container associating symbols and samples
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef PROFILE_CONTAINER_H
-#define PROFILE_CONTAINER_H
-
-#include <string>
-#include <vector>
-
-#include "profile.h"
-#include "utility.h"
-#include "op_bfd.h"
-#include "sample_container.h"
-#include "symbol_container.h"
-#include "format_flags.h"
-
-class string_filter;
-class symbol_entry;
-class sample_entry;
-
-/**
- * Store multiple samples files belonging to the same profiling session.
- * This is the main container capable of holding the profiles for arbitrary
- * binary images and arbitrary profile classes.
- */
-class profile_container : noncopyable {
-public:
- /**
- * Build an object to store information on samples. All parameters
- * acts as hint for what you will request after recording samples and
- * so allow optimizations during recording the information.
- *
- * @param debug_info If true line numbers and source files are recorded.
- *
- * @param need_details If true if we need to record all samples or to
- * to record them at symbol level.
- */
- profile_container(bool debug_info, bool need_details);
-
- ~profile_container();
-
- /**
- * add() - record symbols/samples in the underlying container
- *
- * @param profile the samples files container
- * @param abfd the associated bfd object
- * @param app_name the owning application name of sample
- * @param pclass the profile class to add results for
- *
- * add() is an helper for delayed ctor. Take care you can't safely
- * make any call to add after any other member function call.
- * Obviously you can add only samples files which are coherent (same
- * sampling rate, same events etc.)
- */
- void add(profile_t const & profile, op_bfd const & abfd,
- std::string const & app_name, size_t pclass);
-
- /// Find a symbol from its image_name, vma, return zero if no symbol
- /// for this image at this vma
- symbol_entry const * find_symbol(std::string const & image_name,
- bfd_vma vma) const;
-
- /// Find a symbol from its filename, linenr, return zero if no symbol
- /// at this location
- symbol_entry const * find_symbol(debug_name_id filename,
- size_t linenr) const;
-
- /// Find a sample by its symbol, vma, return zero if there is no sample
- /// at this vma
- sample_entry const * find_sample(symbol_entry const * symbol,
- bfd_vma vma) const;
-
- /// Find a symbol. Return NULL if not found.
- symbol_entry const * find(symbol_entry const & symbol) const;
-
- /// used for select_symbols()
- struct symbol_choice {
- symbol_choice()
- : hints(cf_none), threshold(0.0), match_image(false) {}
-
- /// hints filled in
- column_flags hints;
- /// percentage threshold
- double threshold;
- /// match the image name only
- bool match_image;
- /// owning image name
- std::string image_name;
- };
-
- /**
- * select_symbols - create a set of symbols sorted by sample count
- * @param choice parameters to use/fill in when selecting
- */
- symbol_collection const select_symbols(symbol_choice & choice) const;
-
- /// Like select_symbols for filename without allowing sort by vma.
- std::vector<debug_name_id> const select_filename(double threshold) const;
-
- /// return the total number of samples
- count_array_t samples_count() const;
-
- /// Get the samples count which belongs to filename. Return 0 if
- /// no samples found.
- count_array_t samples_count(debug_name_id filename_id) const;
- /// Get the samples count which belongs to filename, linenr. Return
- /// 0 if no samples found.
- count_array_t samples_count(debug_name_id filename,
- size_t linenr) const;
-
- /// return an iterator to the first symbol
- symbol_container::symbols_t::iterator begin_symbol() const;
- /// return an iterator to the last symbol
- symbol_container::symbols_t::iterator end_symbol() const;
-
- /// return iterator to the first samples
- sample_container::samples_iterator begin() const;
- /// return iterator to the last samples
- sample_container::samples_iterator end() const;
-
- /// return iterator to the first samples for this symbol
- sample_container::samples_iterator begin(symbol_entry const *) const;
- /// return iterator to the last samples for this symbol
- sample_container::samples_iterator end(symbol_entry const *) const;
-
-private:
- /// helper for add()
- void add_samples(op_bfd const & abfd, symbol_index_t sym_index,
- profile_t::iterator_pair const &,
- symbol_entry const * symbol, size_t pclass);
-
- /**
- * create an unique artificial symbol for an offset range. The range
- * is only a hint of the maximum size of the created symbol. We
- * give to the symbol an unique name as ?image_file_name#order and
- * a range up to the nearest of syms or for the whole range if no
- * syms exist after the start offset. the end parameter is updated
- * to reflect the symbol range.
- *
- * The rationale here is to try to create symbols for alignment between
- * function as little as possible and to create meaningfull symbols
- * for special case such image w/o symbol.
- */
- std::string create_artificial_symbol(op_bfd const & abfd, u32 start,
- u32 & end, size_t & order);
-
- /// The symbols collected by pp tools sorted by increased vma, provide
- /// also a sort order on samples count for each profile class
- scoped_ptr<symbol_container> symbols;
- /// The samples count collected by pp tools sorted by increased vma,
- /// provide also a sort order on (filename, linenr)
- scoped_ptr<sample_container> samples;
- /// build() must count samples count for each profile class so cache it
- /// here since user of profile_container often need it later.
- count_array_t total_count;
-
- /**
- * Optimization hints for what information we are going to need,
- * see the explanation in profile_container()
- */
- //@{
- bool debug_info;
- bool need_details;
- //@}
-};
-
-#endif /* !PROFILE_CONTAINER_H */
diff --git a/libpp/profile_spec.cpp b/libpp/profile_spec.cpp
deleted file mode 100644
index f244e7c..0000000
--- a/libpp/profile_spec.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/**
- * @file profile_spec.cpp
- * Contains a PP profile specification
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#include <algorithm>
-#include <set>
-#include <sstream>
-#include <iterator>
-#include <iostream>
-
-#include "file_manip.h"
-#include "op_config.h"
-#include "profile_spec.h"
-#include "string_manip.h"
-#include "glob_filter.h"
-#include "locate_images.h"
-#include "op_exception.h"
-
-using namespace std;
-
-namespace {
-
-// PP:3.7, full path, or relative path. If we can't find it,
-// we should maintain the original to maintain the wordexp etc.
-string const fixup_image_spec(string const & str, extra_images const & extra)
-{
- string dummy_archive_path;
- // FIXME: what todo if an error in find_image_path() ?
- image_error error;
- return find_image_path(dummy_archive_path, str, extra, error);
-}
-
-
-void fixup_image_spec(vector<string> & images, extra_images const & extra)
-{
- vector<string>::iterator it = images.begin();
- vector<string>::iterator const end = images.end();
-
- for (; it != end; ++it) {
- *it = fixup_image_spec(*it, extra);
- }
-}
-
-} // anon namespace
-
-
-profile_spec::profile_spec(extra_images const & extra)
- : extra(extra)
-{
- parse_table["archive"] = &profile_spec::parse_archive_path;
- parse_table["session"] = &profile_spec::parse_session;
- parse_table["session-exclude"] =
- &profile_spec::parse_session_exclude;
- parse_table["image"] = &profile_spec::parse_image;
- parse_table["image-exclude"] = &profile_spec::parse_image_exclude;
- parse_table["lib-image"] = &profile_spec::parse_lib_image;
- parse_table["event"] = &profile_spec::parse_event;
- parse_table["count"] = &profile_spec::parse_count;
- parse_table["unit-mask"] = &profile_spec::parse_unitmask;
- parse_table["tid"] = &profile_spec::parse_tid;
- parse_table["tgid"] = &profile_spec::parse_tgid;
- parse_table["cpu"] = &profile_spec::parse_cpu;
-}
-
-
-void profile_spec::parse(string const & tag_value)
-{
- string value;
- action_t action = get_handler(tag_value, value);
- if (!action) {
- throw invalid_argument("profile_spec::parse(): not "
- "a valid tag \"" + tag_value + "\"");
- }
-
- (this->*action)(value);
-}
-
-
-bool profile_spec::is_valid_tag(string const & tag_value)
-{
- string value;
- return get_handler(tag_value, value);
-}
-
-
-void profile_spec::set_image_or_lib_name(string const & str)
-{
- /* FIXME: what does spec say about this being allowed to be
- * a comma list or not ? */
- image_or_lib_image.push_back(fixup_image_spec(str, extra));
-}
-
-
-void profile_spec::parse_archive_path(string const & str)
-{
- archive_path = op_realpath(str);
-}
-
-
-string profile_spec::get_archive_path() const
-{
- return archive_path;
-}
-
-
-void profile_spec::parse_session(string const & str)
-{
- session = separate_token(str, ',');
-}
-
-
-void profile_spec::parse_session_exclude(string const & str)
-{
- session_exclude = separate_token(str, ',');
-}
-
-
-void profile_spec::parse_image(string const & str)
-{
- image = separate_token(str, ',');
- fixup_image_spec(image, extra);
-}
-
-
-void profile_spec::parse_image_exclude(string const & str)
-{
- image_exclude = separate_token(str, ',');
-}
-
-
-void profile_spec::parse_lib_image(string const & str)
-{
- lib_image = separate_token(str, ',');
- fixup_image_spec(image, extra);
-}
-
-
-void profile_spec::parse_event(string const & str)
-{
- event.set(str);
-}
-
-
-void profile_spec::parse_count(string const & str)
-{
- count.set(str);
-}
-
-
-void profile_spec::parse_unitmask(string const & str)
-{
- unitmask.set(str);
-}
-
-
-void profile_spec::parse_tid(string const & str)
-{
- tid.set(str);
-}
-
-
-void profile_spec::parse_tgid(string const & str)
-{
- tgid.set(str);
-}
-
-
-void profile_spec::parse_cpu(string const & str)
-{
- cpu.set(str);
-}
-
-
-profile_spec::action_t
-profile_spec::get_handler(string const & tag_value, string & value)
-{
- string::size_type pos = tag_value.find_first_of(':');
- if (pos == string::npos) {
- return 0;
- }
-
- string tag(tag_value.substr(0, pos));
- value = tag_value.substr(pos + 1);
-
- parse_table_t::const_iterator it = parse_table.find(tag);
- if (it == parse_table.end()) {
- return 0;
- }
-
- return it->second;
-}
-
-
-namespace {
-
-/// return true if the value from the profile spec may match the comma
-/// list
-template<typename T>
-bool comma_match(comma_list<T> const & cl, generic_spec<T> const & value)
-{
- // if the profile spec is "all" we match the sample file
- if (!cl.is_set())
- return true;
-
- // an "all" sample file should never match specified profile
- // spec values
- if (!value.is_set())
- return false;
-
- // now match each profile spec value against the sample file
- return cl.match(value.value());
-}
-
-}
-
-
-bool profile_spec::match(filename_spec const & spec) const
-{
- bool matched_by_image_or_lib_image = false;
-
- // PP:3.19
- if (!image_or_lib_image.empty()) {
- // Need the path search for the benefit of modules
- // which have "/oprofile" or similar
- string simage = fixup_image_spec(spec.image, extra);
- string slib_image = fixup_image_spec(spec.lib_image, extra);
- glob_filter filter(image_or_lib_image, image_exclude);
- if (filter.match(simage) || filter.match(slib_image)) {
- matched_by_image_or_lib_image = true;
- }
- }
-
- if (!matched_by_image_or_lib_image) {
- // PP:3.7 3.8
- if (!image.empty()) {
- glob_filter filter(image, image_exclude);
- if (!filter.match(spec.image)) {
- return false;
- }
- } else if (!image_or_lib_image.empty()) {
- // image.empty() means match all except if user
- // specified image_or_lib_image
- return false;
- }
-
- // PP:3.9 3.10
- if (!lib_image.empty()) {
- glob_filter filter(lib_image, image_exclude);
- if (!filter.match(spec.lib_image)) {
- return false;
- }
- } else if (image.empty() && !image_or_lib_image.empty()) {
- // lib_image empty means match all except if user
- // specified image_or_lib_image *or* we already
- // matched this spec through image
- return false;
- }
- }
-
- if (!matched_by_image_or_lib_image) {
- // if we don't match by image_or_lib_image we must try to
- // exclude from spec, exclusion from image_or_lib_image has
- // been handled above
- vector<string> empty;
- glob_filter filter(empty, image_exclude);
- if (!filter.match(spec.image)) {
- return false;
- }
- if (!spec.lib_image.empty() && !filter.match(spec.lib_image)) {
- return false;
- }
- }
-
- if (!event.match(spec.event))
- return false;
-
- if (!count.match(spec.count))
- return false;
-
- if (!unitmask.match(spec.unitmask))
- return false;
-
- if (!comma_match(cpu, spec.cpu))
- return false;
-
- if (!comma_match(tid, spec.tid))
- return false;
-
- if (!comma_match(tgid, spec.tgid))
- return false;
-
- return true;
-}
-
-
-profile_spec profile_spec::create(list<string> const & args,
- extra_images const & extra)
-{
- profile_spec spec(extra);
- set<string> tag_seen;
-
- list<string>::const_iterator it = args.begin();
- list<string>::const_iterator end = args.end();
-
- for (; it != end; ++it) {
- if (spec.is_valid_tag(*it)) {
- if (tag_seen.find(*it) != tag_seen.end()) {
- throw op_runtime_error("tag specified "
- "more than once: " + *it);
- }
- tag_seen.insert(*it);
- spec.parse(*it);
- } else {
- string const file = op_realpath(*it);
- spec.set_image_or_lib_name(file);
- }
- }
-
- // PP:3.5 no session given means use the current session.
- if (spec.session.empty()) {
- spec.session.push_back("current");
- }
-
- return spec;
-}
-
-namespace {
-
-vector<string> filter_session(vector<string> const & session,
- vector<string> const & session_exclude)
-{
- vector<string> result(session);
-
- if (result.empty()) {
- result.push_back("current");
- }
-
- for (size_t i = 0 ; i < session_exclude.size() ; ++i) {
- // FIXME: would we use fnmatch on each item, are we allowed
- // to --session=current* ?
- vector<string>::iterator it =
- find(result.begin(), result.end(), session_exclude[i]);
-
- if (it != result.end()) {
- result.erase(it);
- }
- }
-
- return result;
-}
-
-
-bool valid_candidate(string const & base_dir, string const & filename,
- profile_spec const & spec, bool exclude_dependent,
- bool exclude_cg)
-{
- if (exclude_cg && filename.find("{cg}") != string::npos)
- return false;
-
- // strip out non sample files
- string const & sub = filename.substr(base_dir.size(), string::npos);
- if (!is_prefix(sub, "/{root}/") && !is_prefix(sub, "/{kern}/"))
- return false;
-
- filename_spec file_spec(filename);
- if (spec.match(file_spec)) {
- if (exclude_dependent && file_spec.is_dependent())
- return false;
- return true;
- }
-
- return false;
-}
-
-} // anonymous namespace
-
-
-list<string> profile_spec::generate_file_list(bool exclude_dependent,
- bool exclude_cg) const
-{
- // FIXME: isn't remove_duplicates faster than doing this, then copy() ?
- set<string> unique_files;
-
- vector<string> sessions = filter_session(session, session_exclude);
-
- if (sessions.empty()) {
- ostringstream os;
- os << "No session given\n"
- << "included session was:\n";
- copy(session.begin(), session.end(),
- ostream_iterator<string>(os, "\n"));
- os << "excluded session was:\n";
- copy(session_exclude.begin(), session_exclude.end(),
- ostream_iterator<string>(os, "\n"));
- throw invalid_argument(os.str());
- }
-
- bool found_file = false;
-
- vector<string>::const_iterator cit = sessions.begin();
- vector<string>::const_iterator end = sessions.end();
-
- for (; cit != end; ++cit) {
- if (cit->empty())
- continue;
-
- string base_dir;
- if ((*cit)[0] != '.' && (*cit)[0] != '/')
- base_dir = archive_path + OP_SAMPLES_DIR;
- base_dir += *cit;
-
- base_dir = op_realpath(base_dir);
-
- list<string> files;
- create_file_list(files, base_dir, "*", true);
-
- if (!files.empty())
- found_file = true;
-
- list<string>::const_iterator it = files.begin();
- list<string>::const_iterator fend = files.end();
- for (; it != fend; ++it) {
- if (valid_candidate(base_dir, *it, *this,
- exclude_dependent, exclude_cg)) {
- unique_files.insert(*it);
- }
- }
- }
-
- if (!found_file) {
- ostringstream os;
- os << "No sample file found: try running opcontrol --dump\n"
- << "or specify a session containing sample files\n";
- throw op_fatal_error(os.str());
- }
-
- list<string> result;
- copy(unique_files.begin(), unique_files.end(), back_inserter(result));
-
- return result;
-}
diff --git a/libpp/profile_spec.h b/libpp/profile_spec.h
deleted file mode 100644
index 1e02abb..0000000
--- a/libpp/profile_spec.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * @file profile_spec.h
- * Contains a PP profile specification
- *
- * @remark Copyright 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- */
-
-#ifndef PROFILE_SPEC_H
-#define PROFILE_SPEC_H
-
-#include <map>
-#include <vector>
-#include <list>
-
-#include "filename_spec.h"
-#include "comma_list.h"
-
-class extra_images;
-
-/**
- * Holds a parsed profile spec composed of tag:value pairs, as given in
- * pp_interface documentation.
- *
- * @internal implemented through a map of string, pointer to function member
- * indexed by tag_name.
- */
-class profile_spec
-{
-public:
- /**
- * @param args a vector of non options strings
- * @param extra extra image paths to search
- *
- * Factory returning a profile_spec instance storing all valid
- * tag:value contained in args vector doing also alias
- * substitution, non-valid tag:value options are considered
- * as image:value
- */
- static profile_spec create(std::list<std::string> const & args,
- extra_images const & extra);
-
- /**
- * @param exclude_dependent whether to exclude dependent sub-images
- * @param exclude_cg whether to exclude call graph file
- *
- * Use the spec to generate the list of candidate sample files.
- */
- std::list<std::string>
- generate_file_list(bool exclude_dependent, bool exclude_cg) const;
-
- /**
- * @param file_spec the filename specification to check
- *
- * return true if filename match the spec. PP:3.24 internal loop
- */
- bool match(filename_spec const & file_spec) const;
-
- /**
- * return archive name
- * returns an empty string if not using an archive.
- */
- std::string get_archive_path() const;
-
-private:
- profile_spec(extra_images const & extra);
-
- /**
- * @param tag_value a "tag:value" to interpret, all error throw an
- * invalid_argument exception.
- */
- void parse(std::string const & tag_value);
-
- /**
- * @param image an image or a libray name given on command line
- *
- * Used for e.g. "opreport /bin/mybinary". We don't know yet
- * if this is an application or a dependent image.
- */
- void set_image_or_lib_name(std::string const & image);
-
- /**
- * @param str a "tag:value"
- *
- * return true if tag is a valid tag
- */
- bool is_valid_tag(std::string const & str);
-
- /**
- * implement tag parsing: PP:3.3 to 3.16
- */
- void parse_archive_path(std::string const &);
- void parse_session(std::string const &);
- void parse_session_exclude(std::string const &);
- void parse_image(std::string const &);
- void parse_image_exclude(std::string const &);
- void parse_lib_image(std::string const &);
- void parse_event(std::string const &);
- void parse_count(std::string const &);
- void parse_unitmask(std::string const &);
- void parse_tid(std::string const &);
- void parse_tgid(std::string const &);
- void parse_cpu(std::string const &);
-
- typedef void (profile_spec::*action_t)(std::string const &);
- typedef std::map<std::string, action_t> parse_table_t;
- parse_table_t parse_table;
-
- /**
- * @param tag_value input "tag:value" string
- * @param value if success return the value part of tag_value
- * helper for set/is_valid_tag public interface
- *
- * return null if tag is not valid, else return the pointer to member
- * function to apply and the value in value parameter
- */
- action_t get_handler(std::string const & tag_value,
- std::string & value);
-
- std::string archive_path;
- std::string binary;
- std::vector<std::string> session;
- std::vector<std::string> session_exclude;
- std::vector<std::string> image;
- std::vector<std::string> image_exclude;
- std::vector<std::string> lib_image;
- comma_list<std::string> event;
- comma_list<int> count;
- comma_list<unsigned int> unitmask;
- comma_list<pid_t> tid;
- comma_list<pid_t> tgid;
- comma_list<int> cpu;
- // specified by user on command like opreport image1 image2 ...
- std::vector<std::string> image_or_lib_image;
-
- /// extra search path for images
- extra_images const & extra;
-};
-
-#endif /* !PROFILE_SPEC_H */
diff --git a/libpp/sample_container.cpp b/libpp/sample_container.cpp
deleted file mode 100644
index 7a9f4af..0000000
--- a/libpp/sample_container.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * @file sample_container.cpp
- * Internal container for samples
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <set>
-#include <numeric>
-#include <algorithm>
-#include <vector>
-
-#include "sample_container.h"
-
-using namespace std;
-
-namespace {
-
-// FIXME: efficiency ?
-count_array_t add_counts(count_array_t const & counts,
- sample_entry const * s)
-{
- count_array_t temp(counts);
- temp += s->counts;
- return temp;
-}
-
-} // namespace anon
-
-
-sample_container::samples_iterator sample_container::begin() const
-{
- return samples.begin();
-}
-
-
-sample_container::samples_iterator sample_container::end() const
-{
- return samples.end();
-}
-
-
-sample_container::samples_iterator
-sample_container::begin(symbol_entry const * symbol) const
-{
- samples_storage::key_type key(symbol, 0);
-
- return samples.lower_bound(key);
-}
-
-
-sample_container::samples_iterator
-sample_container::end(symbol_entry const * symbol) const
-{
- samples_storage::key_type key(symbol, ~bfd_vma(0));
-
- return samples.upper_bound(key);
-}
-
-
-void sample_container::insert(symbol_entry const * symbol,
- sample_entry const & sample)
-{
- samples_storage::key_type key(symbol, sample.vma);
-
- samples_storage::iterator it = samples.find(key);
- if (it != samples.end()) {
- it->second.counts += sample.counts;
- } else {
- samples[key] = sample;
- }
-}
-
-
-count_array_t
-sample_container::accumulate_samples(debug_name_id filename_id) const
-{
- build_by_loc();
-
- sample_entry lower, upper;
-
- lower.file_loc.filename = upper.file_loc.filename = filename_id;
- lower.file_loc.linenr = 0;
- upper.file_loc.linenr = INT_MAX;
-
- typedef samples_by_loc_t::const_iterator iterator;
-
- iterator it1 = samples_by_loc.lower_bound(&lower);
- iterator it2 = samples_by_loc.upper_bound(&upper);
-
- return accumulate(it1, it2, count_array_t(), add_counts);
-}
-
-
-sample_entry const *
-sample_container::find_by_vma(symbol_entry const * symbol, bfd_vma vma) const
-{
- sample_index_t key(symbol, vma);
- samples_iterator it = samples.find(key);
- if (it != samples.end())
- return &it->second;
-
- return 0;
-}
-
-
-count_array_t
-sample_container::accumulate_samples(debug_name_id filename,
- size_t linenr) const
-{
- build_by_loc();
-
- sample_entry sample;
-
- sample.file_loc.filename = filename;
- sample.file_loc.linenr = linenr;
-
- typedef pair<samples_by_loc_t::const_iterator,
- samples_by_loc_t::const_iterator> it_pair;
-
- it_pair itp = samples_by_loc.equal_range(&sample);
-
- return accumulate(itp.first, itp.second, count_array_t(), add_counts);
-}
-
-
-void sample_container::build_by_loc() const
-{
- if (!samples_by_loc.empty())
- return;
-
- samples_iterator cit = samples.begin();
- samples_iterator end = samples.end();
- for (; cit != end; ++cit)
- samples_by_loc.insert(&cit->second);
-}
diff --git a/libpp/sample_container.h b/libpp/sample_container.h
deleted file mode 100644
index 74c9ab0..0000000
--- a/libpp/sample_container.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file sample_container.h
- * Internal implementation of sample container
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef SAMPLE_CONTAINER_H
-#define SAMPLE_CONTAINER_H
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "symbol.h"
-#include "symbol_functors.h"
-
-/**
- * Arbitrary container of sample entries. Can return
- * number of samples for a file or line number and
- * return the particular sample information for a VMA.
- */
-class sample_container {
- typedef std::pair<symbol_entry const *, bfd_vma> sample_index_t;
-public:
- typedef std::map<sample_index_t, sample_entry> samples_storage;
- typedef samples_storage::const_iterator samples_iterator;
-
- /// return iterator to the first samples for this symbol
- samples_iterator begin(symbol_entry const *) const;
- /// return iterator to the last samples for this symbol
- samples_iterator end(symbol_entry const *) const;
-
- /// return iterator to the first samples
- samples_iterator begin() const;
- /// return iterator to the last samples
- samples_iterator end() const;
-
- /// insert a sample entry by creating a new entry or by cumulating
- /// samples into an existing one. Can only be done before any lookups
- void insert(symbol_entry const * symbol, sample_entry const &);
-
- /// return nr of samples in the given filename
- count_array_t accumulate_samples(debug_name_id filename_id) const;
-
- /// return nr of samples at the given line nr in the given file
- count_array_t accumulate_samples(debug_name_id, size_t linenr) const;
-
- /// return the sample entry for the given image_name and vma if any
- sample_entry const * find_by_vma(symbol_entry const * symbol,
- bfd_vma vma) const;
-
-private:
- /// build the symbol by file-location cache
- void build_by_loc() const;
-
- /// main sample entry container
- samples_storage samples;
-
- typedef std::multiset<sample_entry const *, less_by_file_loc>
- samples_by_loc_t;
-
- // must be declared after the samples_storage to ensure a
- // correct life-time.
-
- /**
- * Sample entries by file location. Lazily built when necessary,
- * so mutable.
- */
- mutable samples_by_loc_t samples_by_loc;
-};
-
-#endif /* SAMPLE_CONTAINER_H */
diff --git a/libpp/symbol.cpp b/libpp/symbol.cpp
deleted file mode 100644
index dd94412..0000000
--- a/libpp/symbol.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file symbol.cpp
- * Symbol containers
- *
- * @remark Copyright 2002, 2004 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-
-#include "symbol.h"
-#include <iostream>
-
-using std::cerr;
-using std::endl;
-
-column_flags symbol_entry::output_hint(column_flags fl) const
-{
- if (app_name != image_name)
- fl = column_flags(fl | cf_image_name);
-
- // FIXME: see comment in symbol.h: why we don't use sample.vma + size ?
- if (sample.vma & ~0xffffffffLLU)
- fl = column_flags(fl | cf_64bit_vma);
-
- return fl;
-}
diff --git a/libpp/symbol.h b/libpp/symbol.h
deleted file mode 100644
index 7072d9c..0000000
--- a/libpp/symbol.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * @file symbol.h
- * Symbol containers
- *
- * @remark Copyright 2002, 2004 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef SYMBOL_H
-#define SYMBOL_H
-
-#include "name_storage.h"
-#include "growable_vector.h"
-#include "format_flags.h"
-#include "op_types.h"
-
-#include <bfd.h>
-
-#include <list>
-
-
-/// for storing sample counts
-typedef growable_vector<u32> count_array_t;
-
-
-/// A simple container for a fileno:linenr location.
-struct file_location {
- file_location() : linenr(0) {}
- /// empty if not valid.
- debug_name_id filename;
- /// 0 means invalid or code is generated internally by the compiler
- unsigned int linenr;
-
- bool operator<(file_location const & rhs) const {
- // Note we sort on filename id not on string
- return filename < rhs.filename ||
- (filename == rhs.filename && linenr < rhs.linenr);
- }
-};
-
-
-/// associate vma address with a file location and a samples count
-struct sample_entry {
- sample_entry() : vma(0) {}
- /// From where file location comes the samples
- file_location file_loc;
- /// From where virtual memory address comes the samples
- bfd_vma vma;
- /// the samples count
- count_array_t counts;
-};
-
-
-/// associate a symbol with a file location, samples count and vma address
-struct symbol_entry {
- symbol_entry() : size(0) {}
- /// which image this symbol belongs to
- image_name_id image_name;
- /// owning application name: identical to image name if profiling
- /// session did not separate samples for shared libs or if image_name
- /// is not a shared lib
- image_name_id app_name;
- /// file location, vma and cumulated samples count for this symbol
- sample_entry sample;
- /// name of symbol
- symbol_name_id name;
- /// symbol size as calculated by op_bfd, start of symbol is sample.vma
- size_t size;
-
- /**
- * @param fl input hint
- *
- * combine fl with the calculated hint. It's theoretically possible
- * that we get a symbol where its samples pass the border line, but
- * the start is below it, but the the hint is only used for formatting
- */
- column_flags output_hint(column_flags fl) const;
-};
-
-
-/// a collection of sorted symbols
-typedef std::vector<symbol_entry const *> symbol_collection;
-
-
-/**
- * The public data for call-graph symbols. Each caller/callee has
- * the sample counts replaced with the relevant arc counts, whilst
- * the cg_symbol retains its self count.
- */
-struct cg_symbol : public symbol_entry {
- cg_symbol(symbol_entry const & sym) : symbol_entry(sym) {}
-
- typedef std::vector<symbol_entry> children;
-
- /// all callers of this symbol
- children callers;
- /// total count of callers
- count_array_t total_caller_count;
-
- /// all symbols called by this symbol
- children callees;
- /// total count of callees
- count_array_t total_callee_count;
-};
-
-
-/// a collection of sorted callgraph symbols
-typedef std::vector<cg_symbol> cg_collection;
-
-
-/// for storing diff %ages
-typedef growable_vector<double> diff_array_t;
-
-
-/**
- * Data for a diffed symbol.
- */
-struct diff_symbol : public symbol_entry {
- diff_symbol(symbol_entry const & sym) : symbol_entry(sym) {}
-
- /// diff %age values for each profile class
- diff_array_t diffs;
-};
-
-
-/// a collection of diffed symbols
-typedef std::vector<diff_symbol> diff_collection;
-
-
-#endif /* !SYMBOL_H */
diff --git a/libpp/symbol_container.cpp b/libpp/symbol_container.cpp
deleted file mode 100644
index b7a6d3e..0000000
--- a/libpp/symbol_container.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file symbol_container.cpp
- * Internal container for symbols
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include <string>
-#include <algorithm>
-#include <set>
-#include <vector>
-
-#include "symbol_container.h"
-
-using namespace std;
-
-symbol_container::size_type symbol_container::size() const
-{
- return symbols.size();
-}
-
-
-symbol_entry const * symbol_container::insert(symbol_entry const & symb)
-{
- pair<symbols_t::iterator, bool> p = symbols.insert(symb);
- if (!p.second) {
- // safe: count is not used by sorting criteria
- symbol_entry * symbol = const_cast<symbol_entry*>(&*p.first);
- symbol->sample.counts += symb.sample.counts;
- }
-
- return &*p.first;
-}
-
-
-symbol_entry const *
-symbol_container::find(debug_name_id filename, size_t linenr) const
-{
- build_by_loc();
-
- symbol_entry symbol;
- symbol.sample.file_loc.filename = filename;
- symbol.sample.file_loc.linenr = linenr;
-
- symbols_by_loc_t::const_iterator it = symbols_by_loc.find(&symbol);
-
- if (it != symbols_by_loc.end())
- return *it;
-
- return 0;
-}
-
-
-void symbol_container::build_by_loc() const
-{
- if (!symbols_by_loc.empty())
- return;
-
- symbols_t::const_iterator cit = symbols.begin();
- symbols_t::const_iterator end = symbols.end();
- for (; cit != end; ++cit)
- symbols_by_loc.insert(&*cit);
-}
-
-
-symbol_entry const * symbol_container::find_by_vma(string const & image_name,
- bfd_vma vma) const
-{
- // FIXME: this is too inefficient probably
- symbols_t::const_iterator it;
- for (it = symbols.begin(); it != symbols.end(); ++it) {
- if (it->sample.vma == vma &&
- image_names.name(it->image_name) == image_name)
- return &*it;
- }
-
- return 0;
-}
-
-
-symbol_container::symbols_t::iterator symbol_container::begin()
-{
- return symbols.begin();
-}
-
-
-symbol_container::symbols_t::iterator symbol_container::end()
-{
- return symbols.end();
-}
-
-symbol_entry const * symbol_container::find(symbol_entry const & symbol) const
-{
- symbols_t::const_iterator it = symbols.find(symbol);
- return it == symbols.end() ? 0 : &*it;
-}
diff --git a/libpp/symbol_container.h b/libpp/symbol_container.h
deleted file mode 100644
index 73ca581..0000000
--- a/libpp/symbol_container.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file symbol_container.h
- * Internal container for symbols
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef SYMBOL_CONTAINER_H
-#define SYMBOL_CONTAINER_H
-
-#include <string>
-#include <set>
-
-#include "symbol.h"
-#include "symbol_functors.h"
-
-/**
- * An arbitrary container of symbols. Supports lookup
- * by name, by VMA, and by file location.
- *
- * Lookup by name or by VMA is O(n). Lookup by file location
- * is O(log(n)).
- */
-class symbol_container {
-public:
- /// container type
- typedef std::set<symbol_entry, less_symbol> symbols_t;
-
- typedef symbols_t::size_type size_type;
-
- /// return the number of symbols stored
- size_type size() const;
-
- /**
- * Insert a new symbol. If the symbol already exists in the container,
- * then the sample counts are accumulated.
- * Returns the newly created symbol or the existing one. This pointer
- * remains valid during the whole life time of a symbol_container
- * object and is warranted unique according to less_symbol comparator.
- * Can only be done before any file-location based lookups, since the
- * two lookup methods are not synchronised.
- */
- symbol_entry const * insert(symbol_entry const &);
-
- /// find the symbol at the given filename and line number, if any
- symbol_entry const * find(debug_name_id filename,
- size_t linenr) const;
-
- /// find the symbol with the given image_name vma if any
- symbol_entry const * find_by_vma(std::string const & image_name,
- bfd_vma vma) const;
-
- /// Search a symbol. Return NULL if not found.
- symbol_entry const * find(symbol_entry const & symbol) const;
-
- /// return start of symbols
- symbols_t::iterator begin();
-
- /// return end of symbols
- symbols_t::iterator end();
-
-private:
- /// build the symbol by file-location cache
- void build_by_loc() const;
-
- /**
- * The main container of symbols. Multiple symbols with the same
- * name are allowed.
- */
- symbols_t symbols;
-
- /**
- * Differently-named symbol at same file location are allowed e.g.
- * template instantiation.
- */
- typedef std::multiset<symbol_entry const *, less_by_file_loc>
- symbols_by_loc_t;
-
- // must be declared after the set to ensure a correct life-time.
-
- /**
- * Symbols sorted by location order. Lazily built on request,
- * so mutable.
- */
- mutable symbols_by_loc_t symbols_by_loc;
-};
-
-#endif /* SYMBOL_CONTAINER_H */
diff --git a/libpp/symbol_functors.cpp b/libpp/symbol_functors.cpp
deleted file mode 100644
index a4107c3..0000000
--- a/libpp/symbol_functors.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * @file symbol_functors.cpp
- * Functors for symbol/sample comparison
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include "symbol_functors.h"
-
-bool less_symbol::operator()(symbol_entry const & lhs,
- symbol_entry const & rhs) const
-{
- if (lhs.image_name != rhs.image_name)
- return lhs.image_name < rhs.image_name;
-
- if (lhs.app_name != rhs.app_name)
- return lhs.app_name < rhs.app_name;
-
- if (lhs.name != rhs.name)
- return lhs.name < rhs.name;
-
- if (lhs.sample.vma != rhs.sample.vma)
- return lhs.sample.vma < rhs.sample.vma;
-
- return lhs.size < rhs.size;
-}
diff --git a/libpp/symbol_functors.h b/libpp/symbol_functors.h
deleted file mode 100644
index 53a7253..0000000
--- a/libpp/symbol_functors.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file symbol_functors.h
- * Functors for symbol/sample comparison
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef SYMBOL_FUNCTORS_H
-#define SYMBOL_FUNCTORS_H
-
-#include "symbol.h"
-
-/// compare based on file location
-struct less_by_file_loc {
- bool operator()(sample_entry const * lhs,
- sample_entry const * rhs) const {
- return lhs->file_loc < rhs->file_loc;
- }
-
- bool operator()(symbol_entry const * lhs,
- symbol_entry const * rhs) const {
- return lhs->sample.file_loc < rhs->sample.file_loc;
- }
-};
-
-
-/// compare based on symbol contents
-struct less_symbol {
- // implementation compare by id rather than by string
- bool operator()(symbol_entry const & lhs,
- symbol_entry const & rhs) const;
-};
-
-#endif /* SYMBOL_FUNCTORS_H */
diff --git a/libpp/symbol_sort.cpp b/libpp/symbol_sort.cpp
deleted file mode 100644
index 4b18e59..0000000
--- a/libpp/symbol_sort.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/**
- * @file symbol_sort.cpp
- * Sorting symbols
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#include "symbol_sort.h"
-#include "symbol_functors.h"
-
-#include "name_storage.h"
-#include "op_exception.h"
-
-#include <algorithm>
-#include <sstream>
-
-using namespace std;
-
-namespace {
-
-bool long_filenames;
-
-int image_compare(image_name_id l, image_name_id r)
-{
- if (long_filenames)
- return image_names.name(l).compare(image_names.name(r));
- return image_names.basename(l).compare(image_names.basename(r));
-}
-
-
-int debug_compare(debug_name_id l, debug_name_id r)
-{
- if (long_filenames)
- return debug_names.name(l).compare(debug_names.name(r));
- return debug_names.basename(l).compare(debug_names.basename(r));
-}
-
-
-int compare_by(sort_options::sort_order order,
- symbol_entry const & lhs, symbol_entry const & rhs)
-{
- switch (order) {
- case sort_options::sample:
- if (lhs.sample.counts[0] < rhs.sample.counts[0])
- return 1;
- if (lhs.sample.counts[0] > rhs.sample.counts[0])
- return -1;
- return 0;
-
- case sort_options::symbol:
- return symbol_names.demangle(lhs.name).compare(
- symbol_names.demangle(rhs.name));
-
- case sort_options::image:
- return image_compare(lhs.image_name, rhs.image_name);
-
- case sort_options::app_name:
- return image_compare(lhs.app_name, rhs.app_name);
-
- case sort_options::vma:
- if (lhs.sample.vma < rhs.sample.vma)
- return -1;
- if (lhs.sample.vma > rhs.sample.vma)
- return 1;
- return 0;
-
- case sort_options::debug: {
- file_location const & f1 = lhs.sample.file_loc;
- file_location const & f2 = rhs.sample.file_loc;
- int ret = debug_compare(f1.filename, f2.filename);
- if (ret == 0)
- ret = f1.linenr - f2.linenr;
- return ret;
- }
-
- default: {
- // static_cast<> to shut up g++ 2.91.66 which warn
- // about ambiguity between <<(int) and <<(long int)
- ostringstream os;
- os << "compare_by(): unknown sort option: "
- << static_cast<int>(order) << endl;
- throw op_fatal_error(os.str());
- }
- }
-
- return 0;
-}
-
-
-struct symbol_compare {
- symbol_compare(vector<sort_options::sort_order> const & order,
- bool reverse)
- : compare_order(order), reverse_sort(reverse) {}
-
- bool operator()(symbol_entry const * lhs,
- symbol_entry const * rhs) const {
- return operator()(*lhs, *rhs);
- }
-
- bool operator()(symbol_entry const & lhs,
- symbol_entry const & rhs) const;
-
-protected:
- vector<sort_options::sort_order> const & compare_order;
- bool reverse_sort;
-};
-
-
-bool symbol_compare::operator()(symbol_entry const & lhs,
- symbol_entry const & rhs) const
-{
- for (size_t i = 0; i < compare_order.size(); ++i) {
- int ret = compare_by(compare_order[i], lhs, rhs);
-
- if (reverse_sort)
- ret = -ret;
- if (ret != 0)
- return ret < 0;
- }
- return false;
-}
-
-
-} // anonymous namespace
-
-
-void sort_options::
-sort(symbol_collection & syms, bool reverse_sort, bool lf) const
-{
- long_filenames = lf;
-
- vector<sort_order> sort_option(options);
- for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
- if (find(sort_option.begin(), sort_option.end(), cur) ==
- sort_option.end())
- sort_option.push_back(cur);
- }
-
- stable_sort(syms.begin(), syms.end(),
- symbol_compare(sort_option, reverse_sort));
-}
-
-
-void sort_options::
-sort(cg_collection & syms, bool reverse_sort, bool lf) const
-{
- long_filenames = lf;
-
- vector<sort_order> sort_option(options);
- for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
- if (find(sort_option.begin(), sort_option.end(), cur) ==
- sort_option.end())
- sort_option.push_back(cur);
- }
-
- stable_sort(syms.begin(), syms.end(),
- symbol_compare(sort_option, reverse_sort));
-}
-
-
-void sort_options::
-sort(diff_collection & syms, bool reverse_sort, bool lf) const
-{
- long_filenames = lf;
-
- vector<sort_order> sort_option(options);
- for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
- if (find(sort_option.begin(), sort_option.end(), cur) ==
- sort_option.end())
- sort_option.push_back(cur);
- }
-
- stable_sort(syms.begin(), syms.end(),
- symbol_compare(sort_option, reverse_sort));
-}
-
-
-void sort_options::add_sort_option(string const & name)
-{
- if (name == "vma") {
- options.push_back(vma);
- } else if (name == "sample") {
- options.push_back(sample);
- } else if (name == "symbol") {
- options.push_back(symbol);
- } else if (name == "debug") {
- options.push_back(debug);
- } else if (name == "image") {
- options.push_back(image);
- } else if (name == "app-name") {
- options.push_back(app_name);
- } else {
- ostringstream os;
- os << "unknown sort option: " << name << endl;
- throw op_fatal_error(os.str());
- }
-}
-
-
-void sort_options::add_sort_option(sort_options::sort_order order)
-{
- options.push_back(order);
-}
diff --git a/libpp/symbol_sort.h b/libpp/symbol_sort.h
deleted file mode 100644
index da93d04..0000000
--- a/libpp/symbol_sort.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file symbol_sort.h
- * Sorting symbols
- *
- * @remark Copyright 2002, 2003 OProfile authors
- * @remark Read the file COPYING
- *
- * @author Philippe Elie
- * @author John Levon
- */
-
-#ifndef SYMBOL_SORT_H
-#define SYMBOL_SORT_H
-
-#include "symbol.h"
-
-#include <vector>
-#include <string>
-
-struct sort_options {
- enum sort_order {
- // order give sort order if caller doesn't specify one
- first,
- sample = first,
- image,
- app_name,
- symbol,
- debug,
- vma,
- last
- };
-
- sort_options() {}
-
- void add_sort_option(std::string const & name);
- void add_sort_option(sort_order order);
-
- /**
- * Sort the given container by the given criteria.
- */
- void sort(symbol_collection & syms, bool reverse_sort,
- bool long_filenames) const;
-
- /**
- * Sort the given container by the given criteria.
- */
- void sort(cg_collection & syms, bool reverse_sort,
- bool long_filenames) const;
-
- /**
- * Sort the given container by the given criteria.
- */
- void sort(diff_collection & syms, bool reverse_sort,
- bool long_filenames) const;
-
- std::vector<sort_order> options;
-};
-
-#endif // SYMBOL_SORT_H