diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | dfb3f050a7cebd2030ea23dc6fa8964530e4ddcc (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 | |
parent | b9958da7adae1c7d4482e958b371401eef387a39 (diff) | |
download | oprofile-dfb3f050a7cebd2030ea23dc6fa8964530e4ddcc.tar.gz |
auto import from //depot/cupcake/@135843
103 files changed, 0 insertions, 15275 deletions
diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 582ddc9..0000000 --- a/Android.mk +++ /dev/null @@ -1,3 +0,0 @@ -ifeq ($(TARGET_ARCH),arm) -include $(call all-subdir-makefiles) -endif diff --git a/MODULE_LICENSE_GPL b/MODULE_LICENSE_GPL deleted file mode 100644 index e69de29..0000000 --- a/MODULE_LICENSE_GPL +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/config.h b/config.h deleted file mode 100644 index c220da5..0000000 --- a/config.h +++ /dev/null @@ -1,101 +0,0 @@ -/* config.h. Generated by configure. */ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* whether popt prototype takes a const char ** */ -#define CONST_POPT 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `bfd' library (-lbfd). */ -#define HAVE_LIBBFD 1 - -/* Define to 1 if you have the `iberty' library (-liberty). */ -#define HAVE_LIBIBERTY 1 - -/* Define to 1 if you have the <libiberty.h> header file. */ -/* #undef HAVE_LIBIBERTY_H */ - -/* Define to 1 if you have the `popt' library (-lpopt). */ -#define HAVE_LIBPOPT 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `perfmonctl' function. */ -/* #undef HAVE_PERFMONCTL */ - -/* Define to 1 if you have the `sched_setaffinity' function. */ -/* #undef HAVE_SCHED_SETAFFINITY */ - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `xcalloc' function. */ -#undef HAVE_XCALLOC - -/* Define to 1 if you have the `xmemdup' function. */ -#undef HAVE_XMEMDUP - -/* whether malloc attribute is understood */ -#define MALLOC_ATTRIBUTE_OK 1 - -/* whether to build ABI tools */ -#define OPROF_ABI 1 - -/* package binary directory */ -#define OP_BINDIR "/usr/local/bin/" - -/* package data directory */ -#define OP_DATADIR "/usr/local/share/oprofile/" - -/* Name of package */ -#define PACKAGE "oprofile" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Synthesize special symbols when needed */ -/* #undef SYNTHESIZE_SYMBOLS */ - -/* whether bfd.h defines bool values */ -/* #undef TRUE_FALSE_ALREADY_DEFINED */ - -/* Version number of package */ -#define VERSION "0.9.1" - -/* Define to 1 if the X Window System is missing or not being used. */ -/* #undef X_DISPLAY_MISSING */ diff --git a/daemon/Android.mk b/daemon/Android.mk deleted file mode 100644 index abee74c..0000000 --- a/daemon/Android.mk +++ /dev/null @@ -1,33 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - init.c \ - opd_anon.c \ - opd_cookie.c \ - opd_events.c \ - opd_kernel.c \ - opd_mangling.c \ - opd_perfmon.c \ - opd_pipe.c \ - opd_sfile.c \ - opd_spu.c \ - opd_stats.c \ - opd_trans.c \ - oprofiled.c - -LOCAL_STATIC_LIBRARIES := \ - libpopt libutil libdb libabi libop - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../libdb \ - $(LOCAL_PATH)/../libutil \ - $(LOCAL_PATH)/../libop \ - $(LOCAL_PATH)/../libabi - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE:= oprofiled - -include $(BUILD_EXECUTABLE) diff --git a/daemon/init.c b/daemon/init.c deleted file mode 100644 index be0b9da..0000000 --- a/daemon/init.c +++ /dev/null @@ -1,373 +0,0 @@ -/** - * @file daemon/init.c - * Daemon set up and main loop for 2.6 - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * @Modifications Daniel Hansel - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#include "config.h" - -#include "oprofiled.h" -#include "opd_stats.h" -#include "opd_sfile.h" -#include "opd_pipe.h" -#include "opd_kernel.h" -#include "opd_trans.h" -#include "opd_anon.h" -#include "opd_perfmon.h" -#include "opd_printf.h" - -#include "op_version.h" -#include "op_config.h" -#include "op_deviceio.h" -#include "op_get_time.h" -#include "op_libiberty.h" -#include "op_fileio.h" - -#include <fcntl.h> -#include <stdio.h> -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <sys/time.h> -#if ANDROID -#include <sys/wait.h> -#else -#include <wait.h> -#endif -#include <string.h> - -size_t kernel_pointer_size; - -static fd_t devfd; -static char * sbuf; -static size_t s_buf_bytesize; -extern char * session_dir; -static char start_time_str[32]; -static int jit_conversion_running; - -static void opd_sighup(void); -static void opd_alarm(void); -static void opd_sigterm(void); -static void opd_sigchild(void); -static void opd_do_jitdumps(void); - -/** - * opd_open_files - open necessary files - * - * Open the device files and the log file, - * and mmap() the hash map. - */ -static void opd_open_files(void) -{ - devfd = op_open_device("/dev/oprofile/buffer"); - if (devfd == -1) { - if (errno == EINVAL) - fprintf(stderr, "Failed to open device. Possibly you have passed incorrect\n" - "parameters. Check /var/log/messages."); - else - perror("Failed to open profile device"); - exit(EXIT_FAILURE); - } - - /* give output before re-opening stdout as the logfile */ - printf("Using log file %s\n", op_log_file); - - /* set up logfile */ - close(0); - close(1); - - if (open("/dev/null", O_RDONLY) == -1) { - perror("oprofiled: couldn't re-open stdin as /dev/null: "); - exit(EXIT_FAILURE); - } - - opd_open_logfile(); - opd_create_pipe(); - - printf("oprofiled started %s", op_get_time()); - printf("kernel pointer size: %lu\n", - (unsigned long)kernel_pointer_size); - fflush(stdout); -} - - -/** Done writing out the samples, indicate with complete_dump file */ -static void complete_dump(void) -{ - FILE * status_file; - -retry: - status_file = fopen(op_dump_status, "w"); - - if (!status_file && errno == EMFILE) { - if (sfile_lru_clear()) { - printf("LRU cleared but file open fails for %s.\n", - op_dump_status); - abort(); - } - goto retry; - } - - if (!status_file) { - perror("warning: couldn't set complete_dump: "); - return; - } - - fprintf(status_file, "1\n"); - fclose(status_file); -} - - -/** - * opd_do_samples - process a sample buffer - * @param opd_buf buffer to process - * - * Process a buffer of samples. - * - * If the sample could be processed correctly, it is written - * to the relevant sample file. - */ -static void opd_do_samples(char const * opd_buf, ssize_t count) -{ - size_t num = count / kernel_pointer_size; - - opd_stats[OPD_DUMP_COUNT]++; - - verbprintf(vmisc, "Read buffer of %d entries.\n", (unsigned int)num); - - opd_process_samples(opd_buf, num); - - complete_dump(); -} - -static void opd_do_jitdumps(void) -{ - pid_t childpid; - int arg_num; - unsigned long long end_time = 0ULL; - struct timeval tv; - char end_time_str[32]; - char opjitconv_path[PATH_MAX + 1]; - char * exec_args[6]; - - if (jit_conversion_running) - return; - jit_conversion_running = 1; - - childpid = fork(); - switch (childpid) { - case -1: - perror("Error forking JIT dump process!"); - break; - case 0: - gettimeofday(&tv, NULL); - end_time = tv.tv_sec; - sprintf(end_time_str, "%llu", end_time); - sprintf(opjitconv_path, "%s/%s", OP_BINDIR, "opjitconv"); - arg_num = 0; - exec_args[arg_num++] = opjitconv_path; - if (vmisc) - exec_args[arg_num++] = "-d"; - exec_args[arg_num++] = session_dir; - exec_args[arg_num++] = start_time_str; - exec_args[arg_num++] = end_time_str; - exec_args[arg_num] = (char *) NULL; - execvp("opjitconv", exec_args); - fprintf(stderr, "Failed to exec %s: %s\n", - exec_args[0], strerror(errno)); - /* We don't want any cleanup in the child */ - _exit(EXIT_FAILURE); - default: - break; - } - -} - -/** - * opd_do_read - enter processing loop - * @param buf buffer to read into - * @param size size of buffer - * - * Read some of a buffer from the device and process - * the contents. - */ -static void opd_do_read(char * buf, size_t size) -{ - opd_open_pipe(); - - while (1) { - ssize_t count = -1; - - /* loop to handle EINTR */ - while (count < 0) { - count = op_read_device(devfd, buf, size); - - /* we can lose an alarm or a hup but - * we don't care. - */ - if (signal_alarm) { - signal_alarm = 0; - opd_alarm(); - } - - if (signal_hup) { - signal_hup = 0; - opd_sighup(); - } - - if (signal_term) - opd_sigterm(); - - if (signal_child) - opd_sigchild(); - - if (signal_usr1) { - signal_usr1 = 0; - perfmon_start(); - } - - if (signal_usr2) { - signal_usr2 = 0; - perfmon_stop(); - } - - if (is_jitconv_requested()) { - verbprintf(vmisc, "Start opjitconv was triggered\n"); - opd_do_jitdumps(); - } - } - - opd_do_samples(buf, count); - } - - opd_close_pipe(); -} - - -/** opd_alarm - sync files and report stats */ -static void opd_alarm(void) -{ - sfile_sync_files(); - opd_print_stats(); - alarm(60 * 10); -} - - -/** re-open files for logrotate/opcontrol --reset */ -static void opd_sighup(void) -{ - printf("Received SIGHUP.\n"); - /* We just close them, and re-open them lazily as usual. */ - sfile_close_files(); - close(1); - close(2); - opd_open_logfile(); -} - - -static void clean_exit(void) -{ - perfmon_exit(); - unlink(op_lock_file); -} - - -static void opd_sigterm(void) -{ - opd_do_jitdumps(); - opd_print_stats(); - printf("oprofiled stopped %s", op_get_time()); - exit(EXIT_FAILURE); -} - -/* SIGCHLD received from JIT dump child process. */ -static void opd_sigchild(void) -{ - int child_status; - wait(&child_status); - jit_conversion_running = 0; - if (WIFEXITED(child_status) && (!WEXITSTATUS(child_status))) { - verbprintf(vmisc, "JIT dump processing complete.\n"); - } else { - printf("JIT dump processing exited abnormally: %d\n", - WEXITSTATUS(child_status)); - } - -} - -static void opd_26_init(void) -{ - size_t i; - size_t opd_buf_size; - unsigned long long start_time = 0ULL; - struct timeval tv; - - opd_create_vmlinux(vmlinux, kernel_range); - opd_create_xen(xenimage, xen_range); - - opd_buf_size = opd_read_fs_int("/dev/oprofile/", "buffer_size", 1); - kernel_pointer_size = opd_read_fs_int("/dev/oprofile/", "pointer_size", 1); - - s_buf_bytesize = opd_buf_size * kernel_pointer_size; - - sbuf = xmalloc(s_buf_bytesize); - - opd_reread_module_info(); - - for (i = 0; i < OPD_MAX_STATS; i++) - opd_stats[i] = 0; - - perfmon_init(); - - cookie_init(); - sfile_init(); - anon_init(); - - /* must be /after/ perfmon_init() at least */ - if (atexit(clean_exit)) { - perfmon_exit(); - perror("oprofiled: couldn't set exit cleanup: "); - exit(EXIT_FAILURE); - } - - /* trigger kernel module setup before returning control to opcontrol */ - opd_open_files(); - gettimeofday(&tv, NULL); - start_time = 0ULL; - start_time = tv.tv_sec; - sprintf(start_time_str, "%llu", start_time); - -} - - -static void opd_26_start(void) -{ - /* simple sleep-then-process loop */ - opd_do_read(sbuf, s_buf_bytesize); -} - - -static void opd_26_exit(void) -{ - opd_print_stats(); - printf("oprofiled stopped %s", op_get_time()); - - free(sbuf); - free(vmlinux); - /* FIXME: free kernel images, sfiles etc. */ -} - -struct oprofiled_ops opd_26_ops = { - .init = opd_26_init, - .start = opd_26_start, - .exit = opd_26_exit, -}; diff --git a/daemon/opd_anon.c b/daemon/opd_anon.c deleted file mode 100644 index 9caea3d..0000000 --- a/daemon/opd_anon.c +++ /dev/null @@ -1,228 +0,0 @@ -/** - * @file opd_anon.c - * Anonymous region handling. - * - * Our caching of maps has some problems: if we get tgid reuse, - * and it's the same application, we might end up with wrong - * maps. The same happens in an unmap-remap case. There's not much - * we can do about this, we just hope it's not too common... - * - * What is relatively common is expanding anon maps, which leaves us - * with lots of separate sample files. - * - * @remark Copyright 2005 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @Modifications Gisle Dankel - */ - -#include "opd_anon.h" -#include "opd_trans.h" -#include "opd_sfile.h" -#include "opd_printf.h" -#include "op_libiberty.h" - -#include <limits.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#define HASH_SIZE 1024 -#define HASH_BITS (HASH_SIZE - 1) - -/* - * Note that this value is tempered by the fact that when we miss in the - * anon cache, we'll tear down all the mappings for that tgid. Thus, LRU - * of a mapping can potentially clear out a much larger number of - * mappings. - */ -#define LRU_SIZE 8192 -#define LRU_AMOUNT (LRU_SIZE/8) - -static struct list_head hashes[HASH_SIZE]; -static struct list_head lru; -static size_t nr_lru; - -static void do_lru(struct transient * trans) -{ - size_t nr_to_kill = LRU_AMOUNT; - struct list_head * pos; - struct list_head * pos2; - struct anon_mapping * entry; - - list_for_each_safe(pos, pos2, &lru) { - entry = list_entry(pos, struct anon_mapping, lru_list); - if (trans->anon == entry) - clear_trans_current(trans); - if (trans->last_anon == entry) - clear_trans_last(trans); - sfile_clear_anon(entry); - list_del(&entry->list); - list_del(&entry->lru_list); - --nr_lru; - free(entry); - if (nr_to_kill-- == 0) - break; - } -} - - -static unsigned long hash_anon(pid_t tgid, cookie_t app) -{ - return ((app >> DCOOKIE_SHIFT) ^ (tgid >> 2)) & (HASH_SIZE - 1); -} - - -static void clear_anon_maps(struct transient * trans) -{ - unsigned long hash = hash_anon(trans->tgid, trans->app_cookie); - pid_t tgid = trans->tgid; - cookie_t app = trans->app_cookie; - struct list_head * pos; - struct list_head * pos2; - struct anon_mapping * entry; - - clear_trans_current(trans); - - list_for_each_safe(pos, pos2, &hashes[hash]) { - entry = list_entry(pos, struct anon_mapping, list); - if (entry->tgid == tgid && entry->app_cookie == app) { - if (trans->last_anon == entry) - clear_trans_last(trans); - sfile_clear_anon(entry); - list_del(&entry->list); - list_del(&entry->lru_list); - --nr_lru; - free(entry); - } - } - - if (vmisc) { - char const * name = verbose_cookie(app); - printf("Cleared anon maps for tgid %u (%s).\n", tgid, name); - } -} - - -static void -add_anon_mapping(struct transient * trans, vma_t start, vma_t end, char * name) -{ - unsigned long hash = hash_anon(trans->tgid, trans->app_cookie); - struct anon_mapping * m = xmalloc(sizeof(struct anon_mapping)); - m->tgid = trans->tgid; - m->app_cookie = trans->app_cookie; - m->start = start; - m->end = end; - strncpy(m->name, name, MAX_IMAGE_NAME_SIZE + 1); - list_add_tail(&m->list, &hashes[hash]); - list_add_tail(&m->lru_list, &lru); - if (++nr_lru == LRU_SIZE) - do_lru(trans); - if (vmisc) { - char const * name = verbose_cookie(m->app_cookie); - printf("Added anon map 0x%llx-0x%llx for tgid %u (%s).\n", - start, end, m->tgid, name); - } -} - - -/* 42000000-4212f000 r-xp 00000000 16:03 424334 /lib/tls/libc-2.3.2.so */ -static void get_anon_maps(struct transient * trans) -{ - FILE * fp = NULL; - char buf[PATH_MAX]; - vma_t start, end; - int ret; - - snprintf(buf, PATH_MAX, "/proc/%d/maps", trans->tgid); - fp = fopen(buf, "r"); - if (!fp) - return; - - while (fgets(buf, PATH_MAX, fp) != NULL) { - char tmp[MAX_IMAGE_NAME_SIZE + 1]; - char name[MAX_IMAGE_NAME_SIZE + 1]; - /* Some anon maps have labels like - * [heap], [stack], [vdso], [vsyscall] ... - * Keep track of these labels. If a map has no name, call it "anon". - * Ignore all mappings starting with "/" (file or shared memory object) - */ - strcpy(name, "anon"); - ret = sscanf(buf, "%llx-%llx %20s %20s %20s %20s %20s", - &start, &end, tmp, tmp, tmp, tmp, name); - if (ret < 6 || name[0] == '/') - continue; - - add_anon_mapping(trans, start, end, name); - } - - fclose(fp); -} - - -static int -anon_match(struct transient const * trans, struct anon_mapping const * anon) -{ - if (!anon) - return 0; - if (trans->tgid != anon->tgid) - return 0; - if (trans->app_cookie != anon->app_cookie) - return 0; - if (trans->pc < anon->start) - return 0; - return (trans->pc < anon->end); -} - - -struct anon_mapping * find_anon_mapping(struct transient * trans) -{ - unsigned long hash = hash_anon(trans->tgid, trans->app_cookie); - struct list_head * pos; - struct anon_mapping * entry; - int tried = 0; - - if (anon_match(trans, trans->anon)) - return (trans->anon); - -retry: - list_for_each(pos, &hashes[hash]) { - entry = list_entry(pos, struct anon_mapping, list); - if (anon_match(trans, entry)) - goto success; - } - - if (!tried) { - clear_anon_maps(trans); - get_anon_maps(trans); - tried = 1; - goto retry; - } - - return NULL; - -success: - /* - * Typically, there's one big mapping that matches. Let's go - * faster. - */ - list_del(&entry->list); - list_add(&entry->list, &hashes[hash]); - - verbprintf(vmisc, "Found range 0x%llx-0x%llx for tgid %u, pc %llx.\n", - entry->start, entry->end, (unsigned int)entry->tgid, - trans->pc); - return entry; -} - - -void anon_init(void) -{ - size_t i; - - for (i = 0; i < HASH_SIZE; ++i) - list_init(&hashes[i]); - - list_init(&lru); -} diff --git a/daemon/opd_anon.h b/daemon/opd_anon.h deleted file mode 100644 index 3f66b55..0000000 --- a/daemon/opd_anon.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file opd_anon.h - * Anonymous region handling. - * - * @remark Copyright 2005 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPD_ANON_H -#define OPD_ANON_H - -#include "op_types.h" -#include "op_list.h" - -#include "opd_cookie.h" - -#include <sys/types.h> - -struct transient; - -/** - * Shift useful bits into play for VMA hashing. - */ -#define VMA_SHIFT 13 - -/* Maximum size of the image name considered */ -#define MAX_IMAGE_NAME_SIZE 20 - -struct anon_mapping { - /** start of the mapping */ - vma_t start; - /** end of the mapping */ - vma_t end; - /** tgid of the app */ - pid_t tgid; - /** cookie of the app */ - cookie_t app_cookie; - /** hash list */ - struct list_head list; - /** lru list */ - struct list_head lru_list; - char name[MAX_IMAGE_NAME_SIZE+1]; -}; - -/** - * Try to find an anonymous mapping for the given pc/tgid pair. - */ -struct anon_mapping * find_anon_mapping(struct transient *); - -void anon_init(void); - -#endif /* OPD_ANON_H */ diff --git a/daemon/opd_cookie.c b/daemon/opd_cookie.c deleted file mode 100644 index 3578e48..0000000 --- a/daemon/opd_cookie.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file opd_cookie.c - * cookie -> name cache - * - * @remark Copyright 2002, 2005 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include "opd_cookie.h" -#include "oprofiled.h" -#include "op_list.h" -#include "op_libiberty.h" - -#include <sys/syscall.h> -#include <unistd.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#ifndef __NR_lookup_dcookie -#if defined(__i386__) -#define __NR_lookup_dcookie 253 -#elif defined(__x86_64__) -#define __NR_lookup_dcookie 212 -#elif defined(__powerpc__) -#define __NR_lookup_dcookie 235 -#elif defined(__alpha__) -#define __NR_lookup_dcookie 406 -#elif defined(__hppa__) -#define __NR_lookup_dcookie 223 -#elif defined(__ia64__) -#define __NR_lookup_dcookie 1237 -#elif defined(__sparc__) -/* untested */ -#define __NR_lookup_dcookie 208 -#elif defined(__s390__) || defined (__s390x__) -#define __NR_lookup_dcookie 110 -#elif defined(__arm__) -#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) -#elif defined(__mips__) -#include <sgidefs.h> -/* O32 */ -#if _MIPS_SIM == _MIPS_SIM_ABI32 -#define __NR_lookup_dcookie 4247 -/* N64 */ -#elif _MIPS_SIM == _MIPS_SIM_ABI64 -#define __NR_lookup_dcookie 5206 -/* N32 */ -#elif _MIPS_SIM == _MIPS_SIM_NABI32 -#define __NR_lookup_dcookie 6206 -#else -#error Unknown MIPS ABI: Dunno __NR_lookup_dcookie -#endif -#else -#error Please define __NR_lookup_dcookie for your architecture -#endif -#endif /* __NR_lookup_dcookie */ - -#if (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__hppa__)\ - || (defined(__s390__) && !defined(__s390x__)) \ - || (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) \ - && defined(__MIPSEB__)) \ - || (defined(__arm__) && defined(__ARM_EABI__) \ - && defined(__ARMEB__)) -static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size) -{ - return syscall(__NR_lookup_dcookie, (unsigned long)(cookie >> 32), - (unsigned long)(cookie & 0xffffffff), buf, size); -} -#elif (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)) \ - || (defined(__arm__) && defined(__ARM_EABI__)) -static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size) -{ - return syscall(__NR_lookup_dcookie, - (unsigned long)(cookie & 0xffffffff), - (unsigned long)(cookie >> 32), buf, size); -} -#else -static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size) -{ - return syscall(__NR_lookup_dcookie, cookie, buf, size); -} -#endif - - -struct cookie_entry { - cookie_t value; - char * name; - int ignored; - struct list_head list; -}; - - -#define HASH_SIZE 512 -#define HASH_BITS (HASH_SIZE - 1) - -static struct list_head hashes[HASH_SIZE]; - -static struct cookie_entry * create_cookie(cookie_t cookie) -{ - int err; - struct cookie_entry * entry = xmalloc(sizeof(struct cookie_entry)); - - entry->value = cookie; - entry->name = xmalloc(PATH_MAX + 1); - - err = lookup_dcookie(cookie, entry->name, PATH_MAX); - - if (err < 0) { - fprintf(stderr, "Lookup of cookie %llx failed, errno=%d\n", - cookie, errno); - free(entry->name); - entry->name = NULL; - entry->ignored = 0; - } else { - entry->ignored = is_image_ignored(entry->name); - } - - return entry; -} - - -/* Cookie monster want cookie! */ -static unsigned long hash_cookie(cookie_t cookie) -{ - return (cookie >> DCOOKIE_SHIFT) & (HASH_SIZE - 1); -} - - -char const * find_cookie(cookie_t cookie) -{ - unsigned long hash = hash_cookie(cookie); - struct list_head * pos; - struct cookie_entry * entry; - - if (cookie == INVALID_COOKIE || cookie == NO_COOKIE) - return NULL; - - list_for_each(pos, &hashes[hash]) { - entry = list_entry(pos, struct cookie_entry, list); - if (entry->value == cookie) - goto out; - } - - /* not sure this can ever happen due to is_cookie_ignored */ - entry = create_cookie(cookie); - list_add(&entry->list, &hashes[hash]); -out: - return entry->name; -} - - -int is_cookie_ignored(cookie_t cookie) -{ - unsigned long hash = hash_cookie(cookie); - struct list_head * pos; - struct cookie_entry * entry; - - if (cookie == INVALID_COOKIE || cookie == NO_COOKIE) - return 1; - - list_for_each(pos, &hashes[hash]) { - entry = list_entry(pos, struct cookie_entry, list); - if (entry->value == cookie) - goto out; - } - - entry = create_cookie(cookie); - list_add(&entry->list, &hashes[hash]); -out: - return entry->ignored; -} - - -char const * verbose_cookie(cookie_t cookie) -{ - unsigned long hash = hash_cookie(cookie); - struct list_head * pos; - struct cookie_entry * entry; - - if (cookie == INVALID_COOKIE) - return "invalid"; - - if (cookie == NO_COOKIE) - return "anonymous"; - - list_for_each(pos, &hashes[hash]) { - entry = list_entry(pos, struct cookie_entry, list); - if (entry->value == cookie) { - if (!entry->name) - return "failed lookup"; - return entry->name; - } - } - - return "not hashed"; -} - - -void cookie_init(void) -{ - size_t i; - - for (i = 0; i < HASH_SIZE; ++i) - list_init(&hashes[i]); -} diff --git a/daemon/opd_cookie.h b/daemon/opd_cookie.h deleted file mode 100644 index a9f13b1..0000000 --- a/daemon/opd_cookie.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file opd_cookie.h - * cookie -> name cache - * - * @remark Copyright 2002, 2005 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPD_COOKIE_H -#define OPD_COOKIE_H - -typedef unsigned long long cookie_t; - -#define INVALID_COOKIE ~0LLU -#define NO_COOKIE 0LLU - -/** - * Shift value to remove trailing zero on a dcookie value, 7 is sufficient - * for most architecture - */ -#define DCOOKIE_SHIFT 7 - -/** - * Return the name of the given dcookie. May return - * NULL on failure. - */ -char const * find_cookie(cookie_t cookie); - -/** return true if this cookie should be ignored */ -int is_cookie_ignored(cookie_t cookie); - -/** give a textual description of the cookie */ -char const * verbose_cookie(cookie_t cookie); - -void cookie_init(void); - -#endif /* OPD_COOKIE_H */ diff --git a/daemon/opd_events.c b/daemon/opd_events.c deleted file mode 100644 index 81a87d2..0000000 --- a/daemon/opd_events.c +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file daemon/opd_events.c - * Event details for each counter - * - * @remark Copyright 2002, 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "config.h" - -#include "opd_events.h" -#include "opd_printf.h" -#include "oprofiled.h" - -#include "op_string.h" -#include "op_config.h" -#include "op_cpufreq.h" -#include "op_cpu_type.h" -#include "op_libiberty.h" -#include "op_hw_config.h" -#include "op_sample_file.h" - -#include <stdlib.h> -#include <stdio.h> - -extern op_cpu cpu_type; - -struct opd_event opd_events[OP_MAX_COUNTERS]; - -static double cpu_speed; - -static void malformed_events(void) -{ - fprintf(stderr, "oprofiled: malformed events passed " - "on the command line\n"); - exit(EXIT_FAILURE); -} - - -static char * copy_token(char ** c, char delim) -{ - char * tmp = *c; - char * tmp2 = *c; - char * str; - - if (!**c) - return NULL; - - while (*tmp2 && *tmp2 != delim) - ++tmp2; - - if (tmp2 == tmp) - return NULL; - - str = op_xstrndup(tmp, tmp2 - tmp); - *c = tmp2; - if (**c) - ++*c; - return str; -} - - -static unsigned long copy_ulong(char ** c, char delim) -{ - unsigned long val = 0; - char * str = copy_token(c, delim); - if (!str) - malformed_events(); - val = strtoul(str, NULL, 0); - free(str); - return val; -} - - -void opd_parse_events(char const * events) -{ - char * ev = xstrdup(events); - char * c; - size_t cur = 0; - - if (cpu_type == CPU_TIMER_INT) { - struct opd_event * event = &opd_events[0]; - event->name = xstrdup("TIMER"); - event->value = event->counter - = event->count = event->um = 0; - event->kernel = 1; - event->user = 1; - return; - } - - if (!ev || !strlen(ev)) { - fprintf(stderr, "oprofiled: no events passed.\n"); - exit(EXIT_FAILURE); - } - - verbprintf(vmisc, "Events: %s\n", ev); - - c = ev; - - while (*c && cur < op_nr_counters) { - struct opd_event * event = &opd_events[cur]; - - if (!(event->name = copy_token(&c, ':'))) - malformed_events(); - event->value = copy_ulong(&c, ':'); - event->counter = copy_ulong(&c, ':'); - event->count = copy_ulong(&c, ':'); - event->um = copy_ulong(&c, ':'); - event->kernel = copy_ulong(&c, ':'); - event->user = copy_ulong(&c, ','); - ++cur; - } - - if (*c) { - fprintf(stderr, "oprofiled: too many events passed.\n"); - exit(EXIT_FAILURE); - } - - free(ev); - - cpu_speed = op_cpu_frequency(); -} - - -struct opd_event * find_counter_event(unsigned long counter) -{ - size_t i; - - for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) { - if (counter == opd_events[i].counter) - return &opd_events[i]; - } - - fprintf(stderr, "Unknown event for counter %lu\n", counter); - abort(); - return NULL; -} - - -void fill_header(struct opd_header * header, unsigned long counter, - vma_t anon_start, vma_t cg_to_anon_start, - int is_kernel, int cg_to_is_kernel, - int spu_samples, uint64_t embed_offset, time_t mtime) -{ - struct opd_event * event = find_counter_event(counter); - - memset(header, '\0', sizeof(struct opd_header)); - header->version = OPD_VERSION; - memcpy(header->magic, OPD_MAGIC, sizeof(header->magic)); - header->cpu_type = cpu_type; - header->ctr_event = event->value; - header->ctr_count = event->count; - header->ctr_um = event->um; - header->is_kernel = is_kernel; - header->cg_to_is_kernel = cg_to_is_kernel; - header->cpu_speed = cpu_speed; - header->mtime = mtime; - header->anon_start = anon_start; - header->spu_profile = spu_samples; - header->embedded_offset = embed_offset; - header->cg_to_anon_start = cg_to_anon_start; -} diff --git a/daemon/opd_events.h b/daemon/opd_events.h deleted file mode 100644 index 3bd0106..0000000 --- a/daemon/opd_events.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @file daemon/opd_events.h - * Event details for each counter - * - * @remark Copyright 2002, 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OPD_EVENTS_H - -#include "op_types.h" - -#include <stdint.h> -#include <time.h> - -/** event description for setup (perfmon) and mangling */ -struct opd_event { - char * name; - unsigned long value; - unsigned long counter; - unsigned long count; - unsigned long um; - unsigned long kernel; - unsigned long user; -}; - -/* needed for opd_perfmon.c */ -extern struct opd_event opd_events[]; - -/** parse the events into the opd_events array */ -void opd_parse_events(char const * events); - -/** Find the event for the given counter */ -struct opd_event * find_counter_event(unsigned long counter); - -struct opd_header; - -/** fill the sample file header with event info etc. */ -void fill_header(struct opd_header * header, unsigned long counter, - vma_t anon_start, vma_t anon_end, - int is_kernel, int cg_to_is_kernel, - int spu_samples, uint64_t embed_offset, time_t mtime); - -#endif /* OPD_EVENTS_H */ diff --git a/daemon/opd_interface.h b/daemon/opd_interface.h deleted file mode 100644 index c876830..0000000 --- a/daemon/opd_interface.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file opd_interface.h - * - * Module / user space interface for 2.6 kernels and above - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#ifndef OPD_INTERFACE_H -#define OPD_INTERFACE_H - -#define CTX_SWITCH_CODE 1 -#define CPU_SWITCH_CODE 2 -#define COOKIE_SWITCH_CODE 3 -#define KERNEL_ENTER_SWITCH_CODE 4 -#define USER_ENTER_SWITCH_CODE 5 -#define MODULE_LOADED_CODE 6 -#define CTX_TGID_CODE 7 -#define TRACE_BEGIN_CODE 8 -/* Code 9 used to be TRACE_END_CODE which is not used anymore */ -/* Code 9 is now considered an unknown escape code */ -#define XEN_ENTER_SWITCH_CODE 10 -/* - * Ugly work-around for the unfortunate collision between Xenoprof's - * DOMAIN_SWITCH_CODE (in use on x86) and Cell's SPU_PROFILING_CODE - * (in use with Power): - */ -#if defined(__powerpc__) -#define SPU_PROFILING_CODE 11 -#define SPU_CTX_SWITCH_CODE 12 -#define DOMAIN_SWITCH_CODE 13 -#define LAST_CODE 14 -#else -#define DOMAIN_SWITCH_CODE 11 -#define LAST_CODE 12 -#endif - -#endif /* OPD_INTERFACE_H */ diff --git a/daemon/opd_kernel.c b/daemon/opd_kernel.c deleted file mode 100644 index 5ebc210..0000000 --- a/daemon/opd_kernel.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - * @file daemon/opd_kernel.c - * Dealing with the kernel and kernel module samples - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#include "opd_kernel.h" -#include "opd_sfile.h" -#include "opd_trans.h" -#include "opd_printf.h" -#include "opd_stats.h" -#include "oprofiled.h" - -#include "op_fileio.h" -#include "op_config.h" -#include "op_libiberty.h" - -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <assert.h> - -static LIST_HEAD(modules); - -static struct kernel_image vmlinux_image; - -static struct kernel_image xen_image; - -void opd_create_vmlinux(char const * name, char const * arg) -{ - /* vmlinux is *not* on the list of modules */ - list_init(&vmlinux_image.list); - - /* for no vmlinux */ - if (no_vmlinux) { - vmlinux_image.name = "no-vmlinux"; - return; - } - - vmlinux_image.name = xstrdup(name); - - sscanf(arg, "%llx,%llx", &vmlinux_image.start, &vmlinux_image.end); - - verbprintf(vmisc, "kernel_start = %llx, kernel_end = %llx\n", - vmlinux_image.start, vmlinux_image.end); - - if (!vmlinux_image.start && !vmlinux_image.end) { - fprintf(stderr, "error: mis-parsed kernel range: %llx-%llx\n", - vmlinux_image.start, vmlinux_image.end); - exit(EXIT_FAILURE); - } -} - -void opd_create_xen(char const * name, char const * arg) -{ - /* xen is *not* on the list of modules */ - list_init(&xen_image.list); - - /* for no xen */ - if (no_xen) { - xen_image.name = "no-xen"; - return; - } - - xen_image.name = xstrdup(name); - - sscanf(arg, "%llx,%llx", &xen_image.start, &xen_image.end); - - verbprintf(vmisc, "xen_start = %llx, xen_end = %llx\n", - xen_image.start, xen_image.end); - - if (!xen_image.start && !xen_image.end) { - fprintf(stderr, "error: mis-parsed xen range: %llx-%llx\n", - xen_image.start, xen_image.end); - exit(EXIT_FAILURE); - } -} - - -/** - * Allocate and initialise a kernel image description - * @param name image name - * @param start start address - * @param end end address - */ -static struct kernel_image * -opd_create_module(char const * name, vma_t start, vma_t end) -{ - struct kernel_image * image = xmalloc(sizeof(struct kernel_image)); - - image->name = xstrdup(name); - image->start = start; - image->end = end; - list_add(&image->list, &modules); - - return image; -} - - -/** - * Clear and free all kernel image information and reset - * values. - */ -static void opd_clear_modules(void) -{ - struct list_head * pos; - struct list_head * pos2; - struct kernel_image * image; - - list_for_each_safe(pos, pos2, &modules) { - image = list_entry(pos, struct kernel_image, list); - if (image->name) - free(image->name); - free(image); - } - - list_init(&modules); - - /* clear out lingering references */ - sfile_clear_kernel(); -} - - -/* - * each line is in the format: - * - * module_name 16480 1 dependencies Live 0xe091e000 - * - * without any blank space in each field - */ -void opd_reread_module_info(void) -{ - FILE * fp; - char * line; - struct kernel_image * image; - int module_size; - char ref_count[32+1]; - int ret; - char module_name[256+1]; - char live_info[32+1]; - char dependencies[4096+1]; - unsigned long long start_address; - - if (no_vmlinux) - return; - - opd_clear_modules(); - - printf("Reading module info.\n"); - - fp = op_try_open_file("/proc/modules", "r"); - - if (!fp) { - printf("oprofiled: /proc/modules not readable, " - "can't process module samples.\n"); - return; - } - - while (1) { - line = op_get_line(fp); - - if (!line) - break; - - if (line[0] == '\0') { - free(line); - continue; - } - - ret = sscanf(line, "%256s %u %32s %4096s %32s %llx", - module_name, &module_size, ref_count, - dependencies, live_info, &start_address); - if (ret != 6) { - printf("bad /proc/modules entry: %s\n", line); - free(line); - continue; - } - - image = opd_create_module(module_name, start_address, - start_address + module_size); - - verbprintf(vmodule, "module %s start %llx end %llx\n", - image->name, image->start, image->end); - - free(line); - } - - op_close_file(fp); -} - - -/** - * find a kernel image by PC value - * @param trans holds PC value to look up - * - * find the kernel image which contains this PC. - * - * Return %NULL if not found. - */ -struct kernel_image * find_kernel_image(struct transient const * trans) -{ - struct list_head * pos; - struct kernel_image * image = &vmlinux_image; - - if (no_vmlinux) - return image; - - if (image->start <= trans->pc && image->end > trans->pc) - return image; - - list_for_each(pos, &modules) { - image = list_entry(pos, struct kernel_image, list); - if (image->start <= trans->pc && image->end > trans->pc) - return image; - } - - if (xen_image.start <= trans->pc && xen_image.end > trans->pc) - return &xen_image; - - return NULL; -} diff --git a/daemon/opd_kernel.h b/daemon/opd_kernel.h deleted file mode 100644 index cb71a30..0000000 --- a/daemon/opd_kernel.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file daemon/opd_kernel.h - * Dealing with the kernel and kernel module images - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#ifndef OPD_KERNEL_H -#define OPD_KERNEL_H - -#include "op_types.h" -#include "op_list.h" - -struct transient; - -/** create the kernel image */ -void opd_create_vmlinux(char const * name, char const * arg); - -void opd_create_xen(char const * name, char const * arg); - -/** opd_reread_module_info - parse /proc/modules for kernel modules */ -void opd_reread_module_info(void); - -/** Describes a kernel module or vmlinux itself */ -struct kernel_image { - char * name; - vma_t start; - vma_t end; - struct list_head list; -}; - -/** Find a kernel_image based upon the given parameters in trans. */ -struct kernel_image * -find_kernel_image(struct transient const * trans); - -#endif /* OPD_KERNEL_H */ diff --git a/daemon/opd_mangling.c b/daemon/opd_mangling.c deleted file mode 100644 index 08a6079..0000000 --- a/daemon/opd_mangling.c +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @file daemon/opd_mangling.c - * Mangling and opening of sample files - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <sys/types.h> - -#include "opd_mangling.h" -#include "opd_kernel.h" -#include "opd_cookie.h" -#include "opd_sfile.h" -#include "opd_anon.h" -#include "opd_printf.h" -#include "opd_events.h" -#include "oprofiled.h" - -#include "op_file.h" -#include "op_sample_file.h" -#include "op_config.h" -#include "op_mangle.h" -#include "op_events.h" -#include "op_libiberty.h" - -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - - -static char const * get_dep_name(struct sfile const * sf) -{ - if (sf->anon) - return find_cookie(sf->app_cookie); - - /* avoid to call find_cookie(), caller can recover using image_name */ - if (sf->cookie == sf->app_cookie) - return NULL; - - if (!separate_kernel && !(separate_lib && !sf->kernel)) - return NULL; - - /* this will fail if e.g. kernel thread */ - if (sf->app_cookie == 0) - return NULL; - - return find_cookie(sf->app_cookie); -} - - -static char * mangle_anon(struct anon_mapping const * anon) -{ - char * name = xmalloc(PATH_MAX); - - snprintf(name, 1024, "%u.0x%llx.0x%llx", (unsigned int)anon->tgid, - anon->start, anon->end); - - return name; -} - - -static char * -mangle_filename(struct sfile * last, struct sfile const * sf, int counter, int cg) -{ - char * mangled; - struct mangle_values values; - struct opd_event * event = find_counter_event(counter); - - values.flags = 0; - - if (sf->kernel) { - values.image_name = sf->kernel->name; - values.flags |= MANGLE_KERNEL; - } else if (sf->anon) { - values.flags |= MANGLE_ANON; - values.image_name = mangle_anon(sf->anon); - values.anon_name = sf->anon->name; - } else { - values.image_name = find_cookie(sf->cookie); - } - - values.dep_name = get_dep_name(sf); - if (!values.dep_name) - values.dep_name = values.image_name; - - /* FIXME: log */ - if (!values.image_name || !values.dep_name) - return NULL; - - if (separate_thread) { - values.flags |= MANGLE_TGID | MANGLE_TID; - values.tid = sf->tid; - values.tgid = sf->tgid; - } - - if (separate_cpu) { - values.flags |= MANGLE_CPU; - values.cpu = sf->cpu; - } - - if (cg) { - values.flags |= MANGLE_CALLGRAPH; - if (last->kernel) { - values.cg_image_name = last->kernel->name; - } else if (last->anon) { - values.flags |= MANGLE_CG_ANON; - values.cg_image_name = mangle_anon(last->anon); - values.anon_name = last->anon->name; - } else { - values.cg_image_name = find_cookie(last->cookie); - } - - /* FIXME: log */ - if (!values.cg_image_name) { - if (values.flags & MANGLE_ANON) - free((char *)values.image_name); - return NULL; - } - } - - values.event_name = event->name; - values.count = event->count; - values.unit_mask = event->um; - - mangled = op_mangle_filename(&values); - - if (values.flags & MANGLE_ANON) - free((char *)values.image_name); - if (values.flags & MANGLE_CG_ANON) - free((char *)values.cg_image_name); - return mangled; -} - - -int opd_open_sample_file(odb_t * file, struct sfile * last, - struct sfile * sf, int counter, int cg) -{ - char * mangled; - char const * binary; - int spu_profile = 0; - vma_t last_start = 0; - int err; - - mangled = mangle_filename(last, sf, counter, cg); - - if (!mangled) - return EINVAL; - - verbprintf(vsfile, "Opening \"%s\"\n", mangled); - - create_path(mangled); - - /* locking sf will lock associated cg files too */ - sfile_get(sf); - if (sf != last) - sfile_get(last); - -retry: - err = odb_open(file, mangled, ODB_RDWR, sizeof(struct opd_header)); - - /* This can naturally happen when racing against opcontrol --reset. */ - if (err) { - if (err == EMFILE) { - if (sfile_lru_clear()) { - printf("LRU cleared but odb_open() fails for %s.\n", mangled); - abort(); - } - goto retry; - } - - fprintf(stderr, "oprofiled: open of %s failed: %s\n", - mangled, strerror(err)); - goto out; - } - - if (!sf->kernel) - binary = find_cookie(sf->cookie); - else - binary = sf->kernel->name; - - if (last && last->anon) - last_start = last->anon->start; - - if (sf->embedded_offset != UNUSED_EMBEDDED_OFFSET) - spu_profile = 1; - - fill_header(odb_get_data(file), counter, - sf->anon ? sf->anon->start : 0, last_start, - !!sf->kernel, last ? !!last->kernel : 0, - spu_profile, sf->embedded_offset, - binary ? op_get_mtime(binary) : 0); - -out: - sfile_put(sf); - if (sf != last) - sfile_put(last); - free(mangled); - return err; -} diff --git a/daemon/opd_mangling.h b/daemon/opd_mangling.h deleted file mode 100644 index 0e46ec4..0000000 --- a/daemon/opd_mangling.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file daemon/opd_mangling.h - * Mangling and opening of sample files - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OPD_MANGLING_H -#define OPD_MANGLING_H - -#include "odb.h" - -struct sfile; - -/* - * opd_open_sample_file - open a sample file - * @param sf sfile to open sample file for - * @param counter counter number - * @param cg if this is a callgraph file - * - * Open image sample file for the sfile, counter - * counter and set up memory mappings for it. - * - * Returns 0 on success. - */ -int opd_open_sample_file(odb_t * file, struct sfile * last, - struct sfile * sf, int counter, int cg); - -#endif /* OPD_MANGLING_H */ diff --git a/daemon/opd_perfmon.c b/daemon/opd_perfmon.c deleted file mode 100644 index a1b158a..0000000 --- a/daemon/opd_perfmon.c +++ /dev/null @@ -1,496 +0,0 @@ -/** - * @file opd_perfmon.c - * perfmonctl() handling - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifdef __ia64__ - -/* need this for sched_setaffinity() in <sched.h> */ -#define _GNU_SOURCE - -#include "oprofiled.h" -#include "opd_perfmon.h" -#include "opd_events.h" - -#include "op_cpu_type.h" -#include "op_libiberty.h" -#include "op_hw_config.h" - -#include <sys/syscall.h> -#include <sys/wait.h> -#include <unistd.h> -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#ifdef HAVE_SCHED_SETAFFINITY -#include <sched.h> -#endif - -extern op_cpu cpu_type; - -#ifndef HAVE_SCHED_SETAFFINITY - -/* many glibc's are not yet up to date */ -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 1231 -#endif - -/* Copied from glibc's <sched.h> and <bits/sched.h> and munged */ -#define CPU_SETSIZE 1024 -#define __NCPUBITS (8 * sizeof (unsigned long)) -typedef struct -{ - unsigned long __bits[CPU_SETSIZE / __NCPUBITS]; -} cpu_set_t; - -#define CPU_SET(cpu, cpusetp) \ - ((cpusetp)->__bits[(cpu)/__NCPUBITS] |= (1UL << ((cpu) % __NCPUBITS))) -#define CPU_ZERO(cpusetp) \ - memset((cpusetp), 0, sizeof(cpu_set_t)) - -static int -sched_setaffinity(pid_t pid, size_t len, cpu_set_t const * cpusetp) -{ - return syscall(__NR_sched_setaffinity, pid, len, cpusetp); -} -#endif - - -#ifndef HAVE_PERFMONCTL -#ifndef __NR_perfmonctl -#define __NR_perfmonctl 1175 -#endif - -static int perfmonctl(int fd, int cmd, void * arg, int narg) -{ - return syscall(__NR_perfmonctl, fd, cmd, arg, narg); -} -#endif - - -static unsigned char uuid[16] = { - 0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, - 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c -}; - - -static size_t nr_cpus; - -struct child { - pid_t pid; - int up_pipe[2]; - int ctx_fd; - sig_atomic_t sigusr1; - sig_atomic_t sigusr2; - sig_atomic_t sigterm; -}; - -static struct child * children; - -static void perfmon_start_child(int ctx_fd) -{ - if (perfmonctl(ctx_fd, PFM_START, 0, 0) == -1) { - perror("Couldn't start perfmon: "); - exit(EXIT_FAILURE); - } -} - - -static void perfmon_stop_child(int ctx_fd) -{ - if (perfmonctl(ctx_fd, PFM_STOP, 0, 0) == -1) { - perror("Couldn't stop perfmon: "); - exit(EXIT_FAILURE); - } -} - - -static void child_sigusr1(int val __attribute__((unused))) -{ - size_t i; - - for (i = 0; i < nr_cpus; ++i) { - if (children[i].pid == getpid()) { - children[i].sigusr1 = 1; - return; - } - } -} - - -static void child_sigusr2(int val __attribute__((unused))) -{ - size_t i; - - for (i = 0; i < nr_cpus; ++i) { - if (children[i].pid == getpid()) { - children[i].sigusr2 = 1; - return; - } - } -} - - -static void child_sigterm(int val __attribute__((unused))) -{ - printf("Child received SIGTERM, killing parent.\n"); - kill(getppid(), SIGTERM); -} - - -static void set_affinity(size_t cpu) -{ - cpu_set_t set; - - CPU_ZERO(&set); - CPU_SET(cpu, &set); - - int err = sched_setaffinity(getpid(), sizeof(set), &set); - - if (err == -1) { - fprintf(stderr, "Failed to set affinity: %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } -} - - -static void setup_signals(void) -{ - struct sigaction act; - sigset_t mask; - - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - sigaddset(&mask, SIGUSR2); - sigprocmask(SIG_BLOCK, &mask, NULL); - - act.sa_handler = child_sigusr1; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGUSR1, &act, NULL)) { - perror("oprofiled: install of SIGUSR1 handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = child_sigusr2; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGUSR2, &act, NULL)) { - perror("oprofiled: install of SIGUSR2 handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = child_sigterm; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGTERM, &act, NULL)) { - perror("oprofiled: install of SIGTERM handler failed: "); - exit(EXIT_FAILURE); - } -} - - -/** create the per-cpu context */ -static void create_context(struct child * self) -{ - pfarg_context_t ctx; - int err; - - memset(&ctx, 0, sizeof(pfarg_context_t)); - memcpy(&ctx.ctx_smpl_buf_id, &uuid, 16); - ctx.ctx_flags = PFM_FL_SYSTEM_WIDE; - - err = perfmonctl(0, PFM_CREATE_CONTEXT, &ctx, 1); - if (err == -1) { - fprintf(stderr, "CREATE_CONTEXT failed: %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - - self->ctx_fd = ctx.ctx_fd; -} - - -/** program the perfmon counters */ -static void write_pmu(struct child * self) -{ - pfarg_reg_t pc[OP_MAX_COUNTERS]; - pfarg_reg_t pd[OP_MAX_COUNTERS]; - int err; - size_t i; - - memset(pc, 0, sizeof(pc)); - memset(pd, 0, sizeof(pd)); - -#define PMC_GEN_INTERRUPT (1UL << 5) -#define PMC_PRIV_MONITOR (1UL << 6) -/* McKinley requires pmc4 to have bit 23 set (enable PMU). - * It is supposedly ignored in other pmc registers. - */ -#define PMC_MANDATORY (1UL << 23) -#define PMC_USER (1UL << 3) -#define PMC_KERNEL (1UL << 0) - for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) { - struct opd_event * event = &opd_events[i]; - pc[i].reg_num = event->counter + 4; - pc[i].reg_value = PMC_GEN_INTERRUPT; - pc[i].reg_value |= PMC_PRIV_MONITOR; - pc[i].reg_value |= PMC_MANDATORY; - (event->user) ? (pc[i].reg_value |= PMC_USER) - : (pc[i].reg_value &= ~PMC_USER); - (event->kernel) ? (pc[i].reg_value |= PMC_KERNEL) - : (pc[i].reg_value &= ~PMC_KERNEL); - pc[i].reg_value &= ~(0xff << 8); - pc[i].reg_value |= ((event->value & 0xff) << 8); - pc[i].reg_value &= ~(0xf << 16); - pc[i].reg_value |= ((event->um & 0xf) << 16); - pc[i].reg_smpl_eventid = event->counter; - } - - for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) { - struct opd_event * event = &opd_events[i]; - pd[i].reg_value = ~0UL - event->count + 1; - pd[i].reg_short_reset = ~0UL - event->count + 1; - pd[i].reg_num = event->counter + 4; - } - - err = perfmonctl(self->ctx_fd, PFM_WRITE_PMCS, pc, i); - if (err == -1) { - perror("Couldn't write PMCs: "); - exit(EXIT_FAILURE); - } - - err = perfmonctl(self->ctx_fd, PFM_WRITE_PMDS, pd, i); - if (err == -1) { - perror("Couldn't write PMDs: "); - exit(EXIT_FAILURE); - } -} - - -static void load_context(struct child * self) -{ - pfarg_load_t load_args; - int err; - - memset(&load_args, 0, sizeof(load_args)); - load_args.load_pid = self->pid; - - err = perfmonctl(self->ctx_fd, PFM_LOAD_CONTEXT, &load_args, 1); - if (err == -1) { - perror("Couldn't load context: "); - exit(EXIT_FAILURE); - } -} - - -static void notify_parent(struct child * self, size_t cpu) -{ - for (;;) { - ssize_t ret; - ret = write(self->up_pipe[1], &cpu, sizeof(size_t)); - if (ret == sizeof(size_t)) - break; - if (ret < 0 && errno != EINTR) { - fprintf(stderr, "Failed to write child pipe with %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - } -} - - -static void run_child(size_t cpu) -{ - struct child * self = &children[cpu]; - - self->pid = getpid(); - self->sigusr1 = 0; - self->sigusr2 = 0; - self->sigterm = 0; - - setup_signals(); - - set_affinity(cpu); - - create_context(self); - - write_pmu(self); - - load_context(self); - - notify_parent(self, cpu); - - for (;;) { - sigset_t sigmask; - sigfillset(&sigmask); - sigdelset(&sigmask, SIGUSR1); - sigdelset(&sigmask, SIGUSR2); - sigdelset(&sigmask, SIGTERM); - - if (self->sigusr1) { - printf("PFM_START on CPU%d\n", (int)cpu); - fflush(stdout); - perfmon_start_child(self->ctx_fd); - self->sigusr1 = 0; - } - - if (self->sigusr2) { - printf("PFM_STOP on CPU%d\n", (int)cpu); - fflush(stdout); - perfmon_stop_child(self->ctx_fd); - self->sigusr2 = 0; - } - - sigsuspend(&sigmask); - } -} - - -static void wait_for_child(struct child * child) -{ - size_t tmp; - for (;;) { - ssize_t ret; - ret = read(child->up_pipe[0], &tmp, sizeof(size_t)); - if (ret == sizeof(size_t)) - break; - if (ret < 0 && errno != EINTR) { - fprintf(stderr, "Failed to read child pipe with %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - } - printf("Perfmon child up on CPU%d\n", (int)tmp); - fflush(stdout); - - close(child->up_pipe[0]); - close(child->up_pipe[1]); -} - -static struct child* xen_ctx; - -void perfmon_init(void) -{ - size_t i; - long nr; - - if (cpu_type == CPU_TIMER_INT) - return; - - if (!no_xen) { - xen_ctx = xmalloc(sizeof(struct child)); - xen_ctx->pid = getpid(); - xen_ctx->up_pipe[0] = -1; - xen_ctx->up_pipe[1] = -1; - xen_ctx->sigusr1 = 0; - xen_ctx->sigusr2 = 0; - xen_ctx->sigterm = 0; - - create_context(xen_ctx); - - write_pmu(xen_ctx); - - load_context(xen_ctx); - return; - } - - - nr = sysconf(_SC_NPROCESSORS_ONLN); - if (nr == -1) { - fprintf(stderr, "Couldn't determine number of CPUs.\n"); - exit(EXIT_FAILURE); - } - - nr_cpus = nr; - - children = xmalloc(sizeof(struct child) * nr_cpus); - - for (i = 0; i < nr_cpus; ++i) { - int ret; - - if (pipe(children[i].up_pipe)) { - perror("Couldn't create child pipe.\n"); - exit(EXIT_FAILURE); - } - - ret = fork(); - if (ret == -1) { - fprintf(stderr, "Couldn't fork perfmon child.\n"); - exit(EXIT_FAILURE); - } else if (ret == 0) { - printf("Running perfmon child on CPU%d.\n", (int)i); - fflush(stdout); - run_child(i); - } else { - children[i].pid = ret; - printf("Waiting on CPU%d\n", (int)i); - wait_for_child(&children[i]); - } - } -} - - -void perfmon_exit(void) -{ - size_t i; - - if (cpu_type == CPU_TIMER_INT) - return; - - if (!no_xen) - return; - - for (i = 0; i < nr_cpus; ++i) { - kill(children[i].pid, SIGKILL); - waitpid(children[i].pid, NULL, 0); - } -} - - -void perfmon_start(void) -{ - size_t i; - - if (cpu_type == CPU_TIMER_INT) - return; - - if (!no_xen) { - perfmon_start_child(xen_ctx->ctx_fd); - return; - } - - for (i = 0; i < nr_cpus; ++i) - kill(children[i].pid, SIGUSR1); -} - - -void perfmon_stop(void) -{ - size_t i; - - if (cpu_type == CPU_TIMER_INT) - return; - - if (!no_xen) { - perfmon_stop_child(xen_ctx->ctx_fd); - return; - } - - for (i = 0; i < nr_cpus; ++i) - kill(children[i].pid, SIGUSR2); -} - -#endif /* __ia64__ */ diff --git a/daemon/opd_perfmon.h b/daemon/opd_perfmon.h deleted file mode 100644 index 9b4267f..0000000 --- a/daemon/opd_perfmon.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file opd_perfmon.h - * perfmonctl() handling - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#ifndef OPD_PERFMON_H -#define OPD_PERFMON_H - -#ifdef __ia64__ - -#include <stdlib.h> - -void perfmon_init(void); -void perfmon_exit(void); -void perfmon_start(void); -void perfmon_stop(void); - -/* The following is from asm/perfmon.h. When it's installed on - * enough boxes, we can remove this and include the platform - * perfmon.h - */ - -typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */ - -/* - * Request structure used to define a context - */ -typedef struct { - pfm_uuid_t ctx_smpl_buf_id; /* which buffer format to use (if needed) */ - unsigned long ctx_flags; /* noblock/block */ - unsigned short ctx_nextra_sets; /* number of extra event sets (you always get 1) */ - unsigned short ctx_reserved1; /* for future use */ - int ctx_fd; /* return arg: unique identification for context */ - void *ctx_smpl_vaddr; /* return arg: virtual address of sampling buffer, is used */ - unsigned long ctx_reserved2[11];/* for future use */ -} pfarg_context_t; - -/* - * Request structure used to write/read a PMC or PMD - */ -typedef struct { - unsigned int reg_num; /* which register */ - unsigned short reg_set; /* event set for this register */ - unsigned short reg_reserved1; /* for future use */ - - unsigned long reg_value; /* initial pmc/pmd value */ - unsigned long reg_flags; /* input: pmc/pmd flags, return: reg error */ - - unsigned long reg_long_reset; /* reset after buffer overflow notification */ - unsigned long reg_short_reset; /* reset after counter overflow */ - - unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */ - unsigned long reg_random_seed; /* seed value when randomization is used */ - unsigned long reg_random_mask; /* bitmask used to limit random value */ - unsigned long reg_last_reset_val;/* return: PMD last reset value */ - - unsigned long reg_smpl_pmds[4]; /* which pmds are accessed when PMC overflows */ - unsigned long reg_smpl_eventid; /* opaque sampling event identifier */ - - unsigned long reg_reserved2[3]; /* for future use */ -} pfarg_reg_t; - -typedef struct { - pid_t load_pid; /* process to load the context into */ - unsigned short load_set; /* first event set to load */ - unsigned short load_reserved1; /* for future use */ - unsigned long load_reserved2[3]; /* for future use */ -} pfarg_load_t; - -#define PFM_WRITE_PMCS 0x01 -#define PFM_WRITE_PMDS 0x02 -#define PFM_STOP 0x04 -#define PFM_START 0x05 -#define PFM_CREATE_CONTEXT 0x08 -#define PFM_LOAD_CONTEXT 0x10 -#define PFM_FL_SYSTEM_WIDE 0x02 - -#else - -void perfmon_init(void) -{ -} - - -void perfmon_exit(void) -{ -} - - -void perfmon_start(void) -{ -} - - -void perfmon_stop(void) -{ -} - -#endif /* __ia64__ */ - -#endif /* OPD_PERFMON_H */ diff --git a/daemon/opd_pipe.c b/daemon/opd_pipe.c deleted file mode 100644 index a5c334a..0000000 --- a/daemon/opd_pipe.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file daemon/opd_pipe.c - * Functions handling the $SESSIONDIR/opd_pipe FIFO special file. - * NOTE: This code is dealing with potentially insecure input. - * - * @remark Copyright 2008 OProfile authors - * @remark Read the file COPYING - * - * @author Daniel Hansel - */ - -#include "opd_pipe.h" -#include "opd_printf.h" -#include "op_config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/stat.h> - -static int fifo; - -void opd_create_pipe(void) -{ - mode_t orig_umask = umask(0111); - if (mkfifo(op_pipe_file, 0666) == -1) { - if (errno != EEXIST) { - perror("oprofiled: couldn't create pipe: "); - exit(EXIT_FAILURE); - } - } - umask(orig_umask); -} - - -void opd_open_pipe(void) -{ - fifo = open(op_pipe_file, O_RDONLY | O_NONBLOCK); - if (fifo == -1) { - perror("oprofiled: couldn't open pipe: "); - exit(EXIT_FAILURE); - } -} - - -void opd_close_pipe(void) -{ - close(fifo); -} - - -int is_jitconv_requested(void) -{ - /* number of dropped (unknown) requests */ - static long nr_drops = 0; - /* modulus to output only a few warnings to avoid flooding oprofiled.log */ - static int mod_cnt_drops = 1; - FILE * fd; - char line[256]; - int i, ret = 0; - - /* get a file descriptor to the pipe */ - fd = fdopen(fifo, "r"); - - if (fd == NULL) { - perror("oprofiled: couldn't create file descriptor: "); - exit(EXIT_FAILURE); - } - - /* read up to 99 lines to check for 'do_jitconv' */ - for (i = 0; i < 99; i++) { - /* just break if no new line is found */ - if (fgets(line, 256, fd) == NULL) - break; - line[strlen(line) - 1] = '\0'; - - if (strstr(line, "do_jitconv") != NULL) { - ret = 1; - } else { - nr_drops++; - - if (nr_drops % mod_cnt_drops == 0) { - printf( - "Warning: invalid pipe request received (dropped request(s): %ld)\n", - nr_drops); - /* increase modulus to avoid flooding log file */ - mod_cnt_drops *= 5; - } - } - } - - return ret; -} diff --git a/daemon/opd_pipe.h b/daemon/opd_pipe.h deleted file mode 100644 index 7f96b07..0000000 --- a/daemon/opd_pipe.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file daemon/opd_pipe.h - * Functions handling the $SESSIONDIR/opd_pipe FIFO special file. - * NOTE: This code is dealing with potencially insecure input. - * - * @remark Copyright 2008 OProfile authors - * @remark Read the file COPYING - * - * @author Daniel Hansel - */ - -#ifndef OPD_PIPE_H_ -#define OPD_PIPE_H_ - -/** - * opd_create_pipe - creates the oprofiled fifo file - * - * Creates the Oprofile daemon fifo pipe to enable communication between - * the daemon and the 'opcontrol --dump' command. Failure to create the pipe - * is a fatal error. - */ -void opd_create_pipe(void); - -/** - * opd_open_pipe - opens the oprofiled fifo file - */ -void opd_open_pipe(void); - -/** - * opd_close_pipe - closes the oprofiled fifo file - * - * Closes the Oprofile daemon fifo pipe. - */ -void opd_close_pipe(void); - -/** - * is_jitconv_requested - check for request to jit conversion - * - * Checks the Oprofile daemon fifo pipe for do_jitconv request. - * If jit conversion is requested ('do_jitconv' is sent) the check returns 1. - * Otherwise it returns 0. - */ -int is_jitconv_requested(void); - -#endif /*OPD_PIPE_H_*/ diff --git a/daemon/opd_printf.h b/daemon/opd_printf.h deleted file mode 100644 index e1f8476..0000000 --- a/daemon/opd_printf.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file daemon/opd_printf.h - * Output routines - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OPD_PRINTF_H -#define OPD_PRINTF_H - -/// log all sample file name manipulation; sample files open, close, -/// sfile LRU etc. voluminous. FIXME need to be splitted (filename manip, files -/// handling) ? -extern int vsfile; -/// log samples, voluminous. -extern int vsamples; -/// log arc, very voluminous. -extern int varcs; -/// kernel module handling -extern int vmodule; -/// all others not fitting in above category, not voluminous. -extern int vmisc; - -#define verbprintf(x, args...) \ - do { \ - /* look like fragile but we must catch verbrintf("%s", "") */ \ - if (x == 1) \ - printf(args); \ - } while (0) - -#endif /* OPD_PRINTF_H */ diff --git a/daemon/opd_sfile.c b/daemon/opd_sfile.c deleted file mode 100644 index 03ebf55..0000000 --- a/daemon/opd_sfile.c +++ /dev/null @@ -1,619 +0,0 @@ -/** - * @file daemon/opd_sfile.c - * Management of sample files - * - * @remark Copyright 2002, 2005 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "opd_sfile.h" - -#include "opd_trans.h" -#include "opd_kernel.h" -#include "opd_mangling.h" -#include "opd_anon.h" -#include "opd_printf.h" -#include "opd_stats.h" -#include "oprofiled.h" - -#include "op_libiberty.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define HASH_SIZE 2048 -#define HASH_BITS (HASH_SIZE - 1) - -/** All sfiles are hashed into these lists */ -static struct list_head hashes[HASH_SIZE]; - -/** All sfiles are on this list. */ -static LIST_HEAD(lru_list); - - -/* FIXME: can undoubtedly improve this hashing */ -/** Hash the transient parameters for lookup. */ -static unsigned long -sfile_hash(struct transient const * trans, struct kernel_image * ki) -{ - unsigned long val = 0; - - if (separate_thread) { - val ^= trans->tid << 2; - val ^= trans->tgid << 2; - } - - if (separate_kernel || ((trans->anon || separate_lib) && !ki)) - val ^= trans->app_cookie >> (DCOOKIE_SHIFT + 3); - - if (separate_cpu) - val ^= trans->cpu; - - /* cookie meaningless for kernel, shouldn't hash */ - if (trans->in_kernel) { - val ^= ki->start >> 14; - val ^= ki->end >> 7; - return val & HASH_BITS; - } - - if (trans->cookie != NO_COOKIE) { - val ^= trans->cookie >> DCOOKIE_SHIFT; - return val & HASH_BITS; - } - - if (!separate_thread) - val ^= trans->tgid << 2; - - if (trans->anon) { - val ^= trans->anon->start >> VMA_SHIFT; - val ^= trans->anon->end >> (VMA_SHIFT + 1); - } - - return val & HASH_BITS; -} - - -static int -do_match(struct sfile const * sf, cookie_t cookie, cookie_t app_cookie, - struct kernel_image const * ki, struct anon_mapping const * anon, - pid_t tgid, pid_t tid, unsigned int cpu) -{ - /* this is a simplified check for "is a kernel image" AND - * "is the right kernel image". Also handles no-vmlinux - * correctly. - */ - if (sf->kernel != ki) - return 0; - - if (separate_thread) { - if (sf->tid != tid || sf->tgid != tgid) - return 0; - } - - if (separate_cpu) { - if (sf->cpu != cpu) - return 0; - } - - if (separate_kernel || ((anon || separate_lib) && !ki)) { - if (sf->app_cookie != app_cookie) - return 0; - } - - /* ignore the cached trans->cookie for kernel images, - * it's meaningless and we checked all others already - */ - if (ki) - return 1; - - if (sf->anon != anon) - return 0; - - return sf->cookie == cookie; -} - - -static int -trans_match(struct transient const * trans, struct sfile const * sfile, - struct kernel_image const * ki) -{ - return do_match(sfile, trans->cookie, trans->app_cookie, ki, - trans->anon, trans->tgid, trans->tid, trans->cpu); -} - - -static int -sfile_equal(struct sfile const * sf, struct sfile const * sf2) -{ - return do_match(sf, sf2->cookie, sf2->app_cookie, sf2->kernel, - sf2->anon, sf2->tgid, sf2->tid, sf2->cpu); -} - - -static int -is_sf_ignored(struct sfile const * sf) -{ - if (sf->kernel) { - if (!is_image_ignored(sf->kernel->name)) - return 0; - - /* Let a dependent kernel image redeem the sf if we're - * executing on behalf of an application. - */ - return is_cookie_ignored(sf->app_cookie); - } - - /* Anon regions are always dependent on the application. - * Otherwise, let a dependent image redeem the sf. - */ - if (sf->anon || is_cookie_ignored(sf->cookie)) - return is_cookie_ignored(sf->app_cookie); - - return 0; -} - - -/** create a new sfile matching the current transient parameters */ -static struct sfile * -create_sfile(unsigned long hash, struct transient const * trans, - struct kernel_image * ki) -{ - size_t i; - struct sfile * sf; - - sf = xmalloc(sizeof(struct sfile)); - - sf->hashval = hash; - - /* The logic here: if we're in the kernel, the cached cookie is - * meaningless (though not the app_cookie if separate_kernel) - */ - sf->cookie = trans->in_kernel ? INVALID_COOKIE : trans->cookie; - sf->app_cookie = INVALID_COOKIE; - sf->tid = (pid_t)-1; - sf->tgid = (pid_t)-1; - sf->cpu = 0; - sf->kernel = ki; - sf->anon = trans->anon; - - for (i = 0 ; i < op_nr_counters ; ++i) - odb_init(&sf->files[i]); - - for (i = 0; i < CG_HASH_SIZE; ++i) - list_init(&sf->cg_hash[i]); - - if (separate_thread) - sf->tid = trans->tid; - if (separate_thread || trans->cookie == NO_COOKIE) - sf->tgid = trans->tgid; - - if (separate_cpu) - sf->cpu = trans->cpu; - - if (separate_kernel || ((trans->anon || separate_lib) && !ki)) - sf->app_cookie = trans->app_cookie; - - sf->ignored = is_sf_ignored(sf); - - sf->embedded_offset = trans->embedded_offset; - - /* If embedded_offset is a valid value, it means we're - * processing a Cell BE SPU profile; in which case, we - * want sf->app_cookie to hold trans->app_cookie. - */ - if (trans->embedded_offset != UNUSED_EMBEDDED_OFFSET) - sf->app_cookie = trans->app_cookie; - return sf; -} - - -struct sfile * sfile_find(struct transient const * trans) -{ - struct sfile * sf; - struct list_head * pos; - struct kernel_image * ki = NULL; - unsigned long hash; - - if (trans->tracing != TRACING_ON) { - opd_stats[OPD_SAMPLES]++; - opd_stats[trans->in_kernel == 1 ? OPD_KERNEL : OPD_PROCESS]++; - } - - /* There is a small race where this *can* happen, see - * caller of cpu_buffer_reset() in the kernel - */ - if (trans->in_kernel == -1) { - verbprintf(vsamples, "Losing sample at 0x%llx of unknown provenance.\n", - trans->pc); - opd_stats[OPD_NO_CTX]++; - return NULL; - } - - /* we might need a kernel image start/end to hash on */ - if (trans->in_kernel) { - ki = find_kernel_image(trans); - if (!ki) { - verbprintf(vsamples, "Lost kernel sample %llx\n", trans->pc); - opd_stats[OPD_LOST_KERNEL]++; - return NULL; - } - } else if (trans->cookie == NO_COOKIE && !trans->anon) { - if (vsamples) { - char const * app = verbose_cookie(trans->app_cookie); - printf("No anon map for pc %llx, app %s.\n", - trans->pc, app); - } - opd_stats[OPD_LOST_NO_MAPPING]++; - return NULL; - } - - hash = sfile_hash(trans, ki); - list_for_each(pos, &hashes[hash]) { - sf = list_entry(pos, struct sfile, hash); - if (trans_match(trans, sf, ki)) { - sfile_get(sf); - goto lru; - } - } - - sf = create_sfile(hash, trans, ki); - list_add(&sf->hash, &hashes[hash]); - -lru: - sfile_put(sf); - return sf; -} - - -static void sfile_dup(struct sfile * to, struct sfile * from) -{ - size_t i; - - memcpy(to, from, sizeof (struct sfile)); - - for (i = 0 ; i < op_nr_counters ; ++i) - odb_init(&to->files[i]); - - for (i = 0; i < CG_HASH_SIZE; ++i) - list_init(&to->cg_hash[i]); - - list_init(&to->hash); - list_init(&to->lru); -} - - -static odb_t * get_file(struct transient const * trans, int is_cg) -{ - struct sfile * sf = trans->current; - struct sfile * last = trans->last; - struct cg_entry * cg; - struct list_head * pos; - unsigned long hash; - odb_t * file; - - if (trans->event >= op_nr_counters) { - fprintf(stderr, "%s: Invalid counter %lu\n", __FUNCTION__, - trans->event); - abort(); - } - - file = &sf->files[trans->event]; - - if (!is_cg) - goto open; - - hash = last->hashval & (CG_HASH_SIZE - 1); - - /* Need to look for the right 'to'. Since we're looking for - * 'last', we use its hash. - */ - list_for_each(pos, &sf->cg_hash[hash]) { - cg = list_entry(pos, struct cg_entry, hash); - if (sfile_equal(last, &cg->to)) { - file = &cg->to.files[trans->event]; - goto open; - } - } - - cg = xmalloc(sizeof(struct cg_entry)); - sfile_dup(&cg->to, last); - list_add(&cg->hash, &sf->cg_hash[hash]); - file = &cg->to.files[trans->event]; - -open: - if (!odb_open_count(file)) - opd_open_sample_file(file, last, sf, trans->event, is_cg); - - /* Error is logged by opd_open_sample_file */ - if (!odb_open_count(file)) - return NULL; - - return file; -} - - -static void verbose_print_sample(struct sfile * sf, vma_t pc, uint counter) -{ - char const * app = verbose_cookie(sf->app_cookie); - printf("0x%llx(%u): ", pc, counter); - if (sf->anon) { - printf("anon (tgid %u, 0x%llx-0x%llx), ", - (unsigned int)sf->anon->tgid, - sf->anon->start, sf->anon->end); - } else if (sf->kernel) { - printf("kern (name %s, 0x%llx-0x%llx), ", sf->kernel->name, - sf->kernel->start, sf->kernel->end); - } else { - printf("%s(%llx), ", verbose_cookie(sf->cookie), sf->cookie); - } - printf("app %s(%llx)", app, sf->app_cookie); -} - - -static void verbose_sample(struct transient const * trans, vma_t pc) -{ - printf("Sample "); - verbose_print_sample(trans->current, pc, trans->event); - printf("\n"); -} - - -static void -verbose_arc(struct transient const * trans, vma_t from, vma_t to) -{ - printf("Arc "); - verbose_print_sample(trans->current, from, trans->event); - printf(" -> 0x%llx", to); - printf("\n"); -} - - -static void sfile_log_arc(struct transient const * trans) -{ - int err; - vma_t from = trans->pc; - vma_t to = trans->last_pc; - uint64_t key; - odb_t * file; - - file = get_file(trans, 1); - - /* absolute value -> offset */ - if (trans->current->kernel) - from -= trans->current->kernel->start; - - if (trans->last->kernel) - to -= trans->last->kernel->start; - - if (trans->current->anon) - from -= trans->current->anon->start; - - if (trans->last->anon) - to -= trans->last->anon->start; - - if (varcs) - verbose_arc(trans, from, to); - - if (!file) { - opd_stats[OPD_LOST_SAMPLEFILE]++; - return; - } - - /* Possible narrowings to 32-bit value only. */ - key = to & (0xffffffff); - key |= ((uint64_t)from) << 32; - - err = odb_update_node(file, key); - if (err) { - fprintf(stderr, "%s: %s\n", __FUNCTION__, strerror(err)); - abort(); - } -} - - -void sfile_log_sample(struct transient const * trans) -{ - int err; - vma_t pc = trans->pc; - odb_t * file; - - if (trans->tracing == TRACING_ON) { - /* can happen if kernel sample falls through the cracks, - * see opd_put_sample() */ - if (trans->last) - sfile_log_arc(trans); - return; - } - - file = get_file(trans, 0); - - /* absolute value -> offset */ - if (trans->current->kernel) - pc -= trans->current->kernel->start; - - if (trans->current->anon) - pc -= trans->current->anon->start; - - if (vsamples) - verbose_sample(trans, pc); - - if (!file) { - opd_stats[OPD_LOST_SAMPLEFILE]++; - return; - } - - err = odb_update_node(file, (uint64_t)pc); - if (err) { - fprintf(stderr, "%s: %s\n", __FUNCTION__, strerror(err)); - abort(); - } -} - - -static int close_sfile(struct sfile * sf, void * data __attribute__((unused))) -{ - size_t i; - - /* it's OK to close a non-open odb file */ - for (i = 0; i < op_nr_counters; ++i) - odb_close(&sf->files[i]); - - return 0; -} - - -static void kill_sfile(struct sfile * sf) -{ - close_sfile(sf, NULL); - list_del(&sf->hash); - list_del(&sf->lru); -} - - -static int sync_sfile(struct sfile * sf, void * data __attribute__((unused))) -{ - size_t i; - - for (i = 0; i < op_nr_counters; ++i) - odb_sync(&sf->files[i]); - - return 0; -} - - -static int is_sfile_kernel(struct sfile * sf, void * data __attribute__((unused))) -{ - return !!sf->kernel; -} - - -static int is_sfile_anon(struct sfile * sf, void * data) -{ - return sf->anon == data; -} - - -typedef int (*sfile_func)(struct sfile *, void *); - -static void -for_one_sfile(struct sfile * sf, sfile_func func, void * data) -{ - size_t i; - int free_sf = func(sf, data); - - for (i = 0; i < CG_HASH_SIZE; ++i) { - struct list_head * pos; - struct list_head * pos2; - list_for_each_safe(pos, pos2, &sf->cg_hash[i]) { - struct cg_entry * cg = - list_entry(pos, struct cg_entry, hash); - if (free_sf || func(&cg->to, data)) { - kill_sfile(&cg->to); - list_del(&cg->hash); - free(cg); - } - } - } - - if (free_sf) { - kill_sfile(sf); - free(sf); - } -} - - -static void for_each_sfile(sfile_func func, void * data) -{ - struct list_head * pos; - struct list_head * pos2; - - list_for_each_safe(pos, pos2, &lru_list) { - struct sfile * sf = list_entry(pos, struct sfile, lru); - for_one_sfile(sf, func, data); - } -} - - -void sfile_clear_kernel(void) -{ - for_each_sfile(is_sfile_kernel, NULL); -} - - -void sfile_clear_anon(struct anon_mapping * anon) -{ - for_each_sfile(is_sfile_anon, anon); -} - - -void sfile_sync_files(void) -{ - for_each_sfile(sync_sfile, NULL); -} - - -void sfile_close_files(void) -{ - for_each_sfile(close_sfile, NULL); -} - - -static int always_true(void) -{ - return 1; -} - - -#define LRU_AMOUNT 256 - -/* - * Clear out older sfiles. Note the current sfiles we're using - * will not be present in this list, due to sfile_get/put() pairs - * around the caller of this. - */ -int sfile_lru_clear(void) -{ - struct list_head * pos; - struct list_head * pos2; - int amount = LRU_AMOUNT; - - if (list_empty(&lru_list)) - return 1; - - list_for_each_safe(pos, pos2, &lru_list) { - struct sfile * sf; - if (!--amount) - break; - sf = list_entry(pos, struct sfile, lru); - for_one_sfile(sf, (sfile_func)always_true, NULL); - } - - return 0; -} - - -void sfile_get(struct sfile * sf) -{ - if (sf) - list_del(&sf->lru); -} - - -void sfile_put(struct sfile * sf) -{ - if (sf) - list_add_tail(&sf->lru, &lru_list); -} - - -void sfile_init(void) -{ - size_t i = 0; - - for (; i < HASH_SIZE; ++i) - list_init(&hashes[i]); -} diff --git a/daemon/opd_sfile.h b/daemon/opd_sfile.h deleted file mode 100644 index 86d5025..0000000 --- a/daemon/opd_sfile.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file daemon/opd_sfile.h - * Management of sample files - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OPD_SFILE_H -#define OPD_SFILE_H - -#include "opd_cookie.h" - -#include "odb.h" -#include "op_hw_config.h" -#include "op_types.h" -#include "op_list.h" - -#include <sys/types.h> - -struct kernel_image; -struct transient; - -#define CG_HASH_SIZE 16 -#define UNUSED_EMBEDDED_OFFSET ~0LLU - -/** - * Each set of sample files (where a set is over the physical counter - * types) will have one of these for it. We match against the - * descriptions here to find which sample DB file we need to modify. - * - * cg files are stored in the hash. - */ -struct sfile { - /** hash value for this sfile */ - unsigned long hashval; - /** cookie value for the binary profiled */ - cookie_t cookie; - /** cookie value for the application owner, INVALID_COOKIE if not set */ - cookie_t app_cookie; - /** thread ID, -1 if not set */ - pid_t tid; - /** thread group ID, -1 if not set */ - pid_t tgid; - /** CPU number */ - unsigned int cpu; - /** kernel image if applicable */ - struct kernel_image * kernel; - /** anonymous mapping */ - struct anon_mapping * anon; - /** embedded offset for Cell BE SPU */ - uint64_t embedded_offset; - - /** hash table link */ - struct list_head hash; - /** lru list */ - struct list_head lru; - /** true if this file should be ignored in profiles */ - int ignored; - /** opened sample files */ - odb_t files[OP_MAX_COUNTERS]; - /** hash table of opened cg sample files */ - struct list_head cg_hash[CG_HASH_SIZE]; -}; - -/** a call-graph entry */ -struct cg_entry { - /** where arc is to */ - struct sfile to; - /** next in the hash slot */ - struct list_head hash; -}; - -/** clear any sfiles that are for the kernel */ -void sfile_clear_kernel(void); - -struct anon_mapping; - -/** clear any sfiles for the given anon mapping */ -void sfile_clear_anon(struct anon_mapping *); - -/** sync sample files */ -void sfile_sync_files(void); - -/** close sample files */ -void sfile_close_files(void); - -/** clear out a certain amount of LRU entries - * return non-zero if the lru is already empty */ -int sfile_lru_clear(void); - -/** remove a sfile from the lru list, protecting it from sfile_lru_clear() */ -void sfile_get(struct sfile * sf); - -/** add this sfile to lru list */ -void sfile_put(struct sfile * sf); - -/** - * Find the sfile for the current parameters. Note that is required - * that the PC value be set appropriately (needed for kernel images) - */ -struct sfile * sfile_find(struct transient const * trans); - -/** Log the sample in a previously located sfile. */ -void sfile_log_sample(struct transient const * trans); - -/** initialise hashes */ -void sfile_init(void); - -#endif /* OPD_SFILE_H */ diff --git a/daemon/opd_spu.c b/daemon/opd_spu.c deleted file mode 100644 index 62a2c2b..0000000 --- a/daemon/opd_spu.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file daemon/opd_spu.c - * Processing the sample buffer for Cell BE SPU profile - * - * @remark Copyright 2007 OProfile authors - * @remark Read the file COPYING - * - * @author Maynard Johnson - * (C) Copyright IBM Corporation 2007 - */ - -#include "opd_interface.h" -#include "opd_printf.h" -#include "opd_sfile.h" -#include "opd_stats.h" -#include "opd_trans.h" -#include "op_libiberty.h" - -#include <stdlib.h> -#include <stdio.h> - -struct spu_context_info { - pid_t tid; - pid_t tgid; - cookie_t app_cookie; - uint64_t embedded_offset; - cookie_t spu_cookie; -}; - -static struct spu_context_info * spu_context_cache; - -/* Forward declaration */ -static void process_spu_samples(struct transient * trans); - -void (*special_processor)(struct transient *); - -/* - * This function is called when the first value found in the - * buffer (after the beginning ESCAPE_CODE) is SPU_PROFILING_CODE. - * Once we get here, the rest of the processing of the buffer is - * Cell-SPU-specific, so we do not need to return until the - * trans.buffer is empty. - */ -void code_spu_profiling(struct transient * trans) -{ - /* Next value in buffer is the number of SPUs. */ - unsigned long long num_spus = pop_buffer_value(trans); - /* Free the cache from previous run */ - free(spu_context_cache); - spu_context_cache = xmalloc(sizeof(struct spu_context_info) * num_spus); - special_processor = process_spu_samples; - process_spu_samples(trans); -} - -void code_spu_ctx_switch(struct transient * trans) -{ - clear_trans_current(trans); - - if (!enough_remaining(trans, 6)) { - trans->remaining = 0; - return; - } - - /* First value in the buffer for an SPU context switch is - * the SPU number. For SPU profiling, 'cpu' = 'spu'. - */ - trans->cpu = pop_buffer_value(trans); - trans->tid = pop_buffer_value(trans); - trans->tgid = pop_buffer_value(trans); - trans->app_cookie = pop_buffer_value(trans); - - if (vmisc) { - char const * app = find_cookie(trans->app_cookie); - printf("SPU_CTX_SWITCH to tid %lu, tgid %lu, cookie %llx(%s)\n", - (unsigned long)trans->tid, (unsigned long)trans->tgid, - trans->app_cookie, app ? app : "none"); - } - - /* The trans->cookie will point to the binary file where the SPU ELF - * can be found. If the SPU ELF is embedded, it may be embedded in - * either the executable application binary or a shared lib. If shared - * library, then trans->cookie will differ from the previously obtained - * trans->app_cookie. For the non-embedded case, trans->cookie always - * points to a separate binary file. - */ - trans->cookie = pop_buffer_value(trans); - trans->embedded_offset = pop_buffer_value(trans); -} - - -static void cache_spu_context_info(struct transient * trans) -{ - int i = trans->cpu; - spu_context_cache[i].tid = trans->tid; - spu_context_cache[i].tgid = trans->tgid; - spu_context_cache[i].app_cookie = trans->app_cookie; - spu_context_cache[i].embedded_offset = trans->embedded_offset; - spu_context_cache[i].spu_cookie = trans->cookie; -} - -static void update_trans_for_spu(struct transient * trans) -{ - int i = trans->cpu; - trans->tid = spu_context_cache[i].tid; - trans->tgid = spu_context_cache[i].tgid; - trans->app_cookie = spu_context_cache[i].app_cookie; - trans->embedded_offset = spu_context_cache[i].embedded_offset; - trans->cookie = spu_context_cache[i].spu_cookie; -} -#define SPU_NUM_MASK 0xFFFFFFFF00000000ULL -#define SPU_CYCLES_COUNTER 0 - -static void opd_put_spu_sample -(struct transient * trans, unsigned long long pc) -{ - unsigned long spu_number = (pc & SPU_NUM_MASK) >> 32; - if (trans->cpu != spu_number) { - trans->cpu = spu_number; - clear_trans_current(trans); - update_trans_for_spu(trans); - } - /* get the current sfile if needed */ - if (!trans->current) - trans->current = sfile_find(trans); - - if (trans->tracing != TRACING_ON) - trans->event = SPU_CYCLES_COUNTER; - - trans->pc = (pc & ~SPU_NUM_MASK); - /* log the sample or arc */ - sfile_log_sample(trans); - - /* switch to trace mode */ - if (trans->tracing == TRACING_START) - trans->tracing = TRACING_ON; - - update_trans_last(trans); -} - -/* - * This function processes SPU context switches and - * SPU program counter samples. After processing a - * context switch (via handlers[code)), we cache the - * SPU context information that has been temporarily - * stored in trans. - */ -static void process_spu_samples(struct transient * trans) -{ - unsigned long long code; - trans->in_kernel = 0; - while (trans->remaining) { - code = pop_buffer_value(trans); - - if (!is_escape_code(code)) { - opd_put_spu_sample(trans, code); - continue; - } - - if (!trans->remaining) { - verbprintf(vmisc, "Dangling ESCAPE_CODE.\n"); - opd_stats[OPD_DANGLING_CODE]++; - break; - } - - /* started with ESCAPE_CODE, next is type */ - code = pop_buffer_value(trans); - - if (code >= LAST_CODE) { - fprintf(stderr, "Unknown code %llu\n", code); - abort(); - } - - handlers[code](trans); - cache_spu_context_info(trans); - } -} diff --git a/daemon/opd_stats.c b/daemon/opd_stats.c deleted file mode 100644 index ddb1940..0000000 --- a/daemon/opd_stats.c +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file daemon/opd_stats.c - * Management of daemon statistics - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "opd_stats.h" -#include "oprofiled.h" - -#include "op_get_time.h" - -#include <dirent.h> -#include <stdlib.h> -#include <stdio.h> - -unsigned long opd_stats[OPD_MAX_STATS]; - -/** - * print_if - print an integer value read from file filename, - * do nothing if the value read == -1 except if force is non-zero - */ -static void print_if(char const * fmt, char const * path, char const * filename, int force) -{ - int value = opd_read_fs_int(path, filename, 0); - if (value != -1 || force) - printf(fmt, value); -} - -/** - * opd_print_stats - print out latest statistics - */ -void opd_print_stats(void) -{ - DIR * dir; - struct dirent * dirent; - - printf("\n%s\n", op_get_time()); - printf("Nr. sample dumps: %lu\n", opd_stats[OPD_DUMP_COUNT]); - printf("Nr. non-backtrace samples: %lu\n", opd_stats[OPD_SAMPLES]); - printf("Nr. kernel samples: %lu\n", opd_stats[OPD_KERNEL]); - printf("Nr. lost samples (no kernel/user): %lu\n", opd_stats[OPD_NO_CTX]); - printf("Nr. lost kernel samples: %lu\n", opd_stats[OPD_LOST_KERNEL]); - printf("Nr. incomplete code structs: %lu\n", opd_stats[OPD_DANGLING_CODE]); - printf("Nr. samples lost due to sample file open failure: %lu\n", - opd_stats[OPD_LOST_SAMPLEFILE]); - printf("Nr. samples lost due to no permanent mapping: %lu\n", - opd_stats[OPD_LOST_NO_MAPPING]); - print_if("Nr. event lost due to buffer overflow: %u\n", - "/dev/oprofile/stats", "event_lost_overflow", 1); - print_if("Nr. samples lost due to no mapping: %u\n", - "/dev/oprofile/stats", "sample_lost_no_mapping", 1); - print_if("Nr. backtraces skipped due to no file mapping: %u\n", - "/dev/oprofile/stats", "bt_lost_no_mapping", 0); - print_if("Nr. samples lost due to no mm: %u\n", - "/dev/oprofile/stats", "sample_lost_no_mm", 1); - - if (!(dir = opendir("/dev/oprofile/stats/"))) - goto out; - while ((dirent = readdir(dir))) { - int cpu_nr; - char path[256]; - if (sscanf(dirent->d_name, "cpu%d", &cpu_nr) != 1) - continue; - snprintf(path, 256, "/dev/oprofile/stats/%s", dirent->d_name); - - print_if("Nr. samples lost cpu buffer overflow: %u\n", - path, "sample_lost_overflow", 1); - print_if("Nr. samples lost task exit: %u\n", - path, "sample_lost_task_exit", 0); - print_if("Nr. samples received: %u\n", - path, "sample_received", 1); - print_if("Nr. backtrace aborted: %u\n", - path, "backtrace_aborted", 0); - print_if("Nr. samples lost invalid pc: %u\n", - path, "sample_invalid_eip", 0); - } - closedir(dir); -out: - fflush(stdout); -} diff --git a/daemon/opd_stats.h b/daemon/opd_stats.h deleted file mode 100644 index 177b86a..0000000 --- a/daemon/opd_stats.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file daemon/opd_stats.h - * Management of daemon statistics - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OPD_STATS_H -#define OPD_STATS_H - -extern unsigned long opd_stats[]; - -enum { OPD_SAMPLES, /**< nr. samples */ - OPD_KERNEL, /**< nr. kernel samples */ - OPD_PROCESS, /**< nr. userspace samples */ - OPD_NO_CTX, /**< nr. samples lost due to not knowing if in the kernel or not */ - OPD_LOST_KERNEL, /**< nr. kernel samples lost */ - OPD_LOST_SAMPLEFILE, /**< nr samples for which sample file can't be opened */ - OPD_LOST_NO_MAPPING, /**< nr samples lost due to no mapping */ - OPD_DUMP_COUNT, /**< nr. of times buffer is read */ - OPD_DANGLING_CODE, /**< nr. partial code notifications (buffer overflow */ - OPD_MAX_STATS /**< end of stats */ -}; - -void opd_print_stats(void); - -#endif /* OPD_STATS_H */ diff --git a/daemon/opd_trans.c b/daemon/opd_trans.c deleted file mode 100644 index 871e6e6..0000000 --- a/daemon/opd_trans.c +++ /dev/null @@ -1,349 +0,0 @@ -/** - * @file daemon/opd_trans.c - * Processing the sample buffer - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - * - * Modified by Maynard Johnson <maynardj@us.ibm.com> - * These modifications are: - * (C) Copyright IBM Corporation 2007 - */ - -#include "opd_trans.h" -#include "opd_kernel.h" -#include "opd_sfile.h" -#include "opd_anon.h" -#include "opd_stats.h" -#include "opd_printf.h" -#include "opd_interface.h" - -#include <limits.h> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> - -extern size_t kernel_pointer_size; - - -void clear_trans_last(struct transient * trans) -{ - trans->last = NULL; - trans->last_anon = NULL; -} - - -void clear_trans_current(struct transient * trans) -{ - trans->current = NULL; - trans->anon = NULL; -} - - -uint64_t pop_buffer_value(struct transient * trans) -{ - uint64_t val; - - if (!trans->remaining) { - fprintf(stderr, "BUG: popping empty buffer !\n"); - abort(); - } - - if (kernel_pointer_size == 4) { - uint32_t const * lbuf = (void const *)trans->buffer; - val = *lbuf; - } else { - uint64_t const * lbuf = (void const *)trans->buffer; - val = *lbuf; - } - - trans->remaining--; - trans->buffer += kernel_pointer_size; - return val; -} - - -int enough_remaining(struct transient * trans, size_t size) -{ - if (trans->remaining >= size) - return 1; - - verbprintf(vmisc, "Dangling ESCAPE_CODE.\n"); - opd_stats[OPD_DANGLING_CODE]++; - return 0; -} - - -static void opd_put_sample(struct transient * trans, unsigned long long pc) -{ - unsigned long long event; - - if (!enough_remaining(trans, 1)) { - trans->remaining = 0; - return; - } - - event = pop_buffer_value(trans); - - if (trans->tracing != TRACING_ON) - trans->event = event; - - trans->pc = pc; - - /* sfile can change at each sample for kernel */ - if (trans->in_kernel != 0) - clear_trans_current(trans); - - if (!trans->in_kernel && trans->cookie == NO_COOKIE) - trans->anon = find_anon_mapping(trans); - - /* get the current sfile if needed */ - if (!trans->current) - trans->current = sfile_find(trans); - - /* - * can happen if kernel sample falls through the cracks, or if - * it's a sample from an anon region we couldn't find - */ - if (!trans->current) - goto out; - - /* FIXME: this logic is perhaps too harsh? */ - if (trans->current->ignored || (trans->last && trans->last->ignored)) - goto out; - - /* log the sample or arc */ - sfile_log_sample(trans); - -out: - /* switch to trace mode */ - if (trans->tracing == TRACING_START) - trans->tracing = TRACING_ON; - - update_trans_last(trans); -} - - -static void code_unknown(struct transient * trans __attribute__((unused))) -{ - fprintf(stderr, "Unknown code !\n"); - abort(); -} - - -static void code_ctx_switch(struct transient * trans) -{ - clear_trans_current(trans); - - if (!enough_remaining(trans, 5)) { - trans->remaining = 0; - return; - } - - trans->tid = pop_buffer_value(trans); - trans->app_cookie = pop_buffer_value(trans); - /* must be ESCAPE_CODE, CTX_TGID_CODE, tgid. Like this - * because tgid was added later in a compatible manner. - */ - pop_buffer_value(trans); - pop_buffer_value(trans); - trans->tgid = pop_buffer_value(trans); - - if (vmisc) { - char const * app = find_cookie(trans->app_cookie); - printf("CTX_SWITCH to tid %lu, tgid %lu, cookie %llx(%s)\n", - (unsigned long)trans->tid, (unsigned long)trans->tgid, - trans->app_cookie, app ? app : "none"); - } -} - - -static void code_cpu_switch(struct transient * trans) -{ - clear_trans_current(trans); - - if (!enough_remaining(trans, 1)) { - trans->remaining = 0; - return; - } - - trans->cpu = pop_buffer_value(trans); - verbprintf(vmisc, "CPU_SWITCH to %lu\n", trans->cpu); -} - - -static void code_cookie_switch(struct transient * trans) -{ - clear_trans_current(trans); - - if (!enough_remaining(trans, 1)) { - trans->remaining = 0; - return; - } - - trans->cookie = pop_buffer_value(trans); - - if (vmisc) { - char const * name = verbose_cookie(trans->cookie); - verbprintf(vmisc, "COOKIE_SWITCH to cookie %s(%llx)\n", - name, trans->cookie); - } -} - - -static void code_kernel_enter(struct transient * trans) -{ - verbprintf(vmisc, "KERNEL_ENTER_SWITCH to kernel\n"); - trans->in_kernel = 1; - clear_trans_current(trans); - /* subtlety: we must keep trans->cookie cached, - * even though it's meaningless for the kernel - - * we won't necessarily get a cookie switch on - * kernel exit. See comments in opd_sfile.c - */ -} - - -static void code_user_enter(struct transient * trans) -{ - verbprintf(vmisc, "USER_ENTER_SWITCH to user-space\n"); - trans->in_kernel = 0; - clear_trans_current(trans); - clear_trans_last(trans); -} - - -static void code_module_loaded(struct transient * trans __attribute__((unused))) -{ - verbprintf(vmodule, "MODULE_LOADED_CODE\n"); - opd_reread_module_info(); - clear_trans_current(trans); - clear_trans_last(trans); -} - - -/* - * This also implicitly signals the end of the previous - * trace, so we never explicitly set TRACING_OFF when - * processing a buffer. - */ -static void code_trace_begin(struct transient * trans) -{ - verbprintf(varcs, "TRACE_BEGIN\n"); - trans->tracing = TRACING_START; -} - -static void code_xen_enter(struct transient * trans) -{ - verbprintf(vmisc, "XEN_ENTER_SWITCH to xen\n"); - trans->in_kernel = 1; - trans->current = NULL; - /* subtlety: we must keep trans->cookie cached, even though it's - * meaningless for Xen - we won't necessarily get a cookie switch - * on Xen exit. See comments in opd_sfile.c. It seems that we can - * get away with in_kernel = 1 as long as we supply the correct - * Xen image, and its address range in startup find_kernel_image - * is modified to look in the Xen image also - */ -} - -extern void code_spu_profiling(struct transient * trans); -extern void code_spu_ctx_switch(struct transient * trans); - -handler_t handlers[LAST_CODE + 1] = { - &code_unknown, - &code_ctx_switch, - &code_cpu_switch, - &code_cookie_switch, - &code_kernel_enter, - &code_user_enter, - &code_module_loaded, - /* tgid handled differently */ - &code_unknown, - &code_trace_begin, - &code_unknown, - &code_xen_enter, -#if defined(__powerpc__) - &code_spu_profiling, - &code_spu_ctx_switch, -#endif - &code_unknown, -}; - -extern void (*special_processor)(struct transient *); - -void opd_process_samples(char const * buffer, size_t count) -{ - struct transient trans = { - .buffer = buffer, - .remaining = count, - .tracing = TRACING_OFF, - .current = NULL, - .last = NULL, - .cookie = INVALID_COOKIE, - .app_cookie = INVALID_COOKIE, - .anon = NULL, - .last_anon = NULL, - .pc = 0, - .last_pc = 0, - .event = 0, - .in_kernel = -1, - .cpu = -1, - .tid = -1, - .embedded_offset = UNUSED_EMBEDDED_OFFSET, - .tgid = -1 - }; - - /* FIXME: was uint64_t but it can't compile on alpha where uint64_t - * is an unsigned long and below the printf("..." %llu\n", code) - * generate a warning, this look like a stopper to use c98 types :/ - */ - unsigned long long code; - - if (special_processor) { - special_processor(&trans); - return; - } - - int i; - - for (i = 0; i < count && i < 200; i++) { - verbprintf(vmisc, "buffer[%d] is %x\n", i, buffer[i]); - } - - while (trans.remaining) { - code = pop_buffer_value(&trans); - - verbprintf(vmisc, "In opd_process_samples (code is %lld)\n", code); - - if (!is_escape_code(code)) { - opd_put_sample(&trans, code); - continue; - } - - if (!trans.remaining) { - verbprintf(vmisc, "Dangling ESCAPE_CODE.\n"); - opd_stats[OPD_DANGLING_CODE]++; - break; - } - - // started with ESCAPE_CODE, next is type - code = pop_buffer_value(&trans); - - verbprintf(vmisc, "next code is %lld\n", code); - if (code >= LAST_CODE) { - fprintf(stderr, "Unknown code %llu\n", code); - abort(); - } - - handlers[code](&trans); - } -} diff --git a/daemon/opd_trans.h b/daemon/opd_trans.h deleted file mode 100644 index ab4e816..0000000 --- a/daemon/opd_trans.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file daemon/opd_trans.h - * Processing the sample buffer - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * - * Modified by Maynard Johnson <maynardj@us.ibm.com> - * These modifications are: - * (C) Copyright IBM Corporation 2007 - */ - -#ifndef OPD_TRANS_H -#define OPD_TRANS_H - -#include "opd_cookie.h" -#include "op_types.h" - -#include <stdint.h> - -struct sfile; -struct anon_mapping; - -enum tracing_type { - TRACING_OFF, - TRACING_START, - TRACING_ON -}; - -/** - * Transient values used for parsing the event buffer. - * Note that these are reset for each buffer read, but - * that should be ok as in the kernel, cpu_buffer_reset() - * ensures that a correct context starts off the buffer. - */ -struct transient { - char const * buffer; - size_t remaining; - enum tracing_type tracing; - struct sfile * current; - struct sfile * last; - struct anon_mapping * anon; - struct anon_mapping * last_anon; - cookie_t cookie; - cookie_t app_cookie; - vma_t pc; - vma_t last_pc; - unsigned long event; - int in_kernel; - unsigned long cpu; - pid_t tid; - pid_t tgid; - uint64_t embedded_offset; -}; - -typedef void (*handler_t)(struct transient *); -extern handler_t handlers[]; - -uint64_t pop_buffer_value(struct transient * trans); -int enough_remaining(struct transient * trans, size_t size); -static inline void update_trans_last(struct transient * trans) -{ - trans->last = trans->current; - trans->last_anon = trans->anon; - trans->last_pc = trans->pc; -} - -extern size_t kernel_pointer_size; -static inline int is_escape_code(uint64_t code) -{ - return kernel_pointer_size == 4 ? code == ~0LU : code == ~0LLU; -} - -void opd_process_samples(char const * buffer, size_t count); - -/** used when we need to clear data that's been freed */ -void clear_trans_last(struct transient * trans); - -/** used when we need to clear data that's been freed */ -void clear_trans_current(struct transient * trans); - -#endif /* OPD_TRANS_H */ diff --git a/daemon/oprofiled.c b/daemon/oprofiled.c deleted file mode 100644 index ec2ea1b..0000000 --- a/daemon/oprofiled.c +++ /dev/null @@ -1,522 +0,0 @@ -/** - * @file daemon/oprofiled.c - * Initialisation and setup - * - * @remark Copyright 2002, 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#include "config.h" - -#include "oprofiled.h" -#include "opd_printf.h" -#include "opd_events.h" - -#include "op_config.h" -#include "op_version.h" -#include "op_hw_config.h" -#include "op_libiberty.h" -#include "op_file.h" -#include "op_abi.h" -#include "op_string.h" -#include "op_cpu_type.h" -#include "op_popt.h" -#include "op_lockfile.h" -#include "op_list.h" -#include "op_fileio.h" - -#include <sys/types.h> -#include <sys/resource.h> -#include <stdlib.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <assert.h> -#include <dirent.h> -#include <limits.h> - -sig_atomic_t signal_alarm; -sig_atomic_t signal_hup; -sig_atomic_t signal_term; -sig_atomic_t signal_child; -sig_atomic_t signal_usr1; -sig_atomic_t signal_usr2; - -uint op_nr_counters; -op_cpu cpu_type; -int vsfile; -int vsamples; -int varcs; -int vmodule; -int vmisc; -int separate_lib; -int separate_kernel; -int separate_thread; -int separate_cpu; -int no_vmlinux; -char * vmlinux; -char * kernel_range; -char * session_dir; -int no_xen; -char * xenimage; -char * xen_range; -static char * verbose; -static char * binary_name_filter; -static char * events; -static int showvers; -static struct oprofiled_ops * opd_ops; -extern struct oprofiled_ops opd_24_ops; -extern struct oprofiled_ops opd_26_ops; - -#define OPD_IMAGE_FILTER_HASH_SIZE 32 -static struct list_head images_filter[OPD_IMAGE_FILTER_HASH_SIZE]; - -static struct poptOption options[] = { - { "session-dir", 0, POPT_ARG_STRING, &session_dir, 0, "place sample database in dir instead of default location", "/var/lib/oprofile", }, - { "kernel-range", 'r', POPT_ARG_STRING, &kernel_range, 0, "Kernel VMA range", "start-end", }, - { "vmlinux", 'k', POPT_ARG_STRING, &vmlinux, 0, "vmlinux kernel image", "file", }, - { "no-vmlinux", 0, POPT_ARG_NONE, &no_vmlinux, 0, "vmlinux kernel image file not available", NULL, }, - { "xen-range", 0, POPT_ARG_STRING, &xen_range, 0, "Xen VMA range", "start-end", }, - { "xen-image", 0, POPT_ARG_STRING, &xenimage, 0, "Xen image", "file", }, - { "image", 0, POPT_ARG_STRING, &binary_name_filter, 0, "image name filter", "profile these comma separated image" }, - { "separate-lib", 0, POPT_ARG_INT, &separate_lib, 0, "separate library samples for each distinct application", "[0|1]", }, - { "separate-kernel", 0, POPT_ARG_INT, &separate_kernel, 0, "separate kernel samples for each distinct application", "[0|1]", }, - { "separate-thread", 0, POPT_ARG_INT, &separate_thread, 0, "thread-profiling mode", "[0|1]" }, - { "separate-cpu", 0, POPT_ARG_INT, &separate_cpu, 0, "separate samples for each CPU", "[0|1]" }, - { "events", 'e', POPT_ARG_STRING, &events, 0, "events list", "[events]" }, - { "version", 'v', POPT_ARG_NONE, &showvers, 0, "show version", NULL, }, - { "verbose", 'V', POPT_ARG_STRING, &verbose, 0, "be verbose in log file", "all,sfile,arcs,samples,module,misc", }, - POPT_AUTOHELP - { NULL, 0, 0, NULL, 0, NULL, NULL, }, -}; - - -void opd_open_logfile(void) -{ - if (open(op_log_file, O_WRONLY|O_CREAT|O_NOCTTY|O_APPEND, 0644) == -1) { - perror("oprofiled: couldn't re-open stdout: "); - exit(EXIT_FAILURE); - } - - if (dup2(1, 2) == -1) { - perror("oprofiled: couldn't dup stdout to stderr: "); - exit(EXIT_FAILURE); - } -} - - -/** - * opd_fork - fork and return as child - * - * fork() and exit the parent with _exit(). - * Failure is fatal. - */ -static void opd_fork(void) -{ - switch (fork()) { - case -1: - perror("oprofiled: fork() failed: "); - exit(EXIT_FAILURE); - break; - case 0: - break; - default: - /* parent */ - _exit(EXIT_SUCCESS); - break; - } -} - - -static void opd_go_daemon(void) -{ - opd_fork(); - - if (chdir(op_session_dir)) { - fprintf(stderr, "oprofiled: opd_go_daemon: couldn't chdir to %s: %s", - op_session_dir, strerror(errno)); - exit(EXIT_FAILURE); - } - - if (setsid() < 0) { - perror("oprofiled: opd_go_daemon: couldn't setsid: "); - exit(EXIT_FAILURE); - } - - opd_fork(); -} - - -static void opd_write_abi(void) -{ - char * cbuf; - - cbuf = xmalloc(strlen(op_session_dir) + 5); - strcpy(cbuf, op_session_dir); - strcat(cbuf, "/abi"); - op_write_abi_to_file(cbuf); - free(cbuf); -} - - -/** - * opd_alarm - sync files and report stats - */ -static void opd_alarm(int val __attribute__((unused))) -{ - signal_alarm = 1; -} - - -/* re-open logfile for logrotate */ -static void opd_sighup(int val __attribute__((unused))) -{ - signal_hup = 1; -} - - -static void opd_sigterm(int val __attribute__((unused))) -{ - signal_term = 1; -} - -static void opd_sigchild(int val __attribute__((unused))) -{ - signal_child = 1; -} - - -static void opd_sigusr1(int val __attribute__((unused))) -{ - signal_usr1 = 1; -} - - -static void opd_sigusr2(int val __attribute__((unused))) -{ - signal_usr2 = 1; -} - - -static void opd_setup_signals(void) -{ - struct sigaction act; - - act.sa_handler = opd_alarm; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - - if (sigaction(SIGALRM, &act, NULL)) { - perror("oprofiled: install of SIGALRM handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = opd_sighup; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGALRM); - - if (sigaction(SIGHUP, &act, NULL)) { - perror("oprofiled: install of SIGHUP handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = opd_sigterm; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGTERM); - - if (sigaction(SIGTERM, &act, NULL)) { - perror("oprofiled: install of SIGTERM handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = opd_sigchild; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGCHLD); - - if (sigaction(SIGCHLD, &act, NULL)) { - perror("oprofiled: install of SIGCHLD handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = opd_sigusr1; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGTERM); - - if (sigaction(SIGUSR1, &act, NULL)) { - perror("oprofiled: install of SIGUSR1 handler failed: "); - exit(EXIT_FAILURE); - } - - act.sa_handler = opd_sigusr2; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGTERM); - - if (sigaction(SIGUSR2, &act, NULL)) { - perror("oprofiled: install of SIGUSR2 handler failed: "); - exit(EXIT_FAILURE); - } -} - - -struct opd_hashed_name { - char * name; - struct list_head next; -}; - - -static void add_image_filter(char const * name) -{ - size_t hash; - struct opd_hashed_name * elt = xmalloc(sizeof(struct opd_hashed_name)); - elt->name = xmalloc(PATH_MAX); - if (!realpath(name, elt->name)) { - free(elt->name); - free(elt); - return; - } - hash = op_hash_string(elt->name); - verbprintf(vmisc, "Adding to image filter: \"%s\"\n", elt->name); - list_add(&elt->next, &images_filter[hash % OPD_IMAGE_FILTER_HASH_SIZE]); -} - - -static void opd_parse_image_filter(void) -{ - size_t i; - char const * last = binary_name_filter; - char const * cur = binary_name_filter; - - if (!binary_name_filter) - return; - - for (i = 0; i < OPD_IMAGE_FILTER_HASH_SIZE; ++i) - list_init(&images_filter[i]); - - while ((cur = strchr(last, ',')) != NULL) { - char * tmp = op_xstrndup(last, cur - last); - add_image_filter(tmp); - free(tmp); - last = cur + 1; - } - add_image_filter(last); -} - - -int is_image_ignored(char const * name) -{ - size_t hash; - struct list_head * pos; - - if (!binary_name_filter) - return 0; - - hash = op_hash_string(name); - - list_for_each(pos, &images_filter[hash % OPD_IMAGE_FILTER_HASH_SIZE]) { - struct opd_hashed_name * hashed_name = - list_entry(pos, struct opd_hashed_name, next); - if (!strcmp(hashed_name->name, name)) - return 0; - } - - return 1; -} - - -/** return the int in the given oprofilefs file */ -int opd_read_fs_int(char const * path, char const * name, int fatal) -{ - char filename[PATH_MAX + 1]; - snprintf(filename, PATH_MAX, "%s/%s", path, name); - return op_read_int_from_file(filename, fatal); -} - - -static void opd_handle_verbose_option(char const * name) -{ - if (!strcmp(name, "all")) { - vsfile = 1; - vsamples = 1; - varcs = 1; - vmodule = 1; - vmisc = 1; - } else if (!strcmp(name, "sfile")) { - vsfile = 1; - } else if (!strcmp(name, "arcs")) { - varcs = 1; - } else if (!strcmp(name, "samples")) { - vsamples = 1; - } else if (!strcmp(name, "module")) { - vmodule = 1; - } else if (!strcmp(name, "misc")) { - vmisc = 1; - } else { - fprintf(stderr, "unknown verbose options\n"); - exit(EXIT_FAILURE); - } -} - -static void opd_parse_verbose(void) -{ - char const * last = verbose; - char const * cur = verbose; - - if (!verbose) - return; - - while ((cur = strchr(last, ',')) != NULL) { - char * tmp = op_xstrndup(last, cur - last); - opd_handle_verbose_option(tmp); - free(tmp); - last = cur + 1; - } - opd_handle_verbose_option(last); -} - - -static void opd_options(int argc, char const * argv[]) -{ - poptContext optcon; - char * tmp; - - optcon = op_poptGetContext(NULL, argc, argv, options, 0); - - if (showvers) - show_version(argv[0]); - - opd_parse_verbose(); - - if (separate_kernel) - separate_lib = 1; - - cpu_type = op_get_cpu_type(); - op_nr_counters = op_get_nr_counters(cpu_type); - - if (!no_vmlinux) { - if (!vmlinux || !strcmp("", vmlinux)) { - fprintf(stderr, "oprofiled: no vmlinux specified.\n"); - poptPrintHelp(optcon, stderr, 0); - exit(EXIT_FAILURE); - } - - /* canonicalise vmlinux filename. fix #637805 */ - tmp = xmalloc(PATH_MAX); - if (realpath(vmlinux, tmp)) - vmlinux = tmp; - else - free(tmp); - - if (!kernel_range || !strcmp("", kernel_range)) { - fprintf(stderr, "oprofiled: no kernel VMA range specified.\n"); - poptPrintHelp(optcon, stderr, 0); - exit(EXIT_FAILURE); - } - } - - if (events == NULL) { - fprintf(stderr, "oprofiled: no events specified.\n"); - poptPrintHelp(optcon, stderr, 0); - exit(EXIT_FAILURE); - } - - if (!xenimage || !strcmp("", xenimage)) { - no_xen = 1; - } else { - no_xen = 0; - - /* canonicalise xen image filename. */ - tmp = xmalloc(PATH_MAX); - if (realpath(xenimage, tmp)) - xenimage = tmp; - else - free(tmp); - - if (!xen_range || !strcmp("", xen_range)) { - fprintf(stderr, "oprofiled: no Xen VMA range specified.\n"); - poptPrintHelp(optcon, stderr, 0); - exit(EXIT_FAILURE); - } - } - - opd_parse_events(events); - - opd_parse_image_filter(); - - poptFreeContext(optcon); -} - - -/* determine what kernel we're running and which daemon - * to use - */ -static struct oprofiled_ops * get_ops(void) -{ - switch (op_get_interface()) { -#ifndef ANDROID - case OP_INTERFACE_24: - printf("Using 2.4 OProfile kernel interface.\n"); - return &opd_24_ops; -#endif - case OP_INTERFACE_26: - printf("Using 2.6+ OProfile kernel interface.\n"); - return &opd_26_ops; - default: - break; - } - - fprintf(stderr, "Couldn't determine kernel version.\n"); - exit(EXIT_FAILURE); - return NULL; -} - - -int main(int argc, char const * argv[]) -{ - int err; - struct rlimit rlim = { 2048, 2048 }; - - opd_options(argc, argv); - init_op_config_dirs(session_dir); - - opd_setup_signals(); - - err = setrlimit(RLIMIT_NOFILE, &rlim); - if (err) - perror("warning: could not set RLIMIT_NOFILE to 2048: "); - - opd_write_abi(); - - opd_ops = get_ops(); - - opd_ops->init(); - - opd_go_daemon(); - - /* clean up every 10 minutes */ - alarm(60 * 10); - - if (op_write_lock_file(op_lock_file)) { - fprintf(stderr, "oprofiled: could not create lock file %s\n", - op_lock_file); - exit(EXIT_FAILURE); - } - - opd_ops->start(); - - opd_ops->exit(); - - return 0; -} diff --git a/daemon/oprofiled.h b/daemon/oprofiled.h deleted file mode 100644 index b319df1..0000000 --- a/daemon/oprofiled.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file daemon/oprofiled.h - * Initialisation and setup - * - * @remark Copyright 2002, 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#ifndef OPROFILED_H - -#include <signal.h> - -struct oprofiled_ops { - void (*init)(void); - void (*start)(void); - void (*exit)(void); -}; - - -/** - * opd_open_logfile - open the log file - * - * Open the logfile on stdout and stderr. This function - * assumes that 1 and 2 are the lowest close()d file - * descriptors. Failure to open on either descriptor is - * a fatal error. - */ -void opd_open_logfile(void); - - -/** - * is_image_ignored - check if we must ignore this image - * @param name the name to check - * - * Return true if the image should not be profiled - */ -int is_image_ignored(char const * name); - -/** return the int in the given oprofilefs file, error is fatal if !is_fatal */ -int opd_read_fs_int(char const * path, char const * name, int is_fatal); - - -/** global variable positioned by signal handler */ -extern sig_atomic_t signal_alarm; -extern sig_atomic_t signal_hup; -extern sig_atomic_t signal_term; -extern sig_atomic_t signal_child; -extern sig_atomic_t signal_usr1; -extern sig_atomic_t signal_usr2; - -extern unsigned int op_nr_counters; -extern int separate_lib; -extern int separate_kernel; -extern int separate_thread; -extern int separate_cpu; -extern int no_vmlinux; -extern char * vmlinux; -extern char * kernel_range; -extern int no_xen; -extern char * xenimage; -extern char * xen_range; - -#endif /* OPROFILED_H */ diff --git a/libabi/Android.mk b/libabi/Android.mk deleted file mode 100644 index 3213c1e..0000000 --- a/libabi/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= op_abi.c - -LOCAL_MODULE := libabi - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../libdb \ - $(LOCAL_PATH)/../libutil \ - $(LOCAL_PATH)/../libop - -include $(BUILD_STATIC_LIBRARY) diff --git a/libabi/abi.cpp b/libabi/abi.cpp deleted file mode 100644 index 04a6b2d..0000000 --- a/libabi/abi.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file abi.cpp - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - * @author John Levon - * @author Philippe Elie - */ - -#include "abi.h" -#include "op_abi.h" -#include "odb.h" -#include "op_sample_file.h" - -#include <iostream> -#include <cassert> - -using namespace std; - -typedef map<string, int> abi_map; -typedef abi_map::const_iterator abi_iter; - -abi_exception::abi_exception(string const d) : desc(d) {} - - -abi::abi() -{ - op_abi_entry const * entry = get_abi(); - for ( ; entry->name != 0; ++entry) - slots[entry->name] = entry->offset; - - slots["little_endian"] = op_little_endian(); -} - - -int abi::need(string const key) const throw (abi_exception) -{ - if (slots.find(key) != slots.end()) - return slots.find(key)->second; - else - throw abi_exception(string("missing ABI key: ") + key); -} - - -bool abi::operator==(abi const & other) const -{ - return slots == other.slots; -} - - -ostream & operator<<(ostream & o, abi const & abi) -{ - abi_iter i = abi.slots.begin(); - abi_iter e = abi.slots.end(); - - for (; i != e; ++i) - o << i->first << " " << i->second << endl; - - return o; -} - - -istream & operator>>(istream & i, abi & abi) -{ - string key; - int val; - abi.slots.clear(); - - while(i >> key >> val) - abi.slots[key] = val; - - return i; -} diff --git a/libabi/abi.h b/libabi/abi.h deleted file mode 100644 index 8b63e7f..0000000 --- a/libabi/abi.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file abi.h - * - * Contains internal ABI management class - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - */ - -#ifndef OPROF_ABI_H -#define OPROF_ABI_H - -#include <string> -#include <map> -#include <iosfwd> - -struct abi_exception : std::exception { - std::string const desc; - - explicit abi_exception(std::string const d); - - ~abi_exception() throw() {} -}; - - -class abi { -public: - abi(); - - int need(std::string const key) const throw (abi_exception); - - bool operator==(abi const & other) const; - friend std::ostream & operator<<(std::ostream & o, abi const & abi); - friend std::istream & operator>>(std::istream & i, abi & abi); - -private: - std::map<std::string, int> slots; -}; - -#endif // OPROF_ABI_H diff --git a/libabi/op_abi.c b/libabi/op_abi.c deleted file mode 100644 index 283e3ff..0000000 --- a/libabi/op_abi.c +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @file op_abi.c - * This file contains a simple C interface to the ABI-describing functionality, - * the majority of which is implemented in C++. This is the file which is - * intended for use in files outside the /libabi directory. - * - * @remark Copyright 2002, 2005 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - * @author Philippe Elie - */ - -#include "op_abi.h" -#include "odb.h" -#include "op_sample_file.h" - -#include <stdio.h> -#include <stddef.h> -#include <assert.h> - -static struct op_abi_entry const abi_entries[] = { - { "sizeof_double", sizeof(double) }, - { "sizeof_time_t", sizeof(time_t) }, - { "sizeof_u8", sizeof(u8) }, - { "sizeof_u32", sizeof(u32) }, - { "sizeof_int", sizeof(int) }, - { "sizeof_unsigned_int", sizeof(unsigned int) }, - { "sizeof_odb_key_t", sizeof(odb_key_t) }, - { "sizeof_odb_index_t", sizeof(odb_index_t) }, - { "sizeof_odb_value_t", sizeof(odb_value_t) }, - { "sizeof_odb_node_nr_t", sizeof(odb_node_nr_t) }, - { "sizeof_odb_descr_t", sizeof(odb_descr_t) }, - { "sizeof_odb_node_t", sizeof(odb_node_t) }, - { "sizeof_struct_opd_header", sizeof(struct opd_header) }, - - { "offsetof_node_key", offsetof(odb_node_t, key) }, - { "offsetof_node_value", offsetof(odb_node_t, value) }, - { "offsetof_node_next", offsetof(odb_node_t, next) }, - - { "offsetof_descr_size", offsetof(odb_descr_t, size) }, - { "offsetof_descr_current_size", offsetof(odb_descr_t, current_size) }, - - { "offsetof_header_magic", offsetof(struct opd_header, magic) }, - { "offsetof_header_version", offsetof(struct opd_header, version) }, - { "offsetof_header_cpu_type", offsetof(struct opd_header, cpu_type) }, - { "offsetof_header_ctr_event", offsetof(struct opd_header, ctr_event) }, - { "offsetof_header_ctr_um", offsetof(struct opd_header, ctr_um) }, - { "offsetof_header_ctr_count", offsetof(struct opd_header, ctr_count) }, - { "offsetof_header_is_kernel", offsetof(struct opd_header, is_kernel) }, - { "offsetof_header_cpu_speed", offsetof(struct opd_header, cpu_speed) }, - { "offsetof_header_mtime", offsetof(struct opd_header, mtime) }, - { "offsetof_header_cg_to_is_kernel", offsetof(struct opd_header, cg_to_is_kernel), }, - { "offsetof_header_anon_start", offsetof(struct opd_header, anon_start) }, - { "offsetof_header_cg_to_anon_start", offsetof(struct opd_header, cg_to_anon_start) }, - - { NULL, 0 }, -}; - - -struct op_abi_entry const * get_abi(void) -{ - return abi_entries; -} - - -int op_little_endian(void) -{ - unsigned int probe = 0xff; - size_t sz = sizeof(unsigned int); - unsigned char * probe_byte = (unsigned char *)&probe; - - assert(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff); - - return probe_byte[0] == 0xff; -} - - -int op_write_abi_to_file(char const * abi_file) -{ - FILE * fp; - struct op_abi_entry const * abi_entry; - - if ((fp = fopen(abi_file, "w")) == NULL) - return 0; - - for (abi_entry = get_abi() ; abi_entry->name != NULL; ++abi_entry) - fprintf(fp, "%s %u\n", abi_entry->name, abi_entry->offset); - fprintf(fp, "little_endian %d\n", op_little_endian()); - - fclose(fp); - - return 1; -} diff --git a/libabi/op_abi.h b/libabi/op_abi.h deleted file mode 100644 index fbd337b..0000000 --- a/libabi/op_abi.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file op_abi.h - * This file contains a simple C interface to the ABI-describing functionality, - * the majority of which is implemented in C++. this is the file which is - * intended for use in files outside the /libabi directory. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - * @author Philippe Elie - */ - -#ifndef OP_ABI_H -#define OP_ABI_H - -struct op_abi_entry { - char const * name; - /// offset or size of the named entry - int offset; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/// return array is terminated by a NULL entry in name field -struct op_abi_entry const * get_abi(void); - -/// return non zero if the abi is little endian -int op_little_endian(void); - -/** - * Write current abi to file. - * return 1 on success, 0 on failure - */ -int op_write_abi_to_file(char const * abi_file); - -#ifdef __cplusplus -} -#endif - -#endif // OP_ABI_H diff --git a/libabi/opimport.cpp b/libabi/opimport.cpp deleted file mode 100644 index 57f74a7..0000000 --- a/libabi/opimport.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file opimport.cpp - * Import sample files from other ABI - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - */ - -#include "abi.h" -#include "odb.h" -#include "popt_options.h" -#include "op_sample_file.h" - -#include <fstream> -#include <iostream> -#include <vector> -#include <cassert> -#include <cstring> -#include <cstdlib> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> -#include <cstdlib> -#include <cstring> - -using namespace std; - -namespace { - string output_filename; - string abi_filename; - bool verbose; - bool force; -}; - - -popt::option options_array[] = { - popt::option(verbose, "verbose", 'V', "verbose output"), - popt::option(output_filename, "output", 'o', "output to file", "filename"), - popt::option(abi_filename, "abi", 'a', "abi description", "filename"), - popt::option(force, "force", 'f', "force conversion, even if identical") -}; - - -struct extractor { - - abi const & theabi; - - unsigned char const * begin; - unsigned char const * end; - bool little_endian; - - explicit - extractor(abi const & a, unsigned char const * src, size_t len) - : theabi(a), begin(src), end(src + len) { - little_endian = theabi.need(string("little_endian")) == 1; - if (verbose) { - cerr << "source byte order is: " - << string(little_endian ? "little" : "big") - << " endian" << endl; - } - } - - template <typename T> - void extract(T & targ, void const * src_, - char const * sz, char const * off); -}; - - -template <typename T> -void extractor::extract(T & targ, void const * src_, - char const * sz, char const * off) -{ - unsigned char const * src = static_cast<unsigned char const *>(src_) - + theabi.need(off); - size_t nbytes = theabi.need(sz); - - if (nbytes == 0) - return; - - assert(nbytes <= sizeof(T)); - assert(src >= begin); - assert(src + nbytes <= end); - - if (verbose) - cerr << hex << "get " << sz << " = " << nbytes - << " bytes @ " << off << " = " << (src - begin) - << " : "; - - targ = 0; - if (little_endian) - while(nbytes--) - targ = (targ << 8) | src[nbytes]; - else - for(size_t i = 0; i < nbytes; ++i) - targ = (targ << 8) | src[i]; - - if (verbose) - cerr << " = " << targ << endl; -} - - -void import_from_abi(abi const & abi, void const * srcv, - size_t len, odb_t * dest) throw (abi_exception) -{ - struct opd_header * head = - static_cast<opd_header *>(odb_get_data(dest)); - unsigned char const * src = static_cast<unsigned char const *>(srcv); - unsigned char const * const begin = src; - extractor ext(abi, src, len); - - memcpy(head->magic, src + abi.need("offsetof_header_magic"), 4); - - // begin extracting opd header - ext.extract(head->version, src, "sizeof_u32", "offsetof_header_version"); - ext.extract(head->cpu_type, src, "sizeof_u32", "offsetof_header_cpu_type"); - ext.extract(head->ctr_event, src, "sizeof_u32", "offsetof_header_ctr_event"); - ext.extract(head->ctr_um, src, "sizeof_u32", "offsetof_header_ctr_um"); - ext.extract(head->ctr_count, src, "sizeof_u32", "offsetof_header_ctr_count"); - ext.extract(head->is_kernel, src, "sizeof_u32", "offsetof_header_is_kernel"); - // "double" extraction is unlikely to work - head->cpu_speed = 0.0; - ext.extract(head->mtime, src, "sizeof_time_t", "offsetof_header_mtime"); - ext.extract(head->cg_to_is_kernel, src, "sizeof_u32", - "offsetof_header_cg_to_is_kernel"); - ext.extract(head->anon_start, src, "sizeof_u32", - "offsetof_header_anon_start"); - ext.extract(head->cg_to_anon_start, src, "sizeof_u32", - "offsetof_header_cg_to_anon_start"); - src += abi.need("sizeof_struct_opd_header"); - // done extracting opd header - - // begin extracting necessary parts of descr - odb_node_nr_t node_nr; - ext.extract(node_nr, src, "sizeof_odb_node_nr_t", "offsetof_descr_current_size"); - src += abi.need("sizeof_odb_descr_t"); - // done extracting descr - - // skip node zero, it is reserved and contains nothing usefull - src += abi.need("sizeof_odb_node_t"); - - // begin extracting nodes - unsigned int step = abi.need("sizeof_odb_node_t"); - if (verbose) - cerr << "extracting " << node_nr << " nodes of " << step << " bytes each " << endl; - - assert(src + (node_nr * step) <= begin + len); - - for (odb_node_nr_t i = 1 ; i < node_nr ; ++i, src += step) { - odb_key_t key; - odb_value_t val; - ext.extract(key, src, "sizeof_odb_key_t", "offsetof_node_key"); - ext.extract(val, src, "sizeof_odb_value_t", "offsetof_node_value"); - int rc = odb_add_node(dest, key, val); - if (rc != EXIT_SUCCESS) { - cerr << strerror(rc) << endl; - exit(EXIT_FAILURE); - } - } - // done extracting nodes -} - - -int main(int argc, char const ** argv) -{ - - vector<string> inputs; - popt::parse_options(argc, argv, inputs); - - if (inputs.size() != 1) { - cerr << "error: must specify exactly 1 input file" << endl; - exit(1); - } - - abi current_abi, input_abi; - - { - ifstream abi_file(abi_filename.c_str()); - if (!abi_file) { - cerr << "error: cannot open abi file " - << abi_filename << endl; - exit(1); - } - abi_file >> input_abi; - } - - if (!force && current_abi == input_abi) { - cerr << "input abi is identical to native. " - << "no conversion necessary." << endl; - exit(1); - } - - int in_fd; - struct stat statb; - void * in; - odb_t dest; - int rc; - - assert((in_fd = open(inputs[0].c_str(), O_RDONLY)) > 0); - assert(fstat(in_fd, &statb) == 0); - assert((in = mmap(0, statb.st_size, PROT_READ, - MAP_PRIVATE, in_fd, 0)) != (void *)-1); - - rc = odb_open(&dest, output_filename.c_str(), ODB_RDWR, - sizeof(struct opd_header)); - if (rc) { - cerr << "odb_open() fail:\n" - << strerror(rc) << endl; - exit(EXIT_FAILURE); - } - - try { - import_from_abi(input_abi, in, statb.st_size, &dest); - } catch (abi_exception & e) { - cerr << "caught abi exception: " << e.desc << endl; - } - - odb_close(&dest); - - assert(munmap(in, statb.st_size) == 0); -} diff --git a/libdb/Android.mk b/libdb/Android.mk deleted file mode 100644 index 1594fe8..0000000 --- a/libdb/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - db_debug.c \ - db_insert.c \ - db_manage.c \ - db_stat.c \ - db_travel.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../libutil - -LOCAL_MODULE := libdb - -include $(BUILD_STATIC_LIBRARY) diff --git a/libdb/db_debug.c b/libdb/db_debug.c deleted file mode 100644 index 0575570..0000000 --- a/libdb/db_debug.c +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file db_debug.c - * Debug routines for libdb - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "odb.h" - -static int check_circular_list(odb_data_t const * data) -{ - odb_node_nr_t pos; - int do_abort = 0; - unsigned char * bitmap = malloc(data->descr->current_size); - memset(bitmap, '\0', data->descr->current_size); - - for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) { - - odb_index_t index = data->hash_base[pos]; - if (index && !do_abort) { - while (index) { - if (bitmap[index]) - do_abort = 1; - - bitmap[index] = 1; - index = data->node_base[index].next; - } - } - - if (do_abort) { - printf("circular list detected size: %d\n", - data->descr->current_size); - - memset(bitmap, '\0', data->descr->current_size); - - index = data->hash_base[pos]; - while (index) { - printf("%d ", index); - if (bitmap[index]) - exit(1); - - bitmap[index] = 1; - index = data->node_base[index].next; - } - } - - /* purely an optimization: intead of memset the map reset only - * the needed part: not my use to optimize test but here the - * test was so slow it was useless */ - index = data->hash_base[pos]; - while (index) { - bitmap[index] = 1; - index = data->node_base[index].next; - } - } - - free(bitmap); - - return do_abort; -} - -static int check_redundant_key(odb_data_t const * data, odb_key_t max) -{ - odb_node_nr_t pos; - - unsigned char * bitmap = malloc(max + 1); - memset(bitmap, '\0', max + 1); - - for (pos = 1 ; pos < data->descr->current_size ; ++pos) { - if (bitmap[data->node_base[pos].key]) { - printf("redundant key found %lld\n", - (unsigned long long)data->node_base[pos].key); - return 1; - } - bitmap[data->node_base[pos].key] = 1; - } - free(bitmap); - - return 0; -} - -int odb_check_hash(odb_t const * odb) -{ - odb_node_nr_t pos; - odb_node_nr_t nr_node = 0; - odb_node_nr_t nr_node_out_of_bound = 0; - int ret = 0; - odb_key_t max = 0; - odb_data_t * data = odb->data; - - for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) { - odb_index_t index = data->hash_base[pos]; - while (index) { - if (index >= data->descr->current_size) { - nr_node_out_of_bound++; - break; - } - ++nr_node; - - if (data->node_base[index].key > max) - max = data->node_base[index].key; - - index = data->node_base[index].next; - } - } - - if (nr_node != data->descr->current_size - 1) { - printf("hash table walk found %d node expect %d node\n", - nr_node, data->descr->current_size - 1); - ret = 1; - } - - if (nr_node_out_of_bound) { - printf("out of bound node index: %d\n", nr_node_out_of_bound); - ret = 1; - } - - if (ret == 0) - ret = check_circular_list(data); - - if (ret == 0) - ret = check_redundant_key(data, max); - - return ret; -} diff --git a/libdb/db_insert.c b/libdb/db_insert.c deleted file mode 100644 index 018c294..0000000 --- a/libdb/db_insert.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file db_insert.c - * Inserting a key-value pair into a DB - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "odb.h" - - -static inline int add_node(odb_data_t * data, odb_key_t key, odb_value_t value) -{ - odb_index_t new_node; - odb_node_t * node; - odb_index_t index; - - /* no locking is necessary: iteration interface retrieve data through - * the node_base array, we doesn't increase current_size now but it's - * done by odb_commit_reservation() so the new slot is visible only - * after the increment - */ - if (data->descr->current_size >= data->descr->size) { - if (odb_grow_hashtable(data)) - return EINVAL; - } - new_node = data->descr->current_size; - - node = &data->node_base[new_node]; - node->value = value; - node->key = key; - - index = odb_do_hash(data, key); - node->next = data->hash_base[index]; - data->hash_base[index] = new_node; - - /* FIXME: we need wrmb() here */ - odb_commit_reservation(data); - - return 0; -} - -int odb_update_node(odb_t * odb, odb_key_t key) -{ - odb_index_t index; - odb_node_t * node; - odb_data_t * data; - - data = odb->data; - index = data->hash_base[odb_do_hash(data, key)]; - while (index) { - node = &data->node_base[index]; - if (node->key == key) { - if (node->value + 1 != 0) { - node->value += 1; - } else { - /* post profile tools must handle overflow */ - /* FIXME: the tricky way will be just to add - * a goto to jump right before the return - * add_node(), in this way we no longer can - * overflow. It'll work because new node are - * linked at the start of the node list for - * this bucket so this loop will see first a - * non overflowed node if one exist. When we - * grow the hashtable the most recently - * allocated node for this key will be setup - * last, so again it'll be linked at start of - * the list. pp tools looke like ok with this - * change. - * - * This change doesn't involve any file format - * change but perhaps it's a bit hacky to do - * this w/o bumping the sample file format - * version. The drawback of this is the added - * node are additive not multiplicative. - * (multiplicative as if we add more bits to - * store a value) - */ - } - return 0; - } - - index = node->next; - } - - return add_node(data, key, 1); -} - - -int odb_add_node(odb_t * odb, odb_key_t key, odb_value_t value) -{ - return add_node(odb->data, key, value); -} diff --git a/libdb/db_manage.c b/libdb/db_manage.c deleted file mode 100644 index d8a6fcb..0000000 --- a/libdb/db_manage.c +++ /dev/null @@ -1,311 +0,0 @@ -/** - * @file db_manage.c - * Management of a DB file - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#define _GNU_SOURCE - -#include <stdlib.h> -#ifndef ANDROID -#include <sys/fcntl.h> -#else -#include <fcntl.h> -#endif -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> - -#include "odb.h" -#include "op_string.h" -#include "op_libiberty.h" - - -static __inline odb_descr_t * odb_to_descr(odb_data_t * data) -{ - return (odb_descr_t *)(((char*)data->base_memory) + data->sizeof_header); -} - - -static __inline odb_node_t * odb_to_node_base(odb_data_t * data) -{ - return (odb_node_t *)(((char *)data->base_memory) + data->offset_node); -} - - -static __inline odb_index_t * odb_to_hash_base(odb_data_t * data) -{ - return (odb_index_t *)(((char *)data->base_memory) + - data->offset_node + - (data->descr->size * sizeof(odb_node_t))); -} - - -/** - * return the number of bytes used by hash table, node table and header. - */ -static unsigned int tables_size(odb_data_t const * data, odb_node_nr_t node_nr) -{ - size_t size; - - size = node_nr * (sizeof(odb_index_t) * BUCKET_FACTOR); - size += node_nr * sizeof(odb_node_t); - size += data->offset_node; - - return size; -} - - -int odb_grow_hashtable(odb_data_t * data) -{ - unsigned int old_file_size; - unsigned int new_file_size; - unsigned int pos; - void * new_map; - - old_file_size = tables_size(data, data->descr->size); - new_file_size = tables_size(data, data->descr->size * 2); - - if (ftruncate(data->fd, new_file_size)) - return 1; - - new_map = mremap(data->base_memory, - old_file_size, new_file_size, MREMAP_MAYMOVE); - - if (new_map == MAP_FAILED) - return 1; - - data->base_memory = new_map; - data->descr = odb_to_descr(data); - data->descr->size *= 2; - data->node_base = odb_to_node_base(data); - data->hash_base = odb_to_hash_base(data); - data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; - - /* rebuild the hash table, node zero is never used. This works - * because layout of file is node table then hash table, - * sizeof(node) > sizeof(bucket) and when we grow table we - * double size ==> old hash table and new hash table can't - * overlap so on the new hash table is entirely in the new - * memory area (the grown part) and we know the new hash - * hash table is zeroed. That's why we don't need to zero init - * the new table */ - /* OK: the above is not exact - * if BUCKET_FACTOR < sizeof(bd_node_t) / sizeof(bd_node_nr_t) - * all things are fine and we don't need to init the hash - * table because in this case the new hash table is completely - * inside the new growed part. Avoiding to touch this memory is - * useful. - */ -#if 0 - for (pos = 0 ; pos < data->descr->size*BUCKET_FACTOR ; ++pos) - data->hash_base[pos] = 0; -#endif - - for (pos = 1; pos < data->descr->current_size; ++pos) { - odb_node_t * node = &data->node_base[pos]; - size_t index = odb_do_hash(data, node->key); - node->next = data->hash_base[index]; - data->hash_base[index] = pos; - } - - return 0; -} - - -void odb_init(odb_t * odb) -{ - odb->data = NULL; -} - - -/* the default number of page, calculated to fit in 4096 bytes */ -#define DEFAULT_NODE_NR(offset_node) 128 -#define FILES_HASH_SIZE 512 - -static struct list_head files_hash[FILES_HASH_SIZE]; - - -static void init_hash() -{ - size_t i; - for (i = 0; i < FILES_HASH_SIZE; ++i) - list_init(&files_hash[i]); -} - - -static odb_data_t * -find_samples_data(size_t hash, char const * filename) -{ - struct list_head * pos; - - /* FIXME: maybe an initial init routine ? */ - if (files_hash[0].next == NULL) { - init_hash(); - return NULL; - } - - list_for_each(pos, &files_hash[hash]) { - odb_data_t * entry = list_entry(pos, odb_data_t, list); - if (strcmp(entry->filename, filename) == 0) - return entry; - } - - return NULL; -} - - -int odb_open(odb_t * odb, char const * filename, enum odb_rw rw, - size_t sizeof_header) -{ - struct stat stat_buf; - odb_node_nr_t nr_node; - odb_data_t * data; - size_t hash; - int err = 0; - - int flags = (rw == ODB_RDWR) ? (O_CREAT | O_RDWR) : O_RDONLY; - int mmflags = (rw == ODB_RDWR) ? (PROT_READ | PROT_WRITE) : PROT_READ; - - hash = op_hash_string(filename) % FILES_HASH_SIZE; - data = find_samples_data(hash, filename); - if (data) { - odb->data = data; - data->ref_count++; - return 0; - } - - data = xmalloc(sizeof(odb_data_t)); - memset(data, '\0', sizeof(odb_data_t)); - list_init(&data->list); - data->offset_node = sizeof_header + sizeof(odb_descr_t); - data->sizeof_header = sizeof_header; - data->ref_count = 1; - data->filename = xstrdup(filename); - - data->fd = open(filename, flags, 0644); - if (data->fd < 0) { - err = errno; - goto out; - } - - if (fstat(data->fd, &stat_buf)) { - err = errno; - goto fail; - } - - if (stat_buf.st_size == 0) { - size_t file_size; - - if (rw == ODB_RDONLY) { - err = EIO; - goto fail; - } - - nr_node = DEFAULT_NODE_NR(data->offset_node); - - file_size = tables_size(data, nr_node); - if (ftruncate(data->fd, file_size)) { - err = errno; - goto fail; - } - } else { - /* Calculate nr node allowing a sanity check later */ - nr_node = (stat_buf.st_size - data->offset_node) / - ((sizeof(odb_index_t) * BUCKET_FACTOR) + sizeof(odb_node_t)); - } - - data->base_memory = mmap(0, tables_size(data, nr_node), mmflags, - MAP_SHARED, data->fd, 0); - - if (data->base_memory == MAP_FAILED) { - err = errno; - goto fail; - } - - data->descr = odb_to_descr(data); - - if (stat_buf.st_size == 0) { - data->descr->size = nr_node; - /* page zero is not used */ - data->descr->current_size = 1; - } else { - /* file already exist, sanity check nr node */ - if (nr_node != data->descr->size) { - err = EINVAL; - goto fail_unmap; - } - } - - data->hash_base = odb_to_hash_base(data); - data->node_base = odb_to_node_base(data); - data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; - - list_add(&data->list, &files_hash[hash]); - odb->data = data; -out: - return err; -fail_unmap: - munmap(data->base_memory, tables_size(data, nr_node)); -fail: - close(data->fd); - free(data->filename); - free(data); - odb->data = NULL; - goto out; -} - - -void odb_close(odb_t * odb) -{ - odb_data_t * data = odb->data; - - if (data) { - data->ref_count--; - if (data->ref_count == 0) { - size_t size = tables_size(data, data->descr->size); - list_del(&data->list); - munmap(data->base_memory, size); - if (data->fd >= 0) - close(data->fd); - free(data->filename); - free(data); - odb->data = NULL; - } - } -} - - -int odb_open_count(odb_t const * odb) -{ - if (!odb->data) - return 0; - return odb->data->ref_count; -} - - -void * odb_get_data(odb_t * odb) -{ - return odb->data->base_memory; -} - - -void odb_sync(odb_t const * odb) -{ - odb_data_t * data = odb->data; - size_t size; - - if (!data) - return; - - size = tables_size(data, data->descr->size); - msync(data->base_memory, size, MS_ASYNC); -} diff --git a/libdb/db_stat.c b/libdb/db_stat.c deleted file mode 100644 index 6d29e9a..0000000 --- a/libdb/db_stat.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file db_stat.c - * Statistics routines for libdb - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#include <stdlib.h> -#include <stdio.h> - -#include "odb.h" -#include "op_types.h" - -/// hold various statistics data for a db file -struct odb_hash_stat_t { - odb_node_nr_t node_nr; /**< allocated node number */ - odb_node_nr_t used_node_nr; /**< in use node number */ - count_type total_count; /**< cumulated samples count */ - odb_index_t hash_table_size; /**< hash table entry number */ - odb_node_nr_t max_list_length; /**< worst case */ - double average_list_length; /**< average case */ - /* do we need variance ? */ -}; - -odb_hash_stat_t * odb_hash_stat(odb_t const * odb) -{ - size_t max_length = 0; - double total_length = 0.0; - size_t nr_non_empty_list = 0; - size_t pos; - odb_data_t * data = odb->data; - - odb_hash_stat_t * result = calloc(1, sizeof(odb_hash_stat_t)); - if (!result) { - fprintf(stderr, "not enough memory\n"); - exit(EXIT_FAILURE); - } - - result->node_nr = data->descr->size; - result->used_node_nr = data->descr->current_size; - result->hash_table_size = data->descr->size * BUCKET_FACTOR; - - /* FIXME: I'm dubious if this do right statistics for hash table - * efficiency check */ - - for (pos = 0 ; pos < result->hash_table_size ; ++pos) { - size_t cur_length = 0; - size_t index = data->hash_base[pos]; - while (index) { - result->total_count += data->node_base[index].value; - index = data->node_base[index].next; - ++cur_length; - } - - if (cur_length > max_length) - max_length = cur_length; - - if (cur_length) { - total_length += cur_length; - ++nr_non_empty_list; - } - } - - result->max_list_length = max_length; - result->average_list_length = total_length / nr_non_empty_list; - - return result; -} - - -void odb_hash_display_stat(odb_hash_stat_t const * stat) -{ - printf("total node number: %d\n", stat->node_nr); - printf("total used node: %d\n", stat->used_node_nr); - printf("total count: %llu\n", stat->total_count); - printf("hash table size: %d\n", stat->hash_table_size); - printf("greater list length: %d\n", stat->max_list_length); - printf("average non empty list length: %2.4f\n", stat->average_list_length); -} - - -void odb_hash_free_stat(odb_hash_stat_t * stat) -{ - free(stat); -} diff --git a/libdb/db_travel.c b/libdb/db_travel.c deleted file mode 100644 index 3ed467b..0000000 --- a/libdb/db_travel.c +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file db_travel.c - * Inspection of a DB - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#include "odb.h" - -odb_node_t * odb_get_iterator(odb_t const * odb, odb_node_nr_t * nr) -{ - /* node zero is unused */ - *nr = odb->data->descr->current_size - 1; - return odb->data->node_base + 1; -} diff --git a/libdb/odb.h b/libdb/odb.h deleted file mode 100644 index c190b57..0000000 --- a/libdb/odb.h +++ /dev/null @@ -1,223 +0,0 @@ -/** - * @file odb.h - * This file contains various definitions and interface for management - * of in-memory, through mmaped file, growable hash table, that stores - * sample files. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#ifndef ODB_HASH_H -#define ODB_HASH_H - -#include <stddef.h> -#include <stdint.h> - -#include "op_list.h" - -/** the type of key. 64-bit because CG needs 32-bit pair {from,to} */ -typedef uint64_t odb_key_t; -/** the type of an information in the database */ -typedef unsigned int odb_value_t; -/** the type of index (node number), list are implemented through index */ -typedef unsigned int odb_index_t; -/** the type store node number */ -typedef odb_index_t odb_node_nr_t; -/** store the hash mask, hash table size are always power of two */ -typedef odb_index_t odb_hash_mask_t; - -/* there is (bucket factor * nr node) entry in hash table, this can seem - * excessive but hash coding eip don't give a good distributions and our - * goal is to get a O(1) amortized insert time. bucket factor must be a - * power of two. FIXME: see big comment in odb_hash_add_node, you must - * re-enable zeroing hash table if BUCKET_FACTOR > 2 (roughly exact, you - * want to read the comment in odb_hash_add_node() if you tune this define) - */ -#define BUCKET_FACTOR 1 - -/** a db hash node */ -typedef struct { - odb_key_t key; /**< eip */ - odb_value_t value; /**< samples count */ - odb_index_t next; /**< next entry for this bucket */ -} odb_node_t; - -/** the minimal information which must be stored in the file to reload - * properly the data base, following this header is the node array then - * the hash table (when growing we avoid to copy node array) - */ -typedef struct { - odb_node_nr_t size; /**< in node nr (power of two) */ - odb_node_nr_t current_size; /**< nr used node + 1, node 0 unused */ - int padding[6]; /**< for padding and future use */ -} odb_descr_t; - -/** a "database". this is an in memory only description. - * - * We allow to manage a database inside a mapped file with an "header" of - * unknown size so odb_open get a parameter to specify the size of this header. - * A typical use is: - * - * struct header { int etc; ... }; - * odb_open(&hash, filename, ODB_RW, sizeof(header)); - * so on this library have no dependency on the header type. - * - * the internal memory layout from base_memory is: - * the unknown header (sizeof_header) - * odb_descr_t - * the node array: (descr->size * sizeof(odb_node_t) entries - * the hash table: array of odb_index_t indexing the node array - * (descr->size * BUCKET_FACTOR) entries - */ -typedef struct odb_data { - odb_node_t * node_base; /**< base memory area of the page */ - odb_index_t * hash_base; /**< base memory of hash table */ - odb_descr_t * descr; /**< the current state of database */ - odb_hash_mask_t hash_mask; /**< == descr->size - 1 */ - unsigned int sizeof_header; /**< from base_memory to odb header */ - unsigned int offset_node; /**< from base_memory to node array */ - void * base_memory; /**< base memory of the maped memory */ - int fd; /**< mmaped memory file descriptor */ - char * filename; /**< full path name of sample file */ - int ref_count; /**< reference count */ - struct list_head list; /**< hash bucket list */ -} odb_data_t; - -typedef struct { - odb_data_t * data; -} odb_t; - -#ifdef __cplusplus -extern "C" { -#endif - -/* db_manage.c */ - -/** how to open the DB file */ -enum odb_rw { - ODB_RDONLY = 0, /**< open for read only */ - ODB_RDWR = 1 /**< open for read and/or write */ -}; - -/** - * odb_init - initialize a DB file - * @param odb the DB file to init - */ -void odb_init(odb_t * odb); - -/** - * odb_open - open a DB file - * @param odb the data base object to setup - * @param filename the filename where go the maped memory - * @param rw \enum ODB_RW if opening for writing, else \enum ODB_RDONLY - * @param sizeof_header size of the file header if any - * - * The sizeof_header parameter allows the data file to have a header - * at the start of the file which is skipped. - * odb_open() always preallocate a few number of pages. - * returns 0 on success, errno on failure - */ -int odb_open(odb_t * odb, char const * filename, - enum odb_rw rw, size_t sizeof_header); - -/** Close the given ODB file */ -void odb_close(odb_t * odb); - -/** return the number of times this sample file is open */ -int odb_open_count(odb_t const * odb); - -/** return the start of the mapped data */ -void * odb_get_data(odb_t * odb); - -/** issue a msync on the used size of the mmaped file */ -void odb_sync(odb_t const * odb); - -/** - * grow the hashtable in such way current_size is the index of the first free - * node. Take care all node pointer can be invalidated by this call. - * - * Node allocation is done in a two step way 1st) ensure a free node exist - * eventually, caller can setup it, 2nd) commit the node allocation with - * odb_commit_reservation(). - * This is done in this way to ensure node setup is visible from another - * process like pp tools in an atomic way. - * - * returns 0 on success, non zero on failure in this case this function do - * nothing and errno is set by the first libc call failure allowing to retry - * after cleanup some program resource. - */ -int odb_grow_hashtable(odb_data_t * data); -/** - * commit a previously successfull node reservation. This can't fail. - */ -static __inline void odb_commit_reservation(odb_data_t * data) -{ - ++data->descr->current_size; -} - -/** "immpossible" node number to indicate an error from odb_hash_add_node() */ -#define ODB_NODE_NR_INVALID ((odb_node_nr_t)-1) - -/* db_debug.c */ -/** check that the hash is well built */ -int odb_check_hash(odb_t const * odb); - -/* db_stat.c */ -typedef struct odb_hash_stat_t odb_hash_stat_t; -odb_hash_stat_t * odb_hash_stat(odb_t const * odb); -void odb_hash_display_stat(odb_hash_stat_t const * stats); -void odb_hash_free_stat(odb_hash_stat_t * stats); - -/* db_insert.c */ -/** update info at key by incrementing its associated value by one, - * if the key does not exist a new node is created and the value associated - * is set to one. - * - * returns EXIT_SUCCESS on success, EXIT_FAILURE on failure - */ -int odb_update_node(odb_t * odb, odb_key_t key); - -/** Add a new node w/o regarding if a node with the same key already exists - * - * returns EXIT_SUCCESS on success, EXIT_FAILURE on failure - */ -int odb_add_node(odb_t * odb, odb_key_t key, odb_value_t value); - -/* db_travel.c */ -/** - * return a base pointer to the node array and number of node in this array - * caller then will iterate through: - * - * odb_node_nr_t node_nr, pos; - * odb_node_t * node = odb_get_iterator(odb, &node_nr); - * for ( pos = 0 ; pos < node_nr ; ++pos) - * // do something - * - * note than caller does not need to filter nil key as it's a valid key, - * The returned range is all valid (i.e. should never contain zero value). - */ -odb_node_t * odb_get_iterator(odb_t const * odb, odb_node_nr_t * nr); - -static __inline unsigned int -odb_do_hash(odb_data_t const * data, odb_key_t value) -{ - /* FIXME: better hash for eip value, needs to instrument code - * and do a lot of tests ... */ - /* trying to combine high order bits his a no-op: inside a binary image - * high order bits don't vary a lot, hash table start with 7 bits mask - * so this hash coding use bits 0-7, 8-15. Hash table is stored in - * files avoiding to rebuilding them at profiling re-start so - * on changing do_hash() change the file format! - */ - uint32_t temp = (value >> 32) ^ value; - return ((temp << 0) ^ (temp >> 8)) & data->hash_mask; -} - -#ifdef __cplusplus -} -#endif - -#endif /* !ODB_H */ diff --git a/libop/Android.mk b/libop/Android.mk deleted file mode 100644 index 8fbd1e6..0000000 --- a/libop/Android.mk +++ /dev/null @@ -1,19 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - op_alloc_counter.c \ - op_config.c \ - op_cpu_type.c \ - op_events.c \ - op_get_interface.c \ - op_mangle.c \ - op_parse_event.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../libutil - -LOCAL_MODULE := libop - -include $(BUILD_STATIC_LIBRARY) diff --git a/libop/op_alloc_counter.c b/libop/op_alloc_counter.c deleted file mode 100644 index 353100a..0000000 --- a/libop/op_alloc_counter.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file op_alloc_counter.c - * hardware counter allocation - * - * You can have silliness here. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdlib.h> -#include <ctype.h> -#include <dirent.h> - -#include "op_events.h" -#include "op_libiberty.h" - - -typedef struct counter_arc_head { - /** the head of allowed counter for this event */ - struct list_head next; -} counter_arc_head; - - -typedef struct counter_arc { - /** counter nr */ - int counter; - /** the next counter allowed for this event */ - struct list_head next; -} counter_arc; - - -/** - * @param pev an array of event - * @param nr_events number of entry in pev - * - * build an array of counter list allowed for each events - * counter_arc_head[i] is the list of allowed counter for pev[i] events - * The returned pointer is an array of nr_events entry - */ -static counter_arc_head * -build_counter_arc(struct op_event const * pev[], int nr_events) -{ - counter_arc_head * ctr_arc; - int i; - - ctr_arc = xmalloc(nr_events * sizeof(*ctr_arc)); - - for (i = 0; i < nr_events; ++i) { - int j; - u32 mask = pev[i]->counter_mask; - - list_init(&ctr_arc[i].next); - for (j = 0; mask; ++j) { - if (mask & (1 << j)) { - counter_arc * arc = - xmalloc(sizeof(counter_arc)); - arc->counter = j; - /* we are looping by increasing counter number, - * allocation use a left to right tree walking - * so we add at end to ensure counter will - * be allocated by increasing number: it's not - * required but a bit less surprising when - * debugging code - */ - list_add_tail(&arc->next, &ctr_arc[i].next); - mask &= ~(1 << j); - } - } - } - - return ctr_arc; -} - - -/** - * @param ctr_arc the array to deallocate - * @param nr_events number of entry in array - * - * deallocate all previously allocated resource by build_counter_arc() - */ -static void delete_counter_arc(counter_arc_head * ctr_arc, int nr_events) -{ - int i; - for (i = 0; i < nr_events; ++i) { - struct list_head * pos, * pos2; - list_for_each_safe(pos, pos2, &ctr_arc[i].next) { - counter_arc * arc = list_entry(pos, counter_arc, next); - list_del(&arc->next); - free(arc); - } - } - free(ctr_arc); -} - - -/** - * @param ctr_arc tree description, ctr_arc[i] is the i-th level of tree. - * @param max_depth number of entry in array ctr_arc == depth of tree - * @param depth current level we are exploring - * @param allocated_mask current counter already allocated mask - * @param counter_map array of counter number mapping, returned results go - * here - * - * return non zero on succees, in this case counter_map is set to the counter - * mapping number. - * - * Solution is searched through a simple backtracking exploring recursively all - * possible solution until one is found, prunning is done in O(1) by tracking - * a bitmask of already allocated counter. Walking through node is done in - * preorder left to right. - * - * Possible improvment if neccessary: partition counters in class of counter, - * two counter belong to the same class if they allow exactly the same set of - * event. Now using a variant of the backtrack algo can works on class of - * counter rather on counter (this is not an improvment if each counter goes - * in it's own class) - */ -static int -allocate_counter(counter_arc_head const * ctr_arc, int max_depth, int depth, - u32 allocated_mask, size_t * counter_map) -{ - struct list_head * pos; - - if (depth == max_depth) - return 1; - - list_for_each(pos, &ctr_arc[depth].next) { - counter_arc const * arc = list_entry(pos, counter_arc, next); - - if (allocated_mask & (1 << arc->counter)) - continue; - - counter_map[depth] = arc->counter; - - if (allocate_counter(ctr_arc, max_depth, depth + 1, - allocated_mask | (1 << arc->counter), - counter_map)) - return 1; - } - - return 0; -} - -/* determine which directories are counter directories - */ -static int perfcounterdir(const struct dirent * entry) -{ - return (isdigit(entry->d_name[0])); -} - - -/** - * @param mask pointer where to place bit mask of unavailable counters - * - * return >= 0 number of counters that are available - * < 0 could not determine number of counters - * - */ -static int op_get_counter_mask(u32 * mask) -{ - struct dirent **counterlist; - int count, i; - /* assume nothing is available */ - u32 available=0; - - count = scandir("/dev/oprofile", &counterlist, perfcounterdir, alphasort); - if (count < 0) - /* unable to determine bit mask */ - return -1; - /* convert to bit map (0 where counter exists) */ - for (i=0; i<count; ++i) { - available |= 1 << atoi(counterlist[i]->d_name); - free(counterlist[i]); - } - *mask=~available; - free(counterlist); - return count; -} - -size_t * map_event_to_counter(struct op_event const * pev[], int nr_events, - op_cpu cpu_type) -{ - counter_arc_head * ctr_arc; - size_t * counter_map; - int nr_counters; - u32 unavailable_counters = 0; - - nr_counters = op_get_counter_mask(&unavailable_counters); - /* no counters then probably perfmon managing perfmon hw */ - if (nr_counters <= 0) { - nr_counters = op_get_nr_counters(cpu_type); - unavailable_counters = (~0) << nr_counters; - } - if (nr_counters < nr_events) - return 0; - - ctr_arc = build_counter_arc(pev, nr_events); - - counter_map = xmalloc(nr_counters * sizeof(size_t)); - - if (!allocate_counter(ctr_arc, nr_events, 0, unavailable_counters, - counter_map)) { - free(counter_map); - counter_map = 0; - } - - delete_counter_arc(ctr_arc, nr_events); - return counter_map; -} diff --git a/libop/op_alloc_counter.h b/libop/op_alloc_counter.h deleted file mode 100644 index 40b4ebf..0000000 --- a/libop/op_alloc_counter.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file op_alloc_counter.h - * hardware counter allocation - * - * You can have silliness here. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_ALLOC_COUNTER_H -#define OP_ALLOC_COUNTER_H - -#include <stddef.h> - -#include "op_cpu_type.h" - -struct op_event; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @param pev array of selected event we want to bind to counter - * @param nr_events size of pev array - * @param cpu_type cpu type - * - * Try to calculate a binding between passed event in pev and counter number. - * The binding is returned in a size_t * where returned ptr[i] is the counter - * number bound to pev[i] - */ -size_t * map_event_to_counter(struct op_event const * pev[], int nr_events, - op_cpu cpu_type); - -#ifdef __cplusplus -} -#endif - -#endif /* !OP_ALLOC_COUNTER_H */ diff --git a/libop/op_config.c b/libop/op_config.c deleted file mode 100644 index 837242b..0000000 --- a/libop/op_config.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file op_config.c - * Oprofile configuration parameters. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Nathan Tallent - * @Modifications Daniel Hansel - */ - -#include "op_config.h" -#include "op_config_24.h" - -#include <limits.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -/* paths in op_config.h */ -char op_session_dir[PATH_MAX]; -char op_samples_dir[PATH_MAX]; -char op_samples_current_dir[PATH_MAX]; -char op_lock_file[PATH_MAX]; -char op_log_file[PATH_MAX]; -char op_pipe_file[PATH_MAX]; -char op_dump_status[PATH_MAX]; - -/* paths in op_config_24.h */ -char op_device[PATH_MAX]; -char op_note_device[PATH_MAX]; -char op_hash_device[PATH_MAX]; - -void -init_op_config_dirs(char const * session_dir) -{ - int session_dir_len; - - assert(session_dir); - session_dir_len = strlen(session_dir); - - if (session_dir_len + strlen("/samples/oprofiled.log") > PATH_MAX) { - fprintf(stderr, "Session_dir string \"%s\" is too large.\n", - session_dir); - exit(EXIT_FAILURE); - } - - strcpy(op_session_dir, session_dir); - - strcpy(op_samples_dir, op_session_dir); - strcat(op_samples_dir, "/samples/"); - - strcpy(op_samples_current_dir, op_samples_dir); - strcat(op_samples_current_dir, "/current/"); - - strcpy(op_lock_file, op_session_dir); - strcat(op_lock_file, "/lock"); - - strcpy(op_pipe_file, op_session_dir); - strcat(op_pipe_file, "/opd_pipe"); - - strcpy(op_log_file, op_samples_dir); - strcat(op_log_file, "oprofiled.log"); - - strcpy(op_dump_status, op_session_dir); - strcat(op_dump_status, "/complete_dump"); - - strcpy(op_device, op_session_dir); - strcat(op_device, "/opdev"); - - strcpy(op_note_device, op_session_dir); - strcat(op_note_device, "/opnotedev"); - - strcpy(op_hash_device, op_session_dir); - strcat(op_hash_device, "/ophashmapdev"); -} diff --git a/libop/op_config.h b/libop/op_config.h deleted file mode 100644 index b384497..0000000 --- a/libop/op_config.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file op_config.h - * - * Parameters a user may want to change. See - * also op_config_24.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * @Modifications Daniel Hansel - */ - -#ifndef OP_CONFIG_H -#define OP_CONFIG_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * must be called to initialize the paths below. - * @param session_dir the non-NULL value of the base session directory - */ -void init_op_config_dirs(char const * session_dir); - -/* - * various paths, corresponding to opcontrol, that should be - * initialized by init_op_config_dirs() above. - */ -extern char op_session_dir[]; -extern char op_samples_dir[]; -extern char op_samples_current_dir[]; -extern char op_lock_file[]; -extern char op_log_file[]; -extern char op_pipe_file[]; -extern char op_dump_status[]; - -#define OP_DRIVER_BASE "/dev/oprofile" -#define OP_DATA_DIR "/data/oprofile" - -/* Global directory that stores debug files */ -#ifndef DEBUGDIR -#define DEBUGDIR "/usr/lib/debug" -#endif - -#define OPD_MAGIC "DAE\n" -#define OPD_VERSION 0x11 - -#define OP_MIN_CPU_BUF_SIZE 2048 -#define OP_MAX_CPU_BUF_SIZE 131072 - -#if defined(__cplusplus) -} -#endif - -#endif /* OP_CONFIG_H */ diff --git a/libop/op_config_24.h b/libop/op_config_24.h deleted file mode 100644 index 1786fae..0000000 --- a/libop/op_config_24.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file op_config_24.h - * - * Parameters a user may want to change - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_CONFIG_24_H -#define OP_CONFIG_24_H - -#define OP_MOUNT "/proc/sys/dev/oprofile/" - -extern char op_device[]; -extern char op_note_device[]; -extern char op_hash_device[]; - -/*@{\name module default/min/max settings */ - -/** 65536 * sizeof(op_sample) */ -#define OP_DEFAULT_BUF_SIZE 65536 -/** - * we don't try to wake-up daemon until it remains more than this free entry - * in eviction buffer - */ -#define OP_PRE_WATERMARK(buffer_size) \ - (((buffer_size) / 8) < OP_MIN_PRE_WATERMARK \ - ? OP_MIN_PRE_WATERMARK \ - : (buffer_size) / 8) -/** minimal buffer water mark before we try to wakeup daemon */ -#define OP_MIN_PRE_WATERMARK 8192 -/** maximum number of entry in samples eviction buffer */ -#define OP_MAX_BUF_SIZE 1048576 -/** minimum number of entry in samples eviction buffer */ -#define OP_MIN_BUF_SIZE (32768 + OP_PRE_WATERMARK(32768)) - -/** 16384 * sizeof(op_note) = 273680 bytes default */ -#define OP_DEFAULT_NOTE_SIZE 16384 -/** - * we don't try to wake-up daemon until it remains more than this free entry - * in note buffer - */ -#define OP_PRE_NOTE_WATERMARK(note_size) \ - (((note_size) / 32) < OP_MIN_NOTE_PRE_WATERMARK \ - ? OP_MIN_NOTE_PRE_WATERMARK \ - : (note_size) / 32) -/** minimal note buffer water mark before we try to wakeup daemon */ -#define OP_MIN_NOTE_PRE_WATERMARK 512 -/** maximum number of entry in note buffer */ -#define OP_MAX_NOTE_TABLE_SIZE 1048576 -/** minimum number of entry in note buffer */ -#define OP_MIN_NOTE_TABLE_SIZE (1024 + OP_PRE_NOTE_WATERMARK(1024)) - -/** maximum sampling rate when using RTC */ -#define OP_MAX_RTC_COUNT 4096 -/** minimum sampling rate when using RTC */ -#define OP_MIN_RTC_COUNT 2 - -/*@}*/ - -/** - * nr entries in hash map. This is the maximum number of name components - * allowed. Must be a prime number - */ -#define OP_HASH_MAP_NR 4093 - -/** size of string pool in bytes */ -#define POOL_SIZE 65536 - -#ifndef NR_CPUS -/** maximum number of cpus present in the box */ -#define NR_CPUS 32 -#endif - -#endif /* OP_CONFIG_24_H */ diff --git a/libop/op_cpu_type.c b/libop/op_cpu_type.c deleted file mode 100644 index b9d13de..0000000 --- a/libop/op_cpu_type.c +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @file op_cpu_type.c - * CPU type determination - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "op_cpu_type.h" - -struct cpu_descr { - char const * pretty; - char const * name; - op_cpu cpu; - unsigned int nr_counters; -}; - -static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = { - { "Pentium Pro", "i386/ppro", CPU_PPRO, 2 }, - { "PII", "i386/pii", CPU_PII, 2 }, - { "PIII", "i386/piii", CPU_PIII, 2 }, - { "Athlon", "i386/athlon", CPU_ATHLON, 4 }, - { "CPU with timer interrupt", "timer", CPU_TIMER_INT, 1 }, - { "CPU with RTC device", "rtc", CPU_RTC, 1 }, - { "P4 / Xeon", "i386/p4", CPU_P4, 8 }, - { "IA64", "ia64/ia64", CPU_IA64, 4 }, - { "Itanium", "ia64/itanium", CPU_IA64_1, 4 }, - { "Itanium 2", "ia64/itanium2", CPU_IA64_2, 4 }, - { "AMD64 processors", "x86-64/hammer", CPU_HAMMER, 4 }, - { "P4 / Xeon with 2 hyper-threads", "i386/p4-ht", CPU_P4_HT2, 4 }, - { "Alpha EV4", "alpha/ev4", CPU_AXP_EV4, 2 }, - { "Alpha EV5", "alpha/ev5", CPU_AXP_EV5, 3 }, - { "Alpha PCA56", "alpha/pca56", CPU_AXP_PCA56, 3 }, - { "Alpha EV6", "alpha/ev6", CPU_AXP_EV6, 2 }, - { "Alpha EV67", "alpha/ev67", CPU_AXP_EV67, 20 }, - { "Pentium M (P6 core)", "i386/p6_mobile", CPU_P6_MOBILE, 2 }, - { "ARM/XScale PMU1", "arm/xscale1", CPU_ARM_XSCALE1, 3 }, - { "ARM/XScale PMU2", "arm/xscale2", CPU_ARM_XSCALE2, 5 }, - { "ppc64 POWER4", "ppc64/power4", CPU_PPC64_POWER4, 8 }, - { "ppc64 POWER5", "ppc64/power5", CPU_PPC64_POWER5, 6 }, - { "ppc64 POWER5+", "ppc64/power5+", CPU_PPC64_POWER5p, 6 }, - { "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 }, - { "MIPS 20K", "mips/20K", CPU_MIPS_20K, 1}, - { "MIPS 24K", "mips/24K", CPU_MIPS_24K, 2}, - { "MIPS 25K", "mips/25K", CPU_MIPS_25K, 2}, - { "MIPS 34K", "mips/34K", CPU_MIPS_34K, 4}, - { "MIPS 5K", "mips/5K", CPU_MIPS_5K, 2}, - { "MIPS R10000", "mips/r10000", CPU_MIPS_R10000, 2 }, - { "MIPS R12000", "mips/r12000", CPU_MIPS_R12000, 4 }, - { "QED RM7000", "mips/rm7000", CPU_MIPS_RM7000, 1 }, - { "PMC-Sierra RM9000", "mips/rm9000", CPU_MIPS_RM9000, 2 }, - { "Sibyte SB1", "mips/sb1", CPU_MIPS_SB1, 4 }, - { "NEC VR5432", "mips/vr5432", CPU_MIPS_VR5432, 2 }, - { "NEC VR5500", "mips/vr5500", CPU_MIPS_VR5500, 2 }, - { "e500", "ppc/e500", CPU_PPC_E500, 4 }, - { "e500v2", "ppc/e500v2", CPU_PPC_E500_2, 4 }, - { "Core Solo / Duo", "i386/core", CPU_CORE, 2 }, - { "PowerPC G4", "ppc/7450", CPU_PPC_7450, 6 }, - { "Core 2", "i386/core_2", CPU_CORE_2, 2 }, - { "ppc64 POWER6", "ppc64/power6", CPU_PPC64_POWER6, 4 }, - { "ppc64 970MP", "ppc64/970MP", CPU_PPC64_970MP, 8 }, - { "ppc64 Cell Broadband Engine", "ppc64/cell-be", CPU_PPC64_CELL, 8 }, - { "AMD64 family10", "x86-64/family10", CPU_FAMILY10, 4 }, - { "ppc64 PA6T", "ppc64/pa6t", CPU_PPC64_PA6T, 6 }, - { "ARM MPCore", "arm/mpcore", CPU_ARM_MPCORE, 2 }, - { "ARM V6 PMU", "arm/armv6", CPU_ARM_V6, 3 }, - { "ppc64 POWER5++", "ppc64/power5++", CPU_PPC64_POWER5pp, 6 }, - { "e300", "ppc/e300", CPU_PPC_E300, 4 }, - { "AVR32", "avr32", CPU_AVR32, 3 }, -}; - -static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr); - -op_cpu op_get_cpu_type(void) -{ - int cpu_type = CPU_NO_GOOD; - char str[100]; - FILE * fp; - - fp = fopen("/proc/sys/dev/oprofile/cpu_type", "r"); - if (!fp) { - /* Try 2.6's oprofilefs one instead. */ - fp = fopen("/dev/oprofile/cpu_type", "r"); - if (!fp) { - fprintf(stderr, "Unable to open cpu_type file for reading\n"); - fprintf(stderr, "Make sure you have done opcontrol --init\n"); - return cpu_type; - } - } - - if (!fgets(str, 99, fp)) { - fprintf(stderr, "Could not read cpu type.\n"); - return CPU_NO_GOOD; - } - - cpu_type = op_get_cpu_number(str); - - fclose(fp); - - return cpu_type; -} - - -op_cpu op_get_cpu_number(char const * cpu_string) -{ - int cpu_type = CPU_NO_GOOD; - size_t i; - - for (i = 0; i < nr_cpu_descrs; ++i) { - if (!strcmp(cpu_descrs[i].name, cpu_string)) { - cpu_type = cpu_descrs[i].cpu; - break; - } - } - - /* Attempt to convert into a number */ - if (cpu_type == CPU_NO_GOOD) - sscanf(cpu_string, "%d\n", &cpu_type); - - if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) - cpu_type = CPU_NO_GOOD; - - return cpu_type; -} - - -char const * op_get_cpu_type_str(op_cpu cpu_type) -{ - if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) - return "invalid cpu type"; - - return cpu_descrs[cpu_type].pretty; -} - - -char const * op_get_cpu_name(op_cpu cpu_type) -{ - if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) - return "invalid cpu type"; - - return cpu_descrs[cpu_type].name; -} - - -int op_get_nr_counters(op_cpu cpu_type) -{ - if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) - return 0; - - return cpu_descrs[cpu_type].nr_counters; -} diff --git a/libop/op_cpu_type.h b/libop/op_cpu_type.h deleted file mode 100644 index be95ae2..0000000 --- a/libop/op_cpu_type.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file op_cpu_type.h - * CPU type determination - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_CPU_TYPE_H -#define OP_CPU_TYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Supported cpu type. Always add new CPU types at the very end. - */ -typedef enum { - CPU_NO_GOOD = -1, /**< unsupported CPU type */ - CPU_PPRO, /**< Pentium Pro */ - CPU_PII, /**< Pentium II series */ - CPU_PIII, /**< Pentium III series */ - CPU_ATHLON, /**< AMD P6 series */ - CPU_TIMER_INT, /**< CPU using the timer interrupt */ - CPU_RTC, /**< other CPU to use the RTC */ - CPU_P4, /**< Pentium 4 / Xeon series */ - CPU_IA64, /**< Generic IA64 */ - CPU_IA64_1, /**< IA64 Merced */ - CPU_IA64_2, /**< IA64 McKinley */ - CPU_HAMMER, /**< AMD Hammer family */ - CPU_P4_HT2, /**< Pentium 4 / Xeon series with 2 hyper-threads */ - CPU_AXP_EV4, /**< Alpha EV4 family */ - CPU_AXP_EV5, /**< Alpha EV5 family */ - CPU_AXP_PCA56, /**< Alpha PCA56 family */ - CPU_AXP_EV6, /**< Alpha EV6 family */ - CPU_AXP_EV67, /**< Alpha EV67 family */ - CPU_P6_MOBILE, /**< Pentium M series */ - CPU_ARM_XSCALE1, /**< ARM XScale 1 */ - CPU_ARM_XSCALE2, /**< ARM XScale 2 */ - CPU_PPC64_POWER4, /**< ppc64 POWER4 family */ - CPU_PPC64_POWER5, /**< ppc64 POWER5 family */ - CPU_PPC64_POWER5p, /**< ppc64 Power5+ family */ - CPU_PPC64_970, /**< ppc64 970 family */ - CPU_MIPS_20K, /**< MIPS 20K */ - CPU_MIPS_24K, /**< MIPS 24K */ - CPU_MIPS_25K, /**< MIPS 25K */ - CPU_MIPS_34K, /**< MIPS 34K */ - CPU_MIPS_5K, /**< MIPS 5K */ - CPU_MIPS_R10000, /**< MIPS R10000 */ - CPU_MIPS_R12000, /**< MIPS R12000 */ - CPU_MIPS_RM7000, /**< QED RM7000 */ - CPU_MIPS_RM9000, /**< PMC-Sierra RM9000 */ - CPU_MIPS_SB1, /**< Broadcom SB1 */ - CPU_MIPS_VR5432, /**< NEC VR5432 */ - CPU_MIPS_VR5500, /**< MIPS VR5500, VR5532 and VR7701 */ - CPU_PPC_E500, /**< e500 */ - CPU_PPC_E500_2, /**< e500v2 */ - CPU_CORE, /**< Core Solo / Duo series */ - CPU_PPC_7450, /**< PowerPC G4 */ - CPU_CORE_2, /**< Intel Core 2 */ - CPU_PPC64_POWER6, /**< ppc64 POWER6 family */ - CPU_PPC64_970MP, /**< ppc64 970MP */ - CPU_PPC64_CELL, /**< ppc64 Cell Broadband Engine*/ - CPU_FAMILY10, /**< AMD family 10 */ - CPU_PPC64_PA6T, /**< ppc64 PA6T */ - CPU_ARM_MPCORE, /**< ARM MPCore */ - CPU_ARM_V6, /**< ARM V6 */ - CPU_PPC64_POWER5pp, /**< ppc64 Power5++ family */ - CPU_PPC_E300, /**< e300 */ - CPU_AVR32, /**< AVR32 */ - MAX_CPU_TYPE -} op_cpu; - -/** - * get the CPU type from the kernel - * - * returns CPU_NO_GOOD if the CPU could not be identified. - * This function can not work if the module is not loaded - */ -op_cpu op_get_cpu_type(void); - -/** - * get the cpu number based on string - * @param cpu_string with either the cpu type identifier or cpu type number - * - * The function returns CPU_NO_GOOD if no matching string was found. - */ -op_cpu op_get_cpu_number(char const * cpu_string); - -/** - * get the cpu string. - * @param cpu_type the cpu type identifier - * - * The function always return a valid char const * the core cpu denomination - * or "invalid cpu type" if cpu_type is not valid. - */ -char const * op_get_cpu_type_str(op_cpu cpu_type); - -/** - * op_get_cpu_name - get the cpu name - * @param cpu_type the cpu identifier name - * - * The function always return a valid char const * - * Return the OProfile CPU name, e.g. "i386/pii" - */ -char const * op_get_cpu_name(op_cpu cpu_type); - -/** - * compute the number of counters available - * @param cpu_type numeric processor type - * - * returns 0 if the CPU could not be identified - */ -int op_get_nr_counters(op_cpu cpu_type); - -typedef enum { - OP_INTERFACE_NO_GOOD = -1, - OP_INTERFACE_24, - OP_INTERFACE_26 -} op_interface; - -/** - * get the INTERFACE used to communicate between daemon and the kernel - * - * returns OP_INTERFACE_NO_GOOD if the INTERFACE could not be identified. - * This function will identify the interface as OP_INTERFACE_NO_GOOD if - * the module is not loaded. - */ -op_interface op_get_interface(void); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_CPU_TYPE_H */ diff --git a/libop/op_events.c b/libop/op_events.c deleted file mode 100644 index b4a10e7..0000000 --- a/libop/op_events.c +++ /dev/null @@ -1,862 +0,0 @@ -/** - * @file op_events.c - * Details of PMC profiling events - * - * You can have silliness here. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "op_events.h" -#include "op_libiberty.h" -#include "op_fileio.h" -#include "op_string.h" -#include "op_cpufreq.h" - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -static LIST_HEAD(events_list); -static LIST_HEAD(um_list); - -static char const * filename; -static unsigned int line_nr; - -static void parse_error(char const * context) -{ - fprintf(stderr, "oprofile: parse error in %s, line %u\n", - filename, line_nr); - fprintf(stderr, "%s\n", context); - exit(EXIT_FAILURE); -} - - -static int parse_int(char const * str) -{ - int value; - if (sscanf(str, "%d", &value) != 1) - parse_error("expected decimal value"); - - return value; -} - - -static int parse_hex(char const * str) -{ - int value; - /* 0x/0X to force the use of hexa notation for field intended to - be in hexadecimal */ - if (sscanf(str, "0x%x", &value) != 1 && - sscanf(str, "0X%x", &value) != 1) - parse_error("expected hexadecimal value"); - - return value; -} - - -static u64 parse_long_hex(char const * str) -{ - u64 value; - if (sscanf(str, "%Lx", &value) != 1) - parse_error("expected long hexadecimal value"); - - fflush(stderr); - return value; -} - - -/* name:MESI type:bitmask default:0x0f */ -static void parse_um(struct op_unit_mask * um, char const * line) -{ - int seen_name = 0; - int seen_type = 0; - int seen_default = 0; - char const * valueend = line + 1; - char const * tagend = line + 1; - char const * start = line; - - while (*valueend) { - valueend = skip_nonws(valueend); - - while (*tagend != ':' && *tagend) - ++tagend; - - if (valueend == tagend) - break; - - if (!*tagend) - parse_error("parse_um() expected :value"); - - ++tagend; - - if (strisprefix(start, "name")) { - if (seen_name) - parse_error("duplicate name: tag"); - seen_name = 1; - um->name = op_xstrndup(tagend, valueend - tagend); - } else if (strisprefix(start, "type")) { - if (seen_type) - parse_error("duplicate type: tag"); - seen_type = 1; - if (strisprefix(tagend, "mandatory")) { - um->unit_type_mask = utm_mandatory; - } else if (strisprefix(tagend, "bitmask")) { - um->unit_type_mask = utm_bitmask; - } else if (strisprefix(tagend, "exclusive")) { - um->unit_type_mask = utm_exclusive; - } else { - parse_error("invalid unit mask type"); - } - } else if (strisprefix(start, "default")) { - if (seen_default) - parse_error("duplicate default: tag"); - seen_default = 1; - um->default_mask = parse_hex(tagend); - } else { - parse_error("invalid unit mask tag"); - } - - valueend = skip_ws(valueend); - tagend = valueend; - start = valueend; - } -} - - -/* \t0x08 (M)odified cache state */ -static void parse_um_entry(struct op_described_um * entry, char const * line) -{ - char const * c = line; - - c = skip_ws(c); - entry->value = parse_hex(c); - c = skip_nonws(c); - - if (!*c) - parse_error("invalid unit mask entry"); - - c = skip_ws(c); - - if (!*c) - parse_error("invalid unit mask entry"); - - entry->desc = xstrdup(c); -} - - -static struct op_unit_mask * new_unit_mask(void) -{ - struct op_unit_mask * um = xmalloc(sizeof(struct op_unit_mask)); - memset(um, '\0', sizeof(struct op_unit_mask)); - list_add_tail(&um->um_next, &um_list); - - return um; -} - - -/* - * name:zero type:mandatory default:0x0 - * \t0x0 No unit mask - */ -static void read_unit_masks(char const * file) -{ - struct op_unit_mask * um = NULL; - char * line; - FILE * fp = fopen(file, "r"); - - if (!fp) { - fprintf(stderr, - "oprofile: could not open unit mask description file %s\n", file); - exit(EXIT_FAILURE); - } - - filename = file; - line_nr = 1; - - line = op_get_line(fp); - - while (line) { - if (empty_line(line) || comment_line(line)) - goto next; - - if (line[0] != '\t') { - um = new_unit_mask(); - parse_um(um, line); - } else { - if (!um) - parse_error("no unit mask name line"); - if (um->num >= MAX_UNIT_MASK) - parse_error("oprofile: maximum unit mask entries exceeded"); - - parse_um_entry(&um->um[um->num], line); - ++(um->num); - } - -next: - free(line); - line = op_get_line(fp); - ++line_nr; - } - - fclose(fp); -} - - -static u32 parse_counter_mask(char const * str) -{ - u32 mask = 0; - char const * numstart = str; - - while (*numstart) { - mask |= 1 << parse_int(numstart); - - while (*numstart && *numstart != ',') - ++numstart; - /* skip , unless we reach eos */ - if (*numstart) - ++numstart; - - numstart = skip_ws(numstart); - } - - return mask; -} - - -static struct op_unit_mask * find_um(char const * value) -{ - struct list_head * pos; - - list_for_each(pos, &um_list) { - struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next); - if (strcmp(value, um->name) == 0) - return um; - } - - fprintf(stderr, "oprofile: could not find unit mask %s\n", value); - exit(EXIT_FAILURE); -} - - -/* parse either a "tag:value" or a ": trailing description string" */ -static int next_token(char const ** cp, char ** name, char ** value) -{ - size_t tag_len; - size_t val_len; - char const * c = *cp; - char const * end; - char const * colon; - - c = skip_ws(c); - end = colon = c; - end = skip_nonws(end); - - colon = strchr(colon, ':'); - - if (!colon) { - if (*c) - parse_error("next_token(): garbage at end of line"); - return 0; - } - - if (colon >= end) - parse_error("next_token() expected ':'"); - - tag_len = colon - c; - val_len = end - (colon + 1); - - if (!tag_len) { - /* : trailing description */ - end = skip_ws(end); - *name = xstrdup("desc"); - *value = xstrdup(end); - end += strlen(end); - } else { - /* tag:value */ - *name = op_xstrndup(c, tag_len); - *value = op_xstrndup(colon + 1, val_len); - end = skip_ws(end); - } - - *cp = end; - return 1; -} - - -static struct op_event * new_event(void) -{ - struct op_event * event = xmalloc(sizeof(struct op_event)); - memset(event, '\0', sizeof(struct op_event)); - list_add_tail(&event->event_next, &events_list); - - return event; -} - - -/* event:0x00 counters:0 um:zero minimum:4096 name:ISSUES : Total issues */ -static void read_events(char const * file) -{ - struct op_event * event = NULL; - char * line; - char * name; - char * value; - char const * c; - int seen_event, seen_counters, seen_um, seen_minimum, seen_name; - FILE * fp = fopen(file, "r"); - - if (!fp) { - fprintf(stderr, "oprofile: could not open event description file %s\n", file); - exit(EXIT_FAILURE); - } - - filename = file; - line_nr = 1; - - line = op_get_line(fp); - - while (line) { - if (empty_line(line) || comment_line(line)) - goto next; - - seen_name = 0; - seen_event = 0; - seen_counters = 0; - seen_um = 0; - seen_minimum = 0; - event = new_event(); - - c = line; - while (next_token(&c, &name, &value)) { - if (strcmp(name, "name") == 0) { - if (seen_name) - parse_error("duplicate name: tag"); - seen_name = 1; - if (strchr(value, '/') != NULL) - parse_error("invalid event name"); - if (strchr(value, '.') != NULL) - parse_error("invalid event name"); - event->name = value; - } else if (strcmp(name, "event") == 0) { - if (seen_event) - parse_error("duplicate event: tag"); - seen_event = 1; - event->val = parse_hex(value); - free(value); - } else if (strcmp(name, "counters") == 0) { - if (seen_counters) - parse_error("duplicate counters: tag"); - seen_counters = 1; - event->counter_mask = parse_counter_mask(value); - free(value); - } else if (strcmp(name, "um") == 0) { - if (seen_um) - parse_error("duplicate um: tag"); - seen_um = 1; - event->unit = find_um(value); - event->unit->used = 1; - free(value); - } else if (strcmp(name, "minimum") == 0) { - if (seen_minimum) - parse_error("duplicate minimum: tag"); - seen_minimum = 1; - event->min_count = parse_int(value); - free(value); - } else if (strcmp(name, "desc") == 0) { - event->desc = value; - } else { - parse_error("unknown tag"); - } - - free(name); - } -next: - free(line); - line = op_get_line(fp); - ++line_nr; - } - - fclose(fp); -} - - -/* usefull for make check */ -static void check_unit_mask(struct op_unit_mask const * um, - char const * cpu_name) -{ - u32 i; - - if (!um->used) { - fprintf(stderr, "um %s is not used\n", um->name); - exit(EXIT_FAILURE); - } - - if (um->unit_type_mask == utm_mandatory && um->num != 1) { - fprintf(stderr, "mandatory um %s doesn't contain exactly one " - "entry (%s)\n", um->name, cpu_name); - exit(EXIT_FAILURE); - } else if (um->unit_type_mask == utm_bitmask) { - u32 default_mask = um->default_mask; - for (i = 0; i < um->num; ++i) - default_mask &= ~um->um[i].value; - - if (default_mask) { - fprintf(stderr, "um %s default mask is not valid " - "(%s)\n", um->name, cpu_name); - exit(EXIT_FAILURE); - } - } else { - for (i = 0; i < um->num; ++i) { - if (um->default_mask == um->um[i].value) - break; - } - - if (i == um->num) { - fprintf(stderr, "exclusive um %s default value is not " - "valid (%s)\n", um->name, cpu_name); - exit(EXIT_FAILURE); - } - } -} - - -static void load_events(op_cpu cpu_type) -{ - char const * cpu_name = op_get_cpu_name(cpu_type); - char * event_dir; - char * event_file; - char * um_file; - char * dir; - struct list_head * pos; - - if (!list_empty(&events_list)) - return; - - dir = getenv("OPROFILE_EVENTS_DIR"); - if (dir == NULL) - dir = OP_DATADIR; - - event_dir = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) + - strlen("/") + 1); - strcpy(event_dir, dir); - strcat(event_dir, "/"); - - strcat(event_dir, cpu_name); - strcat(event_dir, "/"); - - event_file = xmalloc(strlen(event_dir) + strlen("events") + 1); - strcpy(event_file, event_dir); - strcat(event_file, "events"); - - um_file = xmalloc(strlen(event_dir) + strlen("unit_masks") + 1); - strcpy(um_file, event_dir); - strcat(um_file, "unit_masks"); - - read_unit_masks(um_file); - read_events(event_file); - - /* sanity check: all unit mask must be used */ - list_for_each(pos, &um_list) { - struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next); - - check_unit_mask(um, cpu_name); - } - - free(um_file); - free(event_file); - free(event_dir); -} - - -struct list_head * op_events(op_cpu cpu_type) -{ - load_events(cpu_type); - return &events_list; -} - - -static void delete_unit_mask(struct op_unit_mask * unit) -{ - u32 cur; - for (cur = 0 ; cur < unit->num ; ++cur) { - if (unit->um[cur].desc) - free(unit->um[cur].desc); - } - - if (unit->name) - free(unit->name); - - list_del(&unit->um_next); - free(unit); -} - - -static void delete_event(struct op_event * event) -{ - if (event->name) - free(event->name); - if (event->desc) - free(event->desc); - - list_del(&event->event_next); - free(event); -} - - -void op_free_events(void) -{ - struct list_head * pos, * pos2; - list_for_each_safe(pos, pos2, &events_list) { - struct op_event * event = list_entry(pos, struct op_event, event_next); - delete_event(event); - } - - list_for_each_safe(pos, pos2, &um_list) { - struct op_unit_mask * unit = list_entry(pos, struct op_unit_mask, um_next); - delete_unit_mask(unit); - } -} - - -static struct op_event * find_event(u32 nr) -{ - struct list_head * pos; - - list_for_each(pos, &events_list) { - struct op_event * event = list_entry(pos, struct op_event, event_next); - if (event->val == nr) - return event; - } - - return NULL; -} - - -static FILE * open_event_mapping_file(char const * cpu_name) -{ - char * ev_map_file; - char * dir; - dir = getenv("OPROFILE_EVENTS_DIR"); - if (dir == NULL) - dir = OP_DATADIR; - - ev_map_file = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) + - strlen("/") + + strlen("event_mappings") + 1); - strcpy(ev_map_file, dir); - strcat(ev_map_file, "/"); - - strcat(ev_map_file, cpu_name); - strcat(ev_map_file, "/"); - strcat(ev_map_file, "event_mappings"); - filename = ev_map_file; - return (fopen(ev_map_file, "r")); -} - - -/** - * This function is PPC64-specific. - */ -static char const * get_mapping(u32 nr, FILE * fp) -{ - char * line; - char * name; - char * value; - char const * c; - char * map = NULL; - int seen_event = 0, seen_mmcr0 = 0, seen_mmcr1 = 0, seen_mmcra = 0; - u32 mmcr0 = 0; - u64 mmcr1 = 0; - u32 mmcra = 0; - int event_found = 0; - - line_nr = 1; - line = op_get_line(fp); - while (line && !event_found) { - if (empty_line(line) || comment_line(line)) - goto next; - - seen_event = 0; - seen_mmcr0 = 0; - seen_mmcr1 = 0; - seen_mmcra = 0; - mmcr0 = 0; - mmcr1 = 0; - mmcra = 0; - - c = line; - while (next_token(&c, &name, &value)) { - if (strcmp(name, "event") == 0) { - u32 evt; - if (seen_event) - parse_error("duplicate event tag"); - seen_event = 1; - evt = parse_hex(value); - if (evt == nr) - event_found = 1; - free(value); - } else if (strcmp(name, "mmcr0") == 0) { - if (seen_mmcr0) - parse_error("duplicate mmcr0 tag"); - seen_mmcr0 = 1; - mmcr0 = parse_hex(value); - free(value); - } else if (strcmp(name, "mmcr1") == 0) { - if (seen_mmcr1) - parse_error("duplicate mmcr1: tag"); - seen_mmcr1 = 1; - mmcr1 = parse_long_hex(value); - free(value); - } else if (strcmp(name, "mmcra") == 0) { - if (seen_mmcra) - parse_error("duplicate mmcra: tag"); - seen_mmcra = 1; - mmcra = parse_hex(value); - free(value); - } else { - parse_error("unknown tag"); - } - - free(name); - } -next: - free(line); - line = op_get_line(fp); - ++line_nr; - } - if (event_found) { - if (!seen_mmcr0 || !seen_mmcr1 || !seen_mmcra) { - fprintf(stderr, "Error: Missing information in line %d of event mapping file %s\n", line_nr, filename); - exit(EXIT_FAILURE); - } - map = xmalloc(70); - snprintf(map, 70, "mmcr0:%u mmcr1:%Lu mmcra:%u", - mmcr0, mmcr1, mmcra); - } - - return map; -} - - -char const * find_mapping_for_event(u32 nr, op_cpu cpu_type) -{ - char const * cpu_name = op_get_cpu_name(cpu_type); - FILE * fp = open_event_mapping_file(cpu_name); - char const * map = NULL; - switch (cpu_type) { - case CPU_PPC64_PA6T: - case CPU_PPC64_970: - case CPU_PPC64_970MP: - case CPU_PPC64_POWER4: - case CPU_PPC64_POWER5: - case CPU_PPC64_POWER5p: - case CPU_PPC64_POWER5pp: - case CPU_PPC64_POWER6: - if (!fp) { - fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename); - exit(EXIT_FAILURE); - } else { - map = get_mapping(nr, fp); - } - break; - default: - break; - } - - if (fp) - fclose(fp); - - return map; -} - - -struct op_event * find_event_by_name(char const * name) -{ - struct list_head * pos; - - list_for_each(pos, &events_list) { - struct op_event * event = list_entry(pos, struct op_event, event_next); - if (strcmp(event->name, name) == 0) - return event; - } - - return NULL; -} - - -struct op_event * op_find_event(op_cpu cpu_type, u32 nr) -{ - struct op_event * event; - - load_events(cpu_type); - - event = find_event(nr); - - return event; -} - - -int op_check_events(int ctr, u32 nr, u32 um, op_cpu cpu_type) -{ - int ret = OP_OK_EVENT; - struct op_event * event; - size_t i; - u32 ctr_mask = 1 << ctr; - - load_events(cpu_type); - - event = find_event(nr); - - if (!event) { - ret |= OP_INVALID_EVENT; - return ret; - } - - if ((event->counter_mask & ctr_mask) == 0) - ret |= OP_INVALID_COUNTER; - - if (event->unit->unit_type_mask == utm_bitmask) { - for (i = 0; i < event->unit->num; ++i) - um &= ~(event->unit->um[i].value); - - if (um) - ret |= OP_INVALID_UM; - - } else { - for (i = 0; i < event->unit->num; ++i) { - if (event->unit->um[i].value == um) - break; - } - - if (i == event->unit->num) - ret |= OP_INVALID_UM; - } - - return ret; -} - - -void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr) -{ - descr->name = ""; - descr->um = 0x0; - /* A fixed value of CPU cycles; this should ensure good - * granulity even on faster CPUs, though it will generate more - * interrupts. - */ - descr->count = 100000; - - switch (cpu_type) { - case CPU_PPRO: - case CPU_PII: - case CPU_PIII: - case CPU_P6_MOBILE: - case CPU_CORE: - case CPU_CORE_2: - case CPU_ATHLON: - case CPU_HAMMER: - case CPU_FAMILY10: - descr->name = "CPU_CLK_UNHALTED"; - break; - - case CPU_RTC: - descr->name = "RTC_INTERRUPTS"; - descr->count = 1024; - break; - - case CPU_P4: - case CPU_P4_HT2: - descr->name = "GLOBAL_POWER_EVENTS"; - descr->um = 0x1; - break; - - case CPU_IA64: - case CPU_IA64_1: - case CPU_IA64_2: - descr->count = 1000000; - descr->name = "CPU_CYCLES"; - break; - - case CPU_AXP_EV4: - case CPU_AXP_EV5: - case CPU_AXP_PCA56: - case CPU_AXP_EV6: - case CPU_AXP_EV67: - descr->name = "CYCLES"; - break; - - // we could possibly use the CCNT - case CPU_ARM_XSCALE1: - case CPU_ARM_XSCALE2: - case CPU_ARM_MPCORE: - case CPU_ARM_V6: - case CPU_AVR32: - descr->name = "CPU_CYCLES"; - break; - - case CPU_PPC64_PA6T: - case CPU_PPC64_970: - case CPU_PPC64_970MP: - case CPU_PPC_7450: - case CPU_PPC64_POWER4: - case CPU_PPC64_POWER5: - case CPU_PPC64_POWER6: - case CPU_PPC64_POWER5p: - case CPU_PPC64_POWER5pp: - case CPU_PPC64_CELL: - descr->name = "CYCLES"; - break; - - case CPU_MIPS_20K: - descr->name = "CYCLES"; - break; - - case CPU_MIPS_24K: - descr->name = "INSTRUCTIONS"; - break; - - case CPU_MIPS_34K: - descr->name = "INSTRUCTIONS"; - break; - - case CPU_MIPS_5K: - case CPU_MIPS_25K: - descr->name = "CYCLES"; - break; - - case CPU_MIPS_R10000: - case CPU_MIPS_R12000: - descr->name = "INSTRUCTIONS_GRADUATED"; - break; - - case CPU_MIPS_RM7000: - case CPU_MIPS_RM9000: - descr->name = "INSTRUCTIONS_ISSUED"; - break; - - case CPU_MIPS_SB1: - descr->name = "INSN_SURVIVED_STAGE7"; - break; - - case CPU_MIPS_VR5432: - case CPU_MIPS_VR5500: - descr->name = "INSTRUCTIONS_EXECUTED"; - break; - - case CPU_PPC_E500: - case CPU_PPC_E500_2: - case CPU_PPC_E300: - descr->name = "CPU_CLK"; - break; - - // don't use default, if someone add a cpu he wants a compiler - // warning if he forgets to handle it here. - case CPU_TIMER_INT: - case CPU_NO_GOOD: - case MAX_CPU_TYPE: - break; - } -} diff --git a/libop/op_events.h b/libop/op_events.h deleted file mode 100644 index f6462fc..0000000 --- a/libop/op_events.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file op_events.h - * Details of PMC profiling events - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_EVENTS_H -#define OP_EVENTS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "op_cpu_type.h" -#include "op_types.h" -#include "op_list.h" - -/** Describe an unit mask type. Events can optionally use a filter called - * the unit mask. the mask type can be a bitmask or a discrete value */ -enum unit_mask_type { - utm_mandatory, /**< useless but required by the hardware */ - utm_exclusive, /**< only one of the values is allowed */ - utm_bitmask /**< bitmask */ -}; - -/** up to thirty two allowed unit masks */ -#define MAX_UNIT_MASK 32 - - -/** Describe an unit mask. */ -struct op_unit_mask { - char * name; /**< name of unit mask type */ - u32 num; /**< number of possible unit masks */ - enum unit_mask_type unit_type_mask; - u32 default_mask; /**< only the gui use it */ - struct op_described_um { - u32 value; - char * desc; - } um[MAX_UNIT_MASK]; - struct list_head um_next; /**< next um in list */ - int used; /**< used by events file parser */ -}; - - -/** Describe an event. */ -struct op_event { - u32 counter_mask; /**< bitmask of allowed counter */ - u32 val; /**< event number */ - /** which unit mask if any allowed */ - struct op_unit_mask * unit; - char * name; /**< the event name */ - char * desc; /**< the event description */ - int min_count; /**< minimum counter value allowed */ - struct list_head event_next; /**< next event in list */ -}; - -/** Return the known events list. Idempotent */ -struct list_head * op_events(op_cpu cpu_type); - -/** Find a given event, returns NULL on error */ -struct op_event * op_find_event(op_cpu cpu_type, u32 nr); - -/** Find a given event by name */ -struct op_event * find_event_by_name(char const * name); - -/** - * Find a mapping for a given event ID for architectures requiring additional information - * from what is held in the events file. - */ -char const * find_mapping_for_event(u32 val, op_cpu cpu_type); - - -/** op_check_events() return code */ -enum op_event_check { - OP_OK_EVENT = 0, /**< event is valid and allowed */ - OP_INVALID_EVENT = 1, /**< event number is invalid */ - OP_INVALID_UM = 2, /**< unit mask is invalid */ - OP_INVALID_COUNTER = 4 /**< event is not allowed for the given counter */ -}; - -/** - * sanity check event values - * @param ctr counter number - * @param event value for counter - * @param um unit mask for counter - * @param cpu_type processor type - * - * Check that the counter event and unit mask values are allowed. - * - * The function returns bitmask of failure cause 0 otherwise - * - * \sa op_cpu, OP_EVENTS_OK - */ -int op_check_events(int ctr, u32 event, u32 um, op_cpu cpu_type); - -/** - * free memory used by any call to above function. Need to be called only once - */ -void op_free_events(void); - -struct op_default_event_descr { - char * name; - unsigned long count; - unsigned long um; -}; - -/** - * op_default_event - return the details of the default event - * @param cpu_type cpu type - * @param descr filled event description - * - * Fills in the event description if applicable - */ -void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_EVENTS_H */ diff --git a/libop/op_get_interface.c b/libop/op_get_interface.c deleted file mode 100644 index bdf72a5..0000000 --- a/libop/op_get_interface.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file op_get_interface.c - * Determine which oprofile kernel interface used - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Will Cohen - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "op_cpu_type.h" -#include "op_file.h" - -op_interface op_get_interface(void) -{ - static op_interface current_interface = OP_INTERFACE_NO_GOOD; - - if (current_interface != OP_INTERFACE_NO_GOOD) - return current_interface; - - if (op_file_readable("/proc/sys/dev/oprofile/cpu_type")) { - current_interface = OP_INTERFACE_24; - } else if (op_file_readable("/dev/oprofile/cpu_type")) { - current_interface = OP_INTERFACE_26; - } - - return current_interface; -} diff --git a/libop/op_hw_config.h b/libop/op_hw_config.h deleted file mode 100644 index 169b36b..0000000 --- a/libop/op_hw_config.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file op_hw_config.h - * Configuration parameters that are dependent on CPU/architecture - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_HW_CONFIG_H -#define OP_HW_CONFIG_H - -/** maximum number of counters, up to 4 for Athlon (18 for P4). The primary - * use of this variable is for static/local array dimension. Never use it in - * loop or in array index access/index checking unless you know what you - * made. */ -#ifdef __alpha__ -#define OP_MAX_COUNTERS 20 -#else -#define OP_MAX_COUNTERS 8 -#endif - -/** maximum number of events between interrupts. Counters are 40 bits, but - * for convenience we only use 32 bits. The top bit is used for overflow - * detection, so user can set up to (2^31)-1 */ -#define OP_MAX_PERF_COUNT 2147483647UL - -#endif /* OP_HW_CONFIG_H */ diff --git a/libop/op_interface.h b/libop/op_interface.h deleted file mode 100644 index fa2ecbd..0000000 --- a/libop/op_interface.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file op_interface.h - * - * Module / user space interface for 2.4 - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_INTERFACE_H -#define OP_INTERFACE_H - -#include "op_config.h" -#include "op_types.h" - -/*@{\name notifications types encoded in op_note::type */ -/** fork(),vfork(),clone() */ -#define OP_FORK 1 -/** mapping */ -#define OP_MAP 2 -/** execve() */ -#define OP_EXEC 4 -/** init_module() */ -#define OP_DROP_MODULES 8 -/** exit() */ -#define OP_EXIT 16 -/*@}*/ - -/** Data type to transfer samples counts from the module to the daemon */ -struct op_sample { - unsigned long eip; /**< eip value where occur interrupt */ - u32 counter; /**< counter nr */ - u32 pid; /**< 32 bits can hold any pid */ - u32 tgid; /**< always equal to pid for kernel < 2.4.0 */ -}; - -/** the current kernel-side profiler state */ -enum oprof_state { - STOPPED = 0, - STOPPING = 1, - RUNNING = 2 -}; - -/** - * The head structure of a kernel sample buffer. - */ -struct op_buffer_head { - int cpu_nr; /**< the CPU number of this buffer */ - size_t count; /**< number of samples in this buffer */ - enum oprof_state state; /**< current profiler state */ - struct op_sample buffer[0]; /**< the sample buffer */ -} __attribute__((__packed__)); - -/** - * Data type used by the module to notify daemon of fork/exit/mapping etc. - * Meanings of fields depend on the type of notification encoded in the type - * field. - * \sa OP_FORK, OP_EXEC, OP_MAP, OP_DROP_MODULES and OP_EXIT - */ -struct op_note { - unsigned long addr; - unsigned long len; - unsigned long offset; - unsigned int hash; - unsigned int pid; - unsigned int tgid; - unsigned short type; -}; - -/** - * A path component. Directory name are stored as a stack of path components. - * Note than the name index acts also as an unique identifier - */ -struct op_hash_index { - /** index inside the string pool */ - u32 name; - /** parent component, zero if this component is the root */ - u32 parent; -} __attribute__((__packed__)); - -/** size of hash map in bytes */ -#define OP_HASH_MAP_SIZE (OP_HASH_MAP_NR * sizeof(struct op_hash_index) + POOL_SIZE) - -#endif /* OP_INTERFACE_H */ diff --git a/libop/op_mangle.c b/libop/op_mangle.c deleted file mode 100644 index 1efe5b1..0000000 --- a/libop/op_mangle.c +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file op_mangle.c - * Mangling of sample file names - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "op_mangle.h" - -#include <string.h> -#include <stdio.h> - -#include "op_libiberty.h" - -#include "op_sample_file.h" -#include "op_config.h" - -static void append_image(char * dest, int flags, int anon, char const * name, char const * anon_name) -{ - if ((flags & MANGLE_KERNEL) && !strchr(name, '/')) { - strcat(dest, "{kern}/"); - } else if (anon) { - strcat(dest, "{anon:"); - strcat(dest, anon_name); - strcat(dest,"}/"); - } else { - strcat(dest, "{root}/"); - } - - strcat(dest, name); - strcat(dest, "/"); -} - -char * op_mangle_filename(struct mangle_values const * values) -{ - char * mangled; - size_t len; - int anon = values->flags & MANGLE_ANON; - int cg_anon = values->flags & MANGLE_CG_ANON; - /* if dep_name != image_name we need to invert them (and so revert them - * unconditionally because if they are equal it doesn't hurt to invert - * them), see P:3, FIXME: this is a bit weirds, we prolly need to - * reword pp_interface */ - char const * image_name = values->dep_name; - char const * anon_name = values->anon_name; - char const * dep_name = values->image_name; - char const * cg_image_name = values->cg_image_name; - - len = strlen(op_samples_current_dir) + strlen(dep_name) + 1 - + strlen(values->event_name) + 1 + strlen(image_name) + 1; - - if (values->flags & MANGLE_CALLGRAPH) - len += strlen(cg_image_name) + 1; - - if (anon || cg_anon) - len += strlen(anon_name); - - /* provision for tgid, tid, unit_mask, cpu and some {root}, {dep}, - * {kern}, {anon} and {cg} marker */ - /* FIXME: too ugly */ - len += 256; - - mangled = xmalloc(len); - - strcpy(mangled, op_samples_current_dir); - append_image(mangled, values->flags, 0, image_name, anon_name); - - strcat(mangled, "{dep}" "/"); - append_image(mangled, values->flags, anon, dep_name, anon_name); - - if (values->flags & MANGLE_CALLGRAPH) { - strcat(mangled, "{cg}" "/"); - append_image(mangled, values->flags, cg_anon, - cg_image_name, anon_name); - } - - strcat(mangled, values->event_name); - sprintf(mangled + strlen(mangled), ".%d.%d.", - values->count, values->unit_mask); - - if (values->flags & MANGLE_TGID) { - sprintf(mangled + strlen(mangled), "%d.", values->tgid); - } else { - sprintf(mangled + strlen(mangled), "%s.", "all"); - } - - if (values->flags & MANGLE_TID) { - sprintf(mangled + strlen(mangled), "%d.", values->tid); - } else { - sprintf(mangled + strlen(mangled), "%s.", "all"); - } - - if (values->flags & MANGLE_CPU) { - sprintf(mangled + strlen(mangled), "%d", values->cpu); - } else { - sprintf(mangled + strlen(mangled), "%s", "all"); - } - - return mangled; -} diff --git a/libop/op_mangle.h b/libop/op_mangle.h deleted file mode 100644 index 9b600dc..0000000 --- a/libop/op_mangle.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file op_mangle.h - * Mangling of sample file names - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_MANGLE_H -#define OP_MANGLE_H - -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -enum mangle_flags { - MANGLE_NONE = 0, - MANGLE_CPU = (1 << 0), - MANGLE_TGID = (1 << 1), - MANGLE_TID = (1 << 2), - MANGLE_KERNEL = (1 << 3), - MANGLE_CALLGRAPH = (1 << 4), - MANGLE_ANON = (1 << 5), - MANGLE_CG_ANON = (1 << 6), -}; - -/** - * Temporary structure for passing parameters to - * op_mangle_filename. - */ -struct mangle_values { - int flags; - - char const * image_name; - char const * anon_name; - char const * dep_name; - char const * cg_image_name; - char const * event_name; - int count; - unsigned int unit_mask; - pid_t tgid; - pid_t tid; - int cpu; -}; - -/** - * op_mangle_filename - mangle a sample filename - * @param values parameters to use as mangling input - * - * See also PP:3 for the encoding scheme - * - * Returns a char* pointer to the mangled string. Caller - * is responsible for freeing this string. - */ -char * op_mangle_filename(struct mangle_values const * values); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_MANGLE_H */ diff --git a/libop/op_parse_event.c b/libop/op_parse_event.c deleted file mode 100644 index 920d617..0000000 --- a/libop/op_parse_event.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file op_parse_event.c - * event parsing - * - * You can have silliness here. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdio.h> -#include <stdlib.h> - -#include "op_parse_event.h" -#include "op_string.h" - -static char * next_part(char const ** str) -{ - char const * c; - char * ret; - - if ((*str)[0] == '\0') - return NULL; - - if ((*str)[0] == ':') - ++(*str); - - c = *str; - - while (*c != '\0' && *c != ':') - ++c; - - if (c == *str) - return NULL; - - ret = op_xstrndup(*str, c - *str); - *str += c - *str; - return ret; -} - - -static int parse_ulong(char const * str) -{ - unsigned long value; - char * end; - value = strtoul(str, &end, 0); - if (end && *end) { - fprintf(stderr, "Invalid event part %s\n", str); - exit(EXIT_FAILURE); - } - - return value; -} - - -size_t parse_events(struct parsed_event * parsed_events, size_t max_events, - char const * const * events) -{ - size_t i = 0; - - while (events[i]) { - char const * cp = events[i]; - char * part = next_part(&cp); - - if (i >= max_events) { - fprintf(stderr, "Too many events specified: CPU " - "only has %lu counters.\n", - (unsigned long) max_events); - exit(EXIT_FAILURE); - } - - if (!part) { - fprintf(stderr, "Invalid event %s\n", cp); - exit(EXIT_FAILURE); - } - - parsed_events[i].name = part; - - part = next_part(&cp); - - if (!part) { - fprintf(stderr, "Invalid count for event %s\n", events[i]); - exit(EXIT_FAILURE); - } - - parsed_events[i].count = parse_ulong(part); - free(part); - - parsed_events[i].unit_mask = 0; - part = next_part(&cp); - - if (part) { - parsed_events[i].unit_mask = parse_ulong(part); - free(part); - } - - parsed_events[i].kernel = 1; - part = next_part(&cp); - - if (part) { - parsed_events[i].kernel = parse_ulong(part); - free(part); - } - - parsed_events[i].user = 1; - part = next_part(&cp); - - if (part) { - parsed_events[i].user = parse_ulong(part); - free(part); - } - - ++i; - } - - return i; -} diff --git a/libop/op_parse_event.h b/libop/op_parse_event.h deleted file mode 100644 index 247a355..0000000 --- a/libop/op_parse_event.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file op_parse_event.h - * event parsing - * - * You can have silliness here. - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_PARSE_EVENT_H -#define OP_PARSE_EVENT_H - -#include <stddef.h> - -struct parsed_event { - char * name; - int count; - int unit_mask; - int kernel; - int user; -}; - -/** - * @param parsed_events array of events to fill in - * @param max_events size of parsed_events - * @param events null terminated array of events string on the form - * event_name:count[:unit_mask:kernel:user] - * - * parse events given by the nil terminated array events and fill in - * parsed_events with results. Events validity are not checked except. - * A fatal error occur if number of events is greater than max_events. - * - * Return the number of events parsed. - */ -size_t parse_events(struct parsed_event * parsed_events, size_t max_events, - char const * const * events); - -#endif /* !OP_PARSE_EVENT_H */ diff --git a/libop/op_sample_file.h b/libop/op_sample_file.h deleted file mode 100644 index 4f9f1d0..0000000 --- a/libop/op_sample_file.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file op_sample_file.h - * Sample file format - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_SAMPLE_FILE_H -#define OP_SAMPLE_FILE_H - -#include "op_types.h" - -#include <stdint.h> -#include <time.h> - -/* header of the sample files */ -struct opd_header { - u8 magic[4]; - u32 version; - u32 cpu_type; - u32 ctr_event; - u32 ctr_um; - u32 ctr_count; - // for cg file the from_cg_is_kernel - u32 is_kernel; - double cpu_speed; - time_t mtime; - u32 cg_to_is_kernel; - /* spu_profile=1 says sample file contains Cell BE SPU profile data */ - u32 spu_profile; - uint64_t embedded_offset; - u64 anon_start; - u64 cg_to_anon_start; - /* binary compatibility reserve */ - u32 reserved1[1]; -}; - -#endif /* OP_SAMPLE_FILE_H */ diff --git a/libpopt/Android.mk b/libpopt/Android.mk deleted file mode 100644 index b20cf55..0000000 --- a/libpopt/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - findme.c \ - popt.c \ - poptconfig.c \ - popthelp.c \ - poptparse.c - -LOCAL_CFLAGS += -DHAVE_CONFIG_H - -LOCAL_MODULE := libpopt - -include $(BUILD_STATIC_LIBRARY) diff --git a/libpopt/config.h b/libpopt/config.h deleted file mode 100644 index 73a0817..0000000 --- a/libpopt/config.h +++ /dev/null @@ -1,329 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#undef ENABLE_NLS - -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - -/* Define to 1 if you have the <argz.h> header file. */ -#undef HAVE_ARGZ_H - -/* Define to 1 if you have the `asprintf' function. */ -#undef HAVE_ASPRINTF - -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -#undef HAVE_CFLOCALECOPYCURRENT - -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -#undef HAVE_CFPREFERENCESCOPYAPPVALUE - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#undef HAVE_DCGETTEXT - -/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you - don't. */ -#undef HAVE_DECL_FEOF_UNLOCKED - -/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if - you don't. */ -#undef HAVE_DECL_FGETS_UNLOCKED - -/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you - don't. */ -#undef HAVE_DECL_GETC_UNLOCKED - -/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you - don't. */ -#undef HAVE_DECL__SNPRINTF - -/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you - don't. */ -#undef HAVE_DECL__SNWPRINTF - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the <float.h> header file. */ -#define HAVE_FLOAT_H 1 - -/* Define to 1 if you have the `fwprintf' function. */ -#undef HAVE_FWPRINTF - -/* Define to 1 if you have the `getcwd' function. */ -#undef HAVE_GETCWD - -/* Define to 1 if you have the `getegid' function. */ -#undef HAVE_GETEGID - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getgid' function. */ -#undef HAVE_GETGID - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#undef HAVE_GETTEXT - -/* Define to 1 if you have the `getuid' function. */ -#undef HAVE_GETUID - -/* Define if you have the iconv() function. */ -#undef HAVE_ICONV - -/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */ -#undef HAVE_INTMAX_T - -/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */ -#define HAVE_INTTYPES_H 1 - -/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and - declares uintmax_t. */ -#undef HAVE_INTTYPES_H_WITH_UINTMAX - -/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ -#undef HAVE_LANGINFO_CODESET - -/* Define if your <locale.h> file defines LC_MESSAGES. */ -#undef HAVE_LC_MESSAGES - -/* Define to 1 if you have the <libintl.h> header file. */ -#undef HAVE_LIBINTL_H - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <locale.h> header file. */ -#undef HAVE_LOCALE_H - -/* Define if you have the 'long double' type. */ -#undef HAVE_LONG_DOUBLE - -/* Define if you have the 'long long' type. */ -#define HAVE_LONG_LONG 1 - -/* Define to 1 if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the <mcheck.h> header file. */ -#undef HAVE_MCHECK_H - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -#define HAVE_MEMPCPY 1 - -/* Define to 1 if you have a working `mmap' system call. */ -#define HAVE_MMAP 1 - -/* Define to 1 if you have the `mtrace' function. */ -#undef HAVE_MTRACE - -/* Define to 1 if you have the `munmap' function. */ -#define HAVE_MUNMAP 1 - -/* Define to 1 if you have the <nl_types.h> header file. */ -#undef HAVE_NL_TYPES_H - -/* Define if your printf() function supports format strings with positions. */ -#define HAVE_POSIX_PRINTF 1 - -/* Define to 1 if you have the `putenv' function. */ -#undef HAVE_PUTENV - -/* Define to 1 if you have the `setenv' function. */ -#undef HAVE_SETENV - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if you have the `setregid' function. */ -#undef HAVE_SETREGID - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares - uintmax_t. */ -#undef HAVE_STDINT_H_WITH_UINTMAX - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#undef HAVE_STPCPY - -/* Define to 1 if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* Define to 1 if you have the <sys/param.h> header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the `tsearch' function. */ -#undef HAVE_TSEARCH - -/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */ -#undef HAVE_UINTMAX_T - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the 'unsigned long long' type. */ -#undef HAVE_UNSIGNED_LONG_LONG - -/* Define if you have the 'wchar_t' type. */ -#undef HAVE_WCHAR_T - -/* Define to 1 if you have the `wcslen' function. */ -#undef HAVE_WCSLEN - -/* Define if you have the 'wint_t' type. */ -#undef HAVE_WINT_T - -/* Define to 1 if you have the `__argz_count' function. */ -#undef HAVE___ARGZ_COUNT - -/* Define to 1 if you have the `__argz_next' function. */ -#undef HAVE___ARGZ_NEXT - -/* Define to 1 if you have the `__argz_stringify' function. */ -#undef HAVE___ARGZ_STRINGIFY - -/* Define to 1 if you have the `__fsetlocking' function. */ -#undef HAVE___FSETLOCKING - -/* Define to 1 if you have the `__secure_getenv' function. */ -#undef HAVE___SECURE_GETENV - -/* Define as const if the declaration of iconv() needs const. */ -#undef ICONV_CONST - -/* Define if integer division by zero raises signal SIGFPE. */ -#undef INTDIV0_RAISES_SIGFPE - -/* Name of package */ -#define PACKAGE "popt" - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Full path to popt top_srcdir. */ -#undef POPT_SOURCE_PATH - -/* Define if <inttypes.h> exists and defines unusable PRI* macros. */ -#undef PRI_MACROS_BROKEN - -/* Define to 1 if the C compiler supports function prototypes. */ -#undef PROTOTYPES - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -#undef SIZE_MAX - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - -/* Define like PROTOTYPES; this can be used by system headers. */ -#undef __PROTOTYPES - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `long' if <sys/types.h> does not define. */ -#undef off_t - -/* Define as the type of the result of subtracting two pointers, if the system - doesn't define it. */ -#undef ptrdiff_t - -/* Define to empty if the C compiler doesn't support this keyword. */ -#undef signed - -/* Define to `unsigned' if <sys/types.h> does not define. */ -#undef size_t - -/* Define to unsigned long or unsigned long long if <stdint.h> and - <inttypes.h> don't define. */ -#undef uintmax_t diff --git a/libpopt/findme.c b/libpopt/findme.c deleted file mode 100644 index 78363e5..0000000 --- a/libpopt/findme.c +++ /dev/null @@ -1,52 +0,0 @@ -/** \ingroup popt - * \file popt/findme.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "findme.h" -#include <unistd.h> - -const char * findProgramPath(const char * argv0) -{ - char * path = getenv("PATH"); - char * pathbuf; - char * start, * chptr; - char * buf; - - if (argv0 == NULL) return NULL; /* XXX can't happen */ - /* If there is a / in the argv[0], it has to be an absolute path */ - if (strchr(argv0, '/')) - return xstrdup(argv0); - - if (path == NULL) return NULL; - - start = pathbuf = alloca(strlen(path) + 1); - buf = malloc(strlen(path) + strlen(argv0) + sizeof("/")); - if (buf == NULL) return NULL; /* XXX can't happen */ - strcpy(pathbuf, path); - - chptr = NULL; - /*@-branchstate@*/ - do { - if ((chptr = strchr(start, ':'))) - *chptr = '\0'; - sprintf(buf, "%s/%s", start, argv0); - - if (!access(buf, X_OK)) - return buf; - - if (chptr) - start = chptr + 1; - else - start = NULL; - } while (start && *start); - /*@=branchstate@*/ - - free(buf); - - return NULL; -} diff --git a/libpopt/findme.h b/libpopt/findme.h deleted file mode 100644 index a016b86..0000000 --- a/libpopt/findme.h +++ /dev/null @@ -1,20 +0,0 @@ -/** \ingroup popt - * \file popt/findme.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_FINDME -#define H_FINDME - -/** - * Return absolute path to executable by searching PATH. - * @param argv0 name of executable - * @return (malloc'd) absolute path to executable (or NULL) - */ -/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) - /*@*/; - -#endif diff --git a/libpopt/popt.c b/libpopt/popt.c deleted file mode 100644 index 4f9e325..0000000 --- a/libpopt/popt.c +++ /dev/null @@ -1,1262 +0,0 @@ -/** \ingroup popt - * \file popt/popt.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist */ - -#undef MYDEBUG - -#include "system.h" - -#if HAVE_FLOAT_H -#include <float.h> -#endif -#include <math.h> - -#include "findme.h" -#include "poptint.h" - -#ifdef MYDEBUG -/*@unchecked@*/ -int _popt_debug = 0; -#endif - -#if !defined(HAVE_STRERROR) && !defined(__LCLINT__) -static char * strerror(int errno) -{ - extern int sys_nerr; - extern char * sys_errlist[]; - - if ((0 <= errno) && (errno < sys_nerr)) - return sys_errlist[errno]; - else - return POPT_("unknown errno"); -} -#endif - -#ifdef MYDEBUG -/*@unused@*/ -static void prtcon(const char *msg, poptContext con) -{ - if (msg) fprintf(stderr, "%s", msg); - fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n", - con, con->os, - (con->os->nextCharArg ? con->os->nextCharArg : ""), - (con->os->nextArg ? con->os->nextArg : ""), - con->os->next, - (con->os->argv && con->os->argv[con->os->next] - ? con->os->argv[con->os->next] : "")); -} -#endif - -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) -{ - con->execPath = _free(con->execPath); - con->execPath = xstrdup(path); - con->execAbsolute = allowAbsolute; - /*@-nullstate@*/ /* LCL: con->execPath not NULL */ - return; - /*@=nullstate@*/ -} - -static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->arg == NULL) continue; /* XXX program error. */ - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - void * arg = opt->arg; -/*@-branchstate@*/ - /* XXX sick hack to preserve pretense of ABI. */ - if (arg == poptHelpOptions) arg = poptHelpOptionsI18N; -/*@=branchstate@*/ - /* Recurse on included sub-tables. */ - invokeCallbacksPRE(con, arg); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - (opt->argInfo & POPT_CBFLAG_PRE)) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)opt->arg; - /*@=castfcnptr@*/ - /* Perform callback. */ - /*@-noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); - /*@=noeffectuncon @*/ - } - } -} - -static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->arg == NULL) continue; /* XXX program error. */ - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - void * arg = opt->arg; -/*@-branchstate@*/ - /* XXX sick hack to preserve pretense of ABI. */ - if (arg == poptHelpOptions) arg = poptHelpOptionsI18N; -/*@=branchstate@*/ - /* Recurse on included sub-tables. */ - invokeCallbacksPOST(con, arg); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - (opt->argInfo & POPT_CBFLAG_POST)) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)opt->arg; - /*@=castfcnptr@*/ - /* Perform callback. */ - /*@-noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip); - /*@=noeffectuncon @*/ - } - } -} - -static void invokeCallbacksOPTION(poptContext con, - const struct poptOption * opt, - const struct poptOption * myOpt, - /*@null@*/ const void * myData, int shorty) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - const struct poptOption * cbopt = NULL; - - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - void * arg = opt->arg; -/*@-branchstate@*/ - /* XXX sick hack to preserve pretense of ABI. */ - if (arg == poptHelpOptions) arg = poptHelpOptionsI18N; -/*@=branchstate@*/ - /* Recurse on included sub-tables. */ - if (opt->arg != NULL) /* XXX program error */ - invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - !(opt->argInfo & POPT_CBFLAG_SKIPOPTION)) { - /* Save callback info. */ - cbopt = opt; - } else if (cbopt != NULL && - ((myOpt->shortName && opt->shortName && shorty && - myOpt->shortName == opt->shortName) || - (myOpt->longName && opt->longName && - /*@-nullpass@*/ /* LCL: opt->longName != NULL */ - !strcmp(myOpt->longName, opt->longName))) - /*@=nullpass@*/ - ) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)cbopt->arg; - /*@=castfcnptr@*/ - const void * cbData = (cbopt->descrip ? cbopt->descrip : myData); - /* Perform callback. */ - if (cb != NULL) { /* XXX program error */ - /*@-noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_OPTION, myOpt, - con->os->nextArg, cbData); - /*@=noeffectuncon @*/ - } - /* Terminate (unless explcitly continuing). */ - if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE)) - return; - } - } -} - -poptContext poptGetContext(const char * name, int argc, const char ** argv, - const struct poptOption * options, int flags) -{ - poptContext con = malloc(sizeof(*con)); - - if (con == NULL) return NULL; /* XXX can't happen */ - memset(con, 0, sizeof(*con)); - - con->os = con->optionStack; - con->os->argc = argc; - /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->os->argv = argv; - /*@=dependenttrans =assignexpose@*/ - con->os->argb = NULL; - - if (!(flags & POPT_CONTEXT_KEEP_FIRST)) - con->os->next = 1; /* skip argv[0] */ - - con->leftovers = calloc( (argc + 1), sizeof(*con->leftovers) ); - /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->options = options; - /*@=dependenttrans =assignexpose@*/ - con->aliases = NULL; - con->numAliases = 0; - con->flags = flags; - con->execs = NULL; - con->numExecs = 0; - con->finalArgvAlloced = argc * 2; - con->finalArgv = calloc( con->finalArgvAlloced, sizeof(*con->finalArgv) ); - con->execAbsolute = 1; - con->arg_strip = NULL; - - if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) - con->flags |= POPT_CONTEXT_POSIXMEHARDER; - - if (name) { - char * t = malloc(strlen(name) + 1); - if (t) con->appName = strcpy(t, name); - } - - /*@-internalglobs@*/ - invokeCallbacksPRE(con, con->options); - /*@=internalglobs@*/ - - return con; -} - -static void cleanOSE(/*@special@*/ struct optionStackEntry *os) - /*@uses os @*/ - /*@releases os->nextArg, os->argv, os->argb @*/ - /*@modifies os @*/ -{ - os->nextArg = _free(os->nextArg); - os->argv = _free(os->argv); - os->argb = PBM_FREE(os->argb); -} - -/*@-boundswrite@*/ -void poptResetContext(poptContext con) -{ - int i; - - if (con == NULL) return; - while (con->os > con->optionStack) { - cleanOSE(con->os--); - } - con->os->argb = PBM_FREE(con->os->argb); - con->os->currAlias = NULL; - con->os->nextCharArg = NULL; - con->os->nextArg = NULL; - con->os->next = 1; /* skip argv[0] */ - - con->numLeftovers = 0; - con->nextLeftover = 0; - con->restLeftover = 0; - con->doExec = NULL; - - if (con->finalArgv != NULL) - for (i = 0; i < con->finalArgvCount; i++) { - /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ - con->finalArgv[i] = _free(con->finalArgv[i]); - /*@=unqualifiedtrans@*/ - } - - con->finalArgvCount = 0; - con->arg_strip = PBM_FREE(con->arg_strip); - /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ - return; - /*@=nullstate@*/ -} -/*@=boundswrite@*/ - -/* Only one of longName, shortName should be set, not both. */ -/*@-boundswrite@*/ -static int handleExec(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, char shortName) - /*@uses con->execs, con->numExecs, con->flags, con->doExec, - con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ - /*@modifies con @*/ -{ - poptItem item; - int i; - - if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numExecs - 1; i >= 0; i--) { - item = con->execs + i; - if (longName && !(item->option.longName && - !strcmp(longName, item->option.longName))) - continue; - else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - - if (con->flags & POPT_CONTEXT_NO_EXEC) - return 1; - - if (con->doExec == NULL) { - con->doExec = con->execs + i; - return 1; - } - - /* We already have an exec to do; remember this option for next - time 'round */ - if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - i = con->finalArgvCount++; - if (con->finalArgv != NULL) /* XXX can't happen */ - { char *s = malloc((longName ? strlen(longName) : 0) + 3); - if (s != NULL) { /* XXX can't happen */ - if (longName) - sprintf(s, "--%s", longName); - else - sprintf(s, "-%c", shortName); - con->finalArgv[i] = s; - } else - con->finalArgv[i] = NULL; - } - - /*@-nullstate@*/ /* FIX: con->finalArgv[] == NULL */ - return 1; - /*@=nullstate@*/ -} -/*@=boundswrite@*/ - -/* Only one of longName, shortName may be set at a time */ -static int handleAlias(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, char shortName, - /*@exposed@*/ /*@null@*/ const char * nextCharArg) - /*@uses con->aliases, con->numAliases, con->optionStack, con->os, - con->os->currAlias, con->os->currAlias->option.longName @*/ - /*@modifies con @*/ -{ - poptItem item = con->os->currAlias; - int rc; - int i; - - if (item) { - if (longName && (item->option.longName && - !strcmp(longName, item->option.longName))) - return 0; - if (shortName && shortName == item->option.shortName) - return 0; - } - - if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numAliases - 1; i >= 0; i--) { - item = con->aliases + i; - if (longName && !(item->option.longName && - !strcmp(longName, item->option.longName))) - continue; - else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - -/*@-boundsread@*/ - if (nextCharArg && *nextCharArg) - con->os->nextCharArg = nextCharArg; -/*@=boundsread@*/ - - con->os++; - con->os->next = 0; - con->os->stuffed = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = con->aliases + i; - rc = poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv, - &con->os->argc, &con->os->argv); - con->os->argb = NULL; - - return (rc ? rc : 1); -} - -/*@-bounds -boundswrite @*/ -static int execCommand(poptContext con) - /*@globals internalState @*/ - /*@modifies internalState @*/ -{ - poptItem item = con->doExec; - const char ** argv; - int argc = 0; - int rc; - - if (item == NULL) /*XXX can't happen*/ - return POPT_ERROR_NOARG; - - if (item->argv == NULL || item->argc < 1 || - (!con->execAbsolute && strchr(item->argv[0], '/'))) - return POPT_ERROR_NOARG; - - argv = malloc(sizeof(*argv) * - (6 + item->argc + con->numLeftovers + con->finalArgvCount)); - if (argv == NULL) return POPT_ERROR_MALLOC; - - if (!strchr(item->argv[0], '/') && con->execPath != NULL) { - char *s = alloca(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); - sprintf(s, "%s/%s", con->execPath, item->argv[0]); - argv[argc] = s; - } else - argv[argc] = findProgramPath(item->argv[0]); - if (argv[argc++] == NULL) return POPT_ERROR_NOARG; - - if (item->argc > 1) { - memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); - argc += (item->argc - 1); - } - - if (con->finalArgv != NULL && con->finalArgvCount > 0) { - memcpy(argv + argc, con->finalArgv, - sizeof(*argv) * con->finalArgvCount); - argc += con->finalArgvCount; - } - - if (con->leftovers != NULL && con->numLeftovers > 0) { - memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); - argc += con->numLeftovers; - } - - argv[argc] = NULL; - -#if defined(hpux) || defined(__hpux) - rc = setresgid(getgid(), getgid(),-1); - if (rc) return POPT_ERROR_ERRNO; - rc = setresuid(getuid(), getuid(),-1); - if (rc) return POPT_ERROR_ERRNO; -#else -/* - * XXX " ... on BSD systems setuid() should be preferred over setreuid()" - * XXX sez' Timur Bakeyev <mc@bat.ru> - * XXX from Norbert Warmuth <nwarmuth@privat.circular.de> - */ -#if defined(HAVE_SETUID) - rc = setgid(getgid()); - if (rc) return POPT_ERROR_ERRNO; - rc = setuid(getuid()); - if (rc) return POPT_ERROR_ERRNO; -#elif defined (HAVE_SETREUID) - rc = setregid(getgid(), getgid()); - if (rc) return POPT_ERROR_ERRNO; - rc = setreuid(getuid(), getuid()); - if (rc) return POPT_ERROR_ERRNO; -#else - ; /* Can't drop privileges */ -#endif -#endif - - if (argv[0] == NULL) - return POPT_ERROR_NOARG; - -#ifdef MYDEBUG -if (_popt_debug) - { const char ** avp; - fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); - for (avp = argv; *avp; avp++) - fprintf(stderr, " '%s'", *avp); - fprintf(stderr, "\n"); - } -#endif - - rc = execvp(argv[0], (char *const *)argv); - - return POPT_ERROR_ERRNO; -} -/*@=bounds =boundswrite @*/ - -/*@-boundswrite@*/ -/*@observer@*/ /*@null@*/ static const struct poptOption * -findOption(const struct poptOption * opt, /*@null@*/ const char * longName, - char shortName, - /*@null@*/ /*@out@*/ poptCallbackType * callback, - /*@null@*/ /*@out@*/ const void ** callbackData, - int singleDash) - /*@modifies *callback, *callbackData */ -{ - const struct poptOption * cb = NULL; - - /* This happens when a single - is given */ - if (singleDash && !shortName && (longName && *longName == '\0')) - shortName = '-'; - - for (; opt->longName || opt->shortName || opt->arg; opt++) { - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - const struct poptOption * opt2; - void * arg = opt->arg; - -/*@-branchstate@*/ - /* XXX sick hack to preserve pretense of ABI. */ - if (arg == poptHelpOptions) arg = poptHelpOptionsI18N; -/*@=branchstate@*/ - /* Recurse on included sub-tables. */ - if (arg == NULL) continue; /* XXX program error */ - opt2 = findOption(arg, longName, shortName, callback, - callbackData, singleDash); - if (opt2 == NULL) continue; - /* Sub-table data will be inheirited if no data yet. */ - if (!(callback && *callback)) return opt2; - if (!(callbackData && *callbackData == NULL)) return opt2; - /*@-observertrans -dependenttrans @*/ - *callbackData = opt->descrip; - /*@=observertrans =dependenttrans @*/ - return opt2; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { - cb = opt; - } else if (longName && opt->longName && - (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && - /*@-nullpass@*/ /* LCL: opt->longName != NULL */ - !strcmp(longName, opt->longName)) - /*@=nullpass@*/ - { - break; - } else if (shortName && shortName == opt->shortName) { - break; - } - } - - if (!opt->longName && !opt->shortName) - return NULL; - /*@-modobserver -mods @*/ - if (callback) *callback = NULL; - if (callbackData) *callbackData = NULL; - if (cb) { - if (callback) - /*@-castfcnptr@*/ - *callback = (poptCallbackType)cb->arg; - /*@=castfcnptr@*/ - if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) { - if (callbackData) - /*@-observertrans@*/ /* FIX: typedef double indirection. */ - *callbackData = cb->descrip; - /*@=observertrans@*/ - } - } - /*@=modobserver =mods @*/ - - return opt; -} -/*@=boundswrite@*/ - -static const char * findNextArg(/*@special@*/ poptContext con, - unsigned argx, int delete_arg) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - struct optionStackEntry * os = con->os; - const char * arg; - - do { - int i; - arg = NULL; - while (os->next == os->argc && os > con->optionStack) os--; - if (os->next == os->argc && os == con->optionStack) break; - if (os->argv != NULL) - for (i = os->next; i < os->argc; i++) { - /*@-sizeoftype@*/ - if (os->argb && PBM_ISSET(i, os->argb)) - /*@innercontinue@*/ continue; - if (*os->argv[i] == '-') - /*@innercontinue@*/ continue; - if (--argx > 0) - /*@innercontinue@*/ continue; - arg = os->argv[i]; - if (delete_arg) { - if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc); - if (os->argb != NULL) /* XXX can't happen */ - PBM_SET(i, os->argb); - } - /*@innerbreak@*/ break; - /*@=sizeoftype@*/ - } - if (os > con->optionStack) os--; - } while (arg == NULL); - return arg; -} - -/*@-boundswrite@*/ -static /*@only@*/ /*@null@*/ const char * -expandNextArg(/*@special@*/ poptContext con, const char * s) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - const char * a = NULL; - size_t alen; - char *t, *te; - size_t tn = strlen(s) + 1; - char c; - - te = t = malloc(tn);; - if (t == NULL) return NULL; /* XXX can't happen */ - while ((c = *s++) != '\0') { - switch (c) { -#if 0 /* XXX can't do this */ - case '\\': /* escape */ - c = *s++; - /*@switchbreak@*/ break; -#endif - case '!': - if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) - /*@switchbreak@*/ break; - /* XXX Make sure that findNextArg deletes only next arg. */ - if (a == NULL) { - if ((a = findNextArg(con, 1, 1)) == NULL) - /*@switchbreak@*/ break; - } - s += 3; - - alen = strlen(a); - tn += alen; - *te = '\0'; - t = realloc(t, tn); - te = t + strlen(t); - strncpy(te, a, alen); te += alen; - continue; - /*@notreached@*/ /*@switchbreak@*/ break; - default: - /*@switchbreak@*/ break; - } - *te++ = c; - } - *te = '\0'; - t = realloc(t, strlen(t) + 1); /* XXX memory leak, hard to plug */ - return t; -} -/*@=boundswrite@*/ - -static void poptStripArg(/*@special@*/ poptContext con, int which) - /*@uses con->arg_strip, con->optionStack @*/ - /*@defines con->arg_strip @*/ - /*@modifies con @*/ -{ - /*@-sizeoftype@*/ - if (con->arg_strip == NULL) - con->arg_strip = PBM_ALLOC(con->optionStack[0].argc); - if (con->arg_strip != NULL) /* XXX can't happen */ - PBM_SET(which, con->arg_strip); - /*@=sizeoftype@*/ - /*@-compdef@*/ /* LCL: con->arg_strip udefined? */ - return; - /*@=compdef@*/ -} - -int poptSaveLong(long * arg, int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (argInfo & POPT_ARGFLAG_NOT) - aLong = ~aLong; - switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { - case 0: - *arg = aLong; - break; - case POPT_ARGFLAG_OR: - *arg |= aLong; - break; - case POPT_ARGFLAG_AND: - *arg &= aLong; - break; - case POPT_ARGFLAG_XOR: - *arg ^= aLong; - break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (argInfo & POPT_ARGFLAG_NOT) - aLong = ~aLong; - switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { - case 0: - *arg = aLong; - break; - case POPT_ARGFLAG_OR: - *arg |= aLong; - break; - case POPT_ARGFLAG_AND: - *arg &= aLong; - break; - case POPT_ARGFLAG_XOR: - *arg ^= aLong; - break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -/*@-boundswrite@*/ -/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ -int poptGetNextOpt(poptContext con) -{ - const struct poptOption * opt = NULL; - int done = 0; - - if (con == NULL) - return -1; - while (!done) { - const char * origOptString = NULL; - poptCallbackType cb = NULL; - const void * cbData = NULL; - const char * longArg = NULL; - int canstrip = 0; - int shorty = 0; - - while (!con->os->nextCharArg && con->os->next == con->os->argc - && con->os > con->optionStack) { - cleanOSE(con->os--); - } - if (!con->os->nextCharArg && con->os->next == con->os->argc) { - /*@-internalglobs@*/ - invokeCallbacksPOST(con, con->options); - /*@=internalglobs@*/ - if (con->doExec) return execCommand(con); - return -1; - } - - /* Process next long option */ - if (!con->os->nextCharArg) { - char * localOptString, * optString; - int thisopt; - - /*@-sizeoftype@*/ - if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { - con->os->next++; - continue; - } - /*@=sizeoftype@*/ - thisopt = con->os->next; - if (con->os->argv != NULL) /* XXX can't happen */ - origOptString = con->os->argv[con->os->next++]; - - if (origOptString == NULL) /* XXX can't happen */ - return POPT_ERROR_BADOPT; - - if (con->restLeftover || *origOptString != '-' || - (*origOptString == '-' && origOptString[1] == '\0')) - { - if (con->flags & POPT_CONTEXT_POSIXMEHARDER) - con->restLeftover = 1; - if (con->flags & POPT_CONTEXT_ARG_OPTS) { - con->os->nextArg = xstrdup(origOptString); - return 0; - } - if (con->leftovers != NULL) /* XXX can't happen */ - con->leftovers[con->numLeftovers++] = origOptString; - continue; - } - - /* Make a copy we can hack at */ - localOptString = optString = - strcpy(alloca(strlen(origOptString) + 1), origOptString); - - if (optString[0] == '\0') - return POPT_ERROR_BADOPT; - - if (optString[1] == '-' && !optString[2]) { - con->restLeftover = 1; - continue; - } else { - char *oe; - int singleDash; - - optString++; - if (*optString == '-') - singleDash = 0, optString++; - else - singleDash = 1; - - /* XXX aliases with arg substitution need "--alias=arg" */ - if (handleAlias(con, optString, '\0', NULL)) - continue; - - if (handleExec(con, optString, '\0')) - continue; - - /* Check for "--long=arg" option. */ - for (oe = optString; *oe && *oe != '='; oe++) - {}; - if (*oe == '=') { - *oe++ = '\0'; - /* XXX longArg is mapped back to persistent storage. */ - longArg = origOptString + (oe - localOptString); - } - - opt = findOption(con->options, optString, '\0', &cb, &cbData, - singleDash); - if (!opt && !singleDash) - return POPT_ERROR_BADOPT; - } - - if (!opt) { - con->os->nextCharArg = origOptString + 1; - } else { - if (con->os == con->optionStack && - opt->argInfo & POPT_ARGFLAG_STRIP) - { - canstrip = 1; - poptStripArg(con, thisopt); - } - shorty = 0; - } - } - - /* Process next short option */ - /*@-branchstate@*/ /* FIX: W2DO? */ - if (con->os->nextCharArg) { - origOptString = con->os->nextCharArg; - - con->os->nextCharArg = NULL; - - if (handleAlias(con, NULL, *origOptString, origOptString + 1)) - continue; - - if (handleExec(con, NULL, *origOptString)) { - /* Restore rest of short options for further processing */ - origOptString++; - if (*origOptString != '\0') - con->os->nextCharArg = origOptString; - continue; - } - - opt = findOption(con->options, NULL, *origOptString, &cb, - &cbData, 0); - if (!opt) - return POPT_ERROR_BADOPT; - shorty = 1; - - origOptString++; - if (*origOptString != '\0') - con->os->nextCharArg = origOptString; - } - /*@=branchstate@*/ - - if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ - if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { - if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L)) - return POPT_ERROR_BADOPERATION; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { - if (opt->arg) { - if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val)) - return POPT_ERROR_BADOPERATION; - } - } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { - con->os->nextArg = _free(con->os->nextArg); - /*@-usedef@*/ /* FIX: W2DO? */ - if (longArg) { - /*@=usedef@*/ - longArg = expandNextArg(con, longArg); - con->os->nextArg = longArg; - } else if (con->os->nextCharArg) { - longArg = expandNextArg(con, con->os->nextCharArg); - con->os->nextArg = longArg; - con->os->nextCharArg = NULL; - } else { - while (con->os->next == con->os->argc && - con->os > con->optionStack) { - cleanOSE(con->os--); - } - if (con->os->next == con->os->argc) { - if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL)) - /*@-compdef@*/ /* FIX: con->os->argv not defined */ - return POPT_ERROR_NOARG; - /*@=compdef@*/ - con->os->nextArg = NULL; - } else { - - /* - * Make sure this isn't part of a short arg or the - * result of an alias expansion. - */ - if (con->os == con->optionStack && - (opt->argInfo & POPT_ARGFLAG_STRIP) && - canstrip) { - poptStripArg(con, con->os->next); - } - - if (con->os->argv != NULL) { /* XXX can't happen */ - /* XXX watchout: subtle side-effects live here. */ - longArg = con->os->argv[con->os->next++]; - longArg = expandNextArg(con, longArg); - con->os->nextArg = longArg; - } - } - } - longArg = NULL; - - if (opt->arg) { - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_STRING: - /* XXX memory leak, hard to plug */ - *((const char **) opt->arg) = (con->os->nextArg) - ? xstrdup(con->os->nextArg) : NULL; - /*@switchbreak@*/ break; - - case POPT_ARG_INT: - case POPT_ARG_LONG: - { long aLong = 0; - char *end; - - if (con->os->nextArg) { - aLong = strtol(con->os->nextArg, &end, 0); - if (!(end && *end == '\0')) - return POPT_ERROR_BADNUMBER; - } - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { - if (aLong == LONG_MIN || aLong == LONG_MAX) - return POPT_ERROR_OVERFLOW; - if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong)) - return POPT_ERROR_BADOPERATION; - } else { - if (aLong > INT_MAX || aLong < INT_MIN) - return POPT_ERROR_OVERFLOW; - if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong)) - return POPT_ERROR_BADOPERATION; - } - } /*@switchbreak@*/ break; - - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - { double aDouble = 0.0; - char *end; - - if (con->os->nextArg) { - /*@-mods@*/ - int saveerrno = errno; - errno = 0; - aDouble = strtod(con->os->nextArg, &end); - if (errno == ERANGE) - return POPT_ERROR_OVERFLOW; - errno = saveerrno; - /*@=mods@*/ - if (*end != '\0') - return POPT_ERROR_BADNUMBER; - } - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) { - *((double *) opt->arg) = aDouble; - } else { -#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) - if ((_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) - return POPT_ERROR_OVERFLOW; - if ((FLT_MIN - _ABS(aDouble)) > DBL_EPSILON) - return POPT_ERROR_OVERFLOW; - *((float *) opt->arg) = aDouble; - } - } /*@switchbreak@*/ break; - default: - fprintf(stdout, - POPT_("option type (%d) not implemented in popt\n"), - (opt->argInfo & POPT_ARG_MASK)); - exit(EXIT_FAILURE); - /*@notreached@*/ /*@switchbreak@*/ break; - } - } - } - - if (cb) { - /*@-internalglobs@*/ - invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); - /*@=internalglobs@*/ - } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) - done = 1; - - if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - if (con->finalArgv != NULL) - { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + 3); - if (s != NULL) { /* XXX can't happen */ - if (opt->longName) - sprintf(s, "%s%s", - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - else - sprintf(s, "-%c", opt->shortName); - con->finalArgv[con->finalArgvCount++] = s; - } else - con->finalArgv[con->finalArgvCount++] = NULL; - } - - if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { - if (con->finalArgv != NULL && con->os->nextArg) - con->finalArgv[con->finalArgvCount++] = - /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */ - xstrdup(con->os->nextArg); - /*@=nullpass@*/ - } - } - - return (opt ? opt->val : -1); /* XXX can't happen */ -} -/*@=boundswrite@*/ - -const char * poptGetOptArg(poptContext con) -{ - const char * ret = NULL; - /*@-branchstate@*/ - if (con) { - ret = con->os->nextArg; - con->os->nextArg = NULL; - } - /*@=branchstate@*/ - return ret; -} - -const char * poptGetArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover++]; - return ret; -} - -const char * poptPeekArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover]; - return ret; -} - -/*@-boundswrite@*/ -const char ** poptGetArgs(poptContext con) -{ - if (con == NULL || - con->leftovers == NULL || con->numLeftovers == con->nextLeftover) - return NULL; - - /* some apps like [like RPM ;-) ] need this NULL terminated */ - con->leftovers[con->numLeftovers] = NULL; - - /*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */ - return (con->leftovers + con->nextLeftover); - /*@=nullret =nullstate @*/ -} -/*@=boundswrite@*/ - -poptContext poptFreeContext(poptContext con) -{ - poptItem item; - int i; - - if (con == NULL) return con; - poptResetContext(con); - con->os->argb = _free(con->os->argb); - - if (con->aliases != NULL) - for (i = 0; i < con->numAliases; i++) { - item = con->aliases + i; - /*@-modobserver -observertrans -dependenttrans@*/ - item->option.longName = _free(item->option.longName); - item->option.descrip = _free(item->option.descrip); - item->option.argDescrip = _free(item->option.argDescrip); - /*@=modobserver =observertrans =dependenttrans@*/ - item->argv = _free(item->argv); - } - con->aliases = _free(con->aliases); - - if (con->execs != NULL) - for (i = 0; i < con->numExecs; i++) { - item = con->execs + i; - /*@-modobserver -observertrans -dependenttrans@*/ - item->option.longName = _free(item->option.longName); - item->option.descrip = _free(item->option.descrip); - item->option.argDescrip = _free(item->option.argDescrip); - /*@=modobserver =observertrans =dependenttrans@*/ - item->argv = _free(item->argv); - } - con->execs = _free(con->execs); - - con->leftovers = _free(con->leftovers); - con->finalArgv = _free(con->finalArgv); - con->appName = _free(con->appName); - con->otherHelp = _free(con->otherHelp); - con->execPath = _free(con->execPath); - con->arg_strip = PBM_FREE(con->arg_strip); - - con = _free(con); - return con; -} - -int poptAddAlias(poptContext con, struct poptAlias alias, - /*@unused@*/ int flags) -{ - poptItem item = alloca(sizeof(*item)); - memset(item, 0, sizeof(*item)); - item->option.longName = alias.longName; - item->option.shortName = alias.shortName; - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - item->option.arg = 0; - item->option.val = 0; - item->option.descrip = NULL; - item->option.argDescrip = NULL; - item->argc = alias.argc; - item->argv = alias.argv; - return poptAddItem(con, item, 0); -} - -/*@-boundswrite@*/ -/*@-mustmod@*/ /* LCL: con not modified? */ -int poptAddItem(poptContext con, poptItem newItem, int flags) -{ - poptItem * items, item; - int * nitems; - - switch (flags) { - case 1: - items = &con->execs; - nitems = &con->numExecs; - break; - case 0: - items = &con->aliases; - nitems = &con->numAliases; - break; - default: - return 1; - /*@notreached@*/ break; - } - - *items = realloc((*items), ((*nitems) + 1) * sizeof(**items)); - if ((*items) == NULL) - return 1; - - item = (*items) + (*nitems); - - item->option.longName = - (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); - item->option.shortName = newItem->option.shortName; - item->option.argInfo = newItem->option.argInfo; - item->option.arg = newItem->option.arg; - item->option.val = newItem->option.val; - item->option.descrip = - (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); - item->option.argDescrip = - (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); - item->argc = newItem->argc; - item->argv = newItem->argv; - - (*nitems)++; - - return 0; -} -/*@=mustmod@*/ -/*@=boundswrite@*/ - -const char * poptBadOption(poptContext con, int flags) -{ - struct optionStackEntry * os = NULL; - - if (con != NULL) - os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; - - /*@-nullderef@*/ /* LCL: os->argv != NULL */ - return (os && os->argv ? os->argv[os->next - 1] : NULL); - /*@=nullderef@*/ -} - -const char * poptStrerror(const int error) -{ - switch (error) { - case POPT_ERROR_NOARG: - return POPT_("missing argument"); - case POPT_ERROR_BADOPT: - return POPT_("unknown option"); - case POPT_ERROR_BADOPERATION: - return POPT_("mutually exclusive logical operations requested"); - case POPT_ERROR_NULLARG: - return POPT_("opt->arg should not be NULL"); - case POPT_ERROR_OPTSTOODEEP: - return POPT_("aliases nested too deeply"); - case POPT_ERROR_BADQUOTE: - return POPT_("error in parameter quoting"); - case POPT_ERROR_BADNUMBER: - return POPT_("invalid numeric value"); - case POPT_ERROR_OVERFLOW: - return POPT_("number too large or too small"); - case POPT_ERROR_MALLOC: - return POPT_("memory allocation failed"); - case POPT_ERROR_ERRNO: - return strerror(errno); - default: - return POPT_("unknown error"); - } -} - -int poptStuffArgs(poptContext con, const char ** argv) -{ - int argc; - int rc; - - if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - - for (argc = 0; argv[argc]; argc++) - {}; - - con->os++; - con->os->next = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = NULL; - rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); - con->os->argb = NULL; - con->os->stuffed = 1; - - return rc; -} - -const char * poptGetInvocationName(poptContext con) -{ - return (con->os->argv ? con->os->argv[0] : ""); -} - -/*@-boundswrite@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) -{ - int numargs = argc; - int j = 1; - int i; - - /*@-sizeoftype@*/ - if (con->arg_strip) - for (i = 1; i < argc; i++) { - if (PBM_ISSET(i, con->arg_strip)) - numargs--; - } - - for (i = 1; i < argc; i++) { - if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) - continue; - argv[j] = (j < numargs) ? argv[i] : NULL; - j++; - } - /*@=sizeoftype@*/ - - return numargs; -} -/*@=boundswrite@*/ diff --git a/libpopt/popt.h b/libpopt/popt.h deleted file mode 100644 index 4f85d9e..0000000 --- a/libpopt/popt.h +++ /dev/null @@ -1,564 +0,0 @@ -/** \file popt/popt.h - * \ingroup popt - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPT -#define H_POPT - -#include <stdio.h> /* for FILE * */ - -#define POPT_OPTION_DEPTH 10 - -/** \ingroup popt - * \name Arg type identifiers - */ -/*@{*/ -#define POPT_ARG_NONE 0 /*!< no arg */ -#define POPT_ARG_STRING 1 /*!< arg will be saved as string */ -#define POPT_ARG_INT 2 /*!< arg will be converted to int */ -#define POPT_ARG_LONG 3 /*!< arg will be converted to long */ -#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */ -#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be - set first in table; arg points - to callback, descrip points to - callback data to pass */ -#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain - for this table and any - included tables; arg points - to the domain string */ -#define POPT_ARG_VAL 7 /*!< arg should take value val */ -#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */ -#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */ - -#define POPT_ARG_MASK 0x0000FFFF -/*@}*/ - -/** \ingroup popt - * \name Arg modifiers - */ -/*@{*/ -#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */ -#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */ -#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */ -#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */ - -#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */ -#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */ -#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */ -#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */ -#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */ -#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */ -#define POPT_ARGFLAG_LOGICALOPS \ - (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) - -#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) - /*!< set arg bit(s) */ -#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) - /*!< clear arg bit(s) */ - -#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */ - -/*@}*/ - -/** \ingroup popt - * \name Callback modifiers - */ -/*@{*/ -#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */ -#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */ -#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line, - not the subtable */ -#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */ -#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */ -/*@}*/ - -/** \ingroup popt - * \name Error return values - */ -/*@{*/ -#define POPT_ERROR_NOARG -10 /*!< missing argument */ -#define POPT_ERROR_BADOPT -11 /*!< unknown option */ -#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ -#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ -#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ -#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ -#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ -#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ -#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ -#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ -/*@}*/ - -/** \ingroup popt - * \name poptBadOption() flags - */ -/*@{*/ -#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */ -/*@}*/ - -/** \ingroup popt - * \name poptGetContext() flags - */ -/*@{*/ -#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */ -#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */ -#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */ -#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */ -/*@}*/ - -/** \ingroup popt - */ -struct poptOption { -/*@observer@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - int argInfo; -/*@shared@*/ /*@null@*/ - void * arg; /*!< depends on argInfo */ - int val; /*!< 0 means don't return, just update flag */ -/*@observer@*/ /*@null@*/ - const char * descrip; /*!< description for autohelp -- may be NULL */ -/*@observer@*/ /*@null@*/ - const char * argDescrip; /*!< argument description for autohelp */ -}; - -/** \ingroup popt - * A popt alias argument for poptAddAlias(). - */ -struct poptAlias { -/*@owned@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - int argc; -/*@owned@*/ - const char ** argv; /*!< must be free()able */ -}; - -/** \ingroup popt - * A popt alias or exec argument for poptAddItem(). - */ -/*@-exporttype@*/ -typedef struct poptItem_s { - struct poptOption option; /*!< alias/exec name(s) and description. */ - int argc; /*!< (alias) no. of args. */ -/*@owned@*/ - const char ** argv; /*!< (alias) args, must be free()able. */ -} * poptItem; -/*@=exporttype@*/ - -/** \ingroup popt - * \name Auto-generated help/usage - */ -/*@{*/ - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptAliasOptions[]; -/*@=exportvar@*/ -#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ - 0, "Options implemented via popt alias/exec:", NULL }, - -/** - * Auto help table options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptHelpOptions[]; -/*@=exportvar@*/ - -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption * poptHelpOptionsI18N; -/*@=exportvar@*/ - -#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ - 0, "Help options:", NULL }, - -#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } -/*@}*/ - -/** \ingroup popt - */ -/*@-exporttype@*/ -typedef /*@abstract@*/ struct poptContext_s * poptContext; -/*@=exporttype@*/ - -/** \ingroup popt - */ -#ifndef __cplusplus -/*@-exporttype -typeuse@*/ -typedef struct poptOption * poptOption; -/*@=exporttype =typeuse@*/ -#endif - -/*@-exportconst@*/ -enum poptCallbackReason { - POPT_CALLBACK_REASON_PRE = 0, - POPT_CALLBACK_REASON_POST = 1, - POPT_CALLBACK_REASON_OPTION = 2 -}; -/*@=exportconst@*/ - -#ifdef __cplusplus -extern "C" { -#endif -/*@-type@*/ - -/** \ingroup popt - * Table callback prototype. - * @param con context - * @param reason reason for callback - * @param opt option that triggered callback - * @param arg @todo Document. - * @param data @todo Document. - */ -typedef void (*poptCallbackType) (poptContext con, - enum poptCallbackReason reason, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * arg, - /*@null@*/ const void * data) - /*@globals internalState @*/ - /*@modifies internalState @*/; - -/** \ingroup popt - * Initialize popt context. - * @param name context name (usually argv[0] program name) - * @param argc no. of arguments - * @param argv argument array - * @param options address of popt option table - * @param flags or'd POPT_CONTEXT_* bits - * @return initialized popt context - */ -/*@only@*/ /*@null@*/ -poptContext poptGetContext( - /*@dependent@*/ /*@keep@*/ const char * name, - int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, - /*@dependent@*/ /*@keep@*/ const struct poptOption * options, - int flags) - /*@*/; - -/** \ingroup popt - * Reinitialize popt context. - * @param con context - */ -/*@unused@*/ -void poptResetContext(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return value of next option found. - * @param con context - * @return next option val, -1 on last item, POPT_ERROR_* on error - */ -int poptGetNextOpt(/*@null@*/poptContext con) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/; - -/** \ingroup popt - * Return next option argument (if any). - * @param con context - * @return option argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptGetOptArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return next argument. - * @param con context - * @return next argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptGetArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Peek at current argument. - * @param con context - * @return current argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptPeekArg(/*@null@*/poptContext con) - /*@*/; - -/** \ingroup popt - * Return remaining arguments. - * @param con context - * @return argument array, NULL terminated - */ -/*@observer@*/ /*@null@*/ -const char ** poptGetArgs(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return the option which caused the most recent error. - * @param con context - * @param flags - * @return offending option - */ -/*@observer@*/ -const char * poptBadOption(/*@null@*/poptContext con, int flags) - /*@*/; - -/** \ingroup popt - * Destroy context. - * @param con context - * @return NULL always - */ -/*@null@*/ -poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Add arguments to context. - * @param con context - * @param argv argument array, NULL terminated - * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure - */ -/*@unused@*/ -int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias to context. - * @todo Pass alias by reference, not value. - * @deprecated Use poptAddItem instead. - * @param con context - * @param alias alias to add - * @param flags (unused) - * @return 0 on success - */ -/*@unused@*/ -int poptAddAlias(poptContext con, struct poptAlias alias, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias/exec item to context. - * @param con context - * @param newItem alias/exec item to add - * @param flags 0 for alias, 1 for exec - * @return 0 on success - */ -int poptAddItem(poptContext con, poptItem newItem, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Read configuration file. - * @param con context - * @param fn file name to read - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -int poptReadConfigFile(poptContext con, const char * fn) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - errno, fileSystem, internalState @*/; - -/** \ingroup popt - * Read default configuration from /etc/popt and $HOME/.popt. - * @param con context - * @param useEnv (unused) - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -/*@unused@*/ -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) - /*@globals fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - fileSystem, internalState @*/; - -/** \ingroup popt - * Duplicate an argument array. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param argc no. of arguments - * @param argv argument array - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - * @return 0 on success, POPT_ERROR_NOARG on failure - */ -int poptDupArgv(int argc, /*@null@*/ const char **argv, - /*@null@*/ /*@out@*/ int * argcPtr, - /*@null@*/ /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parse a string into an argument array. - * The parse allows ', ", and \ quoting, but ' is treated the same as " and - * both may include \ quotes. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param s string to parse - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - */ -int poptParseArgvString(const char * s, - /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parses an input configuration file and returns an string that is a - * command line. For use with popt. You must free the return value when done. - * - * Given the file: -\verbatim -# this line is ignored - # this one too -aaa - bbb - ccc -bla=bla - -this_is = fdsafdas - bad_line= - reall bad line - reall bad line = again -5555= 55555 - test = with lots of spaces -\endverbatim -* -* The result is: -\verbatim ---aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" -\endverbatim -* -* Passing this to poptParseArgvString() yields an argv of: -\verbatim -'--aaa' -'--bbb' -'--ccc' -'--bla=bla' -'--this_is=fdsafdas' -'--5555=55555' -'--test=with lots of spaces' -\endverbatim - * - * @bug NULL is returned if file line is too long. - * @bug Silently ignores invalid lines. - * - * @param fp file handle to read - * @param *argstrp return string of options (malloc'd) - * @param flags unused - * @return 0 on success - * @see poptParseArgvString - */ -/*@-fcnuse@*/ -int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, *argstrp, fileSystem @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return formatted error string for popt failure. - * @param error popt error - * @return error string - */ -/*@observer@*/ -const char * poptStrerror(const int error) - /*@*/; - -/** \ingroup popt - * Limit search for executables. - * @param con context - * @param path single path to search for executables - * @param allowAbsolute absolute paths only? - */ -/*@unused@*/ -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) - /*@modifies con @*/; - -/** \ingroup popt - * Print detailed description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Print terse description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Provide text to replace default "[OPTION...]" in help/usage output. - * @param con context - * @param text replacement text - */ -/*@-fcnuse@*/ -void poptSetOtherOptionHelp(poptContext con, const char * text) - /*@modifies con @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return argv[0] from context. - * @param con context - * @return argv[0] - */ -/*@-fcnuse@*/ -/*@observer@*/ -const char * poptGetInvocationName(poptContext con) - /*@*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Shuffle argv pointers to remove stripped args, returns new argc. - * @param con context - * @param argc no. of args - * @param argv arg vector - * @return new argc - */ -/*@-fcnuse@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) - /*@modifies *argv @*/; -/*@=fcnuse@*/ - -/** - * Save a long, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save an integer, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/*@=type@*/ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libpopt/poptconfig.c b/libpopt/poptconfig.c deleted file mode 100644 index e5cba45..0000000 --- a/libpopt/poptconfig.c +++ /dev/null @@ -1,182 +0,0 @@ -/** \ingroup popt - * \file popt/poptconfig.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "poptint.h" -/*@access poptContext @*/ - -/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ -static void configLine(poptContext con, char * line) - /*@modifies con @*/ -{ - size_t nameLength; - const char * entryType; - const char * opt; - poptItem item = alloca(sizeof(*item)); - int i, j; - - if (con->appName == NULL) - return; - nameLength = strlen(con->appName); - -/*@-boundswrite@*/ - memset(item, 0, sizeof(*item)); - - if (strncmp(line, con->appName, nameLength)) return; - - line += nameLength; - if (*line == '\0' || !isspace(*line)) return; - - while (*line != '\0' && isspace(*line)) line++; - entryType = line; - while (*line == '\0' || !isspace(*line)) line++; - *line++ = '\0'; - - while (*line != '\0' && isspace(*line)) line++; - if (*line == '\0') return; - opt = line; - while (*line == '\0' || !isspace(*line)) line++; - *line++ = '\0'; - - while (*line != '\0' && isspace(*line)) line++; - if (*line == '\0') return; - - /*@-temptrans@*/ /* FIX: line alias is saved */ - if (opt[0] == '-' && opt[1] == '-') - item->option.longName = opt + 2; - else if (opt[0] == '-' && opt[2] == '\0') - item->option.shortName = opt[1]; - /*@=temptrans@*/ - - if (poptParseArgvString(line, &item->argc, &item->argv)) return; - - /*@-modobserver@*/ - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - for (i = 0, j = 0; i < item->argc; i++, j++) { - const char * f; - if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { - f = item->argv[i] + sizeof("--POPTdesc="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.descrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - j--; - } else - if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { - f = item->argv[i] + sizeof("--POPTargs="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.argDescrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - item->option.argInfo |= POPT_ARG_STRING; - j--; - } else - if (j != i) - item->argv[j] = item->argv[i]; - } - if (j != i) { - item->argv[j] = NULL; - item->argc = j; - } - /*@=modobserver@*/ -/*@=boundswrite@*/ - - /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ - if (!strcmp(entryType, "alias")) - (void) poptAddItem(con, item, 0); - else if (!strcmp(entryType, "exec")) - (void) poptAddItem(con, item, 1); - /*@=nullstate@*/ -} -/*@=compmempass@*/ - -int poptReadConfigFile(poptContext con, const char * fn) -{ - const char * file, * chptr, * end; - char * buf; -/*@dependent@*/ char * dst; - int fd, rc; - off_t fileLength; - - fd = open(fn, O_RDONLY); - if (fd < 0) - return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); - - fileLength = lseek(fd, 0, SEEK_END); - if (fileLength == -1 || lseek(fd, 0, 0) == -1) { - rc = errno; - (void) close(fd); - errno = rc; - return POPT_ERROR_ERRNO; - } - - file = alloca(fileLength + 1); - if (read(fd, (char *)file, fileLength) != fileLength) { - rc = errno; - (void) close(fd); - errno = rc; - return POPT_ERROR_ERRNO; - } - if (close(fd) == -1) - return POPT_ERROR_ERRNO; - -/*@-boundswrite@*/ - dst = buf = alloca(fileLength + 1); - - chptr = file; - end = (file + fileLength); - /*@-infloops@*/ /* LCL: can't detect chptr++ */ - while (chptr < end) { - switch (*chptr) { - case '\n': - *dst = '\0'; - dst = buf; - while (*dst && isspace(*dst)) dst++; - if (*dst && *dst != '#') - configLine(con, dst); - chptr++; - /*@switchbreak@*/ break; - case '\\': - *dst++ = *chptr++; - if (chptr < end) { - if (*chptr == '\n') - dst--, chptr++; - /* \ at the end of a line does not insert a \n */ - else - *dst++ = *chptr++; - } - /*@switchbreak@*/ break; - default: - *dst++ = *chptr++; - /*@switchbreak@*/ break; - } - } - /*@=infloops@*/ -/*@=boundswrite@*/ - - return 0; -} - -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) -{ - char * fn, * home; - int rc; - - if (con->appName == NULL) return 0; - - rc = poptReadConfigFile(con, "/etc/popt"); - if (rc) return rc; - - if ((home = getenv("HOME"))) { - fn = alloca(strlen(home) + 20); - strcpy(fn, home); - strcat(fn, "/.popt"); - rc = poptReadConfigFile(con, fn); - if (rc) return rc; - } - - return 0; -} diff --git a/libpopt/popthelp.c b/libpopt/popthelp.c deleted file mode 100644 index 9430a2d..0000000 --- a/libpopt/popthelp.c +++ /dev/null @@ -1,819 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/** \ingroup popt - * \file popt/popthelp.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" - -//#define POPT_WCHAR_HACK -#ifdef POPT_WCHAR_HACK -#include <wchar.h> /* for mbsrtowcs */ -/*@access mbstate_t @*/ -#endif -#include "poptint.h" - -/*@access poptContext@*/ - -/** - * Display arguments. - * @param con context - * @param foo (unused) - * @param key option(s) - * @param arg (unused) - * @param data (unused) - */ -static void displayArgs(poptContext con, - /*@unused@*/ enum poptCallbackReason foo, - struct poptOption * key, - /*@unused@*/ const char * arg, /*@unused@*/ void * data) - /*@globals fileSystem@*/ - /*@modifies fileSystem@*/ -{ - if (key->shortName == '?') - poptPrintHelp(con, stdout, 0); - else - poptPrintUsage(con, stdout, 0); - exit(0); -} - -#ifdef NOTYET -/*@unchecked@*/ -static int show_option_defaults = 0; -#endif - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptAliasOptions[] = { - POPT_TABLEEND -}; - -/** - * Auto help table options. - */ -/*@-castfcnptr@*/ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptHelpOptions[] = { - { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL }, - { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL }, - { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL }, - POPT_TABLEEND -} ; - -/*@observer@*/ /*@unchecked@*/ -static struct poptOption poptHelpOptions2[] = { -/*@-readonlytrans@*/ - { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL}, -/*@=readonlytrans@*/ - { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL }, - { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL }, - { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL }, -#ifdef NOTYET - { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0, - N_("Display option defaults in message"), NULL }, -#endif - POPT_TABLEEND -} ; - -/*@observer@*/ /*@unchecked@*/ -struct poptOption * poptHelpOptionsI18N = poptHelpOptions2; -/*@=castfcnptr@*/ - -/** - * @param table option(s) - */ -/*@observer@*/ /*@null@*/ static const char * -getTableTranslationDomain(/*@null@*/ const struct poptOption *table) - /*@*/ -{ - const struct poptOption *opt; - - if (table != NULL) - for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->argInfo == POPT_ARG_INTL_DOMAIN) - return opt->arg; - } - return NULL; -} - -/** - * @param opt option(s) - * @param translation_domain translation domain - */ -/*@observer@*/ /*@null@*/ static const char * -getArgDescrip(const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - if (!(opt->argInfo & POPT_ARG_MASK)) return NULL; - - if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2)) - if (opt->argDescrip) return POPT_(opt->argDescrip); - - if (opt->argDescrip) return D_(translation_domain, opt->argDescrip); - - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_NONE: return POPT_("NONE"); -#ifdef DYING - case POPT_ARG_VAL: return POPT_("VAL"); -#else - case POPT_ARG_VAL: return NULL; -#endif - case POPT_ARG_INT: return POPT_("INT"); - case POPT_ARG_LONG: return POPT_("LONG"); - case POPT_ARG_STRING: return POPT_("STRING"); - case POPT_ARG_FLOAT: return POPT_("FLOAT"); - case POPT_ARG_DOUBLE: return POPT_("DOUBLE"); - default: return POPT_("ARG"); - } -} - -/** - * Display default value for an option. - * @param lineLength display positions remaining - * @param opt option(s) - * @param translation_domain translation domain - * @return - */ -static /*@only@*/ /*@null@*/ char * -singleOptionDefaultValue(size_t lineLength, - const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - const char * defstr = D_(translation_domain, "default"); - char * le = malloc(4*lineLength + 1); - char * l = le; - - if (le == NULL) return NULL; /* XXX can't happen */ -/*@-boundswrite@*/ - *le = '\0'; - *le++ = '('; - strcpy(le, defstr); le += strlen(le); - *le++ = ':'; - *le++ = ' '; - if (opt->arg) /* XXX programmer error */ - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_VAL: - case POPT_ARG_INT: - { long aLong = *((int *)opt->arg); - le += sprintf(le, "%ld", aLong); - } break; - case POPT_ARG_LONG: - { long aLong = *((long *)opt->arg); - le += sprintf(le, "%ld", aLong); - } break; - case POPT_ARG_FLOAT: - { double aDouble = *((float *)opt->arg); - le += sprintf(le, "%g", aDouble); - } break; - case POPT_ARG_DOUBLE: - { double aDouble = *((double *)opt->arg); - le += sprintf(le, "%g", aDouble); - } break; - case POPT_ARG_STRING: - { const char * s = *(const char **)opt->arg; - if (s == NULL) { - strcpy(le, "null"); le += strlen(le); - } else { - size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")"); - *le++ = '"'; - strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le); - if (slen < strlen(s)) { - strcpy(le, "..."); le += strlen(le); - } - *le++ = '"'; - } - } break; - case POPT_ARG_NONE: - default: - l = _free(l); - return NULL; - /*@notreached@*/ break; - } - *le++ = ')'; - *le = '\0'; -/*@=boundswrite@*/ - - return l; -} - -/** - * Display help text for an option. - * @param fp output file handle - * @param maxLeftCol largest argument display width - * @param opt option(s) - * @param translation_domain translation domain - */ -static void singleOptionHelp(FILE * fp, size_t maxLeftCol, - const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - size_t indentLength = maxLeftCol + 5; - size_t lineLength = 79 - indentLength; - const char * help = D_(translation_domain, opt->descrip); - const char * argDescrip = getArgDescrip(opt, translation_domain); - size_t helpLength; - char * defs = NULL; - char * left; - size_t nb = maxLeftCol + 1; - int displaypad = 0; - - /* Make sure there's more than enough room in target buffer. */ - if (opt->longName) nb += strlen(opt->longName); - if (argDescrip) nb += strlen(argDescrip); - -/*@-boundswrite@*/ - left = malloc(nb); - if (left == NULL) return; /* XXX can't happen */ - left[0] = '\0'; - left[maxLeftCol] = '\0'; - - if (opt->longName && opt->shortName) - sprintf(left, "-%c, %s%s", opt->shortName, - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - else if (opt->shortName != '\0') - sprintf(left, "-%c", opt->shortName); - else if (opt->longName) - sprintf(left, "%s%s", - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - if (!*left) goto out; - - if (argDescrip) { - char * le = left + strlen(left); - - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) - *le++ = '['; - - /* Choose type of output */ - /*@-branchstate@*/ - if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) { - defs = singleOptionDefaultValue(lineLength, opt, translation_domain); - if (defs) { - char * t = malloc((help ? strlen(help) : 0) + - strlen(defs) + sizeof(" ")); - if (t) { - char * te = t; - *te = '\0'; - if (help) { - strcpy(te, help); te += strlen(te); - } - *te++ = ' '; - strcpy(te, defs); - defs = _free(defs); - } - defs = t; - } - } - /*@=branchstate@*/ - - if (opt->argDescrip == NULL) { - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_NONE: - break; - case POPT_ARG_VAL: -#ifdef NOTNOW /* XXX pug ugly nerdy output */ - { long aLong = opt->val; - int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS); - int negate = (opt->argInfo & POPT_ARGFLAG_NOT); - - /* Don't bother displaying typical values */ - if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) - break; - *le++ = '['; - switch (ops) { - case POPT_ARGFLAG_OR: - *le++ = '|'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_AND: - *le++ = '&'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_XOR: - *le++ = '^'; - /*@innerbreak@*/ break; - default: - /*@innerbreak@*/ break; - } - *le++ = (opt->longName != NULL ? '=' : ' '); - if (negate) *le++ = '~'; - /*@-formatconst@*/ - le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); - /*@=formatconst@*/ - *le++ = ']'; - } -#endif - break; - case POPT_ARG_INT: - case POPT_ARG_LONG: - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - case POPT_ARG_STRING: - *le++ = (opt->longName != NULL ? '=' : ' '); - strcpy(le, argDescrip); le += strlen(le); - break; - default: - break; - } - } else { - size_t lelen; - - *le++ = '='; - strcpy(le, argDescrip); - lelen = strlen(le); - le += lelen; - -#ifdef POPT_WCHAR_HACK - { const char * scopy = argDescrip; - mbstate_t t; - size_t n; - - memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */ - /* Determine number of characters. */ - n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t); - - displaypad = (int) (lelen-n); - } -#endif - } - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) - *le++ = ']'; - *le = '\0'; - } -/*@=boundswrite@*/ - - if (help) - fprintf(fp," %-*s ", maxLeftCol+displaypad, left); - else { - fprintf(fp," %s\n", left); - goto out; - } - - left = _free(left); -/*@-branchstate@*/ - if (defs) { - help = defs; - defs = NULL; - } -/*@=branchstate@*/ - - helpLength = strlen(help); -/*@-boundsread@*/ - while (helpLength > lineLength) { - const char * ch; - char format[16]; - - ch = help + lineLength - 1; - while (ch > help && !isspace(*ch)) ch--; - if (ch == help) break; /* give up */ - while (ch > (help + 1) && isspace(*ch)) ch--; - ch++; - - sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), (int) indentLength); - /*@-formatconst@*/ - fprintf(fp, format, help, " "); - /*@=formatconst@*/ - help = ch; - while (isspace(*help) && *help) help++; - helpLength = strlen(help); - } -/*@=boundsread@*/ - - if (helpLength) fprintf(fp, "%s\n", help); - -out: - /*@-dependenttrans@*/ - defs = _free(defs); - /*@=dependenttrans@*/ - left = _free(left); -} - -/** - * Find display width for longest argument string. - * @param opt option(s) - * @param translation_domain translation domain - * @return display width - */ -static size_t maxArgWidth(const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@*/ -{ - size_t max = 0; - size_t len = 0; - const char * s; - - if (opt != NULL) - while (opt->longName || opt->shortName || opt->arg) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - if (opt->arg) /* XXX program error */ - len = maxArgWidth(opt->arg, translation_domain); - if (len > max) max = len; - } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - len = sizeof(" ")-1; - if (opt->shortName != '\0') len += sizeof("-X")-1; - if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1; - if (opt->longName) { - len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH) - ? sizeof("-")-1 : sizeof("--")-1); - len += strlen(opt->longName); - } - - s = getArgDescrip(opt, translation_domain); - -#ifdef POPT_WCHAR_HACK - /* XXX Calculate no. of display characters. */ - if (s) { - const char * scopy = s; - mbstate_t t; - size_t n; - -/*@-boundswrite@*/ - memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */ -/*@=boundswrite@*/ - /* Determine number of characters. */ - n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t); - len += sizeof("=")-1 + n; - } -#else - if (s) - len += sizeof("=")-1 + strlen(s); -#endif - - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1; - if (len > max) max = len; - } - - opt++; - } - - return max; -} - -/** - * Display popt alias and exec help. - * @param fp output file handle - * @param items alias/exec array - * @param nitems no. of alias/exec entries - * @param left largest argument display width - * @param translation_domain translation domain - */ -static void itemHelp(FILE * fp, - /*@null@*/ poptItem items, int nitems, size_t left, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - poptItem item; - int i; - - if (items != NULL) - for (i = 0, item = items; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) - singleOptionHelp(fp, left, opt, translation_domain); - } -} - -/** - * Display help text for a table of options. - * @param con context - * @param fp output file handle - * @param table option(s) - * @param left largest argument display width - * @param translation_domain translation domain - */ -static void singleTableHelp(poptContext con, FILE * fp, - /*@null@*/ const struct poptOption * table, size_t left, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - const struct poptOption * opt; - const char *sub_transdom; - - if (table == poptAliasOptions) { - itemHelp(fp, con->aliases, con->numAliases, left, NULL); - itemHelp(fp, con->execs, con->numExecs, left, NULL); - return; - } - - if (table != NULL) - for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { - if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) - singleOptionHelp(fp, left, opt, translation_domain); - } - - if (table != NULL) - for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { - if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE) - continue; - sub_transdom = getTableTranslationDomain(opt->arg); - if (sub_transdom == NULL) - sub_transdom = translation_domain; - - if (opt->descrip) - fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); - - singleTableHelp(con, fp, opt->arg, left, sub_transdom); - } -} - -/** - * @param con context - * @param fp output file handle - */ -static int showHelpIntro(poptContext con, FILE * fp) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int len = 6; - const char * fn; - - fprintf(fp, POPT_("Usage:")); - if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { -/*@-boundsread@*/ - /*@-nullderef -type@*/ /* LCL: wazzup? */ - fn = con->optionStack->argv[0]; - /*@=nullderef =type@*/ -/*@=boundsread@*/ - if (fn == NULL) return len; - if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; - fprintf(fp, " %s", fn); - len += strlen(fn) + 1; - } - - return len; -} - -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) -{ - size_t leftColWidth; - - (void) showHelpIntro(con, fp); - if (con->otherHelp) - fprintf(fp, " %s\n", con->otherHelp); - else - fprintf(fp, " %s\n", POPT_("[OPTION...]")); - - leftColWidth = maxArgWidth(con->options, NULL); - singleTableHelp(con, fp, con->options, leftColWidth, NULL); -} - -/** - * Display usage text for an option. - * @param fp output file handle - * @param cursor current display position - * @param opt option(s) - * @param translation_domain translation domain - */ -static size_t singleOptionUsage(FILE * fp, size_t cursor, - const struct poptOption * opt, - /*@null@*/ const char *translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - size_t len = 4; - char shortStr[2] = { '\0', '\0' }; - const char * item = shortStr; - const char * argDescrip = getArgDescrip(opt, translation_domain); - - if (opt->shortName != '\0' && opt->longName != NULL) { - len += 2; - if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; - len += strlen(opt->longName); - } else if (opt->shortName != '\0') { - len++; - shortStr[0] = opt->shortName; - shortStr[1] = '\0'; - } else if (opt->longName) { - len += strlen(opt->longName); - if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; - item = opt->longName; - } - - if (len == 4) return cursor; - -#ifdef POPT_WCHAR_HACK - /* XXX Calculate no. of display characters. */ - if (argDescrip) { - const char * scopy = argDescrip; - mbstate_t t; - size_t n; - -/*@-boundswrite@*/ - memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */ -/*@=boundswrite@*/ - /* Determine number of characters. */ - n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t); - len += sizeof("=")-1 + n; - } -#else - if (argDescrip) - len += sizeof("=")-1 + strlen(argDescrip); -#endif - - if ((cursor + len) > 79) { - fprintf(fp, "\n "); - cursor = 7; - } - - if (opt->longName && opt->shortName) { - fprintf(fp, " [-%c|-%s%s%s%s]", - opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"), - opt->longName, - (argDescrip ? " " : ""), - (argDescrip ? argDescrip : "")); - } else { - fprintf(fp, " [-%s%s%s%s]", - ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"), - item, - (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""), - (argDescrip ? argDescrip : "")); - } - - return cursor + len + 1; -} - -/** - * Display popt alias and exec usage. - * @param fp output file handle - * @param cursor current display position - * @param item alias/exec array - * @param nitems no. of ara/exec entries - * @param translation_domain translation domain - */ -static size_t itemUsage(FILE * fp, size_t cursor, - /*@null@*/ poptItem item, int nitems, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int i; - - /*@-branchstate@*/ /* FIX: W2DO? */ - if (item != NULL) - for (i = 0; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - cursor = singleOptionUsage(fp, cursor, opt, translation_domain); - } - } - /*@=branchstate@*/ - - return cursor; -} - -/** - * Keep track of option tables already processed. - */ -typedef struct poptDone_s { - int nopts; - int maxopts; - const void ** opts; -} * poptDone; - -/** - * Display usage text for a table of options. - * @param con context - * @param fp output file handle - * @param cursor current display position - * @param opt option(s) - * @param translation_domain translation domain - * @param done tables already processed - * @return - */ -static size_t singleTableUsage(poptContext con, FILE * fp, size_t cursor, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * translation_domain, - /*@null@*/ poptDone done) - /*@globals fileSystem @*/ - /*@modifies *fp, done, fileSystem @*/ -{ - /*@-branchstate@*/ /* FIX: W2DO? */ - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - if (done) { - int i = 0; - for (i = 0; i < done->nopts; i++) { -/*@-boundsread@*/ - const void * that = done->opts[i]; -/*@=boundsread@*/ - if (that == NULL || that != opt->arg) - /*@innercontinue@*/ continue; - /*@innerbreak@*/ break; - } - /* Skip if this table has already been processed. */ - if (opt->arg == NULL || i < done->nopts) - continue; -/*@-boundswrite@*/ - if (done->nopts < done->maxopts) - done->opts[done->nopts++] = (const void *) opt->arg; -/*@=boundswrite@*/ - } - cursor = singleTableUsage(con, fp, cursor, opt->arg, - translation_domain, done); - } else if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - cursor = singleOptionUsage(fp, cursor, opt, translation_domain); - } - } - /*@=branchstate@*/ - - return cursor; -} - -/** - * Return concatenated short options for display. - * @todo Sub-tables should be recursed. - * @param opt option(s) - * @param fp output file handle - * @retval str concatenation of short options - * @return length of display string - */ -static int showShortOptions(const struct poptOption * opt, FILE * fp, - /*@null@*/ char * str) - /*@globals fileSystem @*/ - /*@modifies *str, *fp, fileSystem @*/ - /*@requires maxRead(str) >= 0 @*/ -{ - /* bufsize larger then the ascii set, lazy alloca on top level call. */ - char * s = (str != NULL ? str : memset(alloca(300), 0, 300)); - int len = 0; - -/*@-boundswrite@*/ - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg); opt++) { - if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) - s[strlen(s)] = opt->shortName; - else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) - if (opt->arg) /* XXX program error */ - len = showShortOptions(opt->arg, fp, s); - } -/*@=boundswrite@*/ - - /* On return to top level, print the short options, return print length. */ - if (s == str && *s != '\0') { - fprintf(fp, " [-%s]", s); - len = strlen(s) + sizeof(" [-]")-1; - } - return len; -} - -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) -{ - poptDone done = memset(alloca(sizeof(*done)), 0, sizeof(*done)); - size_t cursor; - - done->nopts = 0; - done->maxopts = 64; - cursor = done->maxopts * sizeof(*done->opts); -/*@-boundswrite@*/ - done->opts = memset(alloca(cursor), 0, cursor); - /*@-keeptrans@*/ - done->opts[done->nopts++] = (const void *) con->options; - /*@=keeptrans@*/ -/*@=boundswrite@*/ - - cursor = showHelpIntro(con, fp); - cursor += showShortOptions(con->options, fp, NULL); - cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done); - cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL); - cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL); - - if (con->otherHelp) { - cursor += strlen(con->otherHelp) + 1; - if (cursor > 79) fprintf(fp, "\n "); - fprintf(fp, " %s", con->otherHelp); - } - - fprintf(fp, "\n"); -} - -void poptSetOtherOptionHelp(poptContext con, const char * text) -{ - con->otherHelp = _free(con->otherHelp); - con->otherHelp = xstrdup(text); -} diff --git a/libpopt/poptint.h b/libpopt/poptint.h deleted file mode 100644 index 5e75712..0000000 --- a/libpopt/poptint.h +++ /dev/null @@ -1,116 +0,0 @@ -/** \ingroup popt - * \file popt/poptint.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPTINT -#define H_POPTINT - -/** - * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. - * @param p memory to free - * @retval NULL always - */ -/*@unused@*/ static inline /*@null@*/ void * -_free(/*@only@*/ /*@null@*/ const void * p) - /*@modifies p @*/ -{ - if (p != NULL) free((void *)p); - return NULL; -} - -/* Bit mask macros. */ -/*@-exporttype -redef @*/ -typedef unsigned int __pbm_bits; -/*@=exporttype =redef @*/ -#define __PBM_NBITS (8 * sizeof (__pbm_bits)) -#define __PBM_IX(d) ((d) / __PBM_NBITS) -#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) -/*@-exporttype -redef @*/ -typedef struct { - __pbm_bits bits[1]; -} pbm_set; -/*@=exporttype =redef @*/ -#define __PBM_BITS(set) ((set)->bits) - -#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) -#define PBM_FREE(s) _free(s); -#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) -#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) -#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) - -struct optionStackEntry { - int argc; -/*@only@*/ /*@null@*/ - const char ** argv; -/*@only@*/ /*@null@*/ - pbm_set * argb; - int next; -/*@only@*/ /*@null@*/ - const char * nextArg; -/*@observer@*/ /*@null@*/ - const char * nextCharArg; -/*@dependent@*/ /*@null@*/ - poptItem currAlias; - int stuffed; -}; - -struct poptContext_s { - struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; -/*@dependent@*/ - struct optionStackEntry * os; -/*@owned@*/ /*@null@*/ - const char ** leftovers; - int numLeftovers; - int nextLeftover; -/*@keep@*/ - const struct poptOption * options; - int restLeftover; -/*@only@*/ /*@null@*/ - const char * appName; -/*@only@*/ /*@null@*/ - poptItem aliases; - int numAliases; - int flags; -/*@owned@*/ /*@null@*/ - poptItem execs; - int numExecs; -/*@only@*/ /*@null@*/ - const char ** finalArgv; - int finalArgvCount; - int finalArgvAlloced; -/*@dependent@*/ /*@null@*/ - poptItem doExec; -/*@only@*/ - const char * execPath; - int execAbsolute; -/*@only@*/ /*@relnull@*/ - const char * otherHelp; -/*@null@*/ - pbm_set * arg_strip; -}; - -#ifdef HAVE_LIBINTL_H -#include <libintl.h> -#endif - -#if defined(HAVE_GETTEXT) && !defined(__LCLINT__) -#define _(foo) gettext(foo) -#else -#define _(foo) foo -#endif - -#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) -#define D_(dom, str) dgettext(dom, str) -#define POPT_(foo) D_("popt", foo) -#else -#define D_(dom, str) str -#define POPT_(foo) foo -#endif - -#define N_(foo) foo - -#endif diff --git a/libpopt/poptparse.c b/libpopt/poptparse.c deleted file mode 100644 index a0dea80..0000000 --- a/libpopt/poptparse.c +++ /dev/null @@ -1,227 +0,0 @@ -/** \ingroup popt - * \file popt/poptparse.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" - -#define POPT_ARGV_ARRAY_GROW_DELTA 5 - -/*@-boundswrite@*/ -int poptDupArgv(int argc, const char **argv, - int * argcPtr, const char *** argvPtr) -{ - size_t nb = (argc + 1) * sizeof(*argv); - const char ** argv2; - char * dst; - int i; - - if (argc <= 0 || argv == NULL) /* XXX can't happen */ - return POPT_ERROR_NOARG; - for (i = 0; i < argc; i++) { - if (argv[i] == NULL) - return POPT_ERROR_NOARG; - nb += strlen(argv[i]) + 1; - } - - dst = malloc(nb); - if (dst == NULL) /* XXX can't happen */ - return POPT_ERROR_MALLOC; - argv2 = (void *) dst; - dst += (argc + 1) * sizeof(*argv); - - /*@-branchstate@*/ - for (i = 0; i < argc; i++) { - argv2[i] = dst; - dst += strlen(strcpy(dst, argv[i])) + 1; - } - /*@=branchstate@*/ - argv2[argc] = NULL; - - if (argvPtr) { - *argvPtr = argv2; - } else { - free(argv2); - argv2 = NULL; - } - if (argcPtr) - *argcPtr = argc; - return 0; -} -/*@=boundswrite@*/ - -/*@-bounds@*/ -int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) -{ - const char * src; - char quote = '\0'; - int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; - const char ** argv = malloc(sizeof(*argv) * argvAlloced); - int argc = 0; - int buflen = strlen(s) + 1; - char * buf = memset(alloca(buflen), 0, buflen); - int rc = POPT_ERROR_MALLOC; - - if (argv == NULL) return rc; - argv[argc] = buf; - - for (src = s; *src != '\0'; src++) { - if (quote == *src) { - quote = '\0'; - } else if (quote != '\0') { - if (*src == '\\') { - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - if (*src != quote) *buf++ = '\\'; - } - *buf++ = *src; - } else if (isspace(*src)) { - if (*argv[argc] != '\0') { - buf++, argc++; - if (argc == argvAlloced) { - argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; - argv = realloc(argv, sizeof(*argv) * argvAlloced); - if (argv == NULL) goto exit; - } - argv[argc] = buf; - } - } else switch (*src) { - case '"': - case '\'': - quote = *src; - /*@switchbreak@*/ break; - case '\\': - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - /*@fallthrough@*/ - default: - *buf++ = *src; - /*@switchbreak@*/ break; - } - } - - if (strlen(argv[argc])) { - argc++, buf++; - } - - rc = poptDupArgv(argc, argv, argcPtr, argvPtr); - -exit: - if (argv) free(argv); - return rc; -} -/*@=bounds@*/ - -/* still in the dev stage. - * return values, perhaps 1== file erro - * 2== line to long - * 3== umm.... more? - */ -int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) -{ - char line[999]; - char * argstr; - char * p; - char * q; - char * x; - int t; - int argvlen = 0; - size_t maxlinelen = sizeof(line); - size_t linelen; - int maxargvlen = 480; - int linenum = 0; - - *argstrp = NULL; - - /* | this_is = our_line - * p q x - */ - - if (fp == NULL) - return POPT_ERROR_NULLARG; - - argstr = calloc(maxargvlen, sizeof(*argstr)); - if (argstr == NULL) return POPT_ERROR_MALLOC; - - while (fgets(line, (int)maxlinelen, fp) != NULL) { - linenum++; - p = line; - - /* loop until first non-space char or EOL */ - while( *p != '\0' && isspace(*p) ) - p++; - - linelen = strlen(p); - if (linelen >= maxlinelen-1) - return POPT_ERROR_OVERFLOW; /* XXX line too long */ - - if (*p == '\0' || *p == '\n') continue; /* line is empty */ - if (*p == '#') continue; /* comment line */ - - q = p; - - while (*q != '\0' && (!isspace(*q)) && *q != '=') - q++; - - if (isspace(*q)) { - /* a space after the name, find next non space */ - *q++='\0'; - while( *q != '\0' && isspace((int)*q) ) q++; - } - if (*q == '\0') { - /* single command line option (ie, no name=val, just name) */ - q[-1] = '\0'; /* kill off newline from fgets() call */ - argvlen += (t = q - p) + (sizeof(" --")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - continue; - } - if (*q != '=') - continue; /* XXX for now, silently ignore bogus line */ - - /* *q is an equal sign. */ - *q++ = '\0'; - - /* find next non-space letter of value */ - while (*q != '\0' && isspace(*q)) - q++; - if (*q == '\0') - continue; /* XXX silently ignore missing value */ - - /* now, loop and strip all ending whitespace */ - x = p + linelen; - while (isspace(*--x)) - *x = 0; /* null out last char if space (including fgets() NL) */ - - /* rest of line accept */ - t = x - p; - argvlen += t + (sizeof("' --='")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - strcat(argstr, "=\""); - strcat(argstr, q); - strcat(argstr, "\""); - } - - *argstrp = argstr; - return 0; -} diff --git a/libpopt/system.h b/libpopt/system.h deleted file mode 100644 index c3d46cb..0000000 --- a/libpopt/system.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined (__GLIBC__) && defined(__LCLINT__) -/*@-declundef@*/ -/*@unchecked@*/ -extern __const __int32_t *__ctype_tolower; -/*@unchecked@*/ -extern __const __int32_t *__ctype_toupper; -/*@=declundef@*/ -#endif - -#include <ctype.h> - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> - -#if HAVE_MCHECK_H -#include <mcheck.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef __NeXT -/* access macros are not declared in non posix mode in unistd.h - - don't try to use posix on NeXTstep 3.3 ! */ -#include <libc.h> -#endif - -#if defined(__LCLINT__) -/*@-declundef -incondefs @*/ /* LCL: missing annotation */ -/*@only@*/ /*@out@*/ -void * alloca (size_t __size) - /*@ensures MaxSet(result) == (__size - 1) @*/ - /*@*/; -/*@=declundef =incondefs @*/ -#endif - -/* AIX requires this to be the first thing in the file. */ -#ifndef __GNUC__ -# if HAVE_ALLOCA_H -# include <alloca.h> -# else -# ifdef _AIX -#pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#elif defined(__GNUC__) && defined(__STRICT_ANSI__) -#define alloca __builtin_alloca -#endif - -/*@-redecl -redef@*/ -/*@mayexit@*/ /*@only@*/ /*@unused@*/ -char * xstrdup (const char *str) - /*@*/; -/*@=redecl =redef@*/ - -#if HAVE_MCHECK_H && defined(__GNUC__) -#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL) -#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str))) -#else -#define xstrdup(_str) strdup(_str) -#endif /* HAVE_MCHECK_H && defined(__GNUC__) */ - -#if HAVE___SECURE_GETENV && !defined(__LCLINT__) -#define getenv(_s) __secure_getenv(_s) -#endif - -#include "popt.h" diff --git a/libutil/Android.mk b/libutil/Android.mk deleted file mode 100644 index 29f3bfb..0000000 --- a/libutil/Android.mk +++ /dev/null @@ -1,21 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - op_cpufreq.c \ - op_deviceio.c \ - op_file.c \ - op_fileio.c \ - op_get_time.c \ - op_libiberty.c \ - op_lockfile.c \ - op_popt.c \ - op_string.c \ - op_version.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. - -LOCAL_MODULE := libutil - -include $(BUILD_STATIC_LIBRARY) diff --git a/libutil/fscanf.c b/libutil/fscanf.c deleted file mode 100644 index d567324..0000000 --- a/libutil/fscanf.c +++ /dev/null @@ -1,22 +0,0 @@ -#include <stdio.h> - -// ugly hack because we don't have fscanf - -int fscanf(FILE* stream, const char* format, int* value) -{ - int c; - int r = 0; - do { - c = fgetc(stream); - if (c>='0' && c<='9') { - r = r*10 + (c-'0'); - continue; - } - break; - } while (1); - - *value = r; - - // gahhhh - return 1; -} diff --git a/libutil/op_cpufreq.c b/libutil/op_cpufreq.c deleted file mode 100644 index 78a6333..0000000 --- a/libutil/op_cpufreq.c +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file op_cpufreq.c - * get cpu frequency definition - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdio.h> -#include <stdlib.h> - -#include "op_fileio.h" - -double op_cpu_frequency(void) -{ - double fval = 0.0; - unsigned long uval; - char * line = NULL; - - FILE * fp = op_try_open_file("/proc/cpuinfo", "r"); - if (!fp) - return 0.0; - - while (1) { - line = op_get_line(fp); - - if (!line) - break; - - if (line[0] == '\0') { - free(line); - continue; - } - - /* x86/parisc/ia64/x86_64 */ - if (sscanf(line, "cpu MHz : %lf", &fval) == 1) - break; - /* ppc/ppc64 */ - if (sscanf(line, "clock : %lfMHz", &fval) == 1) - break; - /* alpha */ - if (sscanf(line, "cycle frequency [Hz] : %lu", &uval) == 1) { - fval = uval / 1E6; - break; - } - /* sparc64 if CONFIG_SMP only */ - if (sscanf(line, "Cpu0ClkTck : %lx", &uval) == 1) { - fval = uval / 1E6; - break; - } - /* s390 doesn't provide cpu freq, checked up to 2.6-test4 */ - - free(line); - } - - if (line) - free(line); - op_close_file(fp); - - return fval; -} diff --git a/libutil/op_cpufreq.h b/libutil/op_cpufreq.h deleted file mode 100644 index 0a71172..0000000 --- a/libutil/op_cpufreq.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file op_cpufreq.h - * get cpu frequency declaration - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_CPUFREQ_H -#define OP_CPUFREQ_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * return the estimated cpu frequency in Mhz through - * parsing /proc/cpuinfo, return 0 if this information - * is not avalaible e.g. sparc64 with a non SMP kernel - */ -double op_cpu_frequency(void); - -#if defined(__cplusplus) -} -#endif - -#endif /* !OP_CPUFREQ_H */ diff --git a/libutil/op_deviceio.c b/libutil/op_deviceio.c deleted file mode 100644 index 8210304..0000000 --- a/libutil/op_deviceio.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file op_deviceio.c - * Reading from a special device - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "op_deviceio.h" - -#include <sys/types.h> -#include <fcntl.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -fd_t op_open_device(char const * name) -{ - return open(name, O_RDONLY); -} - - -ssize_t op_read_device(fd_t devfd, void * buf, size_t size) -{ - ssize_t count; - - lseek(devfd, 0, SEEK_SET); - - count = read(devfd, buf, size); - - if (count < 0 && errno != EINTR && errno != EAGAIN) { - perror("oprofiled:op_read_device: "); - exit(EXIT_FAILURE); - } - - return count; -} diff --git a/libutil/op_deviceio.h b/libutil/op_deviceio.h deleted file mode 100644 index f3bd4c2..0000000 --- a/libutil/op_deviceio.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file op_deviceio.h - * Reading from a special device - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_DEVICEIO_H -#define OP_DEVICEIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "op_types.h" - -#include <unistd.h> - -/** - * op_open_device - open a special char device for reading - * @param name file name of device file - * - * Open the special file name. Returns the file descriptor - * for the file or -1 on error. - */ -fd_t op_open_device(char const * name); - -/** - * op_read_device - read from a special char device - * @param devfd file descriptor of device - * @param buf buffer - * @param size size of buffer - * - * Read size bytes from a device into buffer buf. - * A seek to the start of the device file is done first - * then a read is requested in one go of size bytes. - * - * It is the caller's responsibility to do further op_read_device() - * calls if the number of bytes read is not what is requested - * (where this is applicable). - * - * The number of bytes read is returned, or a negative number - * on failure (in which case errno will be set). If the call is - * interrupted, then errno will be EINTR, and the client should - * arrange for re-starting the read if necessary. - */ -ssize_t op_read_device(fd_t devfd, void * buf, size_t size); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_DEVICEIO_H */ diff --git a/libutil/op_file.c b/libutil/op_file.c deleted file mode 100644 index e3e6cb6..0000000 --- a/libutil/op_file.c +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file op_file.c - * Useful file management helpers - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> -#include <fnmatch.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <limits.h> - -#include "op_file.h" -#include "op_libiberty.h" - -int op_file_readable(char const * file) -{ - struct stat st; - return !stat(file, &st) && S_ISREG(st.st_mode) && !access(file, R_OK); -} - - -time_t op_get_mtime(char const * file) -{ - struct stat st; - - if (stat(file, &st)) - return 0; - - return st.st_mtime; -} - - -int create_dir(char const * dir) -{ - if (mkdir(dir, 0755)) { - /* FIXME: Does not verify existing is a dir */ - if (errno == EEXIST) - return 0; - return errno; - } - - return 0; -} - - -int create_path(char const * path) -{ - int ret = 0; - - char * str = xstrdup(path); - - char * pos = str[0] == '/' ? str + 1 : str; - - for ( ; (pos = strchr(pos, '/')) != NULL; ++pos) { - *pos = '\0'; - ret = create_dir(str); - *pos = '/'; - if (ret) - break; - } - - free(str); - return ret; -} - - -inline static int is_dot_or_dotdot(char const * name) -{ - return name[0] == '.' && - (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0')); -} - - -/* If non-null is returned, the caller is responsible for freeing - * the memory allocated for the return value. */ -static char * make_pathname_from_dirent(char const * basedir, - struct dirent * ent, - struct stat * st_buf) -{ - int name_len; - char * name; - name_len = strlen(basedir) + strlen("/") + strlen(ent->d_name) + 1; - name = xmalloc(name_len); - sprintf(name, "%s/%s", basedir, ent->d_name); - if (stat(name, st_buf) != 0) { - free(name); - name = NULL; - } - return name; -} - - -int get_matching_pathnames(void * name_list, get_pathname_callback getpathname, - char const * base_dir, char const * filter, - enum recursion_type recursion) -{ -/* The algorithm below depends on recursion type (of which there are 3) - * and whether the current dirent matches the filter. There are 6 possible - * different behaviors, which is why we define 6 case below in the switch - * statement of the algorithm. Actually, when the recursion type is - * MATCH_DIR_ONLY_RECURSION, the behavior is the same, whether or not the dir - * entry matches the filter. However, the behavior of the recursion types - * NO_RECURSION and MATCH_ANY_ENTRY_RECURSION do depend on the dir entry - * filter match, so for simplicity, we perform this match for all recursion - * types and logically OR the match result with the value of the passed - * recursion_type. - */ -#define NO_MATCH 0 -#define MATCH 1 - - DIR * dir; - struct dirent * ent; - struct stat stat_buffer; - int match; - char * name = NULL; - - if (!(dir = opendir(base_dir))) - return -1; - while ((ent = readdir(dir)) != 0) { - if (is_dot_or_dotdot(ent->d_name)) - continue; - if (fnmatch(filter, ent->d_name, 0) == 0) - match = 1; - else - match = 0; - - switch (recursion | match) { - case NO_RECURSION + NO_MATCH: - case MATCH_ANY_ENTRY_RECURSION + NO_MATCH: - // nothing to do but continue the loop - break; - case NO_RECURSION + MATCH: - getpathname(ent->d_name, name_list); - break; - case MATCH_ANY_ENTRY_RECURSION + MATCH: - name = make_pathname_from_dirent(base_dir, ent, - &stat_buffer); - if (name && S_ISDIR(stat_buffer.st_mode) && - !S_ISLNK(stat_buffer.st_mode)) { - get_matching_pathnames( - name_list, getpathname, - name, filter, recursion); - } else { - getpathname(name, name_list); - } - free(name); - break; - case MATCH_DIR_ONLY_RECURSION + NO_MATCH: - case MATCH_DIR_ONLY_RECURSION + MATCH: - name = make_pathname_from_dirent(base_dir, ent, - &stat_buffer); - if (name && S_ISDIR(stat_buffer.st_mode) && - !S_ISLNK(stat_buffer.st_mode)) { - /* Check if full directory name contains - * match to the filter; if so, add it to - * name_list and quit; else, recurse. - */ - if (!fnmatch(filter, name, 0)) { - getpathname(name, name_list); - } else { - get_matching_pathnames( - name_list, getpathname, - name, filter, recursion); - } - } - free(name); - break; - } - } - closedir(dir); - - return 0; -} diff --git a/libutil/op_file.h b/libutil/op_file.h deleted file mode 100644 index d22862c..0000000 --- a/libutil/op_file.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file op_file.h - * Useful file management helpers - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_FILE_H -#define OP_FILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> - -/** - * op_file_readable - is a file readable - * @param file file name - * - * Return true if the given file is readable and regular. - * - * Beware of race conditions ! - */ -int op_file_readable(char const * file); - -/** - * op_get_mtime - get mtime of file - * @param file file name - * - * Returns the mtime of the given file or 0 on failure - */ -time_t op_get_mtime(char const * file); - -/** - * create_dir - create a directory - * @param dir the directory name to create - * - * Returns 0 on success. - */ -int create_dir(char const * dir); - - -/** - * create_path - create a path - * @param path the path to create - * - * create directory for each dir components in path - * the last path component is not considered as a directory - * but as a filename - * - * Returns 0 on success. - */ -int create_path(char const * path); - -/** - * Clients of get_matching_pathnames must provide their own implementation - * of get_pathname_callback. - */ -typedef void (*get_pathname_callback)(char const * pathname, void * name_list); - -/* This enum is intended solely for the use of get_matching_pathnames(), - * bit 0 is reserved for internal use..*/ -enum recursion_type { - NO_RECURSION = 2, - MATCH_ANY_ENTRY_RECURSION = 4, - MATCH_DIR_ONLY_RECURSION = 8, -}; -/** - * @param name_list where to store result - * @param get_pathname_callback client-provided callback function - * @param base_dir directory from where lookup starts - * @param filter a pathname filter - * @param recursion recursion_type -- see above enum and following description: - * NO_RECURSION: Find matching files from passed base_dir and call - * get_pathname_callback to add entry to name_list to be returned. - * MATCH_ANY_ENTRY_RECURSION: Starting at base_dir, for each entry in the - * dir that matches the filter: if entry is of type 'dir', recurse; - * else call get_pathname_callback to add entry to name_list to be - * returned. - * MATCH_DIR_ONLY_RECURSION: Starting at base_dir, if an entry in the - * dir is of type 'dir' and its complete pathname contains a match to - * the filter, call get_pathname_callback to add entry to name_list to - * be returned; else recurse. - * - * Returns 0 on success. - * - * Return a list of pathnames under base_dir, filtered by filter and optionally - * looking in sub-directory. See description above of the recursion_type - * parameter for more details. - * NOTE: For C clients: Your implementation of the get_pathname_callback - * function will probably dynamically allocate storage for elements - * added to name_list. If so, remember to free that memory when it's - * no longer needed. - */ -int get_matching_pathnames(void * name_list, get_pathname_callback, - char const * base_dir, char const * filter, - enum recursion_type recursion); - - -#ifdef __cplusplus -} -#endif - -#endif /* OP_FILE_H */ diff --git a/libutil/op_fileio.c b/libutil/op_fileio.c deleted file mode 100644 index 9b3e21d..0000000 --- a/libutil/op_fileio.c +++ /dev/null @@ -1,228 +0,0 @@ -/** - * @file op_fileio.c - * Reading from / writing to files - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <unistd.h> - -#include "op_fileio.h" - -#include "op_libiberty.h" - -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -static FILE * op_do_open_file(char const * name, char const * mode, int fatal) -{ - FILE * fp; - - fp = fopen(name, mode); - - if (!fp) { - if (fatal) { - fprintf(stderr,"oprofiled:op_do_open_file: %s: %s", - name, strerror(errno)); - exit(EXIT_FAILURE); - } - } - - return fp; -} - - -FILE * op_try_open_file(char const * name, char const * mode) -{ - return op_do_open_file(name, mode, 0); -} - - -FILE * op_open_file(char const * name, char const * mode) -{ - return op_do_open_file(name, mode, 1); -} - - -void op_close_file(FILE * fp) -{ - if (fclose(fp)) - perror("oprofiled:op_close_file: "); -} - - -void op_write_file(FILE * fp, void const * buf, size_t size) -{ - size_t written; - - if (size == 0) - return; - - written = fwrite(buf, size, 1, fp); - - if (written != 1) { - fprintf(stderr, - "oprofiled:op_write_file: wrote less than expected: %lu bytes.\n", - (unsigned long)size); - exit(EXIT_FAILURE); - } -} - - -void op_write_u8(FILE * fp, u8 val) -{ - op_write_file(fp, &val, sizeof(val)); -} - - -void op_write_u32(FILE * fp, u32 val) -{ - op_write_file(fp, &val, sizeof(val)); -} - - -void op_write_u64(FILE * fp, u64 val) -{ - op_write_file(fp, &val, sizeof(val)); -} - - -u32 op_read_int_from_file(char const * filename, int fatal) -{ - FILE * fp; - u32 value; - - fp = fopen(filename, "r"); - if (fp == NULL) { - if (!fatal) - return (u32)-1; - fprintf(stderr, - "op_read_int_from_file: Failed to open %s, reason %s\n", - filename, strerror(errno)); - exit(EXIT_FAILURE); - } - - if (fscanf(fp, "%u", &value) != 1) { - fclose(fp); - if (!fatal) - return (u32)-1; - fprintf(stderr, - "op_read_int_from_file: Failed to convert contents of file %s to integer\n", - filename); - exit(EXIT_FAILURE); - } - - fclose(fp); - - return value; -} - - -char * op_get_line(FILE * fp) -{ - char * buf; - char * cp; - int c; - size_t max = 512; - - buf = xmalloc(max); - cp = buf; - - while (1) { - switch (c = getc(fp)) { - case EOF: - free(buf); - return NULL; - break; - - case '\n': - case '\0': - *cp = '\0'; - return buf; - break; - - default: - *cp = (char)c; - cp++; - if (((size_t)(cp - buf)) == max) { - buf = xrealloc(buf, max + 128); - cp = buf + max; - max += 128; - } - break; - } - } -} - - -/* FIXME the debug info stuff should be handled by binutils */ -unsigned long -calc_crc32(unsigned long crc, unsigned char * buf, size_t len) -{ - static const unsigned long crc32_table[256] = - { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d - }; - unsigned char * end; - - crc = ~crc & 0xffffffff; - for (end = buf + len; buf < end; ++buf) - crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); - return ~crc & 0xffffffff; -} diff --git a/libutil/op_fileio.h b/libutil/op_fileio.h deleted file mode 100644 index 49b126d..0000000 --- a/libutil/op_fileio.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file op_fileio.h - * Reading from / writing to files - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_FILEIO_H -#define OP_FILEIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "op_types.h" - -#include <stdio.h> - -/** - * op_try_open_file - open a file - * @param name file name - * @param mode mode string - * - * Open a file name. - * Returns file handle or %NULL on failure. - */ -FILE * op_try_open_file(char const * name, char const * mode); - -/** - * op_open_file - open a file - * @param name file name - * @param mode mode string - * - * Open a file name. - * Failure to open is fatal. - */ -FILE * op_open_file(char const * name, char const * mode); - -/** - * op_read_int_from_file - parse an ASCII value from a file into an integer - * @param filename name of file to parse integer value from - * @param fatal non-zero if any error must be fatal - * - * Reads an ASCII integer from the given file. If an error occur and fatal is - * zero (u32)-1 is returned else the value read in is returned. - */ -u32 op_read_int_from_file(char const * filename, int fatal); - -/** - * op_close_file - close a file - * @param fp file pointer - * - * Closes a file pointer. A non-fatal - * error message is produced if the - * close fails. - */ -void op_close_file(FILE * fp); - -/** - * op_write_file - write to a file - * @param fp file pointer - * @param buf buffer - * @param size nr. of bytes to write - * - * Write size bytes of buffer buf to a file. - * Failure is fatal. - */ -void op_write_file(FILE * fp, void const * buf, size_t size); - -/** - * op_write_u32 - write four bytes to a file - * @param fp file pointer - * @param val value to write - * - * Write an unsigned four-byte value val to a file. - * Failure is fatal. - * - * No byte-swapping is done. - */ -void op_write_u32(FILE * fp, u32 val); - -/** - * op_write_u64 - write eight bytes to a file - * @param fp file pointer - * @param val value to write - * - * Write an unsigned eight-byte value val to a file. - * Failure is fatal. - * - * No byte-swapping is done. - */ -void op_write_u64(FILE * fp, u64 val); - -/** - * op_write_u8 - write a byte to a file - * @param fp file pointer - * @param val value to write - * - * Write an unsigned byte value val to a file. - * Failure is fatal. - */ -void op_write_u8(FILE * fp, u8 val); - -/** - * op_get_line - read an ASCII line from a file - * @param fp file pointer - * - * Get a line of ASCII text from a file. The file is read - * up to the first '\0' or '\n'. A trailing '\n' is deleted. - * - * Returns the dynamically-allocated string containing - * that line. At the end of a file NULL will be returned. - * be returned. - * - * The string returned must be free()d by the caller. - * - * getline() is not a proper solution to replace this function - */ -char * op_get_line(FILE * fp); - -/** - * calc_crc32 - * @param crc current value - * @param buf pointer to buffer - * @param len - * - * Returns current crc computed from the crc argument and the - * characters in len characters in buf. - */ -unsigned long calc_crc32(unsigned long crc, unsigned char * buf, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_FILEIO_H */ diff --git a/libutil/op_get_time.c b/libutil/op_get_time.c deleted file mode 100644 index c094c63..0000000 --- a/libutil/op_get_time.c +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file op_get_time.c - * Get current time as a string - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "op_get_time.h" - -#include <time.h> - -char * op_get_time(void) -{ - time_t t = time(NULL); - - if (t == -1) - return ""; - - return ctime(&t); -} diff --git a/libutil/op_get_time.h b/libutil/op_get_time.h deleted file mode 100644 index 8f96273..0000000 --- a/libutil/op_get_time.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file op_get_time.h - * Get current time as a string - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_GET_TIME_H -#define OP_GET_TIME_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * op_get_time - get current date and time - * - * Returns a string representing the current date - * and time, or an empty string on error. - * - * The string is statically allocated and should not be freed. - */ -char * op_get_time(void); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_GET_TIME_H */ diff --git a/libutil/op_growable_buffer.c b/libutil/op_growable_buffer.c deleted file mode 100644 index d138f36..0000000 --- a/libutil/op_growable_buffer.c +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file op_growable_buffer.c - * a growable buffer implementation - * - * @remark Copyright 2007 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#include "op_growable_buffer.h" -#include "op_libiberty.h" - -#include <string.h> -#include <stdlib.h> - -void init_buffer(struct growable_buffer * b) -{ - b->max_size = 0; - b->size = 0; - b->p = NULL; -} - - -void free_buffer(struct growable_buffer * b) -{ - free(b->p); -} - - -static void grow_buffer(struct growable_buffer * b) -{ - size_t new_size = (b->max_size + b->size) * 2; - b->p = xrealloc(b->p, new_size); - b->max_size = new_size; -} - - -void add_data(struct growable_buffer * b, void const * data, size_t len) -{ - size_t old_size = b->size; - b->size += len; - if (b->size > b->max_size) - grow_buffer(b); - memcpy(b->p + old_size, data, len); -} diff --git a/libutil/op_growable_buffer.h b/libutil/op_growable_buffer.h deleted file mode 100644 index 491969a..0000000 --- a/libutil/op_growable_buffer.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file op_growable_buffer.h - * a growable buffer interface - * - * @remark Copyright 2007 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#ifndef OP_GROWABLE_BUFFER_H -#define OP_GROWABLE_BUFFER_H - -#include <stddef.h> - -struct growable_buffer { - void * p; - size_t size; - size_t max_size; -}; - -/** - * init_buffer - initialize an empty buffer - * @param buffer the buffer to initialize - * - * init_buffer do not do any allocation, the first allocation will occur - * when add_data() with a non zero len param will be called. - */ -void init_buffer(struct growable_buffer * buffer); - -/** - * free_buffer - free the memory allocated for this buffer - * @param buffer the buffer to free - */ -void free_buffer(struct growable_buffer * buffer); - -/** - * add_data - add data to this buffer - * @param b the buffer where to add data - * @param data a pointer to the data to add - * @param len number of byte to add to the buffer - */ -void add_data(struct growable_buffer * b, void const * data, size_t len); - -#endif /* !OP_GROWABLE_BUFFER_H */ diff --git a/libutil/op_libiberty.c b/libutil/op_libiberty.c deleted file mode 100644 index 0cf45d3..0000000 --- a/libutil/op_libiberty.c +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file op_libiberty.c - * Wrapper for libiberty - always use this instead of - * libiberty.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <string.h> - -#include "op_libiberty.h" - -#ifndef HAVE_XCALLOC -/* some system have a valid libiberty without xcalloc */ -void * xcalloc(size_t n_elem, size_t sz) -{ - void * ptr = xmalloc(n_elem * sz); - - memset(ptr, '\0', n_elem * sz); - - return ptr; -} -#endif - -#ifndef HAVE_XMEMDUP -void * xmemdup (void const * input, size_t copy_size, size_t alloc_size) -{ - void * output = xcalloc(1, alloc_size); - - memcpy(output, input, copy_size); - - return output; -} -#endif diff --git a/libutil/op_libiberty.h b/libutil/op_libiberty.h deleted file mode 100644 index ea02a50..0000000 --- a/libutil/op_libiberty.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file op_libiberty.h - * Wrapper for libiberty - always use this instead of - * libiberty.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_LIBIBERTY_H -#define OP_LIBIBERTY_H - -#include <stddef.h> - -#include "config.h" - -#ifdef MALLOC_ATTRIBUTE_OK -#define OP_ATTRIB_MALLOC __attribute__((malloc)) -#else -#define OP_ATTRIB_MALLOC -#endif - -#ifdef HAVE_LIBIBERTY_H -#include <libiberty.h> -#else - -#ifdef __cplusplus -extern "C" { -#endif - -/* some system have a libiberty.a but no libiberty.h so we must provide - * ourself the missing proto */ -#ifndef HAVE_LIBIBERTY_H - -/* Set the program name used by xmalloc. */ -void xmalloc_set_program_name(char const *); - -/* Allocate memory without fail. If malloc fails, this will print a - message to stderr (using the name set by xmalloc_set_program_name, - if any) and then call xexit. */ -void * xmalloc(size_t) OP_ATTRIB_MALLOC; - -/* Reallocate memory without fail. This works like xmalloc. Note, - realloc type functions are not suitable for attribute malloc since - they may return the same address across multiple calls. */ -void * xrealloc(void *, size_t); - -/* Allocate memory without fail and set it to zero. This works like xmalloc */ -void * xcalloc(size_t, size_t) OP_ATTRIB_MALLOC; - -/* Copy a string into a memory buffer without fail. */ -char * xstrdup(char const *) OP_ATTRIB_MALLOC; - -/** - * Duplicates a region of memory without fail. First, alloc_size bytes - * are allocated, then copy_size bytes from input are copied into - * it, and the new memory is returned. If fewer bytes are copied than were - * allocated, the remaining memory is zeroed. - */ -void * xmemdup(void const *, size_t, size_t) OP_ATTRIB_MALLOC; - -#endif /* !HAVE_LIBIBERTY_H */ - -#ifdef ANDROID -#define xmalloc(s) malloc(s) -#define xrealloc(p,s) realloc(p,s) -#define xstrdup(str) strdup(str) -#define xmalloc_set_program_name(n) -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* !HAVE_LIBIBERTY_H */ - -#endif /* OP_LIBIBERTY_H */ diff --git a/libutil/op_list.h b/libutil/op_list.h deleted file mode 100644 index ed0cd8a..0000000 --- a/libutil/op_list.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file op_list.h - * Kernel-style lists - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Linux kernel authors - */ - -#ifndef OP_LIST_H -#define OP_LIST_H - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head * next, * prev; -}; - -/** - * list_init - init a new entry - * @param ptr the list to init - * - * Init a list head to create an empty list from it - */ -static __inline__ void list_init(struct list_head * ptr) -{ - ptr->next = ptr; - ptr->prev = ptr; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_add(struct list_head * new_entry, - struct list_head * prev, - struct list_head * next) -{ - next->prev = new_entry; - new_entry->next = next; - new_entry->prev = prev; - prev->next = new_entry; -} - -/** - * list_add - add a new entry - * @param new new entry to be added - * @param head list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static __inline__ void list_add(struct list_head * new_entry, struct list_head * head) -{ - __list_add(new_entry, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @param new new entry to be added - * @param head list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static __inline__ void list_add_tail(struct list_head * new_entry, struct list_head * head) -{ - __list_add(new_entry, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_del(struct list_head * prev, - struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @param entry the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static __inline__ void list_del(struct list_head * entry) -{ - __list_del(entry->prev, entry->next); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @param entry the element to delete from the list. - */ -static __inline__ void list_del_init(struct list_head * entry) -{ - __list_del(entry->prev, entry->next); - list_init(entry); -} - -/** - * list_empty - tests whether a list is empty - * @param head the list to test. - */ -static __inline__ int list_empty(struct list_head const * head) -{ - return head->next == head; -} - -/** - * list_splice - join two lists - * @param list the new list to add. - * @param head the place to add it in the first list. - */ -static __inline__ void list_splice(struct list_head * list, struct list_head * head) -{ - struct list_head * first = list->next; - - if (first != list) { - struct list_head * last = list->prev; - struct list_head * at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * list_entry - get the struct for this entry - * @param ptr the &struct list_head pointer. - * @param type the type of the struct this is embedded in. - * @param member the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * list_for_each - iterate over a list - * @param pos the &struct list_head to use as a loop counter. - * @param head the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @param pos the &struct list_head to use as a loop counter. - * @param n another &struct list_head to use as temporary storage - * @param head the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) - -#endif /* OP_LIST_H */ diff --git a/libutil/op_lockfile.c b/libutil/op_lockfile.c deleted file mode 100644 index 26e3249..0000000 --- a/libutil/op_lockfile.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file op_lockfile.c - * PID-based lockfile management - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include "op_lockfile.h" -#include "op_file.h" - -#include <errno.h> - -#include <sys/types.h> -#include <stdio.h> -#include <signal.h> -#include <unistd.h> - -static pid_t op_read_lock_file(char const * file) -{ - FILE * fp; - pid_t value; - - fp = fopen(file, "r"); - if (fp == NULL) - return 0; - - if (fscanf(fp, "%d", &value) != 1) { - fclose(fp); - return 0; - } - - fclose(fp); - - return value; -} - - -int op_write_lock_file(char const * file) -{ - FILE * fp; - - if (op_file_readable(file)) { - pid_t pid = op_read_lock_file(file); - - /* FIXME: ESRCH vs. EPERM */ - if (kill(pid, 0)) { - int err = unlink(file); - fprintf(stderr, "Removing stale lock file %s\n", - file); - if (err) - return err; - } else { - return EEXIST; - } - } - - fp = fopen(file, "w"); - if (!fp) - return errno; - - fprintf(fp, "%d", getpid()); - fclose(fp); - - return 0; -} diff --git a/libutil/op_lockfile.h b/libutil/op_lockfile.h deleted file mode 100644 index fcc269c..0000000 --- a/libutil/op_lockfile.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file op_lockfile.h - * PID-based lockfile management - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_LOCKFILE_H -#define OP_LOCKFILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> - -/** - * op_write_lock_file - write a lock file - * \return errno on failure, or 0 on success - * - * Write the pid into the given lock file. Stale - * lock files are detected and reset. - */ -int op_write_lock_file(char const * file); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_LOCKFILE_H */ diff --git a/libutil/op_popt.c b/libutil/op_popt.c deleted file mode 100644 index de96364..0000000 --- a/libutil/op_popt.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file op_popt.c - * Wrapper for libpopt - always use this rather - * than popt.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdlib.h> -#include "op_libiberty.h" -#include "op_popt.h" - -poptContext op_poptGetContext(char const * name, - int argc, char const ** argv, - struct poptOption const * options, int flags) -{ - poptContext optcon; - int c; - - xmalloc_set_program_name(argv[0]); - -#ifdef CONST_POPT - optcon = poptGetContext(name, argc, argv, options, flags); -#else - optcon = poptGetContext((char *)name, argc, (char **)argv, options, flags); -#endif - - c = poptGetNextOpt(optcon); - - if (c < -1) { - fprintf(stderr, "%s: %s: %s\n", argv[0], - poptBadOption(optcon, POPT_BADOPTION_NOALIAS), - poptStrerror(c)); - poptPrintHelp(optcon, stderr, 0); - exit(EXIT_FAILURE); - } - - return optcon; -} diff --git a/libutil/op_popt.h b/libutil/op_popt.h deleted file mode 100644 index c3dfa6c..0000000 --- a/libutil/op_popt.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file op_popt.h - * Wrapper for libpopt - always use this rather - * than popt.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_POPT_H -#define OP_POPT_H - -#include <popt.h> - -// not in some versions of popt.h -#ifndef POPT_TABLEEND -#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * op_poptGetContext - wrapper for popt - * - * Use this instead of poptGetContext to cope with - * different popt versions. This also handle unrecognized - * options. All error are fatal. - */ -poptContext op_poptGetContext(char const * name, - int argc, char const ** argv, - struct poptOption const * options, int flags); - -#ifdef __cplusplus -} -#endif - -#endif /* OP_POPT_H */ diff --git a/libutil/op_string.c b/libutil/op_string.c deleted file mode 100644 index d440299..0000000 --- a/libutil/op_string.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file op_string.c - * general purpose C string handling implementation. - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <string.h> -#include "op_libiberty.h" - - -char * op_xstrndup(char const * s, size_t len) -{ - return xmemdup(s, len, len + 1); -} - - -size_t op_hash_string(char const * str) -{ - size_t hash = 0; - for (; *str; ++str) - hash ^= (hash << 16) ^ (hash >> 8) ^ *str; - return hash; -} - - -int strisprefix(char const * str, char const * prefix) -{ - return strstr(str, prefix) == str; -} - - -char const * skip_ws(char const * c) -{ - while (*c == ' ' || *c == '\t' || *c == '\n') - ++c; - return c; -} - - -char const * skip_nonws(char const * c) -{ - while (*c && *c != ' ' && *c != '\t' && *c != '\n') - ++c; - return c; -} - - -int empty_line(char const * c) -{ - return !*skip_ws(c); -} - - -int comment_line(char const * c) -{ - return *skip_ws(c) == '#'; -} diff --git a/libutil/op_string.h b/libutil/op_string.h deleted file mode 100644 index 993fa6f..0000000 --- a/libutil/op_string.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file op_string.h - * general purpose C string handling declarations. - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_STRING_H -#define OP_STRING_H - -#include <string.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @param s: input string - * @param len: len char to copy - * - * Allocate and copy len character from s to a newly allocated buffer then - * append a '\0' terminator. Return the newly allocated string - */ -char * op_xstrndup(char const * s, size_t len); - -/** - * @param s: string to hash - * - * Generate a hash code from a string - */ -size_t op_hash_string(char const * s); - -/** - * @param str: string to test - * @param prefix: prefix string - * - * return non zero if prefix parameters is a prefix of str - */ -int strisprefix(char const * str, char const * prefix); - -/** - * @param c: input string - * - * return a pointer to the first location in c which is not a blank space - * where blank space are in " \t\n" - */ -char const * skip_ws(char const * c); - -/** - * @param c: input string - * - * return a pointer to the first location in c which is a blank space - * where blank space are in " \t\n" - */ -char const * skip_nonws(char const * c); - -/** - * @param c: input string - * - * return non zero if c string contains only blank space - * where blank space are in " \t\n" - */ -int empty_line(char const * c); - -/** - * @param c: input string - * - * return non zero if c string is a comment. Comment are lines with optional - * blank space at left then a '#' character. Blank space are in " \t\n" - */ -int comment_line(char const * c); - -#ifdef __cplusplus -} -#endif - -#endif /* !OP_STRING_H */ diff --git a/libutil/op_types.h b/libutil/op_types.h deleted file mode 100644 index c025b23..0000000 --- a/libutil/op_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file op_types.h - * General-utility types - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_TYPES_H -#define OP_TYPES_H - -#ifndef __KERNEL__ - -#include <sys/types.h> - -/*@{\name miscellaneous types */ -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; -typedef int fd_t; -/*@}*/ - -/** generic type for holding addresses */ -typedef unsigned long long vma_t; - -/** generic type to hold a sample count in pp tools */ -typedef u64 count_type; - -#else -#include <linux/types.h> -#endif - -#endif /* OP_TYPES_H */ diff --git a/libutil/op_version.c b/libutil/op_version.c deleted file mode 100644 index 99a844e..0000000 --- a/libutil/op_version.c +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file op_version.c - * output version string - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#include <stdio.h> -#include <stdlib.h> - -#include "op_version.h" -#include "config.h" - -void show_version(char const * app_name) -{ - /* Do not change the version format: it is documented in html doc */ - printf("%s: " PACKAGE " " VERSION " compiled on " - __DATE__ " " __TIME__ "\n", app_name); - exit(EXIT_SUCCESS); -} diff --git a/libutil/op_version.h b/libutil/op_version.h deleted file mode 100644 index 43a8365..0000000 --- a/libutil/op_version.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file op_version.h - * output version string - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - */ - -#ifndef OP_VERSION_H -#define OP_VERSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** output the version string */ -void show_version(char const * app_name); - -#ifdef __cplusplus -} -#endif - -#endif /* !OP_VERSION_H */ diff --git a/opcontrol/Android.mk b/opcontrol/Android.mk deleted file mode 100644 index 56211ad..0000000 --- a/opcontrol/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - opcontrol.cpp - -LOCAL_STATIC_LIBRARIES := \ - libpopt libutil libdb libabi libop - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../libop - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE:= opcontrol - -include $(BUILD_EXECUTABLE) diff --git a/opcontrol/opcontrol.cpp b/opcontrol/opcontrol.cpp deleted file mode 100644 index 2d9cb2f..0000000 --- a/opcontrol/opcontrol.cpp +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Binary implementation of the original opcontrol script due to missing tools - * like awk, test, etc. - */ - -#include <unistd.h> -#include <getopt.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/stat.h> - -#include "op_config.h" - -#if 0 -#define verbose(fmt...) printf(fmt) -#else -#define verbose(fmt...) -#endif - -/* Experiments found that using a small interval may hang the device, and the - * more events tracked simultaneously, the longer the interval has to be. - */ -int min_count[3] = {150000, 200000, 250000}; -int list_events; -int show_usage; -int setup; -int quick; -int num_events; -int start; -int stop; -int reset; - -int selected_events[3]; -int selected_counts[3]; - -char kernel_range[512]; -char vmlinux[512]; - -struct option long_options[] = { - {"help", 0, &show_usage, 1}, - {"list-events", 0, &list_events, 1}, - {"reset", 0, &reset, 1}, - {"setup", 0, &setup, 1}, - {"quick", 0, &quick, 1}, - {"event", 1, 0, 'e'}, - {"vmlinux", 1, 0, 'v'}, - {"kernel-range", 1, 0, 'r'}, - {"start", 0, &start, 1}, - {"stop", 0, &stop, 1}, - {"shutdown", 0, 0, 'h'}, - {"status", 0, 0, 't'}, - {0, 0, 0, 0}, -}; - -struct event_info { - int id; - const char *name; - const char *explanation; -} event_info[] = { - {0x00, "IFU_IFETCH_MISS", - "number of instruction fetch misses"}, - {0x01, "CYCLES_IFU_MEM_STALL", - "cycles instruction fetch pipe is stalled"}, - {0x02, "CYCLES_DATA_STALL", - "cycles stall occurs for due to data dependency"}, - {0x03, "ITLB_MISS", - "number of Instruction MicroTLB misses"}, - {0x04, "DTLB_MISS", - "number of Data MicroTLB misses"}, - {0x05, "BR_INST_EXECUTED", - "branch instruction executed w/ or w/o program flow change"}, - {0x06, "BR_INST_MISS_PRED", - "branch mispredicted"}, - {0x07, "INSN_EXECUTED", - "instructions executed"}, - {0x09, "DCACHE_ACCESS", - "data cache access, cacheable locations"}, - {0x0a, "DCACHE_ACCESS_ALL", - "data cache access, all locations"}, - {0x0b, "DCACHE_MISS", - "data cache miss"}, - {0x0c, "DCACHE_WB", - "data cache writeback, 1 event for every half cacheline"}, - {0x0d, "PC_CHANGE", - "number of times the program counter was changed without a mode switch"}, - {0x0f, "TLB_MISS", - "Main TLB miss"}, - {0x10, "EXP_EXTERNAL", - "Explicit external data access"}, - {0x11, "LSU_STALL", - "cycles stalled because Load Store request queue is full"}, - {0x12, "WRITE_DRAIN", - "Times write buffer was drained"}, - {0xff, "CPU_CYCLES", - "clock cycles counter"}, -}; - -void usage() { - printf("\nopcontrol: usage:\n" - " --list-events list event types\n" - " --help this message\n" - " --setup setup directories\n" - " --quick setup and select CPU_CYCLES:150000\n" - " --status show configuration\n" - " --start start data collection\n" - " --stop stop data collection\n" - " --reset clears out data from current session\n" - " --shutdown kill the oprofile daeman\n" - " --event=eventspec\n" - " Choose an event. May be specified multiple times.\n" - " eventspec is in the form of name[:count], where :\n" - " name: event name, see \"opcontrol --list-events\"\n" - " count: reset counter value\n" - " --vmlinux=file vmlinux kernel image\n" - " --kernel-range=start,end\n" - " kernel range vma address in hexadecimal\n" - ); -} - -void setup_session_dir() { - int fd; - - fd = open(OP_DATA_DIR, O_RDONLY); - if (fd != -1) { - system("rm -r "OP_DATA_DIR); - close(fd); - } - - if (mkdir(OP_DATA_DIR, 755)) { - fprintf(stderr, "Cannot create directory \"%s\": %s\n", - OP_DATA_DIR, strerror(errno)); - } - if (mkdir(OP_DATA_DIR"/samples", 644)) { - fprintf(stderr, "Cannot create directory \"%s\": %s\n", - OP_DATA_DIR"/samples", strerror(errno)); - } -} - -int do_setup() { - char dir[1024]; - - setup_session_dir(); - - if (mkdir(OP_DRIVER_BASE, 644)) { - fprintf(stderr, "Cannot create directory "OP_DRIVER_BASE": %s\n", - strerror(errno)); - return -1; - } - if (system("mount -t oprofilefs nodev "OP_DRIVER_BASE)) { - return -1; - } - return 0; -} - -void do_list_events() -{ - unsigned int i; - - printf("%-20s: %s\n", "name", "meaning"); - printf("----------------------------------------" - "--------------------------------------\n"); - for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) { - printf("%-20s: %s\n", event_info[i].name, event_info[i].explanation); - } -} - -int find_event_id_from_name(const char *name) { - unsigned int i; - - for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) { - if (!strcmp(name, event_info[i].name)) { - return i; - } - } - return -1; -} - -const char * find_event_name_from_id(int id) { - unsigned int i; - - for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) { - if (event_info[i].id == id) { - return event_info[i].name; - } - } - return NULL; -} - -int process_event(const char *event_spec) { - char event_name[512]; - char count_name[512]; - unsigned int i; - int event_id; - int count_val; - - strncpy(event_name, event_spec, 512); - count_name[0] = 0; - - /* First, check if the name is followed by ":" */ - for (i = 0; i < strlen(event_name); i++) { - if (event_name[i] == 0) { - break; - } - if (event_name[i] == ':') { - strncpy(count_name, event_name+i+1, 512); - event_name[i] = 0; - break; - } - } - event_id = find_event_id_from_name(event_name); - if (event_id == -1) { - fprintf(stderr, "Unknown event name: %s\n", event_name); - return -1; - } - - /* Use defualt count */ - if (count_name[0] == 0) { - count_val = min_count[0]; - } else { - count_val = atoi(count_name); - } - - selected_events[num_events] = event_id; - selected_counts[num_events++] = count_val; - verbose("event_id is %d\n", event_id); - verbose("count_val is %d\n", count_val); - return 0; -} - -int echo_dev(const char* str, int val, const char* file, int counter) -{ - char fullname[512]; - char content[128]; - int fd; - - if (counter >= 0) { - snprintf(fullname, 512, OP_DRIVER_BASE"/%d/%s", counter, file); - } - else { - snprintf(fullname, 512, OP_DRIVER_BASE"/%s", file); - } - fd = open(fullname, O_WRONLY); - if (fd<0) { - fprintf(stderr, "Cannot open %s: %s\n", fullname, strerror(errno)); - return fd; - } - if (str == 0) { - sprintf(content, "%d", val); - } - else { - strncpy(content, str, 128); - } - verbose("Configure %s (%s)\n", fullname, content); - write(fd, content, strlen(content)); - close(fd); - return 0; -} - -int read_num(const char* file) -{ - char buffer[256]; - int fd = open(file, O_RDONLY); - if (fd<0) return -1; - int rd = read(fd, buffer, sizeof(buffer)-1); - buffer[rd] = 0; - return atoi(buffer); -} - -void do_status() -{ - int num; - char fullname[512]; - int i; - - printf("Driver directory: %s\n", OP_DRIVER_BASE); - printf("Session directory: %s\n", OP_DATA_DIR); - for (i = 0; i < 3; i++) { - sprintf(fullname, OP_DRIVER_BASE"/%d/enabled", i); - num = read_num(fullname); - if (num > 0) { - printf("Counter %d:\n", i); - - /* event name */ - sprintf(fullname, OP_DRIVER_BASE"/%d/event", i); - num = read_num(fullname); - printf(" name: %s\n", find_event_name_from_id(num)); - - /* profile interval */ - sprintf(fullname, OP_DRIVER_BASE"/%d/count", i); - num = read_num(fullname); - printf(" count: %d\n", num); - } - else { - printf("Counter %d disabled\n", i); - } - } - - num = read_num(OP_DATA_DIR"/lock"); - if (num >= 0) { - int fd; - /* Still needs to check if this lock is left-over */ - sprintf(fullname, "/proc/%d", num); - fd = open(fullname, O_RDONLY); - if (fd == -1) { - printf("Session directory is not clean - do \"opcontrol --setup\"" - " before you continue\n"); - return; - } - else { - close(fd); - printf("oprofiled pid: %d\n", num); - num = read_num(OP_DRIVER_BASE"/enable"); - printf("profiler is%s running\n", num == 0 ? " not" : ""); - num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received"); - printf(" %9u samples received\n", num); - num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_lost_overflow"); - printf(" %9u samples lost overflow\n", num); -#if 0 - /* FIXME - backtrace seems broken */ - num = read_num(OP_DRIVER_BASE"/stats/cpu0/backtrace_aborted"); - printf(" %9u backtrace aborted\n", num); - num = read_num(OP_DRIVER_BASE"/backtrace_depth"); - printf(" %9u backtrace_depth\n", num); -#endif - } - } - else { - printf("oprofiled is not running\n"); - } -} - -void do_reset() -{ - int fd; - - fd = open(OP_DATA_DIR"/samples/current", O_RDONLY); - if (fd == -1) { - return; - } - close(fd); - system("rm -r "OP_DATA_DIR"/samples/current"); -} - -int main(int argc, char * const argv[]) -{ - int option_index; - char command[1024]; - - /* Initialize default strings */ - strcpy(vmlinux, "--no-vmlinux"); - strcpy(kernel_range, ""); - - while (1) { - int c = getopt_long(argc, argv, "", long_options, &option_index); - if (c == -1) { - break; - } - switch (c) { - case 0: - break; - /* --event */ - case 'e': - if (num_events == 3) { - fprintf(stderr, "More than 3 events specified\n"); - exit(1); - } - if (process_event(optarg)) { - exit(1); - } - break; - /* --vmlinux */ - case 'v': - sprintf(vmlinux, "-k %s", optarg); - break; - /* --kernel-range */ - case 'r': - sprintf(kernel_range, "-r %s", optarg); - break; - /* --shutdown */ - case 'h': { - int pid = read_num(OP_DATA_DIR"/lock"); - if (pid >= 0) { - kill(pid, SIGKILL); - } - setup_session_dir(); - break; - } - /* --status */ - case 't': - do_status(); - break; - default: - usage(); - exit(1); - } - } - verbose("list_events = %d\n", list_events); - verbose("setup = %d\n", setup); - - if (list_events) { - do_list_events(); - } - - if (quick) { - process_event("CPU_CYCLES"); - setup = 1; - } - - if (reset) { - do_reset(); - } - - if (show_usage) { - usage(); - } - - if (setup) { - if (do_setup()) { - fprintf(stderr, "do_setup failed"); - exit(1); - } - } - - if (num_events != 0) { - int i; - - strcpy(command, "oprofiled --session-dir="OP_DATA_DIR); - - /* Since counter #3 can only handle CPU_CYCLES, check and shuffle the - * order a bit so that the maximal number of events can be profiled - * simultaneously - */ - if (num_events == 3) { - for (i = 0; i < num_events; i++) { - int event_idx = selected_events[i]; - - if (event_info[event_idx].id == 0xff) { - break; - } - } - - /* No CPU_CYCLES is found */ - if (i == 3) { - fprintf(stderr, "You can only specify three events if one of " - "them is CPU_CYCLES\n"); - exit(1); - } - /* Swap CPU_CYCLES to counter #2 (starting from #0)*/ - else if (i != 2) { - int temp; - - temp = selected_events[2]; - selected_events[2] = selected_events[i]; - selected_events[i] = temp; - - temp = selected_counts[2]; - selected_counts[2] = selected_counts[i]; - selected_counts[i] = temp; - } - } - - - /* Configure the counters and enable them */ - for (i = 0; i < num_events; i++) { - int event_idx = selected_events[i]; - int setup_result = 0; - - if (i == 0) { - snprintf(command+strlen(command), 1024 - strlen(command), - " --events="); - } - else { - snprintf(command+strlen(command), 1024 - strlen(command), - ","); - } - /* Compose name:id:count:unit_mask:kernel:user, something like - * --events=CYCLES_DATA_STALL:2:0:200000:0:1:1,.... - */ - snprintf(command+strlen(command), 1024 - strlen(command), - "%s:%d:%d:%d:0:1:1", - event_info[event_idx].name, - event_info[event_idx].id, - i, - selected_counts[i]); - - setup_result |= echo_dev("1", 0, "user", i); - setup_result |= echo_dev("1", 0, "kernel", i); - setup_result |= echo_dev("0", 0, "unit_mask", i); - setup_result |= echo_dev("1", 0, "enabled", i); - setup_result |= echo_dev(NULL, selected_counts[i], "count", i); - setup_result |= echo_dev(NULL, event_info[event_idx].id, - "event", i); - if (setup_result) { - fprintf(stderr, "Counter configuration failed for %s\n", - event_info[event_idx].name); - fprintf(stderr, "Did you do \"opcontrol --setup\" first?\n"); - exit(1); - } - } - - /* Disable the unused counters */ - for (i = num_events; i < 3; i++) { - echo_dev("0", 0, "enabled", i); - } - - snprintf(command+strlen(command), 1024 - strlen(command), " %s", - vmlinux); - if (kernel_range[0]) { - snprintf(command+strlen(command), 1024 - strlen(command), " %s", - kernel_range); - } - verbose("command: %s\n", command); - system(command); - } - - if (start) { - echo_dev("1", 0, "enable", -1); - } - - if (stop) { - echo_dev("0", 0, "enable", -1); - } -} diff --git a/opimport_pull b/opimport_pull deleted file mode 100755 index 7dbac4a..0000000 --- a/opimport_pull +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python2.4 -E - -import os -import re -import sys - -def PrintUsage(): - print "Usage:" + sys.argv[0] + " dir" - print " dir: directory on the host to store profile results" - -if (len(sys.argv) != 2): - PrintUsage() - sys.exit(1) - -try: - oprofile_event_dir = os.environ['OPROFILE_EVENTS_DIR'] -except: - print "OPROFILE_EVENTS_DIR not set. Run \". envsetup.sh\" first" - sys.exit(1) - -output_dir = sys.argv[1]; - -try: - os.makedirs(output_dir) -except: - if os.path.exists(output_dir): - print "Directory already exists:", output_dir - else: - print "Cannot create", output_dir - sys.exit(1) - -# get the samples off the phone -result = os.system("adb pull /data/oprofile/samples " + output_dir + \ - "/raw_samples > /dev/null 2>&1") -if result != 0: - print "adb pull failure, exiting" - sys.exit(1) - -# enter the destination directory -os.chdir(output_dir) -stream = os.popen("find raw_samples -type f -name \*all") - -# now all the sample files are on the host, we need to invoke opimport one at a -# time to convert the content from the ARM abi to x86 ABI - -# break the full filename into: -# 1: leading dir: "raw_samples" -# 2: intermediate dirs: "/blah/blah/blah" -# 3: filename: e.g. "CPU_CYCLES.150000.0.all.all.all" -pattern = re.compile("(^raw_samples)(.*)/(.*)$") -for line in stream: - match = pattern.search(line) - leading_dir = match.group(1) - middle_part = match.group(2) - file_name = match.group(3) - - dir = "samples" + middle_part - - # if multiple events are collected the directory could have been setup - if not os.path.exists(dir): - os.makedirs(dir) - - cmd = oprofile_event_dir + "/bin/opimport -a " + oprofile_event_dir + \ - "/abi/arm_abi -o samples" + middle_part + "/" + file_name + " " + line - os.system(cmd) - -stream.close() - -# short summary of profiling results -os.system(oprofile_event_dir + "/bin/opreport --session-dir=.") @@ -1,564 +0,0 @@ -/** \file popt/popt.h - * \ingroup popt - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPT -#define H_POPT - -#include <stdio.h> /* for FILE * */ - -#define POPT_OPTION_DEPTH 10 - -/** \ingroup popt - * \name Arg type identifiers - */ -/*@{*/ -#define POPT_ARG_NONE 0 /*!< no arg */ -#define POPT_ARG_STRING 1 /*!< arg will be saved as string */ -#define POPT_ARG_INT 2 /*!< arg will be converted to int */ -#define POPT_ARG_LONG 3 /*!< arg will be converted to long */ -#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */ -#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be - set first in table; arg points - to callback, descrip points to - callback data to pass */ -#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain - for this table and any - included tables; arg points - to the domain string */ -#define POPT_ARG_VAL 7 /*!< arg should take value val */ -#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */ -#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */ - -#define POPT_ARG_MASK 0x0000FFFF -/*@}*/ - -/** \ingroup popt - * \name Arg modifiers - */ -/*@{*/ -#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */ -#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */ -#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */ -#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */ - -#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */ -#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */ -#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */ -#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */ -#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */ -#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */ -#define POPT_ARGFLAG_LOGICALOPS \ - (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) - -#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) - /*!< set arg bit(s) */ -#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) - /*!< clear arg bit(s) */ - -#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */ - -/*@}*/ - -/** \ingroup popt - * \name Callback modifiers - */ -/*@{*/ -#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */ -#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */ -#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line, - not the subtable */ -#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */ -#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */ -/*@}*/ - -/** \ingroup popt - * \name Error return values - */ -/*@{*/ -#define POPT_ERROR_NOARG -10 /*!< missing argument */ -#define POPT_ERROR_BADOPT -11 /*!< unknown option */ -#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ -#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ -#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ -#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ -#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ -#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ -#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ -#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ -/*@}*/ - -/** \ingroup popt - * \name poptBadOption() flags - */ -/*@{*/ -#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */ -/*@}*/ - -/** \ingroup popt - * \name poptGetContext() flags - */ -/*@{*/ -#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */ -#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */ -#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */ -#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */ -/*@}*/ - -/** \ingroup popt - */ -struct poptOption { -/*@observer@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - int argInfo; -/*@shared@*/ /*@null@*/ - void * arg; /*!< depends on argInfo */ - int val; /*!< 0 means don't return, just update flag */ -/*@observer@*/ /*@null@*/ - const char * descrip; /*!< description for autohelp -- may be NULL */ -/*@observer@*/ /*@null@*/ - const char * argDescrip; /*!< argument description for autohelp */ -}; - -/** \ingroup popt - * A popt alias argument for poptAddAlias(). - */ -struct poptAlias { -/*@owned@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - int argc; -/*@owned@*/ - const char ** argv; /*!< must be free()able */ -}; - -/** \ingroup popt - * A popt alias or exec argument for poptAddItem(). - */ -/*@-exporttype@*/ -typedef struct poptItem_s { - struct poptOption option; /*!< alias/exec name(s) and description. */ - int argc; /*!< (alias) no. of args. */ -/*@owned@*/ - const char ** argv; /*!< (alias) args, must be free()able. */ -} * poptItem; -/*@=exporttype@*/ - -/** \ingroup popt - * \name Auto-generated help/usage - */ -/*@{*/ - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptAliasOptions[]; -/*@=exportvar@*/ -#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ - 0, "Options implemented via popt alias/exec:", NULL }, - -/** - * Auto help table options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptHelpOptions[]; -/*@=exportvar@*/ - -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption * poptHelpOptionsI18N; -/*@=exportvar@*/ - -#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ - 0, "Help options:", NULL }, - -#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } -/*@}*/ - -/** \ingroup popt - */ -/*@-exporttype@*/ -typedef /*@abstract@*/ struct poptContext_s * poptContext; -/*@=exporttype@*/ - -/** \ingroup popt - */ -#ifndef __cplusplus -/*@-exporttype -typeuse@*/ -typedef struct poptOption * poptOption; -/*@=exporttype =typeuse@*/ -#endif - -/*@-exportconst@*/ -enum poptCallbackReason { - POPT_CALLBACK_REASON_PRE = 0, - POPT_CALLBACK_REASON_POST = 1, - POPT_CALLBACK_REASON_OPTION = 2 -}; -/*@=exportconst@*/ - -#ifdef __cplusplus -extern "C" { -#endif -/*@-type@*/ - -/** \ingroup popt - * Table callback prototype. - * @param con context - * @param reason reason for callback - * @param opt option that triggered callback - * @param arg @todo Document. - * @param data @todo Document. - */ -typedef void (*poptCallbackType) (poptContext con, - enum poptCallbackReason reason, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * arg, - /*@null@*/ const void * data) - /*@globals internalState @*/ - /*@modifies internalState @*/; - -/** \ingroup popt - * Initialize popt context. - * @param name context name (usually argv[0] program name) - * @param argc no. of arguments - * @param argv argument array - * @param options address of popt option table - * @param flags or'd POPT_CONTEXT_* bits - * @return initialized popt context - */ -/*@only@*/ /*@null@*/ -poptContext poptGetContext( - /*@dependent@*/ /*@keep@*/ const char * name, - int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, - /*@dependent@*/ /*@keep@*/ const struct poptOption * options, - int flags) - /*@*/; - -/** \ingroup popt - * Reinitialize popt context. - * @param con context - */ -/*@unused@*/ -void poptResetContext(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return value of next option found. - * @param con context - * @return next option val, -1 on last item, POPT_ERROR_* on error - */ -int poptGetNextOpt(/*@null@*/poptContext con) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/; - -/** \ingroup popt - * Return next option argument (if any). - * @param con context - * @return option argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptGetOptArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return next argument. - * @param con context - * @return next argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptGetArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Peek at current argument. - * @param con context - * @return current argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptPeekArg(/*@null@*/poptContext con) - /*@*/; - -/** \ingroup popt - * Return remaining arguments. - * @param con context - * @return argument array, NULL terminated - */ -/*@observer@*/ /*@null@*/ -const char ** poptGetArgs(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return the option which caused the most recent error. - * @param con context - * @param flags - * @return offending option - */ -/*@observer@*/ -const char * poptBadOption(/*@null@*/poptContext con, int flags) - /*@*/; - -/** \ingroup popt - * Destroy context. - * @param con context - * @return NULL always - */ -/*@null@*/ -poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Add arguments to context. - * @param con context - * @param argv argument array, NULL terminated - * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure - */ -/*@unused@*/ -int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias to context. - * @todo Pass alias by reference, not value. - * @deprecated Use poptAddItem instead. - * @param con context - * @param alias alias to add - * @param flags (unused) - * @return 0 on success - */ -/*@unused@*/ -int poptAddAlias(poptContext con, struct poptAlias alias, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias/exec item to context. - * @param con context - * @param newItem alias/exec item to add - * @param flags 0 for alias, 1 for exec - * @return 0 on success - */ -int poptAddItem(poptContext con, poptItem newItem, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Read configuration file. - * @param con context - * @param fn file name to read - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -int poptReadConfigFile(poptContext con, const char * fn) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - errno, fileSystem, internalState @*/; - -/** \ingroup popt - * Read default configuration from /etc/popt and $HOME/.popt. - * @param con context - * @param useEnv (unused) - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -/*@unused@*/ -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) - /*@globals fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - fileSystem, internalState @*/; - -/** \ingroup popt - * Duplicate an argument array. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param argc no. of arguments - * @param argv argument array - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - * @return 0 on success, POPT_ERROR_NOARG on failure - */ -int poptDupArgv(int argc, /*@null@*/ const char **argv, - /*@null@*/ /*@out@*/ int * argcPtr, - /*@null@*/ /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parse a string into an argument array. - * The parse allows ', ", and \ quoting, but ' is treated the same as " and - * both may include \ quotes. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param s string to parse - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - */ -int poptParseArgvString(const char * s, - /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parses an input configuration file and returns an string that is a - * command line. For use with popt. You must free the return value when done. - * - * Given the file: -\verbatim -# this line is ignored - # this one too -aaa - bbb - ccc -bla=bla - -this_is = fdsafdas - bad_line= - reall bad line - reall bad line = again -5555= 55555 - test = with lots of spaces -\endverbatim -* -* The result is: -\verbatim ---aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" -\endverbatim -* -* Passing this to poptParseArgvString() yields an argv of: -\verbatim -'--aaa' -'--bbb' -'--ccc' -'--bla=bla' -'--this_is=fdsafdas' -'--5555=55555' -'--test=with lots of spaces' -\endverbatim - * - * @bug NULL is returned if file line is too long. - * @bug Silently ignores invalid lines. - * - * @param fp file handle to read - * @param *argstrp return string of options (malloc'd) - * @param flags unused - * @return 0 on success - * @see poptParseArgvString - */ -/*@-fcnuse@*/ -int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, *argstrp, fileSystem @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return formatted error string for popt failure. - * @param error popt error - * @return error string - */ -/*@observer@*/ -const char * poptStrerror(const int error) - /*@*/; - -/** \ingroup popt - * Limit search for executables. - * @param con context - * @param path single path to search for executables - * @param allowAbsolute absolute paths only? - */ -/*@unused@*/ -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) - /*@modifies con @*/; - -/** \ingroup popt - * Print detailed description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Print terse description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Provide text to replace default "[OPTION...]" in help/usage output. - * @param con context - * @param text replacement text - */ -/*@-fcnuse@*/ -void poptSetOtherOptionHelp(poptContext con, const char * text) - /*@modifies con @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return argv[0] from context. - * @param con context - * @return argv[0] - */ -/*@-fcnuse@*/ -/*@observer@*/ -const char * poptGetInvocationName(poptContext con) - /*@*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Shuffle argv pointers to remove stripped args, returns new argc. - * @param con context - * @param argc no. of args - * @param argv arg vector - * @return new argc - */ -/*@-fcnuse@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) - /*@modifies *argv @*/; -/*@=fcnuse@*/ - -/** - * Save a long, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save an integer, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/*@=type@*/ -#ifdef __cplusplus -} -#endif - -#endif |