diff --git a/VEX/head20041019/.cvsignore b/VEX/head20041019/.cvsignore deleted file mode 100644 index b6b5af993..000000000 --- a/VEX/head20041019/.cvsignore +++ /dev/null @@ -1,22 +0,0 @@ -Makefile.in -Makefile -acinclude.m4 -aclocal.m4 -configure -config.h* -stamp-h* -valgrind -valgrind.spec -cachegrind -vg_annotate -vg_cachegen -default.supp -bin -lib -include -share -cachegrind.out.* -autom4te.cache -autom4te-*.cache -valgrind.pc -.in_place diff --git a/VEX/head20041019/ACKNOWLEDGEMENTS b/VEX/head20041019/ACKNOWLEDGEMENTS deleted file mode 100644 index 36317308e..000000000 --- a/VEX/head20041019/ACKNOWLEDGEMENTS +++ /dev/null @@ -1,26 +0,0 @@ - -The following people contributed in some way to valgrind, during its -long journey over the past two years or so. Here's a list. If I have -forgotten you, I do apologise; let me know (jseward@acm.org) and I'll -fix it. - -Donna Robinson - for many reasons, including endless encouragement, and - persuading me I wasn't crazy to try doing this - -Rob Noble - for early encouragement, support, suggestions, and asking of - many questions - -Reuben Thomas - for discussions about value tag operations, and making me - laugh - -Various KDE folks, for suffering recent versions of valgrind, - providing many patches, questions and helpful feedback - Dirk Mueller - Stephan Kulow - Michael Matz - Simon Hausmann - David Faure - Ellis Whitehead diff --git a/VEX/head20041019/AUTHORS b/VEX/head20041019/AUTHORS deleted file mode 100644 index 725f4620b..000000000 --- a/VEX/head20041019/AUTHORS +++ /dev/null @@ -1,32 +0,0 @@ - -Julian Seward, jseward@acm.org, was the original author, creating the -dynamic translation framework, memcheck stuff, and the -signal/syscall/threads support gunk. - -Nicholas Nethercote, njn25@cam.ac.uk, did the core/tool -generalisation, and wrote Cachegrind and some of the other tools, and -tons of other stuff, including code generation improvments. - -Jeremy Fitzhardinge, jeremy@goop.org, wrote Helgrind, and lots of -syscall/signal simulation stuff, including a complete redesign of how -syscalls and signals are handled. Also code generation improvements. - -Tom Hughes, thh@cyberscience.com, did a vast number of bug fixes, and -helped out with support for more recent Linux/glibc versions. - -Robert Walsh, rjwalsh@durables.org, added file descriptor leakage -checking, new library interception machinery, support for client -allocation pools, and minor other tweakage. - -readelf's dwarf2 source line reader, written by Nick Clifton, was -modified to be used in Valgrind by Daniel Berlin. - -Michael Matz and Simon Hausmann modified the GNU binutils -demangler(s) for use in Valgrind. - -Dirk Mueller contrib'd the malloc-free mismatch checking stuff, -and other bits and pieces. - -Lots of other people sent bug reports, patches, and very -helpful feedback. I thank you all. - diff --git a/VEX/head20041019/COPYING b/VEX/head20041019/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/VEX/head20041019/COPYING +++ /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. - - - Copyright (C) - - 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. - - , 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/VEX/head20041019/CVS/Entries b/VEX/head20041019/CVS/Entries deleted file mode 100644 index 76f702d78..000000000 --- a/VEX/head20041019/CVS/Entries +++ /dev/null @@ -1,43 +0,0 @@ -/.cvsignore/1.7/Tue Mar 23 19:52:03 2004// -/ACKNOWLEDGEMENTS/1.1.1.1/Fri Mar 22 01:29:20 2002// -/AUTHORS/1.8/Tue Jul 20 14:18:51 2004// -/COPYING/1.1.1.1/Fri Mar 22 01:27:57 2002// -/FAQ.txt/1.23/Sun Jul 18 10:35:36 2004// -/INSTALL/1.1.1.1/Fri Mar 22 01:28:00 2002// -/Makefile.all.am/1.1/Wed Sep 1 23:20:46 2004// -/Makefile.am/1.71/Sat Oct 9 15:59:05 2004// -/Makefile.core-AM_CPPFLAGS.am/1.3/Fri Sep 10 14:23:58 2004// -/Makefile.tool-flags.am/1.2/Sat Sep 11 18:27:43 2004// -/Makefile.tool-inplace.am/1.1/Wed Sep 1 23:20:46 2004// -/Makefile.tool.am/1.3/Sat Sep 11 16:45:24 2004// -/NEWS/1.26/Tue Aug 31 00:14:02 2004// -/NOTES.syscalls/1.1/Mon Oct 13 22:26:54 2003// -/README/1.19/Wed Apr 21 09:17:19 2004// -/README_DEVELOPERS/1.3/Sat Oct 9 15:59:05 2004// -/README_MISSING_SYSCALL_OR_IOCTL/1.8/Fri Sep 10 14:23:58 2004// -/README_PACKAGERS/1.5/Tue Aug 24 13:56:54 2004// -/TODO/1.2/Tue Jun 18 16:31:21 2002// -/autogen.sh/1.3/Tue Dec 16 02:15:21 2003// -/configure.in/1.129/Mon Oct 18 18:07:48 2004// -/glibc-2.1.supp/1.11/Sun Apr 25 12:02:31 2004// -/glibc-2.2.supp/1.25/Sat Jul 17 14:16:03 2004// -/glibc-2.3.supp/1.15/Tue Jul 20 22:42:44 2004// -/make-uninstall-docs/1.2/Fri Nov 14 17:47:51 2003// -/valgrind.pc.in/1.2/Thu Oct 14 10:22:19 2004// -/valgrind.spec.in/1.16/Fri Sep 3 13:45:26 2004// -/xfree-3.supp/1.6/Fri Nov 14 17:47:51 2003// -/xfree-4.supp/1.9/Fri Nov 14 17:47:51 2003// -D/addrcheck//// -D/auxprogs//// -D/cachegrind//// -D/corecheck//// -D/coregrind//// -D/docs//// -D/helgrind//// -D/include//// -D/lackey//// -D/massif//// -D/memcheck//// -D/nightly//// -D/none//// -D/tests//// diff --git a/VEX/head20041019/CVS/Repository b/VEX/head20041019/CVS/Repository deleted file mode 100644 index e7af41291..000000000 --- a/VEX/head20041019/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind diff --git a/VEX/head20041019/CVS/Root b/VEX/head20041019/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/CVS/Template b/VEX/head20041019/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/FAQ.txt b/VEX/head20041019/FAQ.txt deleted file mode 100644 index 26a31d67d..000000000 --- a/VEX/head20041019/FAQ.txt +++ /dev/null @@ -1,437 +0,0 @@ -Valgrind FAQ, version 2.1.2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Last revised 18 July 2004 -~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Background -2. Compiling, installing and configuring -3. Valgrind aborts unexpectedly -4. Valgrind behaves unexpectedly -5. Memcheck doesn't find my bug -6. Miscellaneous - - ------------------------------------------------------------------ -1. Background ------------------------------------------------------------------ - -1.1. How do you pronounce "Valgrind"? - -The "Val" as in the world "value". The "grind" is pronounced with a -short 'i' -- ie. "grinned" (rhymes with "tinned") rather than "grined" -(rhymes with "find"). - -Don't feel bad: almost everyone gets it wrong at first. - ------------------------------------------------------------------ - -1.2. Where does the name "Valgrind" come from? - -From Nordic mythology. Originally (before release) the project was -named Heimdall, after the watchman of the Nordic gods. He could "see a -hundred miles by day or night, hear the grass growing, see the wool -growing on a sheep's back" (etc). This would have been a great name, -but it was already taken by a security package "Heimdal". - -Keeping with the Nordic theme, Valgrind was chosen. Valgrind is the -name of the main entrance to Valhalla (the Hall of the Chosen Slain in -Asgard). Over this entrance there resides a wolf and over it there is -the head of a boar and on it perches a huge eagle, whose eyes can see to -the far regions of the nine worlds. Only those judged worthy by the -guardians are allowed to pass through Valgrind. All others are refused -entrance. - -It's not short for "value grinder", although that's not a bad guess. - - ------------------------------------------------------------------ -2. Compiling, installing and configuring ------------------------------------------------------------------ - -2.1. When I trying building Valgrind, 'make' dies partway with an - assertion failure, something like this: make: expand.c:489: - - allocated_variable_append: Assertion - `current_variable_set_list->next != 0' failed. - -It's probably a bug in 'make'. Some, but not all, instances of version 3.79.1 -have this bug, see www.mail-archive.com/bug-make@gnu.org/msg01658.html. Try -upgrading to a more recent version of 'make'. Alternatively, we have heard -that unsetting the CFLAGS environment variable avoids the problem. - - ------------------------------------------------------------------ -3. Valgrind aborts unexpectedly ------------------------------------------------------------------ - -3.1. Programs run OK on Valgrind, but at exit produce a bunch of errors a bit - like this - - ==20755== Invalid read of size 4 - ==20755== at 0x40281C8A: _nl_unload_locale (loadlocale.c:238) - ==20755== by 0x4028179D: free_mem (findlocale.c:257) - ==20755== by 0x402E0962: __libc_freeres (set-freeres.c:34) - ==20755== by 0x40048DCC: vgPlain___libc_freeres_wrapper - (vg_clientfuncs.c:585) - ==20755== Address 0x40CC304C is 8 bytes inside a block of size 380 free'd - ==20755== at 0x400484C9: free (vg_clientfuncs.c:180) - ==20755== by 0x40281CBA: _nl_unload_locale (loadlocale.c:246) - ==20755== by 0x40281218: free_mem (setlocale.c:461) - ==20755== by 0x402E0962: __libc_freeres (set-freeres.c:34) - - and then die with a segmentation fault. - -When the program exits, Valgrind runs the procedure __libc_freeres() in -glibc. This is a hook for memory debuggers, so they can ask glibc to -free up any memory it has used. Doing that is needed to ensure that -Valgrind doesn't incorrectly report space leaks in glibc. - -Problem is that running __libc_freeres() in older glibc versions causes -this crash. - -WORKAROUND FOR 1.1.X and later versions of Valgrind: use the ---run-libc-freeres=no flag. You may then get space leak reports for -glibc-allocations (please _don't_ report these to the glibc people, -since they are not real leaks), but at least the program runs. - ------------------------------------------------------------------ - -3.2. My (buggy) program dies like this: - valgrind: vg_malloc2.c:442 (bszW_to_pszW): - Assertion `pszW >= 0' failed. - -If Memcheck (the memory checker) shows any invalid reads, invalid writes -and invalid frees in your program, the above may happen. Reason is that -your program may trash Valgrind's low-level memory manager, which then -dies with the above assertion, or something like this. The cure is to -fix your program so that it doesn't do any illegal memory accesses. The -above failure will hopefully go away after that. - ------------------------------------------------------------------ - -3.3. My program dies, printing a message like this along the way: - - disInstr: unhandled instruction bytes: 0x66 0xF 0x2E 0x5 - -Older versions did not support some x86 instructions, particularly -SSE/SSE2 instructions. Try a newer Valgrind; we now support almost all -instructions. If it still happens with newer versions, if the failing -instruction is an SSE/SSE2 instruction, you might be able to recompile -your program without it by using the flag -march to gcc. Either way, -let us know and we'll try to fix it. - -Another possibility is that your program has a bug and erroneously jumps -to a non-code address, in which case you'll get a SIGILL signal. -Memcheck/Addrcheck may issue a warning just before this happens, but they -might not if the jump happens to land in addressable memory. - ------------------------------------------------------------------ - -3.4. My program dies like this: - - error: /lib/librt.so.1: symbol __pthread_clock_settime, version - GLIBC_PRIVATE not defined in file libpthread.so.0 with link time - reference - -This is a total swamp. Nevertheless there is a way out. It's a problem -which is not easy to fix. Really the problem is that /lib/librt.so.1 -refers to some symbols __pthread_clock_settime and -__pthread_clock_gettime in /lib/libpthread.so which are not intended to -be exported, ie they are private. - -Best solution is to ensure your program does not use /lib/librt.so.1. - -However .. since you're probably not using it directly, or even -knowingly, that's hard to do. You might instead be able to fix it by -playing around with coregrind/vg_libpthread.vs. Things to try: - -Remove this - - GLIBC_PRIVATE { - __pthread_clock_gettime; - __pthread_clock_settime; - }; - -or maybe remove this - - GLIBC_2.2.3 { - __pthread_clock_gettime; - __pthread_clock_settime; - } GLIBC_2.2; - -or maybe add this - - GLIBC_2.2.4 { - __pthread_clock_gettime; - __pthread_clock_settime; - } GLIBC_2.2; - - GLIBC_2.2.5 { - __pthread_clock_gettime; - __pthread_clock_settime; - } GLIBC_2.2; - -or some combination of the above. After each change you need to delete -coregrind/libpthread.so and do make && make install. - -I just don't know if any of the above will work. If you can find a -solution which works, I would be interested to hear it. - -To which someone replied: - - I deleted this: - - GLIBC_2.2.3 { - __pthread_clock_gettime; - __pthread_clock_settime; - } GLIBC_2.2; - - and it worked. - - ------------------------------------------------------------------ -4. Valgrind behaves unexpectedly ------------------------------------------------------------------ - -4.1. I try running "valgrind my_program", but my_program runs normally, - and Valgrind doesn't emit any output at all. - -For versions prior to 2.1.1: - -Valgrind doesn't work out-of-the-box with programs that are entirely -statically linked. It does a quick test at startup, and if it detects -that the program is statically linked, it aborts with an explanation. - -This test may fail in some obscure cases, eg. if you run a script under -Valgrind and the script interpreter is statically linked. - -If you still want static linking, you can ask gcc to link certain -libraries statically. Try the following options: - - -Wl,-Bstatic -lmyLibrary1 -lotherLibrary -Wl,-Bdynamic - -Just make sure you end with -Wl,-Bdynamic so that libc is dynamically -linked. - -If you absolutely cannot use dynamic libraries, you can try statically -linking together all the .o files in coregrind/, all the .o files of the -tool of your choice (eg. those in memcheck/), and the .o files of your -program. You'll end up with a statically linked binary that runs -permanently under Valgrind's control. Note that we haven't tested this -procedure thoroughly. - - -For versions 2.1.1 and later: - -Valgrind does now work with static binaries, although beware that some -of the tools won't operate as well as normal, because they have access -to less information about how the program runs. Eg. Memcheck will miss -some errors that it would otherwise find. This is because Valgrind -doesn't replace malloc() and friends with its own versions. It's best -if your program is dynamically linked with glibc. - ------------------------------------------------------------------ - -4.2. My threaded server process runs unbelievably slowly on Valgrind. - So slowly, in fact, that at first I thought it had completely - locked up. - -We are not completely sure about this, but one possibility is that -laptops with power management fool Valgrind's timekeeping mechanism, -which is (somewhat in error) based on the x86 RDTSC instruction. A -"fix" which is claimed to work is to run some other cpu-intensive -process at the same time, so that the laptop's power-management -clock-slowing does not kick in. We would be interested in hearing more -feedback on this. - -Another possible cause is that versions prior to 1.9.6 did not support -threading on glibc 2.3.X systems well. Hopefully the situation is much -improved with 1.9.6 and later versions. - ------------------------------------------------------------------ - -4.3. My program uses the C++ STL and string classes. Valgrind - reports 'still reachable' memory leaks involving these classes - at the exit of the program, but there should be none. - -First of all: relax, it's probably not a bug, but a feature. Many -implementations of the C++ standard libraries use their own memory pool -allocators. Memory for quite a number of destructed objects is not -immediately freed and given back to the OS, but kept in the pool(s) for -later re-use. The fact that the pools are not freed at the exit() of -the program cause Valgrind to report this memory as still reachable. -The behaviour not to free pools at the exit() could be called a bug of -the library though. - -Using gcc, you can force the STL to use malloc and to free memory as -soon as possible by globally disabling memory caching. Beware! Doing -so will probably slow down your program, sometimes drastically. - -- With gcc 2.91, 2.95, 3.0 and 3.1, compile all source using the STL - with -D__USE_MALLOC. Beware! This is removed from gcc starting with - version 3.3. - -- With 3.2.2 and later, you should export the environment variable - GLIBCPP_FORCE_NEW before running your program. - -There are other ways to disable memory pooling: using the malloc_alloc -template with your objects (not portable, but should work for gcc) or -even writing your own memory allocators. But all this goes beyond the -scope of this FAQ. Start by reading -http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3 if you -absolutely want to do that. But beware: - -1) there are currently changes underway for gcc which are not totally - reflected in the docs right now ("now" == 26 Apr 03) - -2) allocators belong to the more messy parts of the STL and people went - at great lengths to make it portable across platforms. Chances are - good that your solution will work on your platform, but not on - others. - ------------------------------------------------------------------------------ -4.4. The stack traces given by Memcheck (or another tool) aren't helpful. - How can I improve them? - -If they're not long enough, use --num-callers to make them longer. - -If they're not detailed enough, make sure you are compiling with -g to add -debug information. And don't strip symbol tables (programs should be -unstripped unless you run 'strip' on them; some libraries ship stripped). - -Also, -fomit-frame-pointer and -fstack-check can make stack traces worse. - -Some example sub-traces: - - With debug information and unstripped (best): - - Invalid write of size 1 - at 0x80483BF: really (malloc1.c:20) - by 0x8048370: main (malloc1.c:9) - - With no debug information, unstripped: - - Invalid write of size 1 - at 0x80483BF: really (in /auto/homes/njn25/grind/head5/a.out) - by 0x8048370: main (in /auto/homes/njn25/grind/head5/a.out) - - With no debug information, stripped: - - Invalid write of size 1 - at 0x80483BF: (within /auto/homes/njn25/grind/head5/a.out) - by 0x8048370: (within /auto/homes/njn25/grind/head5/a.out) - by 0x42015703: __libc_start_main (in /lib/tls/libc-2.3.2.so) - by 0x80482CC: (within /auto/homes/njn25/grind/head5/a.out) - - With debug information and -fomit-frame-pointer: - - Invalid write of size 1 - at 0x80483C4: really (malloc1.c:20) - by 0x42015703: __libc_start_main (in /lib/tls/libc-2.3.2.so) - by 0x80482CC: ??? (start.S:81) - ------------------------------------------------------------------ -5. Memcheck doesn't find my bug ------------------------------------------------------------------ - -5.1. I try running "valgrind --tool=memcheck my_program" and get - Valgrind's startup message, but I don't get any errors and I know - my program has errors. - -By default, Valgrind only traces the top-level process. So if your -program spawns children, they won't be traced by Valgrind by default. -Also, if your program is started by a shell script, Perl script, or -something similar, Valgrind will trace the shell, or the Perl -interpreter, or equivalent. - -To trace child processes, use the --trace-children=yes option. - -If you are tracing large trees of processes, it can be less disruptive -to have the output sent over the network. Give Valgrind the flag ---log-socket=127.0.0.1:12345 (if you want logging output sent to port -12345 on localhost). You can use the valgrind-listener program to -listen on that port: - - valgrind-listener 12345 - -Obviously you have to start the listener process first. See the -documentation for more details. - ------------------------------------------------------------------ - -5.2. Why doesn't Memcheck find the array overruns in this program? - - int static[5]; - - int main(void) - { - int stack[5]; - - static[5] = 0; - stack [5] = 0; - - return 0; - } - -Unfortunately, Memcheck doesn't do bounds checking on static or stack -arrays. We'd like to, but it's just not possible to do in a reasonable -way that fits with how Memcheck works. Sorry. - ------------------------------------------------------------------ - -5.3. My program dies with a segmentation fault, but Memcheck doesn't give - any error messages before it, or none that look related. - -One possibility is that your program accesses to memory with -inappropriate permissions set, such as writing to read-only memory. -Maybe your program is writing to a static string like this: - - char* s = "hello"; - s[0] = 'j'; - -or something similar. Writing to read-only memory can also apparently -make LinuxThreads behave strangely. - - ------------------------------------------------------------------ -6. Miscellaneous ------------------------------------------------------------------ - -6.1. I tried writing a suppression but it didn't work. Can you - write my suppression for me? - -Yes! Use the --gen-suppressions=yes feature to spit out suppressions -automatically for you. You can then edit them if you like, eg. -combining similar automatically generated suppressions using wildcards -like '*'. - -If you really want to write suppressions by hand, read the manual -carefully. Note particularly that C++ function names must be _mangled_. - ------------------------------------------------------------------ - -6.2. With Memcheck/Addrcheck's memory leak detector, what's the - difference between "definitely lost", "possibly lost", "still - reachable", and "suppressed"? - -The details are in section 3.6 of the manual. - -In short: - - - "definitely lost" means your program is leaking memory -- fix it! - - - "possibly lost" means your program is probably leaking memory, - unless you're doing funny things with pointers. - - - "still reachable" means your program is probably ok -- it didn't - free some memory it could have. This is quite common and often - reasonable. Don't use --show-reachable=yes if you don't want to see - these reports. - - - "suppressed" means that a leak error has been suppressed. There are - some suppressions in the default suppression files. You can ignore - suppressed errors. - ------------------------------------------------------------------ - -(this is the end of the FAQ.) diff --git a/VEX/head20041019/INSTALL b/VEX/head20041019/INSTALL deleted file mode 100644 index b42a17ac4..000000000 --- a/VEX/head20041019/INSTALL +++ /dev/null @@ -1,182 +0,0 @@ -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. diff --git a/VEX/head20041019/Makefile.all.am b/VEX/head20041019/Makefile.all.am deleted file mode 100644 index d1b45fca3..000000000 --- a/VEX/head20041019/Makefile.all.am +++ /dev/null @@ -1,8 +0,0 @@ - -## This file should be included by *every* Makefile.am, except those for docs/ -## and tests/ subdirectories. - -valdir = $(libdir)/valgrind -inplacedir = $(top_builddir)/.in_place - - diff --git a/VEX/head20041019/Makefile.am b/VEX/head20041019/Makefile.am deleted file mode 100644 index 74f35a963..000000000 --- a/VEX/head20041019/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ - -AUTOMAKE_OPTIONS = foreign 1.6 dist-bzip2 - -include $(top_srcdir)/Makefile.all.am - -## include must be first for tool.h -## addrcheck must come after memcheck, for mac_*.o -SUBDIRS = include coregrind . docs tests auxprogs \ - memcheck \ - addrcheck \ - cachegrind \ - corecheck \ - helgrind \ - massif \ - lackey \ - none - -SUPP_FILES = \ - glibc-2.1.supp glibc-2.2.supp glibc-2.3.supp \ - xfree-3.supp xfree-4.supp - -dist_val_DATA = $(SUPP_FILES) default.supp - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = valgrind.pc - -BUILT_SOURCES = default.supp valgrind.pc - -DISTCLEANFILES = default.supp - -default.supp: $(SUPP_FILES) - -## Preprend @PERL@ because tests/vg_regtest isn't executable -regtest: check - @PERL@ tests/vg_regtest --all - -EXTRA_DIST = \ - FAQ.txt \ - ACKNOWLEDGEMENTS \ - README_DEVELOPERS \ - README_PACKAGERS \ - README_MISSING_SYSCALL_OR_IOCTL TODO \ - valgrind.spec.in valgrind.pc.in \ - Makefile.all.am Makefile.tool.am Makefile.core-AM_CPPFLAGS.am \ - Makefile.tool-inplace.am - -install-exec-hook: - $(mkinstalldirs) $(DESTDIR)$(valdir) - rm -f $(DESTDIR)$(valdir)/libpthread.so.0 - $(LN_S) libpthread.so $(DESTDIR)$(valdir)/libpthread.so.0 - -all-local: - mkdir -p $(inplacedir) - rm -f $(addprefix $(inplacedir)/,default.supp $(SUPP_FILES)) - ln -s ../default.supp $(inplacedir) - ln -s $(addprefix ../$(top_srcdir)/,$(SUPP_FILES)) $(inplacedir) - -distclean-local: - rm -rf $(inplacedir) diff --git a/VEX/head20041019/Makefile.core-AM_CPPFLAGS.am b/VEX/head20041019/Makefile.core-AM_CPPFLAGS.am deleted file mode 100644 index 2e889b4f1..000000000 --- a/VEX/head20041019/Makefile.core-AM_CPPFLAGS.am +++ /dev/null @@ -1,8 +0,0 @@ -add_includes = -I$(top_builddir)/coregrind -I$(top_srcdir)/coregrind \ - -I$(top_srcdir)/coregrind/$(VG_ARCH) \ - -I$(top_srcdir)/coregrind/$(VG_PLATFORM) \ - -I$(top_builddir)/include -I$(top_srcdir)/include \ - -I$(top_srcdir)/include/$(VG_ARCH) - -AM_CPPFLAGS = $(add_includes) - diff --git a/VEX/head20041019/Makefile.tool-flags.am b/VEX/head20041019/Makefile.tool-flags.am deleted file mode 100644 index 435e81e2d..000000000 --- a/VEX/head20041019/Makefile.tool-flags.am +++ /dev/null @@ -1,10 +0,0 @@ -## Need $(top_builddir)/include because tool.h is built from tool.h.base; -## otherwise it will not work if builddir != srcdir. -add_includes = -I$(top_builddir)/include -I$(top_srcdir)/include \ - -I$(top_srcdir)/include/$(VG_ARCH) - -AM_CPPFLAGS = $(add_includes) -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O \ - @PREFERRED_STACK_BOUNDARY@ -g -AM_CCASFLAGS = $(add_includes) - diff --git a/VEX/head20041019/Makefile.tool-inplace.am b/VEX/head20041019/Makefile.tool-inplace.am deleted file mode 100644 index 75d4991df..000000000 --- a/VEX/head20041019/Makefile.tool-inplace.am +++ /dev/null @@ -1,4 +0,0 @@ -all-local: - mkdir -p $(inplacedir) - -rm -f $(addprefix $(inplacedir)/,$(val_PROGRAMS)) - ln -f -s $(addprefix ../$(subdir)/,$(val_PROGRAMS)) $(inplacedir) diff --git a/VEX/head20041019/Makefile.tool.am b/VEX/head20041019/Makefile.tool.am deleted file mode 100644 index 39aa6a15a..000000000 --- a/VEX/head20041019/Makefile.tool.am +++ /dev/null @@ -1,6 +0,0 @@ - -SUBDIRS = . tests docs - -include $(top_srcdir)/Makefile.all.am -include $(top_srcdir)/Makefile.tool-flags.am -include $(top_srcdir)/Makefile.tool-inplace.am diff --git a/VEX/head20041019/NEWS b/VEX/head20041019/NEWS deleted file mode 100644 index 1ae1b64e1..000000000 --- a/VEX/head20041019/NEWS +++ /dev/null @@ -1,739 +0,0 @@ - -Stable release 2.2.0 (31 August 2004) -- CHANGES RELATIVE TO 2.0.0 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.2.0 brings nine months worth of improvements and bug fixes. We -believe it to be a worthy successor to 2.0.0. There are literally -hundreds of bug fixes and minor improvements. There are also some -fairly major user-visible changes: - -* A complete overhaul of handling of system calls and signals, and - their interaction with threads. In general, the accuracy of the - system call, thread and signal simulations is much improved: - - - Blocking system calls behave exactly as they do when running - natively (not on valgrind). That is, if a syscall blocks only the - calling thread when running natively, than it behaves the same on - valgrind. No more mysterious hangs because V doesn't know that some - syscall or other, should block only the calling thread. - - - Interrupted syscalls should now give more faithful results. - - - Signal contexts in signal handlers are supported. - -* Improvements to NPTL support to the extent that V now works - properly on NPTL-only setups. - -* Greater isolation between Valgrind and the program being run, so - the program is less likely to inadvertently kill Valgrind by - doing wild writes. - -* Massif: a new space profiling tool. Try it! It's cool, and it'll - tell you in detail where and when your C/C++ code is allocating heap. - Draws pretty .ps pictures of memory use against time. A potentially - powerful tool for making sense of your program's space use. - -* File descriptor leakage checks. When enabled, Valgrind will print out - a list of open file descriptors on exit. - -* Improved SSE2/SSE3 support. - -* Time-stamped output; use --time-stamp=yes - - - -Stable release 2.2.0 (31 August 2004) -- CHANGES RELATIVE TO 2.1.2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.2.0 is not much different from 2.1.2, released seven weeks ago. -A number of bugs have been fixed, most notably #85658, which gave -problems for quite a few people. There have been many internal -cleanups, but those are not user visible. - -The following bugs have been fixed since 2.1.2: - -85658 Assert in coregrind/vg_libpthread.c:2326 (open64) != - (void*)0 failed - This bug was reported multiple times, and so the following - duplicates of it are also fixed: 87620, 85796, 85935, 86065, - 86919, 86988, 87917, 88156 - -80716 Semaphore mapping bug caused by unmap (sem_destroy) - (Was fixed prior to 2.1.2) - -86987 semctl and shmctl syscalls family is not handled properly - -86696 valgrind 2.1.2 + RH AS2.1 + librt - -86730 valgrind locks up at end of run with assertion failure - in __pthread_unwind - -86641 memcheck doesn't work with Mesa OpenGL/ATI on Suse 9.1 - (also fixes 74298, a duplicate of this) - -85947 MMX/SSE unhandled instruction 'sfence' - -84978 Wrong error "Conditional jump or move depends on - uninitialised value" resulting from "sbbl %reg, %reg" - -86254 ssort() fails when signed int return type from comparison is - too small to handle result of unsigned int subtraction - -87089 memalign( 4, xxx) makes valgrind assert - -86407 Add support for low-level parallel port driver ioctls. - -70587 Add timestamps to Valgrind output? (wishlist) - -84937 vg_libpthread.c:2505 (se_remap): Assertion `res == 0' - (fixed prior to 2.1.2) - -86317 cannot load libSDL-1.2.so.0 using valgrind - -86989 memcpy from mac_replace_strmem.c complains about - uninitialized pointers passed when length to copy is zero - -85811 gnu pascal symbol causes segmentation fault; ok in 2.0.0 - -79138 writing to sbrk()'d memory causes segfault - -77369 sched deadlock while signal received during pthread_join - and the joined thread exited - -88115 In signal handler for SIGFPE, siginfo->si_addr is wrong - under Valgrind - -78765 Massif crashes on app exit if FP exceptions are enabled - -Additionally there are the following changes, which are not -connected to any bug report numbers, AFAICS: - -* Fix scary bug causing mis-identification of SSE stores vs - loads and so causing memcheck to sometimes give nonsense results - on SSE code. - -* Add support for the POSIX message queue system calls. - -* Fix to allow 32-bit Valgrind to run on AMD64 boxes. Note: this does - NOT allow Valgrind to work with 64-bit executables - only with 32-bit - executables on an AMD64 box. - -* At configure time, only check whether linux/mii.h can be processed - so that we don't generate ugly warnings by trying to compile it. - -* Add support for POSIX clocks and timers. - - - -Developer (cvs head) release 2.1.2 (18 July 2004) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.1.2 contains four months worth of bug fixes and refinements. -Although officially a developer release, we believe it to be stable -enough for widespread day-to-day use. 2.1.2 is pretty good, so try it -first, although there is a chance it won't work. If so then try 2.0.0 -and tell us what went wrong." 2.1.2 fixes a lot of problems present -in 2.0.0 and is generally a much better product. - -Relative to 2.1.1, a large number of minor problems with 2.1.1 have -been fixed, and so if you use 2.1.1 you should try 2.1.2. Users of -the last stable release, 2.0.0, might also want to try this release. - -The following bugs, and probably many more, have been fixed. These -are listed at http://bugs.kde.org. Reporting a bug for valgrind in -the http://bugs.kde.org is much more likely to get you a fix than -mailing developers directly, so please continue to keep sending bugs -there. - -76869 Crashes when running any tool under Fedora Core 2 test1 - This fixes the problem with returning from a signal handler - when VDSOs are turned off in FC2. - -69508 java 1.4.2 client fails with erroneous "stack size too small". - This fix makes more of the pthread stack attribute related - functions work properly. Java still doesn't work though. - -71906 malloc alignment should be 8, not 4 - All memory returned by malloc/new etc is now at least - 8-byte aligned. - -81970 vg_alloc_ThreadState: no free slots available - (closed because the workaround is simple: increase - VG_N_THREADS, rebuild and try again.) - -78514 Conditional jump or move depends on uninitialized value(s) - (a slight mishanding of FP code in memcheck) - -77952 pThread Support (crash) (due to initialisation-ordering probs) - (also 85118) - -80942 Addrcheck wasn't doing overlap checking as it should. -78048 return NULL on malloc/new etc failure, instead of asserting -73655 operator new() override in user .so files often doesn't get picked up -83060 Valgrind does not handle native kernel AIO -69872 Create proper coredumps after fatal signals -82026 failure with new glibc versions: __libc_* functions are not exported -70344 UNIMPLEMENTED FUNCTION: tcdrain -81297 Cancellation of pthread_cond_wait does not require mutex -82872 Using debug info from additional packages (wishlist) -83025 Support for ioctls FIGETBSZ and FIBMAP -83340 Support for ioctl HDIO_GET_IDENTITY -79714 Support for the semtimedop system call. -77022 Support for ioctls FBIOGET_VSCREENINFO and FBIOGET_FSCREENINFO -82098 hp2ps ansification (wishlist) -83573 Valgrind SIGSEGV on execve -82999 show which cmdline option was erroneous (wishlist) -83040 make valgrind VPATH and distcheck-clean (wishlist) -83998 Assertion `newfd > vgPlain_max_fd' failed (see below) -82722 Unchecked mmap in as_pad leads to mysterious failures later -78958 memcheck seg faults while running Mozilla -85416 Arguments with colon (e.g. --logsocket) ignored - - -Additionally there are the following changes, which are not -connected to any bug report numbers, AFAICS: - -* Rearranged address space layout relative to 2.1.1, so that - Valgrind/tools will run out of memory later than currently in many - circumstances. This is good news esp. for Calltree. It should - be possible for client programs to allocate over 800MB of - memory when using memcheck now. - -* Improved checking when laying out memory. Should hopefully avoid - the random segmentation faults that 2.1.1 sometimes caused. - -* Support for Fedora Core 2 and SuSE 9.1. Improvements to NPTL - support to the extent that V now works properly on NPTL-only setups. - -* Renamed the following options: - --logfile-fd --> --log-fd - --logfile --> --log-file - --logsocket --> --log-socket - to be consistent with each other and other options (esp. --input-fd). - -* Add support for SIOCGMIIPHY, SIOCGMIIREG and SIOCSMIIREG ioctls and - improve the checking of other interface related ioctls. - -* Fix building with gcc-3.4.1. - -* Remove limit on number of semaphores supported. - -* Add support for syscalls: set_tid_address (258), acct (51). - -* Support instruction "repne movs" -- not official but seems to occur. - -* Implement an emulated soft limit for file descriptors in addition to - the current reserved area, which effectively acts as a hard limit. The - setrlimit system call now simply updates the emulated limits as best - as possible - the hard limit is not allowed to move at all and just - returns EPERM if you try and change it. This should stop reductions - in the soft limit causing assertions when valgrind tries to allocate - descriptors from the reserved area. - (This actually came from bug #83998). - -* Major overhaul of Cachegrind implementation. First user-visible change - is that cachegrind.out files are now typically 90% smaller than they - used to be; code annotation times are correspondingly much smaller. - Second user-visible change is that hit/miss counts for code that is - unloaded at run-time is no longer dumped into a single "discard" pile, - but accurately preserved. - -* Client requests for telling valgrind about memory pools. - - - -Developer (cvs head) release 2.1.1 (12 March 2004) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.1.1 contains some internal structural changes needed for V's -long-term future. These don't affect end-users. Most notable -user-visible changes are: - -* Greater isolation between Valgrind and the program being run, so - the program is less likely to inadvertently kill Valgrind by - doing wild writes. - -* Massif: a new space profiling tool. Try it! It's cool, and it'll - tell you in detail where and when your C/C++ code is allocating heap. - Draws pretty .ps pictures of memory use against time. A potentially - powerful tool for making sense of your program's space use. - -* Fixes for many bugs, including support for more SSE2/SSE3 instructions, - various signal/syscall things, and various problems with debug - info readers. - -* Support for glibc-2.3.3 based systems. - -We are now doing automatic overnight build-and-test runs on a variety -of distros. As a result, we believe 2.1.1 builds and runs on: -Red Hat 7.2, 7.3, 8.0, 9, Fedora Core 1, SuSE 8.2, SuSE 9. - - -The following bugs, and probably many more, have been fixed. These -are listed at http://bugs.kde.org. Reporting a bug for valgrind in -the http://bugs.kde.org is much more likely to get you a fix than -mailing developers directly, so please continue to keep sending bugs -there. - -69616 glibc 2.3.2 w/NPTL is massively different than what valgrind expects -69856 I don't know how to instrument MMXish stuff (Helgrind) -73892 valgrind segfaults starting with Objective-C debug info - (fix for S-type stabs) -73145 Valgrind complains too much about close() -73902 Shadow memory allocation seems to fail on RedHat 8.0 -68633 VG_N_SEMAPHORES too low (V itself was leaking semaphores) -75099 impossible to trace multiprocess programs -76839 the `impossible' happened: disInstr: INT but not 0x80 ! -76762 vg_to_ucode.c:3748 (dis_push_segreg): Assertion `sz == 4' failed. -76747 cannot include valgrind.h in c++ program -76223 parsing B(3,10) gave NULL type => impossible happens -75604 shmdt handling problem -76416 Problems with gcc 3.4 snap 20040225 -75614 using -gstabs when building your programs the `impossible' happened -75787 Patch for some CDROM ioctls CDORM_GET_MCN, CDROM_SEND_PACKET, -75294 gcc 3.4 snapshot's libstdc++ have unsupported instructions. - (REP RET) -73326 vg_symtab2.c:272 (addScopeRange): Assertion `range->size > 0' failed. -72596 not recognizing __libc_malloc -69489 Would like to attach ddd to running program -72781 Cachegrind crashes with kde programs -73055 Illegal operand at DXTCV11CompressBlockSSE2 (more SSE opcodes) -73026 Descriptor leak check reports port numbers wrongly -71705 README_MISSING_SYSCALL_OR_IOCTL out of date -72643 Improve support for SSE/SSE2 instructions -72484 valgrind leaves it's own signal mask in place when execing -72650 Signal Handling always seems to restart system calls -72006 The mmap system call turns all errors in ENOMEM -71781 gdb attach is pretty useless -71180 unhandled instruction bytes: 0xF 0xAE 0x85 0xE8 -69886 writes to zero page cause valgrind to assert on exit -71791 crash when valgrinding gimp 1.3 (stabs reader problem) -69783 unhandled syscall: 218 -69782 unhandled instruction bytes: 0x66 0xF 0x2B 0x80 -70385 valgrind fails if the soft file descriptor limit is less - than about 828 -69529 "rep; nop" should do a yield -70827 programs with lots of shared libraries report "mmap failed" - for some of them when reading symbols -71028 glibc's strnlen is optimised enough to confuse valgrind - - - - -Unstable (cvs head) release 2.1.0 (15 December 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For whatever it's worth, 2.1.0 actually seems pretty darn stable to me -(Julian). It looks eminently usable, and given that it fixes some -significant bugs, may well be worth using on a day-to-day basis. -2.1.0 is known to build and pass regression tests on: SuSE 9, SuSE -8.2, RedHat 8. - -2.1.0 most notably includes Jeremy Fitzhardinge's complete overhaul of -handling of system calls and signals, and their interaction with -threads. In general, the accuracy of the system call, thread and -signal simulations is much improved. Specifically: - -- Blocking system calls behave exactly as they do when running - natively (not on valgrind). That is, if a syscall blocks only the - calling thread when running natively, than it behaves the same on - valgrind. No more mysterious hangs because V doesn't know that some - syscall or other, should block only the calling thread. - -- Interrupted syscalls should now give more faithful results. - -- Finally, signal contexts in signal handlers are supported. As a - result, konqueror on SuSE 9 no longer segfaults when notified of - file changes in directories it is watching. - -Other changes: - -- Robert Walsh's file descriptor leakage checks. When enabled, - Valgrind will print out a list of open file descriptors on - exit. Along with each file descriptor, Valgrind prints out a stack - backtrace of where the file was opened and any details relating to the - file descriptor such as the file name or socket details. - To use, give: --track-fds=yes - -- Implemented a few more SSE/SSE2 instructions. - -- Less crud on the stack when you do 'where' inside a GDB attach. - -- Fixed the following bugs: - 68360: Valgrind does not compile against 2.6.0-testX kernels - 68525: CVS head doesn't compile on C90 compilers - 68566: pkgconfig support (wishlist) - 68588: Assertion `sz == 4' failed in vg_to_ucode.c (disInstr) - 69140: valgrind not able to explicitly specify a path to a binary. - 69432: helgrind asserts encountering a MutexErr when there are - EraserErr suppressions - -- Increase the max size of the translation cache from 200k average bbs - to 300k average bbs. Programs on the size of OOo (680m17) are - thrashing the cache at the smaller size, creating large numbers of - retranslations and wasting significant time as a result. - - - -Stable release 2.0.0 (5 Nov 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -2.0.0 improves SSE/SSE2 support, fixes some minor bugs, and -improves support for SuSE 9 and the Red Hat "Severn" beta. - -- Further improvements to SSE/SSE2 support. The entire test suite of - the GNU Scientific Library (gsl-1.4) compiled with Intel Icc 7.1 - 20030307Z '-g -O -xW' now works. I think this gives pretty good - coverage of SSE/SSE2 floating point instructions, or at least the - subset emitted by Icc. - -- Also added support for the following instructions: - MOVNTDQ UCOMISD UNPCKLPS UNPCKHPS SQRTSS - PUSH/POP %{FS,GS}, and PUSH %CS (Nb: there is no POP %CS). - -- CFI support for GDB version 6. Needed to enable newer GDBs - to figure out where they are when using --gdb-attach=yes. - -- Fix this: - mc_translate.c:1091 (memcheck_instrument): Assertion - `u_in->size == 4 || u_in->size == 16' failed. - -- Return an error rather than panicing when given a bad socketcall. - -- Fix checking of syscall rt_sigtimedwait(). - -- Implement __NR_clock_gettime (syscall 265). Needed on Red Hat Severn. - -- Fixed bug in overlap check in strncpy() -- it was assuming the src was 'n' - bytes long, when it could be shorter, which could cause false - positives. - -- Support use of select() for very large numbers of file descriptors. - -- Don't fail silently if the executable is statically linked, or is - setuid/setgid. Print an error message instead. - -- Support for old DWARF-1 format line number info. - - - -Snapshot 20031012 (12 October 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Three months worth of bug fixes, roughly. Most significant single -change is improved SSE/SSE2 support, mostly thanks to Dirk Mueller. - -20031012 builds on Red Hat Fedora ("Severn") but doesn't really work -(curiosly, mozilla runs OK, but a modest "ls -l" bombs). I hope to -get a working version out soon. It may or may not work ok on the -forthcoming SuSE 9; I hear positive noises about it but haven't been -able to verify this myself (not until I get hold of a copy of 9). - -A detailed list of changes, in no particular order: - -- Describe --gen-suppressions in the FAQ. - -- Syscall __NR_waitpid supported. - -- Minor MMX bug fix. - -- -v prints program's argv[] at startup. - -- More glibc-2.3 suppressions. - -- Suppressions for stack underrun bug(s) in the c++ support library - distributed with Intel Icc 7.0. - -- Fix problems reading /proc/self/maps. - -- Fix a couple of messages that should have been suppressed by -q, - but weren't. - -- Make Addrcheck understand "Overlap" suppressions. - -- At startup, check if program is statically linked and bail out if so. - -- Cachegrind: Auto-detect Intel Pentium-M, also VIA Nehemiah - -- Memcheck/addrcheck: minor speed optimisations - -- Handle syscall __NR_brk more correctly than before. - -- Fixed incorrect allocate/free mismatch errors when using - operator new(unsigned, std::nothrow_t const&) - operator new[](unsigned, std::nothrow_t const&) - -- Support POSIX pthread spinlocks. - -- Fixups for clean compilation with gcc-3.3.1. - -- Implemented more opcodes: - - push %es - - push %ds - - pop %es - - pop %ds - - movntq - - sfence - - pshufw - - pavgb - - ucomiss - - enter - - mov imm32, %esp - - all "in" and "out" opcodes - - inc/dec %esp - - A whole bunch of SSE/SSE2 instructions - -- Memcheck: don't bomb on SSE/SSE2 code. - - -Snapshot 20030725 (25 July 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Fixes some minor problems in 20030716. - -- Fix bugs in overlap checking for strcpy/memcpy etc. - -- Do overlap checking with Addrcheck as well as Memcheck. - -- Fix this: - Memcheck: the `impossible' happened: - get_error_name: unexpected type - -- Install headers needed to compile new skins. - -- Remove leading spaces and colon in the LD_LIBRARY_PATH / LD_PRELOAD - passed to non-traced children. - -- Fix file descriptor leak in valgrind-listener. - -- Fix longstanding bug in which the allocation point of a - block resized by realloc was not correctly set. This may - have caused confusing error messages. - - -Snapshot 20030716 (16 July 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -20030716 is a snapshot of our current CVS head (development) branch. -This is the branch which will become valgrind-2.0. It contains -significant enhancements over the 1.9.X branch. - -Despite this being a snapshot of the CVS head, it is believed to be -quite stable -- at least as stable as 1.9.6 or 1.0.4, if not more so --- and therefore suitable for widespread use. Please let us know asap -if it causes problems for you. - -Two reasons for releasing a snapshot now are: - -- It's been a while since 1.9.6, and this snapshot fixes - various problems that 1.9.6 has with threaded programs - on glibc-2.3.X based systems. - -- So as to make available improvements in the 2.0 line. - -Major changes in 20030716, as compared to 1.9.6: - -- More fixes to threading support on glibc-2.3.1 and 2.3.2-based - systems (SuSE 8.2, Red Hat 9). If you have had problems - with inconsistent/illogical behaviour of errno, h_errno or the DNS - resolver functions in threaded programs, 20030716 should improve - matters. This snapshot seems stable enough to run OpenOffice.org - 1.1rc on Red Hat 7.3, SuSE 8.2 and Red Hat 9, and that's a big - threaded app if ever I saw one. - -- Automatic generation of suppression records; you no longer - need to write them by hand. Use --gen-suppressions=yes. - -- strcpy/memcpy/etc check their arguments for overlaps, when - running with the Memcheck or Addrcheck skins. - -- malloc_usable_size() is now supported. - -- new client requests: - - VALGRIND_COUNT_ERRORS, VALGRIND_COUNT_LEAKS: - useful with regression testing - - VALGRIND_NON_SIMD_CALL[0123]: for running arbitrary functions - on real CPU (use with caution!) - -- The GDB attach mechanism is more flexible. Allow the GDB to - be run to be specified by --gdb-path=/path/to/gdb, and specify - which file descriptor V will read its input from with - --input-fd=. - -- Cachegrind gives more accurate results (wasn't tracking instructions in - malloc() and friends previously, is now). - -- Complete support for the MMX instruction set. - -- Partial support for the SSE and SSE2 instruction sets. Work for this - is ongoing. About half the SSE/SSE2 instructions are done, so - some SSE based programs may work. Currently you need to specify - --skin=addrcheck. Basically not suitable for real use yet. - -- Significant speedups (10%-20%) for standard memory checking. - -- Fix assertion failure in pthread_once(). - -- Fix this: - valgrind: vg_intercept.c:598 (vgAllRoadsLeadToRome_select): - Assertion `ms_end >= ms_now' failed. - -- Implement pthread_mutexattr_setpshared. - -- Understand Pentium 4 branch hints. Also implemented a couple more - obscure x86 instructions. - -- Lots of other minor bug fixes. - -- We have a decent regression test system, for the first time. - This doesn't help you directly, but it does make it a lot easier - for us to track the quality of the system, especially across - multiple linux distributions. - - You can run the regression tests with 'make regtest' after 'make - install' completes. On SuSE 8.2 and Red Hat 9 I get this: - - == 84 tests, 0 stderr failures, 0 stdout failures == - - On Red Hat 8, I get this: - - == 84 tests, 2 stderr failures, 1 stdout failure == - corecheck/tests/res_search (stdout) - memcheck/tests/sigaltstack (stderr) - - sigaltstack is probably harmless. res_search doesn't work - on R H 8 even running natively, so I'm not too worried. - - On Red Hat 7.3, a glibc-2.2.5 system, I get these harmless failures: - - == 84 tests, 2 stderr failures, 1 stdout failure == - corecheck/tests/pth_atfork1 (stdout) - corecheck/tests/pth_atfork1 (stderr) - memcheck/tests/sigaltstack (stderr) - - You need to run on a PII system, at least, since some tests - contain P6-specific instructions, and the test machine needs - access to the internet so that corecheck/tests/res_search - (a test that the DNS resolver works) can function. - -As ever, thanks for the vast amount of feedback :) and bug reports :( -We may not answer all messages, but we do at least look at all of -them, and tend to fix the most frequently reported bugs. - - - -Version 1.9.6 (7 May 2003 or thereabouts) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Major changes in 1.9.6: - -- Improved threading support for glibc >= 2.3.2 (SuSE 8.2, - RedHat 9, to name but two ...) It turned out that 1.9.5 - had problems with threading support on glibc >= 2.3.2, - usually manifested by threaded programs deadlocking in system calls, - or running unbelievably slowly. Hopefully these are fixed now. 1.9.6 - is the first valgrind which gives reasonable support for - glibc-2.3.2. Also fixed a 2.3.2 problem with pthread_atfork(). - -- Majorly expanded FAQ.txt. We've added workarounds for all - common problems for which a workaround is known. - -Minor changes in 1.9.6: - -- Fix identification of the main thread's stack. Incorrect - identification of it was causing some on-stack addresses to not get - identified as such. This only affected the usefulness of some error - messages; the correctness of the checks made is unchanged. - -- Support for kernels >= 2.5.68. - -- Dummy implementations of __libc_current_sigrtmin, - __libc_current_sigrtmax and __libc_allocate_rtsig, hopefully - good enough to keep alive programs which previously died for lack of - them. - -- Fix bug in the VALGRIND_DISCARD_TRANSLATIONS client request. - -- Fix bug in the DWARF2 debug line info loader, when instructions - following each other have source lines far from each other - (e.g. with inlined functions). - -- Debug info reading: read symbols from both "symtab" and "dynsym" - sections, rather than merely from the one that comes last in the - file. - -- New syscall support: prctl(), creat(), lookup_dcookie(). - -- When checking calls to accept(), recvfrom(), getsocketopt(), - don't complain if buffer values are NULL. - -- Try and avoid assertion failures in - mash_LD_PRELOAD_and_LD_LIBRARY_PATH. - -- Minor bug fixes in cg_annotate. - - - -Version 1.9.5 (7 April 2003) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It occurs to me that it would be helpful for valgrind users to record -in the source distribution the changes in each release. So I now -attempt to mend my errant ways :-) Changes in this and future releases -will be documented in the NEWS file in the source distribution. - -Major changes in 1.9.5: - -- (Critical bug fix): Fix a bug in the FPU simulation. This was - causing some floating point conditional tests not to work right. - Several people reported this. If you had floating point code which - didn't work right on 1.9.1 to 1.9.4, it's worth trying 1.9.5. - -- Partial support for Red Hat 9. RH9 uses the new Native Posix - Threads Library (NPTL), instead of the older LinuxThreads. - This potentially causes problems with V which will take some - time to correct. In the meantime we have partially worked around - this, and so 1.9.5 works on RH9. Threaded programs still work, - but they may deadlock, because some system calls (accept, read, - write, etc) which should be nonblocking, in fact do block. This - is a known bug which we are looking into. - - If you can, your best bet (unfortunately) is to avoid using - 1.9.5 on a Red Hat 9 system, or on any NPTL-based distribution. - If your glibc is 2.3.1 or earlier, you're almost certainly OK. - -Minor changes in 1.9.5: - -- Added some #errors to valgrind.h to ensure people don't include - it accidentally in their sources. This is a change from 1.0.X - which was never properly documented. The right thing to include - is now memcheck.h. Some people reported problems and strange - behaviour when (incorrectly) including valgrind.h in code with - 1.9.1 -- 1.9.4. This is no longer possible. - -- Add some __extension__ bits and pieces so that gcc configured - for valgrind-checking compiles even with -Werror. If you - don't understand this, ignore it. Of interest to gcc developers - only. - -- Removed a pointless check which caused problems interworking - with Clearcase. V would complain about shared objects whose - names did not end ".so", and refuse to run. This is now fixed. - In fact it was fixed in 1.9.4 but not documented. - -- Fixed a bug causing an assertion failure of "waiters == 1" - somewhere in vg_scheduler.c, when running large threaded apps, - notably MySQL. - -- Add support for the munlock system call (124). - -Some comments about future releases: - -1.9.5 is, we hope, the most stable Valgrind so far. It pretty much -supersedes the 1.0.X branch. If you are a valgrind packager, please -consider making 1.9.5 available to your users. You can regard the -1.0.X branch as obsolete: 1.9.5 is stable and vastly superior. There -are no plans at all for further releases of the 1.0.X branch. - -If you want a leading-edge valgrind, consider building the cvs head -(from SourceForge), or getting a snapshot of it. Current cool stuff -going in includes MMX support (done); SSE/SSE2 support (in progress), -a significant (10-20%) performance improvement (done), and the usual -large collection of minor changes. Hopefully we will be able to -improve our NPTL support, but no promises. - diff --git a/VEX/head20041019/NOTES.syscalls b/VEX/head20041019/NOTES.syscalls deleted file mode 100644 index 86e3231a8..000000000 --- a/VEX/head20041019/NOTES.syscalls +++ /dev/null @@ -1,195 +0,0 @@ -- works on stock 2.4 kernels, but the scheduler loop must poll -- works on RH9 2.4.20-18.9 kernel, but doesn't seem quite as stable - as 2.5/2.6 - for pending signals rather than relying on the kernel delivering them - to the right place. -- most tested on 2.6.0-test1 and up - -- running job-control programs (ie, bash) under Valgrind won't work - properly without a kernel patch (as of 2.6.0-test2-mm2). This is because - threads in a thread group don't follow the thread group leader's changes - in process group ID, and they can't change it for themselves. - -- SA_NOCLDWAIT doesn't work properly if the program is actually blocked - in wait4() when SIGCHLD arrives; the wait4() will return details for - the exiting child. In other circumstances children should be quietly reaped. - [ This may be fixable when running under RH2.4 and 2.6, since we can - set NOCLDWAIT in the kernel's state without risk of losing our child - threads. ] - -- 2.4 has somewhat disfunctional thread/signal interactions, so many test - do not work as well under 2.4. In general, it should be no worse than - the old signal code. I don't intend spending a lot of time fixing this - because 2.6 is nearly ready for widespread use. - -TODO: - -- support application use of clone(). Interesting question is which - options do we support? Do we need to implement futex as well, or can - we just use the kernel's implementation? - -======================================== -Testing - -I've been testing with the Posix test suite: -http://sourceforge.net/projects/posixtest/, version 1.2.0. - ----------------------------------------- -Expected failures: - -conformance/interfaces/sigwaitinfo/6-1.test - pthread_kill() calls the tkill syscall, which causes a code of - SI_TKILL rather than the SI_USER which this test expects. - -conformance/interfaces/sigrelse/3-*.test - glibc bug in sigrelse(), which fails without Valgrind too. - -conformance/interfaces/pthread_barrier_*/* - Valgrind's libpthreads doesn't implement pthread_barrier_*. - (There are some passes, but I don't know why.) - -conformance/interfaces/pthread_cond_timedwait/2-3 - This test is just completely broken. It does expose a problem - in Valgrind's mutex implementation - it is too dependent on - the client code not doing stupid stuff. This test makes - Valgrind have an assertion failure. - -conformance/interfaces/pthread_condattr_getpshared/* - pthread_condattr_getpshared not implemented - -conformance/interfaces/pthread_condattr_setpshared/* - pthread_condattr_setpshared not implemented - -conformance/interfaces/pthread_key_create/speculative/5-1 - Valgrind should cope with key overload - -conformance/interfaces/pthread_mutex_timedlock/* - not implemented - -conformance/interfaces/pthread_rwlock_rdlock/2-1: - relies on pthread_setschedparam - -conformance/interfaces/pthread_rwlock_timedrdlock/* - valgrind's libpthread.so: UNIMPLEMENTED FUNCTION: pthread_rwlock_timedrdlock - -conformance/interfaces/pthread_rwlockattr_getpshared/* - pthread_rwlockattr_getpshared not implemented - -conformance/interfaces/pthread_rwlockattr_setpshared/* - pthread_rwlockattr_setpshared not implemented - -conformance/interfaces/sched_rr_get_interval/* - syscall 161 (sched_rr_get_interval) not implemented - -conformance/interfaces/sigaction/21-1 - Subtle problem: if app specifies SA_NOCLDWAIT on their SIGCHLD - signal handler, Valgrind will attempt to catch the SIGCHLD and - wait4() on all the children before returning to the app. - However, if the app was running a wait4() at the time the - SIGCHLD arrives, it will get the child's status. Quite what - the app is doing running wait4() when it explicitly asked for - it to be useless, I'm not sure... - -conformance/interfaces/sigaction/17-{3,6,8,12} - (2.4) These fail under 2.4 because they deal with SIGSEGV, SIGBUS - and SIGILL. These signals can only be delivered if there's a - thread immediately ready to handle them, but cannot be left - pending indefinitely. These tests hang forever because the - signal is discarded rather than delivered. - -conformance/interfaces/sigqueue/{1,4,8}-1 - (2.4) Signals that we route manually do not have queued data - associated with them - they are routed with tkill. Also - pending signals are only kept in a mask, not in a queue, so - there can only be one at a time. - ----------------------------------------- - -Still to investigate: - -conformance/interfaces/pthread_detach/4-1 - -+conformance/interfaces/pthread_rwlock_rdlock/4-1: execution: FAILED: Output: -+main: attempt write lock -+main: acquired write lock -+sig_thread: attemp read lock -+main: fire SIGUSR1 to sig_thread -+SIGUSR1 was not caught by sig_thread - - -+conformance/interfaces/pthread_rwlock_unlock/4-1: execution: FAILED: Output: -+Test FAILED: Incorrect error code, expected 0 or EINVAL, got 1 - -+conformance/interfaces/pthread_rwlock_wrlock/2-1: execution: FAILED: Output: -+main: attempt write lock -+sig_thread: attempt write lock -+main: fire SIGUSR1 to sig_thread -+The signal handler did not get called. - -+conformance/interfaces/pthread_rwlock_wrlock/3-1: execution: FAILED: Output: -+ -+sched status: -+ -+Thread 1: status = WaitCV, associated_mx = 0x40115910, associated_cv = 0x401158E0 -+==11243== at 0x40102962: pthread_cond_wait (vg_libpthread.c:1093) -+==11243== by 0x40104976: __pthread_rwlock_wrlock (vg_libpthread.c:2619) -+==11243== by 0x8048588: main (3-1.c:53) -+==11243== by 0x4013DA46: __libc_start_main (in /lib/libc-2.3.2.so) -+ -+==11243== Warning: pthread scheduler exited due to deadlock -+ -+valgrind: vg_main.c:1619 (vgPlain_main): Assertion `vgPlain_threads[vgPlain_last_run_tid].status == VgTs_Runnable' failed. -+ -+sched status: -+ -+Thread 1: status = WaitCV, associated_mx = 0x40115910, associated_cv = 0x401158E0 -+==11243== at 0x40102962: pthread_cond_wait (vg_libpthread.c:1093) -+==11243== by 0x40104976: __pthread_rwlock_wrlock (vg_libpthread.c:2619) -+==11243== by 0x8048588: main (3-1.c:53) -+==11243== by 0x4013DA46: __libc_start_main (in /lib/libc-2.3.2.so) - - -+conformance/interfaces/sem_close/1-1.test: -/home/jeremy/bk/valgrind/syscalls/coregrind/.in_place/libpthread.so.0: -version `GLIBC_2.1.1' not found (required by -conformance/interfaces/sem_close/1-1.test) - -+conformance/interfaces/sem_timedwait/6-1: execution: FAILED: Output: -+TEST FAILED -+conformance/interfaces/sem_timedwait/6-2: execution: FAILED: Output: -+TEST FAILED - -+conformance/interfaces/sem_timedwait/9-1: execution: FAILED: Output: -+In handler -+TEST FAILED: errno != EINTR - - -conformance/interfaces/sigaction/10-1: - Used to work. Mysterious. Works everywhere except in the test harness... - - -+conformance/interfaces/sigpause/1-2: execution: FAILED: Output: -+ -+valgrind: vg_mylibc.c:1324 (vgPlain_read_millisecond_timer): Assertion `rdtsc_now > rdtsc_cal_end_raw' failed. -+ -+sched status: -+ -+Thread 1: status = Sleeping, associated_mx = 0x0, associated_cv = 0x0 -+==19929== at 0x401D6765: __GI___libc_nanosleep (in /lib/libc-2.3.2.so) -+==19929== by 0x80485C1: main (1-2.c:65) -+==19929== by 0x4013DA46: __libc_start_main (in /lib/libc-2.3.2.so) -+==19929== by 0x8048494: ??? (start.S:81) -+ -+Thread 2: status = WaitSys, associated_mx = 0x0, associated_cv = 0x0 -+==19929== at 0x40150796: __libc_sigsuspend (in /lib/libc-2.3.2.so) -+==19929== by 0x401509B3: __GI___sigpause (in /lib/libc-2.3.2.so) -+==19929== by 0x804857C: a_thread_func (1-2.c:48) -+==19929== by 0x40102099: thread_wrapper (vg_libpthread.c:667) - - - ----------------------------------------- - -Fixes: -conformance/interfaces/pthread_detach/4-2 - This fails under NPTL, but passes under Valgrind diff --git a/VEX/head20041019/README b/VEX/head20041019/README deleted file mode 100644 index 32b21ecf6..000000000 --- a/VEX/head20041019/README +++ /dev/null @@ -1,100 +0,0 @@ - -Release notes for Valgrind -~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you are building a binary package of Valgrind for distribution, -please read README_PACKAGERS. It contains some important information. - -If you are developing Valgrind, please read README_DEVELOPERS. It contains -some useful information. - -For instructions on how to build/install, see the end of this file. - -Valgrind works on most, reasonably recent Linux setups. If you have -problems, consult FAQ.txt to see if there are workarounds. - -Executive Summary -~~~~~~~~~~~~~~~~~ -Valgrind is a GPL'd system for debugging and profiling x86-Linux programs. -With the tools that come with Valgrind, you can automatically detect -many memory management and threading bugs, avoiding hours of frustrating -bug-hunting, making your programs more stable. You can also perform -detailed profiling to help speed up your programs. - -The Valgrind distribution includes five tools: two memory error -detectors, a thread error detector, a cache profiler and a heap profiler. -Several other tools have been built with Valgrind. - -To give you an idea of what Valgrind tools do, when a program is run -under the supervision of the first memory error detector tool, all reads -and writes of memory are checked, and calls to malloc/new/free/delete -are intercepted. As a result, it can detect problems such as: - - Use of uninitialised memory - Reading/writing memory after it has been free'd - Reading/writing off the end of malloc'd blocks - Reading/writing inappropriate areas on the stack - Memory leaks -- where pointers to malloc'd blocks are lost forever - Passing of uninitialised and/or unaddressible memory to system calls - Mismatched use of malloc/new/new [] vs free/delete/delete [] - Overlaps of arguments to strcpy() and related functions - Some abuses of the POSIX pthread API - -Problems like these can be difficult to find by other means, often -lying undetected for long periods, then causing occasional, -difficult-to-diagnose crashes. When one of these errors occurs, you can -attach GDB to your program, so you can poke around and see what's going -on. - -Valgrind is closely tied to details of the CPU, operating system and -to a less extent, compiler and basic C libraries. This makes it -difficult to make it portable, so I have chosen at the outset to -concentrate on what I believe to be a widely used platform: x86/Linux. - -Valgrind is licensed under the GNU General Public License, version 2. -Read the file COPYING in the source distribution for details. - - -Documentation -~~~~~~~~~~~~~ -A comprehensive user guide is supplied. Point your browser at -$PREFIX/share/doc/valgrind/manual.html, where $PREFIX is whatever you -specified with --prefix= when building. - - -Building and installing it -~~~~~~~~~~~~~~~~~~~~~~~~~~ -To install from CVS : - - 0. Check out the code from CVS, following the instructions at - http://developer.kde.org/source/anoncvs.html. The 'modulename' is - "valgrind". - - 1. cd into the source directory. - - 2. Run ./autogen.sh to setup the environment (you need the standard - autoconf tools to do so). - -To install from a tar.bz2 distribution: - - 3. Run ./configure, with some options if you wish. The standard - options are documented in the INSTALL file. The only interesting - one is the usual --prefix=/where/you/want/it/installed. - - 4. Do "make". - - 5. Do "make install", possibly as root if the destination permissions - require that. - - 6. See if it works. Try "valgrind --tool=memcheck ls -l". Either - this works, or it bombs out with some complaint. In that case, - please let us know (see valgrind.kde.org/bugs.html). - -Important! Do not move the valgrind installation into a place -different from that specified by --prefix at build time. This will -cause things to break in subtle ways, mostly when Valgrind handles -fork/exec calls. - - -Julian Seward (jseward@acm.org) -Nick Nethercote (njn25@cam.ac.uk) -Jeremy Fitzhardinge (jeremy@goop.org) diff --git a/VEX/head20041019/README_DEVELOPERS b/VEX/head20041019/README_DEVELOPERS deleted file mode 100644 index a7fa4689c..000000000 --- a/VEX/head20041019/README_DEVELOPERS +++ /dev/null @@ -1,49 +0,0 @@ - -Building and not installing it -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To run Valgrind without having to install it, run coregrind/valgrind (prefix -with "sh" because it's not executable) with the --in-place= option, where - is the root of the source tree (and must be an absolute path). Eg: - - sh ~/grind/head4/coregrind/valgrind --in-place=/homes/njn25/grind/head4 - -This allows you to compile and run with "make" instead of "make install", -saving you time. - -I recommend compiling with "make --quiet" to further reduce the amount of -output spewed out during compilation, letting you actually see any errors, -warnings, etc. - - -Running the regression tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To build and run all the regression tests, run "make [--quiet] regtest". - -To run a subset of the regression tests, execute: - - perl tests/vg_regtest - -where is a directory (all tests within will be run) or a single -.vgtest test file, or the name of a program which has a like-named .vgtest -file. Eg: - - perl tests/vg_regtest memcheck - perl tests/vg_regtest memcheck/tests/badfree.vgtest - perl tests/vg_regtest memcheck/tests/badfree - - -Debugging Valgrind with GDB -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To debug Valgrind itself with GDB, start Valgrind like this: - - valgrind --tool=none --wait-for-gdb=yes - -Then start gdb like this in another terminal: - - gdb /usr/lib/valgrind/stage2 - -Where is the pid valgrind printed. Then set whatever breakpoints -you want and do this in gdb: - - jump *$eip - diff --git a/VEX/head20041019/README_MISSING_SYSCALL_OR_IOCTL b/VEX/head20041019/README_MISSING_SYSCALL_OR_IOCTL deleted file mode 100644 index ad919252e..000000000 --- a/VEX/head20041019/README_MISSING_SYSCALL_OR_IOCTL +++ /dev/null @@ -1,166 +0,0 @@ - -Dealing with missing system call or ioctl wrappers in Valgrind -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You're probably reading this because Valgrind bombed out whilst -running your program, and advised you to read this file. The good -news is that, in general, it's easy to write the missing syscall or -ioctl wrappers you need, so that you can continue your debugging. If -you send the resulting patches to me, then you'll be doing a favour to -all future Valgrind users too. - -Note that an "ioctl" is just a special kind of system call, really; so -there's not a lot of need to distinguish them (at least conceptually) -in the discussion that follows. - -All this machinery is in coregrind/vg_syscalls.c. - - -What are syscall/ioctl wrappers? What do they do? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Valgrind does what it does, in part, by keeping track of everything your -program does. When a system call happens, for example a request to read -part of a file, control passes to the Linux kernel, which fulfills the -request, and returns control to your program. The problem is that the -kernel will often change the status of some part of your program's memory -as a result, and tools (instrumentation plug-ins) may need to know about -this. - -Syscall and ioctl wrappers have two jobs: - -1. Tell a tool what's about to happen, before the syscall takes place. A - tool could perform checks beforehand, eg. if memory about to be written - is actually writeable. This part is useful, but not strictly - essential. - -2. Tell a tool what just happened, after a syscall takes place. This is - so it can update its view of the program's state, eg. that memory has - just been written to. This step is essential. - -The "happenings" mostly involve reading/writing of memory. - -So, let's look at an example of a wrapper for a system call which -should be familiar to many Unix programmers. - - -The syscall wrapper for time() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Removing the debug printing clutter, it looks like this: - - PRE(time) - { - /* time_t time(time_t *t); */ - MAYBE_PRINTF("time ( %p )\n",arg1); - if (arg1 != (UInt)NULL) { - SYSCALL_TRACK( pre_mem_write, tid, "time", arg1, sizeof(time_t) ); - } - } - - POST(time) - { - if (arg1 != (UInt)NULL) { - VG_TRACK( post_mem_write, arg1, sizeof(time_t) ); - } - } - -The first thing we do happens before the syscall occurs, in the PRE() function: -if a non-NULL buffer is passed in as the argument, tell the tool that the -buffer is about to be written to: - - if (arg1 != (UInt)NULL) { - SYSCALL_TRACK( pre_mem_write, tst, "time", arg1, sizeof(time_t) ); - } - -Finally, the really important bit, after the syscall occurs, in the POST() -function: if, and only if, the system call was successful, tell the tool that -the memory was written: - - if (arg1 != (UInt)NULL) { - VG_TRACK( post_mem_write, arg1, sizeof(time_t) ); - } - -The POST() function won't be called if the syscall failed, so you -don't need to worry about checking that in the POST() function. -(Note: this is sometimes a bug; some syscalls do return results when -they "fail" - for example, nanosleep returns the amount of unslept -time if interrupted. TODO: add another per-syscall flag for this -case.) - - -Writing your own syscall wrappers (see below for ioctl wrappers) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If Valgrind tells you that system call NNN is unimplemented, do the -following: - -1. Find out the name of the system call: - - grep NNN /usr/include/asm/unistd.h - - This should tell you something like __NR_mysyscallname. - Copy this entry to coregrind/$(VG_PLATFORM)/vki_unistd.h. - -2. Do 'man 2 mysyscallname' to get some idea of what the syscall - does. Note that the actual kernel interface can differ from this, - so you might also want to check a version of the Linux kernel - source. - - NOTE: any syscall which has something to do with signals or - threads is probably "special", and needs more careful handling. - Post something to valgrind-developers if you aren't sure. - - -3. Add a case to the already-huge collection of wrappers in - coregrind/vg_syscalls.c. For each in-memory parameter which is - read or written by the syscall, do one of - - SYSCALL_TRACK( pre_mem_read, ... ) - SYSCALL_TRACK( pre_mem_read_asciiz, ... ) - SYSCALL_TRACK( pre_mem_write, ... ) - - for that parameter. Then do the syscall. Then, if the syscall - succeeds, issue suitable VG_TRACK( post_mem_write, ... ) calls. - (There's no need for post_mem_read calls.) - - Also, add it to the sys_info[] array; use SYSBA if it requires a - PRE() and POST() function, and SYSB_ if it only requires a PRE() - function. The 2nd arg of these macros indicate if the syscall - could possibly block. - - If you find this difficult, read the wrappers for other syscalls - for ideas. A good tip is to look for the wrapper for a syscall - which has a similar behaviour to yours, and use it as a - starting point. - - If you need structure definitions for your syscall, you can copy - structure definitions from the kernel headers into - include/vg_kerneliface.h, with the appropriate vki_* name - mangling. Alternatively, you can #include headers for structure - definitions, put your #includes into vg_unsafe.h (copying - syscall-related things into vg_kerneliface.h is preferred though). - - Test it. - - Note that a common error is to call VG_TRACK( post_mem_write, ... ) - with 0 (NULL) as the first (address) argument. This usually means - your logic is slightly inadequate. It's a sufficiently common bug - that there's a built-in check for it, and you'll get a "probably - sanity check failure" for the syscall wrapper you just made, if this - is the case. - - -4. Once happy, send us the patch. Pretty please. - - - - -Writing your own ioctl wrappers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Is pretty much the same as writing syscall wrappers, except that all -the action happens within PRE(ioctl) and POST(ioctl). - -There's a default case, sometimes it isn't correct and you have to write a -more specific case to get the right behaviour. - -As above, please create a bug report and attach the patch as described -on http://valgrind.kde.org/bugs.html - diff --git a/VEX/head20041019/README_PACKAGERS b/VEX/head20041019/README_PACKAGERS deleted file mode 100644 index 7f220b1e2..000000000 --- a/VEX/head20041019/README_PACKAGERS +++ /dev/null @@ -1,88 +0,0 @@ - -Greetings, packaging person! This information is aimed at people -building binary distributions of Valgrind. - -Thanks for taking the time and effort to make a binary distribution -of Valgrind. The following notes may save you some trouble. - - --- (Unfortunate but true) When you configure to build with the - --prefix=/foo/bar/xyzzy option, the prefix /foo/bar/xyzzy gets - baked into valgrind. The consequence is that you _must_ install - valgrind at the location specified in the prefix. If you don't, - it may appear to work, but will break doing some obscure things, - particularly doing fork() and exec(). - - So you can't build a relocatable RPM / whatever from Valgrind. - - --- Don't strip the debug info off stage2 or libpthread.so. - Valgrind will still work if you do, but it will generate less - helpful error messages. Here's an example: - - Mismatched free() / delete / delete [] - at 0x40043249: free (vg_clientfuncs.c:171) - by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149) - by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60) - by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44) - Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd - at 0x4004318C: __builtin_vec_new (vg_clientfuncs.c:152) - by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314) - by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416) - by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272) - - This tells you that some memory allocated with new[] was freed with - free(). If stage2 was stripped the message would look like this: - - Mismatched free() / delete / delete [] - at 0x40043249: (inside stage2) - by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149) - by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60) - by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44) - Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd - at 0x4004318C: (inside stage2) - by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314) - by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416) - by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272) - - This isn't so helpful. Although you can tell there is a mismatch, - the names of the allocating and deallocating functions are no longer - visible. The same kind of thing occurs in various other messages - from valgrind. - - --- Try and ensure that the /usr/include/asm/unistd.h file on the - build machine contains an entry for all the system calls that - the kernels on the target machines can actually support. On my - Red Hat 7.2 (kernel 2.4.9) box the highest-numbered entry is - #define __NR_fcntl64 221 - but I have heard of 2.2 boxes where it stops at 179 or so. - - Reason for this is that at build time, support for syscalls - is compiled in -- or not -- depending on which of these __NR_* - symbols is defined. Problems arise when /usr/include/asm/unistd.h - fails to give an entry for a system call which is actually - available in the target kernel. In that case, valgrind will - abort if asked to handle such a syscall. This is despite the - fact that (usually) valgrind's sources actually contain the - code to deal with the syscall. - - Several people have reported having this problem. So, please - be aware of it. If it's useful, the syscall wrappers are - all done in vg_syscall_mem.c; you might want to have a little - look in there. - - --- Please test the final installation works by running it on - something huge. I suggest checking that it can start and - exit successfully both Mozilla-1.0 and OpenOffice.org 1.0. - I use these as test programs, and I know they fairly thoroughly - exercise Valgrind. The command lines to use are: - - valgrind -v --trace-children=yes --workaround-gcc296-bugs=yes mozilla - - valgrind -v --trace-children=yes --workaround-gcc296-bugs=yes soffice - - -If you find any more hints/tips for packaging, please report -it as a bugreport. See http://valgrind.kde.org/bugs.html for details. diff --git a/VEX/head20041019/TODO b/VEX/head20041019/TODO deleted file mode 100644 index 738e50944..000000000 --- a/VEX/head20041019/TODO +++ /dev/null @@ -1,15 +0,0 @@ - -Doesn't run -~~~~~~~~~~~ -User Mode Linux. -Wine. - - -Desirable -~~~~~~~~~ -Stack: make return address into NoAccess ? - - -Future -~~~~~~ -Automatic invariant inference and checking. diff --git a/VEX/head20041019/addrcheck/.cvsignore b/VEX/head20041019/addrcheck/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/addrcheck/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/addrcheck/CVS/Entries b/VEX/head20041019/addrcheck/CVS/Entries deleted file mode 100644 index 1295d4696..000000000 --- a/VEX/head20041019/addrcheck/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:20 2002// -/Makefile.am/1.52/Wed Sep 1 23:20:46 2004// -/ac_main.c/1.66/Mon Aug 23 15:06:21 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/addrcheck/CVS/Repository b/VEX/head20041019/addrcheck/CVS/Repository deleted file mode 100644 index 57d147f8f..000000000 --- a/VEX/head20041019/addrcheck/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/addrcheck diff --git a/VEX/head20041019/addrcheck/CVS/Root b/VEX/head20041019/addrcheck/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/addrcheck/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/addrcheck/CVS/Template b/VEX/head20041019/addrcheck/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/Makefile.am b/VEX/head20041019/addrcheck/Makefile.am deleted file mode 100644 index ba2b2c918..000000000 --- a/VEX/head20041019/addrcheck/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -# include memcheck/ for mac_shared.h -AM_CPPFLAGS += -I$(top_srcdir)/memcheck -fomit-frame-pointer - -val_PROGRAMS = vgskin_addrcheck.so vgpreload_addrcheck.so - -vgskin_addrcheck_so_SOURCES = ac_main.c -vgskin_addrcheck_so_LDFLAGS = -shared -vgskin_addrcheck_so_LDADD = \ - ../memcheck/mac_leakcheck.o \ - ../memcheck/mac_malloc_wrappers.o \ - ../memcheck/mac_needs.o - -vgpreload_addrcheck_so_SOURCES = -vgpreload_addrcheck_so_LDADD = \ - $(top_builddir)/coregrind/vg_replace_malloc.o \ - ../memcheck/mac_replace_strmem.o -vgpreload_addrcheck_so_DEPENDENCIES = \ - $(top_builddir)/coregrind/vg_replace_malloc.o \ - ../memcheck/mac_replace_strmem.o -vgpreload_addrcheck_so_LDFLAGS = -shared -Wl,-z,interpose,-z,initfirst - diff --git a/VEX/head20041019/addrcheck/ac_main.c b/VEX/head20041019/addrcheck/ac_main.c deleted file mode 100644 index 70cd1d4a5..000000000 --- a/VEX/head20041019/addrcheck/ac_main.c +++ /dev/null @@ -1,1352 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- The AddrCheck tool: like MemCheck, but only does address ---*/ -/*--- checking. No definedness checking. ---*/ -/*--- ac_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of AddrCheck, a lightweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mac_shared.h" -#include "memcheck.h" -//#include "vg_profile.c" - - -/*------------------------------------------------------------*/ -/*--- Comparing and printing errors ---*/ -/*------------------------------------------------------------*/ - -void SK_(pp_SkinError) ( Error* err ) -{ - MAC_Error* err_extra = VG_(get_error_extra)(err); - - switch (VG_(get_error_kind)(err)) { - case CoreMemErr: - VG_(message)(Vg_UserMsg, "%s contains unaddressable byte(s)", - VG_(get_error_string)(err)); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - break; - - case ParamErr: - VG_(message)(Vg_UserMsg, - "Syscall param %s contains unaddressable byte(s)", - VG_(get_error_string)(err) ); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - case UserErr: - VG_(message)(Vg_UserMsg, - "Unaddressable byte(s) found during client check request"); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - default: - MAC_(pp_shared_SkinError)(err); - break; - } -} - -/*------------------------------------------------------------*/ -/*--- Suppressions ---*/ -/*------------------------------------------------------------*/ - -Bool SK_(recognised_suppression) ( Char* name, Supp* su ) -{ - return MAC_(shared_recognised_suppression)(name, su); -} - -#define DEBUG(fmt, args...) //VG_(printf)(fmt, ## args) - -/*------------------------------------------------------------*/ -/*--- Low-level support for memory checking. ---*/ -/*------------------------------------------------------------*/ - -/* All reads and writes are checked against a memory map, which - records the state of all memory in the process. The memory map is - organised like this: - - The top 16 bits of an address are used to index into a top-level - map table, containing 65536 entries. Each entry is a pointer to a - second-level map, which records the accesibililty and validity - permissions for the 65536 bytes indexed by the lower 16 bits of the - address. Each byte is represented by one bit, indicating - accessibility. So each second-level map contains 8192 bytes. This - two-level arrangement conveniently divides the 4G address space - into 64k lumps, each size 64k bytes. - - All entries in the primary (top-level) map must point to a valid - secondary (second-level) map. Since most of the 4G of address - space will not be in use -- ie, not mapped at all -- there is a - distinguished secondary map, which indicates `not addressible and - not valid' writeable for all bytes. Entries in the primary map for - which the entire 64k is not in use at all point at this - distinguished map. - - [...] lots of stuff deleted due to out of date-ness - - As a final optimisation, the alignment and address checks for - 4-byte loads and stores are combined in a neat way. The primary - map is extended to have 262144 entries (2^18), rather than 2^16. - The top 3/4 of these entries are permanently set to the - distinguished secondary map. For a 4-byte load/store, the - top-level map is indexed not with (addr >> 16) but instead f(addr), - where - - f( XXXX XXXX XXXX XXXX ____ ____ ____ __YZ ) - = ____ ____ ____ __YZ XXXX XXXX XXXX XXXX or - = ____ ____ ____ __ZY XXXX XXXX XXXX XXXX - - ie the lowest two bits are placed above the 16 high address bits. - If either of these two bits are nonzero, the address is misaligned; - this will select a secondary map from the upper 3/4 of the primary - map. Because this is always the distinguished secondary map, a - (bogus) address check failure will result. The failure handling - code can then figure out whether this is a genuine addr check - failure or whether it is a possibly-legitimate access at a - misaligned address. */ - - -/*------------------------------------------------------------*/ -/*--- Function declarations. ---*/ -/*------------------------------------------------------------*/ - -static void ac_ACCESS4_SLOWLY ( Addr a, Bool isWrite ); -static void ac_ACCESS2_SLOWLY ( Addr a, Bool isWrite ); -static void ac_ACCESS1_SLOWLY ( Addr a, Bool isWrite ); -static void ac_fpu_ACCESS_check_SLOWLY ( Addr addr, Int size, Bool isWrite ); - -/*------------------------------------------------------------*/ -/*--- Data defns. ---*/ -/*------------------------------------------------------------*/ - -typedef - struct { - UChar abits[8192]; - } - AcSecMap; - -static AcSecMap* primary_map[ /*65536*/ 262144 ]; -static AcSecMap distinguished_secondary_map; - -static void init_shadow_memory ( void ) -{ - Int i; - - for (i = 0; i < 8192; i++) /* Invalid address */ - distinguished_secondary_map.abits[i] = VGM_BYTE_INVALID; - - /* These entries gradually get overwritten as the used address - space expands. */ - for (i = 0; i < 65536; i++) - primary_map[i] = &distinguished_secondary_map; - - /* These ones should never change; it's a bug in Valgrind if they do. */ - for (i = 65536; i < 262144; i++) - primary_map[i] = &distinguished_secondary_map; -} - -/*------------------------------------------------------------*/ -/*--- Basic bitmap management, reading and writing. ---*/ -/*------------------------------------------------------------*/ - -/* Allocate and initialise a secondary map. */ - -static AcSecMap* alloc_secondary_map ( __attribute__ ((unused)) - Char* caller ) -{ - AcSecMap* map; - UInt i; - PROF_EVENT(10); - - /* Mark all bytes as invalid access and invalid value. */ - map = (AcSecMap *)VG_(shadow_alloc)(sizeof(AcSecMap)); - for (i = 0; i < 8192; i++) - map->abits[i] = VGM_BYTE_INVALID; /* Invalid address */ - - /* VG_(printf)("ALLOC_2MAP(%s)\n", caller ); */ - return map; -} - - -/* Basic reading/writing of the bitmaps, for byte-sized accesses. */ - -static __inline__ UChar get_abit ( Addr a ) -{ - AcSecMap* sm = primary_map[a >> 16]; - UInt sm_off = a & 0xFFFF; - PROF_EVENT(20); -# if 0 - if (IS_DISTINGUISHED_SM(sm)) - VG_(message)(Vg_DebugMsg, - "accessed distinguished 2ndary (A)map! 0x%x\n", a); -# endif - return BITARR_TEST(sm->abits, sm_off) - ? VGM_BIT_INVALID : VGM_BIT_VALID; -} - -static /* __inline__ */ void set_abit ( Addr a, UChar abit ) -{ - AcSecMap* sm; - UInt sm_off; - PROF_EVENT(22); - ENSURE_MAPPABLE(a, "set_abit"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - if (abit) - BITARR_SET(sm->abits, sm_off); - else - BITARR_CLEAR(sm->abits, sm_off); -} - - -/* Reading/writing of the bitmaps, for aligned word-sized accesses. */ - -static __inline__ UChar get_abits4_ALIGNED ( Addr a ) -{ - AcSecMap* sm; - UInt sm_off; - UChar abits8; - PROF_EVENT(24); -# ifdef VG_DEBUG_MEMORY - sk_assert(IS_ALIGNED4_ADDR(a)); -# endif - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - abits8 = sm->abits[sm_off >> 3]; - abits8 >>= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - abits8 &= 0x0F; - return abits8; -} - - - -/*------------------------------------------------------------*/ -/*--- Setting permissions over address ranges. ---*/ -/*------------------------------------------------------------*/ - -static /* __inline__ */ -void set_address_range_perms ( Addr a, UInt len, - UInt example_a_bit ) -{ - UChar abyte8; - UInt sm_off; - AcSecMap* sm; - - PROF_EVENT(30); - - if (len == 0) - return; - - if (len > 100 * 1000 * 1000) { - VG_(message)(Vg_UserMsg, - "Warning: set address range perms: " - "large range %u, a %d", - len, example_a_bit ); - } - - VGP_PUSHCC(VgpSetMem); - - /* Requests to change permissions of huge address ranges may - indicate bugs in our machinery. 30,000,000 is arbitrary, but so - far all legitimate requests have fallen beneath that size. */ - /* 4 Mar 02: this is just stupid; get rid of it. */ - /* sk_assert(len < 30000000); */ - - /* Check the permissions make sense. */ - sk_assert(example_a_bit == VGM_BIT_VALID - || example_a_bit == VGM_BIT_INVALID); - - /* In order that we can charge through the address space at 8 - bytes/main-loop iteration, make up some perms. */ - abyte8 = (example_a_bit << 7) - | (example_a_bit << 6) - | (example_a_bit << 5) - | (example_a_bit << 4) - | (example_a_bit << 3) - | (example_a_bit << 2) - | (example_a_bit << 1) - | (example_a_bit << 0); - -# ifdef VG_DEBUG_MEMORY - /* Do it ... */ - while (True) { - PROF_EVENT(31); - if (len == 0) break; - set_abit ( a, example_a_bit ); - set_vbyte ( a, vbyte ); - a++; - len--; - } - -# else - /* Slowly do parts preceding 8-byte alignment. */ - while (True) { - PROF_EVENT(31); - if (len == 0) break; - if ((a % 8) == 0) break; - set_abit ( a, example_a_bit ); - a++; - len--; - } - - if (len == 0) { - VGP_POPCC(VgpSetMem); - return; - } - sk_assert((a % 8) == 0 && len > 0); - - /* Once aligned, go fast. */ - while (True) { - PROF_EVENT(32); - if (len < 8) break; - ENSURE_MAPPABLE(a, "set_address_range_perms(fast)"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = abyte8; - a += 8; - len -= 8; - } - - if (len == 0) { - VGP_POPCC(VgpSetMem); - return; - } - sk_assert((a % 8) == 0 && len > 0 && len < 8); - - /* Finish the upper fragment. */ - while (True) { - PROF_EVENT(33); - if (len == 0) break; - set_abit ( a, example_a_bit ); - a++; - len--; - } -# endif - - /* Check that zero page and highest page have not been written to - -- this could happen with buggy syscall wrappers. Today - (2001-04-26) had precisely such a problem with __NR_setitimer. */ - sk_assert(SK_(cheap_sanity_check)()); - VGP_POPCC(VgpSetMem); -} - -/* Set permissions for address ranges ... */ - -static void ac_make_noaccess ( Addr a, UInt len ) -{ - PROF_EVENT(35); - DEBUG("ac_make_noaccess(%p, %x)\n", a, len); - set_address_range_perms ( a, len, VGM_BIT_INVALID ); -} - -static void ac_make_accessible ( Addr a, UInt len ) -{ - PROF_EVENT(38); - DEBUG("ac_make_accessible(%p, %x)\n", a, len); - set_address_range_perms ( a, len, VGM_BIT_VALID ); -} - -static __inline__ -void make_aligned_word_noaccess(Addr a) -{ - AcSecMap* sm; - UInt sm_off; - UChar mask; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_word_noaccess"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - mask = 0x0F; - mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - /* mask now contains 1s where we wish to make address bits invalid (1s). */ - sm->abits[sm_off >> 3] |= mask; - VGP_POPCC(VgpESPAdj); -} - -static __inline__ -void make_aligned_word_accessible(Addr a) -{ - AcSecMap* sm; - UInt sm_off; - UChar mask; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_word_accessible"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - mask = 0x0F; - mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - /* mask now contains 1s where we wish to make address bits - invalid (0s). */ - sm->abits[sm_off >> 3] &= ~mask; - VGP_POPCC(VgpESPAdj); -} - -/* Nb: by "aligned" here we mean 8-byte aligned */ -static __inline__ -void make_aligned_doubleword_accessible(Addr a) -{ - AcSecMap* sm; - UInt sm_off; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_doubleword_accessible"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = VGM_BYTE_VALID; - VGP_POPCC(VgpESPAdj); -} - -static __inline__ -void make_aligned_doubleword_noaccess(Addr a) -{ - AcSecMap* sm; - UInt sm_off; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_doubleword_noaccess"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = VGM_BYTE_INVALID; - VGP_POPCC(VgpESPAdj); -} - -/* The %esp update handling functions */ -ESP_UPDATE_HANDLERS ( make_aligned_word_accessible, - make_aligned_word_noaccess, - make_aligned_doubleword_accessible, - make_aligned_doubleword_noaccess, - ac_make_accessible, - ac_make_noaccess - ); - - -/* Block-copy permissions (needed for implementing realloc()). */ - -static void ac_copy_address_range_state ( Addr src, Addr dst, UInt len ) -{ - UInt i; - - DEBUG("ac_copy_address_range_state\n"); - - PROF_EVENT(40); - for (i = 0; i < len; i++) { - UChar abit = get_abit ( src+i ); - PROF_EVENT(41); - set_abit ( dst+i, abit ); - } -} - - -/* Check permissions for address range. If inadequate permissions - exist, *bad_addr is set to the offending address, so the caller can - know what it is. */ - -static __inline__ -Bool ac_check_accessible ( Addr a, UInt len, Addr* bad_addr ) -{ - UInt i; - UChar abit; - PROF_EVENT(48); - for (i = 0; i < len; i++) { - PROF_EVENT(49); - abit = get_abit(a); - if (abit == VGM_BIT_INVALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - a++; - } - return True; -} - -/* The opposite; check that an address range is inaccessible. */ -static -Bool ac_check_noaccess ( Addr a, UInt len, Addr* bad_addr ) -{ - UInt i; - UChar abit; - PROF_EVENT(48); - for (i = 0; i < len; i++) { - PROF_EVENT(49); - abit = get_abit(a); - if (abit == VGM_BIT_VALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - a++; - } - return True; -} - -/* Check a zero-terminated ascii string. Tricky -- don't want to - examine the actual bytes, to find the end, until we're sure it is - safe to do so. */ - -static __inline__ -Bool ac_check_readable_asciiz ( Addr a, Addr* bad_addr ) -{ - UChar abit; - PROF_EVENT(46); - DEBUG("ac_check_readable_asciiz\n"); - while (True) { - PROF_EVENT(47); - abit = get_abit(a); - if (abit != VGM_BIT_VALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - /* Ok, a is safe to read. */ - if (* ((UChar*)a) == 0) return True; - a++; - } -} - - -/*------------------------------------------------------------*/ -/*--- Memory event handlers ---*/ -/*------------------------------------------------------------*/ - -static __inline__ -void ac_check_is_accessible ( CorePart part, ThreadId tid, - Char* s, Addr base, UInt size, Bool isWrite ) -{ - Bool ok; - Addr bad_addr; - - VGP_PUSHCC(VgpCheckMem); - - ok = ac_check_accessible ( base, size, &bad_addr ); - if (!ok) { - switch (part) { - case Vg_CoreSysCall: - MAC_(record_param_error) ( tid, bad_addr, isWrite, s ); - break; - - case Vg_CoreSignal: - sk_assert(isWrite); /* Should only happen with isWrite case */ - /* fall through */ - case Vg_CorePThread: - MAC_(record_core_mem_error)( tid, isWrite, s ); - break; - - /* If we're being asked to jump to a silly address, record an error - message before potentially crashing the entire system. */ - case Vg_CoreTranslate: - sk_assert(!isWrite); /* Should only happen with !isWrite case */ - MAC_(record_jump_error)( tid, bad_addr ); - break; - - default: - VG_(skin_panic)("ac_check_is_accessible: unexpected CorePart"); - } - } - - VGP_POPCC(VgpCheckMem); -} - -static -void ac_check_is_writable ( CorePart part, ThreadId tid, - Char* s, Addr base, UInt size ) -{ - ac_check_is_accessible ( part, tid, s, base, size, /*isWrite*/True ); -} - -static -void ac_check_is_readable ( CorePart part, ThreadId tid, - Char* s, Addr base, UInt size ) -{ - ac_check_is_accessible ( part, tid, s, base, size, /*isWrite*/False ); -} - -static -void ac_check_is_readable_asciiz ( CorePart part, ThreadId tid, - Char* s, Addr str ) -{ - Bool ok = True; - Addr bad_addr; - /* VG_(message)(Vg_DebugMsg,"check is readable asciiz: 0x%x",str); */ - - VGP_PUSHCC(VgpCheckMem); - - sk_assert(part == Vg_CoreSysCall); - ok = ac_check_readable_asciiz ( (Addr)str, &bad_addr ); - if (!ok) { - MAC_(record_param_error) ( tid, bad_addr, /*is_writable =*/False, s ); - } - - VGP_POPCC(VgpCheckMem); -} - -static -void ac_new_mem_startup( Addr a, UInt len, Bool rr, Bool ww, Bool xx ) -{ - /* Ignore the permissions, just make it readable. Seems to work... */ - DEBUG("new_mem_startup(%p, %u, rr=%u, ww=%u, xx=%u)\n", a,len,rr,ww,xx); - ac_make_accessible(a, len); -} - -static -void ac_new_mem_heap ( Addr a, UInt len, Bool is_inited ) -{ - ac_make_accessible(a, len); -} - -static -void ac_set_perms (Addr a, UInt len, Bool rr, Bool ww, Bool xx) -{ - DEBUG("ac_set_perms(%p, %u, rr=%u ww=%u, xx=%u)\n", - a, len, rr, ww, xx); - if (rr || ww || xx) { - ac_make_accessible(a, len); - } else { - ac_make_noaccess(a, len); - } -} - - -/*------------------------------------------------------------*/ -/*--- Functions called directly from generated code. ---*/ -/*------------------------------------------------------------*/ - -static __inline__ UInt rotateRight16 ( UInt x ) -{ - /* Amazingly, gcc turns this into a single rotate insn. */ - return (x >> 16) | (x << 16); -} - -static __inline__ UInt shiftRight16 ( UInt x ) -{ - return x >> 16; -} - - -/* Read/write 1/2/4 sized V bytes, and emit an address error if - needed. */ - -/* ach_ACCESS{1,2,4} handle the common case fast. - Under all other circumstances, it defers to the relevant _SLOWLY - function, which can handle all situations. -*/ -static __inline__ void ach_ACCESS4 ( Addr a, Bool isWrite ) -{ -# ifdef VG_DEBUG_MEMORY - return ac_ACCESS4_SLOWLY(a, isWrite); -# else - UInt sec_no = rotateRight16(a) & 0x3FFFF; - AcSecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - UChar abits = sm->abits[a_off]; - abits >>= (a & 4); - abits &= 15; - PROF_EVENT(66); - if (abits == VGM_NIBBLE_VALID) { - /* Handle common case quickly: a is suitably aligned, is mapped, - and is addressible. So just return. */ - return; - } else { - /* Slow but general case. */ - ac_ACCESS4_SLOWLY(a, isWrite); - } -# endif -} - -static __inline__ void ach_ACCESS2 ( Addr a, Bool isWrite ) -{ -# ifdef VG_DEBUG_MEMORY - return ac_ACCESS2_SLOWLY(a, isWrite); -# else - UInt sec_no = rotateRight16(a) & 0x1FFFF; - AcSecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(67); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - return; - } else { - /* Slow but general case. */ - ac_ACCESS2_SLOWLY(a, isWrite); - } -# endif -} - -static __inline__ void ach_ACCESS1 ( Addr a, Bool isWrite ) -{ -# ifdef VG_DEBUG_MEMORY - return ac_ACCESS1_SLOWLY(a, isWrite); -# else - UInt sec_no = shiftRight16(a); - AcSecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(68); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - return; - } else { - /* Slow but general case. */ - ac_ACCESS1_SLOWLY(a, isWrite); - } -# endif -} - -REGPARM(1) -static void ach_LOAD4 ( Addr a ) -{ - ach_ACCESS4 ( a, /*isWrite*/False ); -} -REGPARM(1) -static void ach_STORE4 ( Addr a ) -{ - ach_ACCESS4 ( a, /*isWrite*/True ); -} - -REGPARM(1) -static void ach_LOAD2 ( Addr a ) -{ - ach_ACCESS2 ( a, /*isWrite*/False ); -} -REGPARM(1) -static void ach_STORE2 ( Addr a ) -{ - ach_ACCESS2 ( a, /*isWrite*/True ); -} - -REGPARM(1) -static void ach_LOAD1 ( Addr a ) -{ - ach_ACCESS1 ( a, /*isWrite*/False ); -} -REGPARM(1) -static void ach_STORE1 ( Addr a ) -{ - ach_ACCESS1 ( a, /*isWrite*/True ); -} - - -/*------------------------------------------------------------*/ -/*--- Fallback functions to handle cases that the above ---*/ -/*--- ach_ACCESS{1,2,4} can't manage. ---*/ -/*------------------------------------------------------------*/ - -static void ac_ACCESS4_SLOWLY ( Addr a, Bool isWrite ) -{ - Bool a0ok, a1ok, a2ok, a3ok; - - PROF_EVENT(76); - - /* First establish independently the addressibility of the 4 bytes - involved. */ - a0ok = get_abit(a+0) == VGM_BIT_VALID; - a1ok = get_abit(a+1) == VGM_BIT_VALID; - a2ok = get_abit(a+2) == VGM_BIT_VALID; - a3ok = get_abit(a+3) == VGM_BIT_VALID; - - /* Now distinguish 3 cases */ - - /* Case 1: the address is completely valid, so: - - no addressing error - */ - if (a0ok && a1ok && a2ok && a3ok) { - return; - } - - /* Case 2: the address is completely invalid. - - emit addressing error - */ - /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok); */ - if (!MAC_(clo_partial_loads_ok) - || ((a & 3) != 0) - || (!a0ok && !a1ok && !a2ok && !a3ok)) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 4, isWrite ); - return; - } - - /* Case 3: the address is partially valid. - - no addressing error - Case 3 is only allowed if MAC_(clo_partial_loads_ok) is True - (which is the default), and the address is 4-aligned. - If not, Case 2 will have applied. - */ - sk_assert(MAC_(clo_partial_loads_ok)); - { - return; - } -} - -static void ac_ACCESS2_SLOWLY ( Addr a, Bool isWrite ) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(77); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+1) != VGM_BIT_VALID) aerr = True; - - /* If an address error has happened, report it. */ - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 2, isWrite ); - } -} - -static void ac_ACCESS1_SLOWLY ( Addr a, Bool isWrite) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(78); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - - /* If an address error has happened, report it. */ - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 1, isWrite ); - } -} - - -/* --------------------------------------------------------------------- - FPU load and store checks, called from generated code. - ------------------------------------------------------------------ */ - -static -void ac_fpu_ACCESS_check ( Addr addr, Int size, Bool isWrite ) -{ - /* Ensure the read area is both addressible and valid (ie, - readable). If there's an address error, don't report a value - error too; but if there isn't an address error, check for a - value error. - - Try to be reasonably fast on the common case; wimp out and defer - to ac_fpu_ACCESS_check_SLOWLY for everything else. */ - - AcSecMap* sm; - UInt sm_off, a_off; - Addr addr4; - - PROF_EVENT(90); - -# ifdef VG_DEBUG_MEMORY - ac_fpu_ACCESS_check_SLOWLY ( addr, size, isWrite ); -# else - - if (size == 4) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow4; - PROF_EVENT(91); - /* Properly aligned. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow4; - /* Properly aligned and addressible. */ - return; - slow4: - ac_fpu_ACCESS_check_SLOWLY ( addr, 4, isWrite ); - return; - } - - if (size == 8) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow8; - PROF_EVENT(92); - /* Properly aligned. Do it in two halves. */ - addr4 = addr + 4; - /* First half. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* First half properly aligned and addressible. */ - /* Second half. */ - sm = primary_map[addr4 >> 16]; - sm_off = addr4 & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* Second half properly aligned and addressible. */ - /* Both halves properly aligned and addressible. */ - return; - slow8: - ac_fpu_ACCESS_check_SLOWLY ( addr, 8, isWrite ); - return; - } - - /* Can't be bothered to huff'n'puff to make these (allegedly) rare - cases go quickly. */ - if (size == 2) { - PROF_EVENT(93); - ac_fpu_ACCESS_check_SLOWLY ( addr, 2, isWrite ); - return; - } - - if (size == 16 || size == 10 || size == 28 || size == 108 || size == 512) { - PROF_EVENT(94); - ac_fpu_ACCESS_check_SLOWLY ( addr, size, isWrite ); - return; - } - - VG_(printf)("size is %d\n", size); - VG_(skin_panic)("fpu_ACCESS_check: unhandled size"); -# endif -} - -REGPARM(2) -static void ach_LOADN ( Addr addr, Int size ) -{ - ac_fpu_ACCESS_check ( addr, size, /*isWrite*/False ); -} - -REGPARM(2) -static void ach_STOREN ( Addr addr, Int size ) -{ - ac_fpu_ACCESS_check ( addr, size, /*isWrite*/True ); -} - -/* --------------------------------------------------------------------- - Slow, general cases for FPU access checks. - ------------------------------------------------------------------ */ - -void ac_fpu_ACCESS_check_SLOWLY ( Addr addr, Int size, Bool isWrite ) -{ - Int i; - Bool aerr = False; - PROF_EVENT(100); - for (i = 0; i < size; i++) { - PROF_EVENT(101); - if (get_abit(addr+i) != VGM_BIT_VALID) - aerr = True; - } - - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), addr, size, isWrite ); - } -} - - -/*------------------------------------------------------------*/ -/*--- Our instrumenter ---*/ -/*------------------------------------------------------------*/ - - -IRBB* SK_(instrument)(IRBB* bb_in, VexGuestLayout* layout, IRType hWordTy ) -{ - Int i, hsz; - IRStmt* st; - IRExpr* data; - IRExpr* aexpr; - IRExpr* guard; - IRDirty* di; - Bool isLoad; - - /* Set up BB */ - IRBB* bb = emptyIRBB(); - bb->tyenv = dopyIRTypeEnv(bb_in->tyenv); - bb->next = dopyIRExpr(bb_in->next); - bb->jumpkind = bb_in->jumpkind; - - /* No loads to consider in ->next. */ - sk_assert(isAtom(bb_in->next)); - - for (i = 0; i < bb_in->stmts_used; i++) { - st = bb_in->stmts[i]; - if (!st) continue; - - /* Examine each stmt in turn to figure out if it needs to be - preceded by a memory access check. If so, collect up the - relevant pieces of information. */ - hsz = 0; - aexpr = NULL; - guard = NULL; - isLoad = True; - - switch (st->tag) { - - case Ist_Tmp: - data = st->Ist.Tmp.data; - if (data->tag == Iex_LDle) { - aexpr = data->Iex.LDle.addr; - hsz = sizeofIRType(data->Iex.LDle.ty); - isLoad = True; - } - break; - - case Ist_STle: - data = st->Ist.STle.data; - aexpr = st->Ist.STle.addr; - sk_assert(isAtom(data)); - sk_assert(isAtom(aexpr)); - hsz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data)); - isLoad = False; - - case Ist_Put: - sk_assert(isAtom(st->Ist.Put.data)); - break; - - case Ist_PutI: - sk_assert(isAtom(st->Ist.PutI.ix)); - sk_assert(isAtom(st->Ist.PutI.data)); - break; - - case Ist_Exit: - sk_assert(isAtom(st->Ist.Exit.guard)); - break; - - case Ist_Dirty: - if (st->Ist.Dirty.details->mFx != Ifx_None) { - /* We classify Ifx_Modify as a load. */ - isLoad = st->Ist.Dirty.details->mFx != Ifx_Write; - hsz = st->Ist.Dirty.details->mSize; - aexpr = st->Ist.Dirty.details->mAddr; - guard = st->Ist.Dirty.details->guard; - sk_assert(isAtom(aexpr)); - } - break; - - default: - VG_(printf)("\n"); - ppIRStmt(st); - VG_(printf)("\n"); - VG_(skin_panic)("addrcheck: unhandled IRStmt"); - } - - /* If needed, add a helper call. */ - if (aexpr) { - sk_assert(hsz > 0); - switch (hsz) { - case 4: - if (isLoad) - di = unsafeIRDirty_0_N( 1, "ach_LOAD4", &ach_LOAD4, - mkIRExprVec_1(aexpr)); - else - di = unsafeIRDirty_0_N( 1, "ach_STORE4", &ach_STORE4, - mkIRExprVec_1(aexpr)); - break; - case 2: - if (isLoad) - di = unsafeIRDirty_0_N( 1, "ach_LOAD2", &ach_LOAD2, - mkIRExprVec_1(aexpr)); - else - di = unsafeIRDirty_0_N( 1, "ach_STORE2", &ach_STORE2, - mkIRExprVec_1(aexpr)); - break; - case 1: - if (isLoad) - di = unsafeIRDirty_0_N( 1, "ach_LOAD1", &ach_LOAD1, - mkIRExprVec_1(aexpr)); - else - di = unsafeIRDirty_0_N( 1, "ach_STORE1", &ach_STORE1, - mkIRExprVec_1(aexpr)); - break; - default: - if (isLoad) - di = unsafeIRDirty_0_N( - 2, "ach_LOADN", &ach_LOADN, - mkIRExprVec_2(aexpr,mkIRExpr_HWord(hsz))); - else - di = unsafeIRDirty_0_N( - 2, "ach_STOREN", &ach_STOREN, - mkIRExprVec_2(aexpr,mkIRExpr_HWord(hsz))); - break; - } - - /* If the call has arisen as a result of a dirty helper which - references memory, we need to inherit the guard from the - dirty helper. */ - if (guard) - di->guard = dopyIRExpr(guard); - - /* emit the helper call */ - addStmtToIRBB( bb, IRStmt_Dirty(di) ); - - } - - /* And finally, copy the expr itself to the output. */ - addStmtToIRBB( bb, dopyIRStmt(st)); - } - - return bb; -} - - -/*------------------------------------------------------------*/ -/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/ -/*------------------------------------------------------------*/ - -/* For the memory leak detector, say whether an entire 64k chunk of - address space is possibly in use, or not. If in doubt return - True. -*/ -static -Bool ac_is_valid_64k_chunk ( UInt chunk_number ) -{ - sk_assert(chunk_number >= 0 && chunk_number < 65536); - if (IS_DISTINGUISHED_SM(primary_map[chunk_number])) { - /* Definitely not in use. */ - return False; - } else { - return True; - } -} - - -/* For the memory leak detector, say whether or not a given word - address is to be regarded as valid. */ -static -Bool ac_is_valid_address ( Addr a ) -{ - UChar abits; - sk_assert(IS_ALIGNED4_ADDR(a)); - abits = get_abits4_ALIGNED(a); - if (abits == VGM_NIBBLE_VALID) { - return True; - } else { - return False; - } -} - - -/* Leak detector for this tool. We don't actually do anything, merely - run the generic leak detector with suitable parameters for this - tool. */ -static void ac_detect_memory_leaks ( void ) -{ - MAC_(do_detect_memory_leaks) ( ac_is_valid_64k_chunk, ac_is_valid_address ); -} - - -/* --------------------------------------------------------------------- - Sanity check machinery (permanently engaged). - ------------------------------------------------------------------ */ - -Bool SK_(cheap_sanity_check) ( void ) -{ - /* nothing useful we can rapidly check */ - return True; -} - -Bool SK_(expensive_sanity_check) ( void ) -{ - Int i; - - /* Make sure nobody changed the distinguished secondary. */ - for (i = 0; i < 8192; i++) - if (distinguished_secondary_map.abits[i] != VGM_BYTE_INVALID) - return False; - - /* Make sure that the upper 3/4 of the primary map hasn't - been messed with. */ - for (i = 65536; i < 262144; i++) - if (primary_map[i] != & distinguished_secondary_map) - return False; - - return True; -} - -/*------------------------------------------------------------*/ -/*--- Client requests ---*/ -/*------------------------------------------------------------*/ - -Bool SK_(handle_client_request) ( ThreadId tid, UInt* arg_block, UInt *ret ) -{ -#define IGNORE(what) \ - do { \ - if (moans-- > 0) { \ - VG_(message)(Vg_UserMsg, \ - "Warning: Addrcheck: ignoring `%s' request.", what); \ - VG_(message)(Vg_UserMsg, \ - " To honour this request, rerun with --tool=memcheck."); \ - } \ - } while (0) - - UInt* arg = arg_block; - static Int moans = 3; - - /* Overload memcheck client reqs */ - if (!VG_IS_SKIN_USERREQ('M','C',arg[0]) - && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0] - && VG_USERREQ__FREELIKE_BLOCK != arg[0] - && VG_USERREQ__CREATE_MEMPOOL != arg[0] - && VG_USERREQ__DESTROY_MEMPOOL != arg[0] - && VG_USERREQ__MEMPOOL_ALLOC != arg[0] - && VG_USERREQ__MEMPOOL_FREE != arg[0]) - return False; - - switch (arg[0]) { - case VG_USERREQ__DO_LEAK_CHECK: - ac_detect_memory_leaks(); - *ret = 0; /* return value is meaningless */ - break; - - /* Ignore these */ - case VG_USERREQ__CHECK_WRITABLE: /* check writable */ - IGNORE("VALGRIND_CHECK_WRITABLE"); - return False; - case VG_USERREQ__CHECK_READABLE: /* check readable */ - IGNORE("VALGRIND_CHECK_READABLE"); - return False; - case VG_USERREQ__MAKE_NOACCESS: /* make no access */ - IGNORE("VALGRIND_MAKE_NOACCESS"); - return False; - case VG_USERREQ__MAKE_WRITABLE: /* make writable */ - IGNORE("VALGRIND_MAKE_WRITABLE"); - return False; - case VG_USERREQ__MAKE_READABLE: /* make readable */ - IGNORE("VALGRIND_MAKE_READABLE"); - return False; - case VG_USERREQ__DISCARD: /* discard */ - IGNORE("VALGRIND_CHECK_DISCARD"); - return False; - - default: - if (MAC_(handle_common_client_requests)(tid, arg_block, ret )) { - return True; - } else { - VG_(message)(Vg_UserMsg, - "Warning: unknown addrcheck client request code %d", - arg[0]); - return False; - } - } - return True; - -#undef IGNORE -} - -/*------------------------------------------------------------*/ -/*--- Setup ---*/ -/*------------------------------------------------------------*/ - -Bool SK_(process_cmd_line_option)(Char* arg) -{ - return MAC_(process_common_cmd_line_option)(arg); -} - -void SK_(print_usage)(void) -{ - MAC_(print_common_usage)(); -} - -void SK_(print_debug_usage)(void) -{ - MAC_(print_common_debug_usage)(); -} - - -/*------------------------------------------------------------*/ -/*--- Setup ---*/ -/*------------------------------------------------------------*/ - -void SK_(pre_clo_init)(void) -{ - VG_(details_name) ("Addrcheck"); - VG_(details_version) (NULL); - VG_(details_description) ("a fine-grained address checker"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 135 ); - - VG_(needs_core_errors) (); - VG_(needs_skin_errors) (); - VG_(needs_libc_freeres) (); - VG_(needs_command_line_options)(); - VG_(needs_client_requests) (); - VG_(needs_syscall_wrapper) (); - VG_(needs_sanity_checks) (); - VG_(needs_shadow_memory) (); - - MAC_( new_mem_heap) = & ac_new_mem_heap; - MAC_( ban_mem_heap) = & ac_make_noaccess; - MAC_(copy_mem_heap) = & ac_copy_address_range_state; - MAC_( die_mem_heap) = & ac_make_noaccess; - MAC_(check_noaccess) = & ac_check_noaccess; - - VG_(init_new_mem_startup) ( & ac_new_mem_startup ); - VG_(init_new_mem_stack_signal) ( & ac_make_accessible ); - VG_(init_new_mem_brk) ( & ac_make_accessible ); - VG_(init_new_mem_mmap) ( & ac_set_perms ); - - VG_(init_copy_mem_remap) ( & ac_copy_address_range_state ); - VG_(init_change_mem_mprotect) ( & ac_set_perms ); - - VG_(init_die_mem_stack_signal) ( & ac_make_noaccess ); - VG_(init_die_mem_brk) ( & ac_make_noaccess ); - VG_(init_die_mem_munmap) ( & ac_make_noaccess ); - - VG_(init_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); - VG_(init_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); - VG_(init_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); - VG_(init_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); - VG_(init_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); - VG_(init_new_mem_stack) ( & MAC_(new_mem_stack) ); - - VG_(init_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); - VG_(init_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); - VG_(init_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); - VG_(init_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); - VG_(init_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); - VG_(init_die_mem_stack) ( & MAC_(die_mem_stack) ); - - VG_(init_ban_mem_stack) ( & ac_make_noaccess ); - - VG_(init_pre_mem_read) ( & ac_check_is_readable ); - VG_(init_pre_mem_read_asciiz) ( & ac_check_is_readable_asciiz ); - VG_(init_pre_mem_write) ( & ac_check_is_writable ); - VG_(init_post_mem_write) ( & ac_make_accessible ); - -#if 0 - VG_(register_compact_helper)((Addr) & ach_LOAD4); - VG_(register_compact_helper)((Addr) & ach_LOAD2); - VG_(register_compact_helper)((Addr) & ach_LOAD1); - VG_(register_compact_helper)((Addr) & ach_STORE4); - VG_(register_compact_helper)((Addr) & ach_STORE2); - VG_(register_compact_helper)((Addr) & ach_STORE1); - VG_(register_noncompact_helper)((Addr) & ac_fpu_READ_check); - VG_(register_noncompact_helper)((Addr) & ac_fpu_WRITE_check); -#endif - - VGP_(register_profile_event) ( VgpSetMem, "set-mem-perms" ); - VGP_(register_profile_event) ( VgpCheckMem, "check-mem-perms" ); - VGP_(register_profile_event) ( VgpESPAdj, "adjust-ESP" ); - - init_shadow_memory(); - MAC_(common_pre_clo_init)(); -} - -void SK_(post_clo_init) ( void ) -{ -} - -void SK_(fini) ( Int exitcode ) -{ - MAC_(common_fini)( ac_detect_memory_leaks ); -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 1./8) - - -/*--------------------------------------------------------------------*/ -/*--- end ac_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/addrcheck/docs/.cvsignore b/VEX/head20041019/addrcheck/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/addrcheck/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/addrcheck/docs/CVS/Entries b/VEX/head20041019/addrcheck/docs/CVS/Entries deleted file mode 100644 index abb809579..000000000 --- a/VEX/head20041019/addrcheck/docs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Thu Oct 3 10:38:40 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:04 2004// -/ac_main.html/1.4/Wed Dec 3 21:44:45 2003// -D diff --git a/VEX/head20041019/addrcheck/docs/CVS/Repository b/VEX/head20041019/addrcheck/docs/CVS/Repository deleted file mode 100644 index 225f3caa2..000000000 --- a/VEX/head20041019/addrcheck/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/addrcheck/docs diff --git a/VEX/head20041019/addrcheck/docs/CVS/Root b/VEX/head20041019/addrcheck/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/addrcheck/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/addrcheck/docs/CVS/Template b/VEX/head20041019/addrcheck/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/docs/Makefile.am b/VEX/head20041019/addrcheck/docs/Makefile.am deleted file mode 100644 index 6e049abc7..000000000 --- a/VEX/head20041019/addrcheck/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = ac_main.html diff --git a/VEX/head20041019/addrcheck/docs/ac_main.html b/VEX/head20041019/addrcheck/docs/ac_main.html deleted file mode 100644 index d540fc005..000000000 --- a/VEX/head20041019/addrcheck/docs/ac_main.html +++ /dev/null @@ -1,103 +0,0 @@ - - - Addrcheck: a lightweight memory checker - - - - -

Addrcheck: a lightweight memory checker

- -To use this tool, you must specify --tool=addrcheck -on the Valgrind command line. - -

5.1  Kinds of bugs that Addrcheck can find

- -Addrcheck is a simplified version of the Memcheck tool described -in Section 3. It is identical in every way to Memcheck, except for -one important detail: it does not do the undefined-value checks that -Memcheck does. This means Addrcheck is about twice as fast as -Memcheck, and uses less memory. Addrcheck can detect the following -errors: -
    -
  • Reading/writing memory after it has been free'd
  • -
  • Reading/writing off the end of malloc'd blocks
  • -
  • Reading/writing inappropriate areas on the stack
  • -
  • Memory leaks -- where pointers to malloc'd blocks are lost - forever
  • -
  • Mismatched use of malloc/new/new [] vs free/delete/delete []
  • -
  • Overlapping src and dst pointers in - memcpy() and related functions
  • -
  • Some misuses of the POSIX pthreads API
  • -
-

- -

-Rather than duplicate much of the Memcheck docs here (a.k.a. since I -am a lazy b'stard), users of Addrcheck are advised to read -the section on Memcheck. Some important points: -

    -
  • Addrcheck is exactly like Memcheck, except that all the - value-definedness tracking machinery has been removed. Therefore, - the Memcheck documentation which discusses definedess ("V-bits") is - irrelevant. The stuff on addressibility ("A-bits") is still - relevant. -

    -

  • Addrcheck accepts the same command-line flags as Memcheck, with - the exception of ... (to be filled in). -

    -

  • Like Memcheck, Addrcheck will do memory leak checking (internally, - the same code does leak checking for both tools). The only - difference is how the two tools decide which memory locations - to consider when searching for pointers to blocks. Memcheck will - only consider 4-byte aligned locations which are validly - addressible and which hold defined values. Addrcheck does not - track definedness and so cannot apply the last, "defined value", - criteria. -

    - The result is that Addrcheck's leak checker may "discover" - pointers to blocks that Memcheck would not. So it is possible - that Memcheck could (correctly) conclude that a block is leaked, - yet Addrcheck would not conclude that. -

    - Whether or not this has any effect in practice is unknown. I - suspect not, but that is mere speculation at this stage. -

- -

-Addrcheck is, therefore, a fine-grained address checker. All it -really does is check each memory reference to say whether or not that -location may validly be addressed. Addrcheck has a memory overhead of -one bit per byte of used address space. In contrast, Memcheck has an -overhead of nine bits per byte. - -

-Due to lazyness on the part of the implementor (Julian), error -messages from Addrcheck do not distinguish reads from writes. So it -will say, for example, "Invalid memory access of size 4", whereas -Memcheck would have said whether the access is a read or a write. -This could easily be remedied, if anyone is particularly bothered. - -

-Addrcheck is quite pleasant to use. It's faster than Memcheck, and -the lack of valid-value checks has another side effect: the errors it -does report are relatively easy to track down, compared to the -tedious and often confusing search sometimes needed to find the -cause of uninitialised-value errors reported by Memcheck. - -

-Because it is faster and lighter than Memcheck, our hope is that -Addrcheck is more suitable for less-intrusive, larger scale testing -than is viable with Memcheck. As of mid-November 2002, we have -experimented with running the KDE-3.1 desktop on Addrcheck (the entire -process tree, starting from startkde). Running on a -512MB, 1.7 GHz P4, the result is nearly usable. The ultimate aim is -that is fast and unintrusive enough that (eg) KDE sessions may be -unintrusively monitored for addressing errors whilst people do real -work with their KDE desktop. - -

-Addrcheck is a new experiment in the Valgrind world. We'd be -interested to hear your feedback on it. - - - diff --git a/VEX/head20041019/addrcheck/tests/.cvsignore b/VEX/head20041019/addrcheck/tests/.cvsignore deleted file mode 100644 index eda090716..000000000 --- a/VEX/head20041019/addrcheck/tests/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.in -Makefile -*.stdout.diff -*.stderr.diff -*.stdout.out -*.stderr.out diff --git a/VEX/head20041019/addrcheck/tests/CVS/Entries b/VEX/head20041019/addrcheck/tests/CVS/Entries deleted file mode 100644 index e95a65bf1..000000000 --- a/VEX/head20041019/addrcheck/tests/CVS/Entries +++ /dev/null @@ -1,34 +0,0 @@ -/.cvsignore/1.3/Fri Jun 25 23:25:10 2004// -/Makefile.am/1.9/Sat Jul 10 14:56:25 2004// -/badrw.stderr.exp/1.4/Wed Jan 7 08:47:03 2004// -/badrw.vgtest/1.1/Fri Sep 5 23:29:33 2003// -/filter_stderr/1.1/Fri Oct 4 11:35:47 2002// -/fprw.stderr.exp/1.4/Tue Apr 13 08:36:35 2004// -/fprw.vgtest/1.1/Fri Sep 5 23:29:33 2003// -/insn_basic.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_fpu.stderr.exp/1.1/Sat Mar 27 18:02:36 2004// -/insn_fpu.stdout.exp/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.vgtest/1.1/Sat Mar 27 18:02:36 2004// -/insn_mmx.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmxext.stderr.exp/1.2/Tue Mar 9 08:50:02 2004// -/insn_mmxext.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_mmxext.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_sse.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_sse2.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/overlap.stderr.exp/1.1/Wed May 5 10:46:21 2004// -/overlap.stdout.exp/1.1/Wed May 5 10:46:21 2004// -/overlap.vgtest/1.1/Wed May 5 10:46:22 2004// -/toobig-allocs.stderr.exp/1.1/Sat Jul 10 14:56:25 2004// -/toobig-allocs.vgtest/1.1/Sat Jul 10 14:56:25 2004// -D diff --git a/VEX/head20041019/addrcheck/tests/CVS/Repository b/VEX/head20041019/addrcheck/tests/CVS/Repository deleted file mode 100644 index a6a3a58b5..000000000 --- a/VEX/head20041019/addrcheck/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/addrcheck/tests diff --git a/VEX/head20041019/addrcheck/tests/CVS/Root b/VEX/head20041019/addrcheck/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/addrcheck/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/addrcheck/tests/CVS/Template b/VEX/head20041019/addrcheck/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/Makefile.am b/VEX/head20041019/addrcheck/tests/Makefile.am deleted file mode 100644 index 7efee7dd6..000000000 --- a/VEX/head20041019/addrcheck/tests/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -noinst_SCRIPTS = filter_stderr - -INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2 - -EXTRA_DIST = $(noinst_SCRIPTS) \ - badrw.stderr.exp badrw.vgtest \ - fprw.stderr.exp fprw.vgtest \ - insn_basic.vgtest insn_cmov.vgtest insn_mmx.vgtest \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ - $(addsuffix .stdout.exp,$(INSN_TESTS)) \ - $(addsuffix .vgtest,$(INSN_TESTS)) \ - overlap.stderr.exp overlap.stdout.exp overlap.vgtest \ - toobig-allocs.stderr.exp toobig-allocs.vgtest - diff --git a/VEX/head20041019/addrcheck/tests/badrw.stderr.exp b/VEX/head20041019/addrcheck/tests/badrw.stderr.exp deleted file mode 100644 index 77c3f4a21..000000000 --- a/VEX/head20041019/addrcheck/tests/badrw.stderr.exp +++ /dev/null @@ -1,35 +0,0 @@ -Invalid read of size 4 - at 0x........: main (badrw.c:19) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 4 - at 0x........: main (badrw.c:20) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid read of size 2 - at 0x........: main (badrw.c:22) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 2 - at 0x........: main (badrw.c:23) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid read of size 1 - at 0x........: main (badrw.c:25) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 1 - at 0x........: main (badrw.c:26) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) diff --git a/VEX/head20041019/addrcheck/tests/badrw.vgtest b/VEX/head20041019/addrcheck/tests/badrw.vgtest deleted file mode 100644 index 6f6830189..000000000 --- a/VEX/head20041019/addrcheck/tests/badrw.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: ../../memcheck/tests/badrw diff --git a/VEX/head20041019/addrcheck/tests/filter_stderr b/VEX/head20041019/addrcheck/tests/filter_stderr deleted file mode 100755 index e7668baff..000000000 --- a/VEX/head20041019/addrcheck/tests/filter_stderr +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/sh - -# Same as for MemCheck - -dir=`dirname $0` - -$dir/../../memcheck/tests/filter_stderr - diff --git a/VEX/head20041019/addrcheck/tests/fprw.stderr.exp b/VEX/head20041019/addrcheck/tests/fprw.stderr.exp deleted file mode 100644 index fdd523734..000000000 --- a/VEX/head20041019/addrcheck/tests/fprw.stderr.exp +++ /dev/null @@ -1,34 +0,0 @@ -Invalid read of size 8 - at 0x........: main (fprw.c:20) - Address 0x........ is 0 bytes inside a block of size 8 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:18) - -Invalid write of size 8 - at 0x........: main (fprw.c:20) - Address 0x........ is 0 bytes inside a block of size 8 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:18) - -Invalid read of size 4 - at 0x........: main (fprw.c:21) - Address 0x........ is 0 bytes inside a block of size 4 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:19) - -Invalid write of size 4 - at 0x........: main (fprw.c:21) - Address 0x........ is 0 bytes inside a block of size 4 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:19) - -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:22) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Invalid write of size 8 - at 0x........: main (fprw.c:24) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:23) diff --git a/VEX/head20041019/addrcheck/tests/fprw.vgtest b/VEX/head20041019/addrcheck/tests/fprw.vgtest deleted file mode 100644 index 9db266e4e..000000000 --- a/VEX/head20041019/addrcheck/tests/fprw.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: --single-step=yes -q -prog: ../../memcheck/tests/fprw diff --git a/VEX/head20041019/addrcheck/tests/insn_basic.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_basic.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_basic.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_basic.stdout.exp deleted file mode 100644 index 40cabbcd0..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_basic.stdout.exp +++ /dev/null @@ -1,1083 +0,0 @@ -aaa_1 ... ok -aaa_2 ... ok -aaa_3 ... ok -aaa_4 ... ok -aaa_5 ... ok -aaa_6 ... ok -aaa_7 ... ok -aaa_8 ... ok -aad_1 ... ok -aad_2 ... ok -aam_1 ... ok -aam_2 ... ok -aas_1 ... ok -aas_2 ... ok -aas_3 ... ok -aas_4 ... ok -aas_5 ... ok -aas_6 ... ok -aas_7 ... ok -aas_8 ... ok -adcb_1 ... ok -adcb_2 ... ok -adcb_3 ... ok -adcb_4 ... ok -adcb_5 ... ok -adcb_6 ... ok -adcb_7 ... ok -adcb_8 ... ok -adcb_9 ... ok -adcb_10 ... ok -adcb_11 ... ok -adcb_12 ... ok -adcw_1 ... ok -adcw_2 ... ok -adcw_3 ... ok -adcw_4 ... ok -adcw_5 ... ok -adcw_6 ... ok -adcw_7 ... ok -adcw_8 ... ok -adcw_9 ... ok -adcw_10 ... ok -adcw_11 ... ok -adcw_12 ... ok -adcw_13 ... ok -adcw_14 ... ok -adcl_1 ... ok -adcl_2 ... ok -adcl_3 ... ok -adcl_4 ... ok -adcl_5 ... ok -adcl_6 ... ok -adcl_7 ... ok -adcl_8 ... ok -adcl_9 ... ok -adcl_10 ... ok -adcl_11 ... ok -adcl_12 ... ok -adcl_13 ... ok -adcl_14 ... ok -addb_1 ... ok -addb_2 ... ok -addb_3 ... ok -addb_4 ... ok -addb_5 ... ok -addb_6 ... ok -addw_1 ... ok -addw_2 ... ok -addw_3 ... ok -addw_4 ... ok -addw_5 ... ok -addw_6 ... ok -addw_7 ... ok -addl_1 ... ok -addl_2 ... ok -addl_3 ... ok -addl_4 ... ok -addl_5 ... ok -addl_6 ... ok -addl_7 ... ok -andb_1 ... ok -andb_2 ... ok -andb_3 ... ok -andb_4 ... ok -andb_5 ... ok -andb_6 ... ok -andw_1 ... ok -andw_2 ... ok -andw_3 ... ok -andw_4 ... ok -andw_5 ... ok -andw_6 ... ok -andw_7 ... ok -andl_1 ... ok -andl_2 ... ok -andl_3 ... ok -andl_4 ... ok -andl_5 ... ok -andl_6 ... ok -andl_7 ... ok -bsfw_1 ... ok -bsfw_2 ... ok -bsfl_1 ... ok -bsfl_2 ... ok -bsrw_1 ... ok -bsrw_2 ... ok -bsrl_1 ... ok -bsrl_2 ... ok -bswapl_1 ... ok -btw_1 ... ok -btw_2 ... ok -btw_3 ... ok -btw_4 ... ok -btw_5 ... ok -btw_6 ... ok -btw_7 ... ok -btw_8 ... ok -btl_1 ... ok -btl_2 ... ok -btl_3 ... ok -btl_4 ... ok -btl_5 ... ok -btl_6 ... ok -btl_7 ... ok -btl_8 ... ok -btcw_1 ... ok -btcw_2 ... ok -btcw_3 ... ok -btcw_4 ... ok -btcw_5 ... ok -btcw_6 ... ok -btcw_7 ... ok -btcw_8 ... ok -btcl_1 ... ok -btcl_2 ... ok -btcl_3 ... ok -btcl_4 ... ok -btcl_5 ... ok -btcl_6 ... ok -btcl_7 ... ok -btcl_8 ... ok -btrw_1 ... ok -btrw_2 ... ok -btrw_3 ... ok -btrw_4 ... ok -btrw_5 ... ok -btrw_6 ... ok -btrw_7 ... ok -btrw_8 ... ok -btrl_1 ... ok -btrl_2 ... ok -btrl_3 ... ok -btrl_4 ... ok -btrl_5 ... ok -btrl_6 ... ok -btrl_7 ... ok -btrl_8 ... ok -btsw_1 ... ok -btsw_2 ... ok -btsw_3 ... ok -btsw_4 ... ok -btsw_5 ... ok -btsw_6 ... ok -btsw_7 ... ok -btsw_8 ... ok -btsl_1 ... ok -btsl_2 ... ok -btsl_3 ... ok -btsl_4 ... ok -btsl_5 ... ok -btsl_6 ... ok -btsl_7 ... ok -btsl_8 ... ok -cbw_1 ... ok -cbw_2 ... ok -cdq_1 ... ok -cdq_2 ... ok -clc_1 ... ok -clc_2 ... ok -cld_1 ... ok -cld_2 ... ok -cmc_1 ... ok -cmc_2 ... ok -cmpb_1 ... ok -cmpb_2 ... ok -cmpb_3 ... ok -cmpb_4 ... ok -cmpb_5 ... ok -cmpb_6 ... ok -cmpb_7 ... ok -cmpb_8 ... ok -cmpb_9 ... ok -cmpb_10 ... ok -cmpb_11 ... ok -cmpb_12 ... ok -cmpb_13 ... ok -cmpb_14 ... ok -cmpb_15 ... ok -cmpb_16 ... ok -cmpb_17 ... ok -cmpb_18 ... ok -cmpb_19 ... ok -cmpb_20 ... ok -cmpb_21 ... ok -cmpb_22 ... ok -cmpb_23 ... ok -cmpb_24 ... ok -cmpb_25 ... ok -cmpb_26 ... ok -cmpb_27 ... ok -cmpb_28 ... ok -cmpb_29 ... ok -cmpb_30 ... ok -cmpb_31 ... ok -cmpb_32 ... ok -cmpb_33 ... ok -cmpb_34 ... ok -cmpb_35 ... ok -cmpb_36 ... ok -cmpb_37 ... ok -cmpb_38 ... ok -cmpb_39 ... ok -cmpb_40 ... ok -cmpb_41 ... ok -cmpb_42 ... ok -cmpb_43 ... ok -cmpb_44 ... ok -cmpb_45 ... ok -cmpb_46 ... ok -cmpb_47 ... ok -cmpb_48 ... ok -cmpb_49 ... ok -cmpb_50 ... ok -cmpb_51 ... ok -cmpb_52 ... ok -cmpb_53 ... ok -cmpb_54 ... ok -cmpb_55 ... ok -cmpb_56 ... ok -cmpb_57 ... ok -cmpb_58 ... ok -cmpb_59 ... ok -cmpb_60 ... ok -cmpw_1 ... ok -cmpw_2 ... ok -cmpw_3 ... ok -cmpw_4 ... ok -cmpw_5 ... ok -cmpw_6 ... ok -cmpw_7 ... ok -cmpw_8 ... ok -cmpw_9 ... ok -cmpw_10 ... ok -cmpw_11 ... ok -cmpw_12 ... ok -cmpw_13 ... ok -cmpw_14 ... ok -cmpw_15 ... ok -cmpw_16 ... ok -cmpw_17 ... ok -cmpw_18 ... ok -cmpw_19 ... ok -cmpw_20 ... ok -cmpw_21 ... ok -cmpw_22 ... ok -cmpw_23 ... ok -cmpw_24 ... ok -cmpw_25 ... ok -cmpw_26 ... ok -cmpw_27 ... ok -cmpw_28 ... ok -cmpw_29 ... ok -cmpw_30 ... ok -cmpw_31 ... ok -cmpw_32 ... ok -cmpw_33 ... ok -cmpw_34 ... ok -cmpw_35 ... ok -cmpw_36 ... ok -cmpw_37 ... ok -cmpw_38 ... ok -cmpw_39 ... ok -cmpw_40 ... ok -cmpw_41 ... ok -cmpw_42 ... ok -cmpw_43 ... ok -cmpw_44 ... ok -cmpw_45 ... ok -cmpw_46 ... ok -cmpw_47 ... ok -cmpw_48 ... ok -cmpw_49 ... ok -cmpw_50 ... ok -cmpw_51 ... ok -cmpw_52 ... ok -cmpw_53 ... ok -cmpw_54 ... ok -cmpw_55 ... ok -cmpw_56 ... ok -cmpw_57 ... ok -cmpw_58 ... ok -cmpw_59 ... ok -cmpw_60 ... ok -cmpw_61 ... ok -cmpw_62 ... ok -cmpw_63 ... ok -cmpw_64 ... ok -cmpw_65 ... ok -cmpw_66 ... ok -cmpw_67 ... ok -cmpw_68 ... ok -cmpw_69 ... ok -cmpw_70 ... ok -cmpw_71 ... ok -cmpw_72 ... ok -cmpw_73 ... ok -cmpw_74 ... ok -cmpw_75 ... ok -cmpw_76 ... ok -cmpw_77 ... ok -cmpw_78 ... ok -cmpw_79 ... ok -cmpw_80 ... ok -cmpl_1 ... ok -cmpl_2 ... ok -cmpl_3 ... ok -cmpl_4 ... ok -cmpl_5 ... ok -cmpl_6 ... ok -cmpl_7 ... ok -cmpl_8 ... ok -cmpl_9 ... ok -cmpl_10 ... ok -cmpl_11 ... ok -cmpl_12 ... ok -cmpl_13 ... ok -cmpl_14 ... ok -cmpl_15 ... ok -cmpl_16 ... ok -cmpl_17 ... ok -cmpl_18 ... ok -cmpl_19 ... ok -cmpl_20 ... ok -cmpl_21 ... ok -cmpl_22 ... ok -cmpl_23 ... ok -cmpl_24 ... ok -cmpl_25 ... ok -cmpl_26 ... ok -cmpl_27 ... ok -cmpl_28 ... ok -cmpl_29 ... ok -cmpl_30 ... ok -cmpl_31 ... ok -cmpl_32 ... ok -cmpl_33 ... ok -cmpl_34 ... ok -cmpl_35 ... ok -cmpl_36 ... ok -cmpl_37 ... ok -cmpl_38 ... ok -cmpl_39 ... ok -cmpl_40 ... ok -cmpl_41 ... ok -cmpl_42 ... ok -cmpl_43 ... ok -cmpl_44 ... ok -cmpl_45 ... ok -cmpl_46 ... ok -cmpl_47 ... ok -cmpl_48 ... ok -cmpl_49 ... ok -cmpl_50 ... ok -cmpl_51 ... ok -cmpl_52 ... ok -cmpl_53 ... ok -cmpl_54 ... ok -cmpl_55 ... ok -cmpl_56 ... ok -cmpl_57 ... ok -cmpl_58 ... ok -cmpl_59 ... ok -cmpl_60 ... ok -cmpl_61 ... ok -cmpl_62 ... ok -cmpl_63 ... ok -cmpl_64 ... ok -cmpl_65 ... ok -cmpl_66 ... ok -cmpl_67 ... ok -cmpl_68 ... ok -cmpl_69 ... ok -cmpl_70 ... ok -cmpl_71 ... ok -cmpl_72 ... ok -cmpl_73 ... ok -cmpl_74 ... ok -cmpl_75 ... ok -cmpl_76 ... ok -cmpl_77 ... ok -cmpl_78 ... ok -cmpl_79 ... ok -cmpl_80 ... ok -cmpxchgb_1 ... ok -cmpxchgb_2 ... ok -cmpxchgb_3 ... ok -cmpxchgb_4 ... ok -cmpxchgw_1 ... ok -cmpxchgw_2 ... ok -cmpxchgw_3 ... ok -cmpxchgw_4 ... ok -cmpxchgl_1 ... ok -cmpxchgl_2 ... ok -cmpxchgl_3 ... ok -cmpxchgl_4 ... ok -cwd_1 ... ok -cwd_2 ... ok -cwde_1 ... ok -cwde_2 ... ok -daa_1 ... ok -daa_2 ... ok -das_1 ... ok -decb_1 ... ok -decb_2 ... ok -decw_1 ... ok -decw_2 ... ok -decl_1 ... ok -decl_2 ... ok -divb_1 ... ok -divb_2 ... ok -divw_1 ... ok -divw_2 ... ok -divl_1 ... ok -divl_2 ... ok -idivb_1 ... ok -idivb_2 ... ok -idivw_1 ... ok -idivw_2 ... ok -idivl_1 ... ok -idivl_2 ... ok -imulb_1 ... ok -imulb_2 ... ok -imulw_1 ... ok -imulw_2 ... ok -imull_1 ... ok -imull_2 ... ok -imulw_3 ... ok -imulw_4 ... ok -imulw_5 ... ok -imulw_6 ... ok -imulw_7 ... ok -imulw_8 ... ok -imulw_9 ... ok -imulw_10 ... ok -imull_3 ... ok -imull_4 ... ok -imull_5 ... ok -imull_6 ... ok -imull_7 ... ok -imull_8 ... ok -imull_9 ... ok -imull_10 ... ok -incb_1 ... ok -incb_2 ... ok -incw_1 ... ok -incw_2 ... ok -incl_1 ... ok -incl_2 ... ok -lahf_1 ... ok -lahf_2 ... ok -movb_1 ... ok -movb_2 ... ok -movb_3 ... ok -movb_4 ... ok -movb_5 ... ok -movw_1 ... ok -movw_2 ... ok -movw_3 ... ok -movw_4 ... ok -movw_5 ... ok -movl_1 ... ok -movl_2 ... ok -movl_3 ... ok -movl_4 ... ok -movl_5 ... ok -movsbw_1 ... ok -movsbw_2 ... ok -movsbl_1 ... ok -movsbl_2 ... ok -movswl_1 ... ok -movswl_2 ... ok -movzbw_1 ... ok -movzbw_2 ... ok -movzbl_1 ... ok -movzbl_2 ... ok -movzwl_1 ... ok -movzwl_2 ... ok -mulb_1 ... ok -mulb_2 ... ok -mulw_1 ... ok -mulw_2 ... ok -mull_1 ... ok -mull_2 ... ok -negb_1 ... ok -negb_2 ... ok -negw_1 ... ok -negw_2 ... ok -negl_1 ... ok -negl_2 ... ok -notb_1 ... ok -notb_2 ... ok -notw_1 ... ok -notw_2 ... ok -notl_1 ... ok -notl_2 ... ok -orb_1 ... ok -orb_2 ... ok -orb_3 ... ok -orb_4 ... ok -orb_5 ... ok -orb_6 ... ok -orw_1 ... ok -orw_2 ... ok -orw_3 ... ok -orw_4 ... ok -orw_5 ... ok -orw_6 ... ok -orw_7 ... ok -orl_1 ... ok -orl_2 ... ok -orl_3 ... ok -orl_4 ... ok -orl_5 ... ok -orl_6 ... ok -orl_7 ... ok -rclb_1 ... ok -rclb_2 ... ok -rclb_3 ... ok -rclb_4 ... ok -rclb_5 ... ok -rclb_6 ... ok -rclw_1 ... ok -rclw_2 ... ok -rclw_3 ... ok -rclw_4 ... ok -rclw_5 ... ok -rclw_6 ... ok -rcll_1 ... ok -rcll_2 ... ok -rcll_3 ... ok -rcll_4 ... ok -rcll_5 ... ok -rcll_6 ... ok -rcrb_1 ... ok -rcrb_2 ... ok -rcrb_3 ... ok -rcrb_4 ... ok -rcrb_5 ... ok -rcrb_6 ... ok -rcrw_1 ... ok -rcrw_2 ... ok -rcrw_3 ... ok -rcrw_4 ... ok -rcrw_5 ... ok -rcrw_6 ... ok -rcrl_1 ... ok -rcrl_2 ... ok -rcrl_3 ... ok -rcrl_4 ... ok -rcrl_5 ... ok -rcrl_6 ... ok -rolb_1 ... ok -rolb_2 ... ok -rolb_3 ... ok -rolb_4 ... ok -rolb_5 ... ok -rolb_6 ... ok -rolw_1 ... ok -rolw_2 ... ok -rolw_3 ... ok -rolw_4 ... ok -rolw_5 ... ok -rolw_6 ... ok -roll_1 ... ok -roll_2 ... ok -roll_3 ... ok -roll_4 ... ok -roll_5 ... ok -roll_6 ... ok -rorb_1 ... ok -rorb_2 ... ok -rorb_3 ... ok -rorb_4 ... ok -rorb_5 ... ok -rorb_6 ... ok -rorw_1 ... ok -rorw_2 ... ok -rorw_3 ... ok -rorw_4 ... ok -rorw_5 ... ok -rorw_6 ... ok -rorl_1 ... ok -rorl_2 ... ok -rorl_3 ... ok -rorl_4 ... ok -rorl_5 ... ok -rorl_6 ... ok -sahf_1 ... ok -sahf_2 ... ok -salb_1 ... ok -salb_2 ... ok -salb_3 ... ok -salb_4 ... ok -salb_5 ... ok -salb_6 ... ok -salw_1 ... ok -salw_2 ... ok -salw_3 ... ok -salw_4 ... ok -salw_5 ... ok -salw_6 ... ok -sall_1 ... ok -sall_2 ... ok -sall_3 ... ok -sall_4 ... ok -sall_5 ... ok -sall_6 ... ok -sarb_1 ... ok -sarb_2 ... ok -sarb_3 ... ok -sarb_4 ... ok -sarb_5 ... ok -sarb_6 ... ok -sarw_1 ... ok -sarw_2 ... ok -sarw_3 ... ok -sarw_4 ... ok -sarw_5 ... ok -sarw_6 ... ok -sarl_1 ... ok -sarl_2 ... ok -sarl_3 ... ok -sarl_4 ... ok -sarl_5 ... ok -sarl_6 ... ok -sbbb_1 ... ok -sbbb_2 ... ok -sbbb_3 ... ok -sbbb_4 ... ok -sbbb_5 ... ok -sbbb_6 ... ok -sbbb_7 ... ok -sbbb_8 ... ok -sbbb_9 ... ok -sbbb_10 ... ok -sbbb_11 ... ok -sbbb_12 ... ok -sbbw_1 ... ok -sbbw_2 ... ok -sbbw_3 ... ok -sbbw_4 ... ok -sbbw_5 ... ok -sbbw_6 ... ok -sbbw_7 ... ok -sbbw_8 ... ok -sbbw_9 ... ok -sbbw_10 ... ok -sbbw_11 ... ok -sbbw_12 ... ok -sbbw_13 ... ok -sbbw_14 ... ok -sbbl_1 ... ok -sbbl_2 ... ok -sbbl_3 ... ok -sbbl_4 ... ok -sbbl_5 ... ok -sbbl_6 ... ok -sbbl_7 ... ok -sbbl_8 ... ok -sbbl_9 ... ok -sbbl_10 ... ok -sbbl_11 ... ok -sbbl_12 ... ok -sbbl_13 ... ok -sbbl_14 ... ok -seta_1 ... ok -seta_2 ... ok -seta_3 ... ok -seta_4 ... ok -seta_5 ... ok -seta_6 ... ok -seta_7 ... ok -seta_8 ... ok -setae_1 ... ok -setae_2 ... ok -setae_3 ... ok -setae_4 ... ok -setb_1 ... ok -setb_2 ... ok -setb_3 ... ok -setb_4 ... ok -setbe_1 ... ok -setbe_2 ... ok -setbe_3 ... ok -setbe_4 ... ok -setbe_5 ... ok -setbe_6 ... ok -setbe_7 ... ok -setbe_8 ... ok -setc_1 ... ok -setc_2 ... ok -setc_3 ... ok -setc_4 ... ok -sete_1 ... ok -sete_2 ... ok -sete_3 ... ok -sete_4 ... ok -setg_1 ... ok -setg_2 ... ok -setg_3 ... ok -setg_4 ... ok -setg_5 ... ok -setg_6 ... ok -setg_7 ... ok -setg_8 ... ok -setg_9 ... ok -setg_10 ... ok -setg_11 ... ok -setg_12 ... ok -setg_13 ... ok -setg_14 ... ok -setg_15 ... ok -setg_16 ... ok -setge_1 ... ok -setge_2 ... ok -setge_3 ... ok -setge_4 ... ok -setge_5 ... ok -setge_6 ... ok -setge_7 ... ok -setge_8 ... ok -setl_1 ... ok -setl_2 ... ok -setl_3 ... ok -setl_4 ... ok -setl_5 ... ok -setl_6 ... ok -setl_7 ... ok -setl_8 ... ok -setle_1 ... ok -setle_2 ... ok -setle_3 ... ok -setle_4 ... ok -setle_5 ... ok -setle_6 ... ok -setle_7 ... ok -setle_8 ... ok -setle_9 ... ok -setle_10 ... ok -setle_11 ... ok -setle_12 ... ok -setle_13 ... ok -setle_14 ... ok -setle_15 ... ok -setle_16 ... ok -setna_1 ... ok -setna_2 ... ok -setna_3 ... ok -setna_4 ... ok -setna_5 ... ok -setna_6 ... ok -setna_7 ... ok -setna_8 ... ok -setnae_1 ... ok -setnae_2 ... ok -setnae_3 ... ok -setnae_4 ... ok -setnb_1 ... ok -setnb_2 ... ok -setnb_3 ... ok -setnb_4 ... ok -setnbe_1 ... ok -setnbe_2 ... ok -setnbe_3 ... ok -setnbe_4 ... ok -setnbe_5 ... ok -setnbe_6 ... ok -setnbe_7 ... ok -setnbe_8 ... ok -setnc_1 ... ok -setnc_2 ... ok -setnc_3 ... ok -setnc_4 ... ok -setne_1 ... ok -setne_2 ... ok -setne_3 ... ok -setne_4 ... ok -setng_1 ... ok -setng_2 ... ok -setng_3 ... ok -setng_4 ... ok -setng_5 ... ok -setng_6 ... ok -setng_7 ... ok -setng_8 ... ok -setng_9 ... ok -setng_10 ... ok -setng_11 ... ok -setng_12 ... ok -setng_13 ... ok -setng_14 ... ok -setng_15 ... ok -setng_16 ... ok -setnge_1 ... ok -setnge_2 ... ok -setnge_3 ... ok -setnge_4 ... ok -setnge_5 ... ok -setnge_6 ... ok -setnge_7 ... ok -setnge_8 ... ok -setnl_1 ... ok -setnl_2 ... ok -setnl_3 ... ok -setnl_4 ... ok -setnl_5 ... ok -setnl_6 ... ok -setnl_7 ... ok -setnl_8 ... ok -setnle_1 ... ok -setnle_2 ... ok -setnle_3 ... ok -setnle_4 ... ok -setnle_5 ... ok -setnle_6 ... ok -setnle_7 ... ok -setnle_8 ... ok -setnle_9 ... ok -setnle_10 ... ok -setnle_11 ... ok -setnle_12 ... ok -setnle_13 ... ok -setnle_14 ... ok -setnle_15 ... ok -setnle_16 ... ok -setno_1 ... ok -setno_2 ... ok -setno_3 ... ok -setno_4 ... ok -setnp_1 ... ok -setnp_2 ... ok -setnp_3 ... ok -setnp_4 ... ok -setns_1 ... ok -setns_2 ... ok -setns_3 ... ok -setns_4 ... ok -setnz_1 ... ok -setnz_2 ... ok -setnz_3 ... ok -setnz_4 ... ok -seto_1 ... ok -seto_2 ... ok -seto_3 ... ok -seto_4 ... ok -setp_1 ... ok -setp_2 ... ok -setp_3 ... ok -setp_4 ... ok -sets_1 ... ok -sets_2 ... ok -sets_3 ... ok -sets_4 ... ok -setz_1 ... ok -setz_2 ... ok -setz_3 ... ok -setz_4 ... ok -shlb_1 ... ok -shlb_2 ... ok -shlb_3 ... ok -shlb_4 ... ok -shlb_5 ... ok -shlb_6 ... ok -shlw_1 ... ok -shlw_2 ... ok -shlw_3 ... ok -shlw_4 ... ok -shlw_5 ... ok -shlw_6 ... ok -shll_1 ... ok -shll_2 ... ok -shll_3 ... ok -shll_4 ... ok -shll_5 ... ok -shll_6 ... ok -shrb_1 ... ok -shrb_2 ... ok -shrb_3 ... ok -shrb_4 ... ok -shrb_5 ... ok -shrb_6 ... ok -shrw_1 ... ok -shrw_2 ... ok -shrw_3 ... ok -shrw_4 ... ok -shrw_5 ... ok -shrw_6 ... ok -shrl_1 ... ok -shrl_2 ... ok -shrl_3 ... ok -shrl_4 ... ok -shrl_5 ... ok -shrl_6 ... ok -shldw_1 ... ok -shldw_2 ... ok -shldw_3 ... ok -shldw_4 ... ok -shldw_5 ... ok -shldw_6 ... ok -shldw_7 ... ok -shldw_8 ... ok -shldl_1 ... ok -shldl_2 ... ok -shldl_3 ... ok -shldl_4 ... ok -shldl_5 ... ok -shldl_6 ... ok -shldl_7 ... ok -shldl_8 ... ok -shrdw_1 ... ok -shrdw_2 ... ok -shrdw_3 ... ok -shrdw_4 ... ok -shrdw_5 ... ok -shrdw_6 ... ok -shrdw_7 ... ok -shrdw_8 ... ok -shrdl_1 ... ok -shrdl_2 ... ok -shrdl_3 ... ok -shrdl_4 ... ok -shrdl_5 ... ok -shrdl_6 ... ok -shrdl_7 ... ok -shrdl_8 ... ok -stc_1 ... ok -stc_2 ... ok -std_1 ... ok -std_2 ... ok -subb_1 ... ok -subb_2 ... ok -subb_3 ... ok -subb_4 ... ok -subb_5 ... ok -subb_6 ... ok -subw_1 ... ok -subw_2 ... ok -subw_3 ... ok -subw_4 ... ok -subw_5 ... ok -subw_6 ... ok -subw_7 ... ok -subl_1 ... ok -subl_2 ... ok -subl_3 ... ok -subl_4 ... ok -subl_5 ... ok -subl_6 ... ok -subl_7 ... ok -testb_1 ... ok -testb_2 ... ok -testb_3 ... ok -testb_4 ... ok -testb_5 ... ok -testb_6 ... ok -testb_7 ... ok -testb_8 ... ok -testb_9 ... ok -testb_10 ... ok -testb_11 ... ok -testb_12 ... ok -testb_13 ... ok -testb_14 ... ok -testb_15 ... ok -testb_16 ... ok -testb_17 ... ok -testb_18 ... ok -testb_19 ... ok -testb_20 ... ok -testb_21 ... ok -testb_22 ... ok -testb_23 ... ok -testb_24 ... ok -testb_25 ... ok -testw_1 ... ok -testw_2 ... ok -testw_3 ... ok -testw_4 ... ok -testw_5 ... ok -testw_6 ... ok -testw_7 ... ok -testw_8 ... ok -testw_9 ... ok -testw_10 ... ok -testw_11 ... ok -testw_12 ... ok -testw_13 ... ok -testw_14 ... ok -testw_15 ... ok -testw_16 ... ok -testw_17 ... ok -testw_18 ... ok -testw_19 ... ok -testw_20 ... ok -testw_21 ... ok -testw_22 ... ok -testw_23 ... ok -testw_24 ... ok -testw_25 ... ok -testl_1 ... ok -testl_2 ... ok -testl_3 ... ok -testl_4 ... ok -testl_5 ... ok -testl_6 ... ok -testl_7 ... ok -testl_8 ... ok -testl_9 ... ok -testl_10 ... ok -testl_11 ... ok -testl_12 ... ok -testl_13 ... ok -testl_14 ... ok -testl_15 ... ok -testl_16 ... ok -testl_17 ... ok -testl_18 ... ok -testl_19 ... ok -testl_20 ... ok -testl_21 ... ok -testl_22 ... ok -testl_23 ... ok -testl_24 ... ok -testl_25 ... ok -xaddb_1 ... ok -xaddb_2 ... ok -xaddw_1 ... ok -xaddw_2 ... ok -xaddl_1 ... ok -xaddl_2 ... ok -xchgb_1 ... ok -xchgb_2 ... ok -xchgb_3 ... ok -xchgw_1 ... ok -xchgw_2 ... ok -xchgw_3 ... ok -xchgw_4 ... ok -xchgw_5 ... ok -xchgl_1 ... ok -xchgl_2 ... ok -xchgl_3 ... ok -xchgl_4 ... ok -xchgl_5 ... ok -xorb_1 ... ok -xorb_2 ... ok -xorb_3 ... ok -xorb_4 ... ok -xorb_5 ... ok -xorb_6 ... ok -xorw_1 ... ok -xorw_2 ... ok -xorw_3 ... ok -xorw_4 ... ok -xorw_5 ... ok -xorw_6 ... ok -xorw_7 ... ok -xorl_1 ... ok -xorl_2 ... ok -xorl_3 ... ok -xorl_4 ... ok -xorl_5 ... ok -xorl_6 ... ok -xorl_7 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_basic.vgtest b/VEX/head20041019/addrcheck/tests/insn_basic.vgtest deleted file mode 100644 index f5329ea81..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_basic.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_basic diff --git a/VEX/head20041019/addrcheck/tests/insn_cmov.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_cmov.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_cmov.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_cmov.stdout.exp deleted file mode 100644 index 31ac17204..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_cmov.stdout.exp +++ /dev/null @@ -1,384 +0,0 @@ -cmova_1 ... ok -cmova_2 ... ok -cmova_3 ... ok -cmova_4 ... ok -cmova_5 ... ok -cmova_6 ... ok -cmova_7 ... ok -cmova_8 ... ok -cmovae_1 ... ok -cmovae_2 ... ok -cmovae_3 ... ok -cmovae_4 ... ok -cmovb_1 ... ok -cmovb_2 ... ok -cmovb_3 ... ok -cmovb_4 ... ok -cmovbe_1 ... ok -cmovbe_2 ... ok -cmovbe_3 ... ok -cmovbe_4 ... ok -cmovbe_5 ... ok -cmovbe_6 ... ok -cmovbe_7 ... ok -cmovbe_8 ... ok -cmovc_1 ... ok -cmovc_2 ... ok -cmovc_3 ... ok -cmovc_4 ... ok -cmove_1 ... ok -cmove_2 ... ok -cmove_3 ... ok -cmove_4 ... ok -cmovg_1 ... ok -cmovg_2 ... ok -cmovg_3 ... ok -cmovg_4 ... ok -cmovg_5 ... ok -cmovg_6 ... ok -cmovg_7 ... ok -cmovg_8 ... ok -cmovg_9 ... ok -cmovg_10 ... ok -cmovg_11 ... ok -cmovg_12 ... ok -cmovg_13 ... ok -cmovg_14 ... ok -cmovg_15 ... ok -cmovg_16 ... ok -cmovge_1 ... ok -cmovge_2 ... ok -cmovge_3 ... ok -cmovge_4 ... ok -cmovge_5 ... ok -cmovge_6 ... ok -cmovge_7 ... ok -cmovge_8 ... ok -cmovl_1 ... ok -cmovl_2 ... ok -cmovl_3 ... ok -cmovl_4 ... ok -cmovl_5 ... ok -cmovl_6 ... ok -cmovl_7 ... ok -cmovl_8 ... ok -cmovle_1 ... ok -cmovle_2 ... ok -cmovle_3 ... ok -cmovle_4 ... ok -cmovle_5 ... ok -cmovle_6 ... ok -cmovle_7 ... ok -cmovle_8 ... ok -cmovle_9 ... ok -cmovle_10 ... ok -cmovle_11 ... ok -cmovle_12 ... ok -cmovle_13 ... ok -cmovle_14 ... ok -cmovle_15 ... ok -cmovle_16 ... ok -cmovna_1 ... ok -cmovna_2 ... ok -cmovna_3 ... ok -cmovna_4 ... ok -cmovna_5 ... ok -cmovna_6 ... ok -cmovna_7 ... ok -cmovna_8 ... ok -cmovnae_1 ... ok -cmovnae_2 ... ok -cmovnae_3 ... ok -cmovnae_4 ... ok -cmovnb_1 ... ok -cmovnb_2 ... ok -cmovnb_3 ... ok -cmovnb_4 ... ok -cmovnbe_1 ... ok -cmovnbe_2 ... ok -cmovnbe_3 ... ok -cmovnbe_4 ... ok -cmovnbe_5 ... ok -cmovnbe_6 ... ok -cmovnbe_7 ... ok -cmovnbe_8 ... ok -cmovnc_1 ... ok -cmovnc_2 ... ok -cmovnc_3 ... ok -cmovnc_4 ... ok -cmovne_1 ... ok -cmovne_2 ... ok -cmovne_3 ... ok -cmovne_4 ... ok -cmovng_1 ... ok -cmovng_2 ... ok -cmovng_3 ... ok -cmovng_4 ... ok -cmovng_5 ... ok -cmovng_6 ... ok -cmovng_7 ... ok -cmovng_8 ... ok -cmovng_9 ... ok -cmovng_10 ... ok -cmovng_11 ... ok -cmovng_12 ... ok -cmovng_13 ... ok -cmovng_14 ... ok -cmovng_15 ... ok -cmovng_16 ... ok -cmovnge_1 ... ok -cmovnge_2 ... ok -cmovnge_3 ... ok -cmovnge_4 ... ok -cmovnge_5 ... ok -cmovnge_6 ... ok -cmovnge_7 ... ok -cmovnge_8 ... ok -cmovnl_1 ... ok -cmovnl_2 ... ok -cmovnl_3 ... ok -cmovnl_4 ... ok -cmovnl_5 ... ok -cmovnl_6 ... ok -cmovnl_7 ... ok -cmovnl_8 ... ok -cmovnle_1 ... ok -cmovnle_2 ... ok -cmovnle_3 ... ok -cmovnle_4 ... ok -cmovnle_5 ... ok -cmovnle_6 ... ok -cmovnle_7 ... ok -cmovnle_8 ... ok -cmovnle_9 ... ok -cmovnle_10 ... ok -cmovnle_11 ... ok -cmovnle_12 ... ok -cmovnle_13 ... ok -cmovnle_14 ... ok -cmovnle_15 ... ok -cmovnle_16 ... ok -cmovno_1 ... ok -cmovno_2 ... ok -cmovno_3 ... ok -cmovno_4 ... ok -cmovnp_1 ... ok -cmovnp_2 ... ok -cmovnp_3 ... ok -cmovnp_4 ... ok -cmovns_1 ... ok -cmovns_2 ... ok -cmovns_3 ... ok -cmovns_4 ... ok -cmovnz_1 ... ok -cmovnz_2 ... ok -cmovnz_3 ... ok -cmovnz_4 ... ok -cmovo_1 ... ok -cmovo_2 ... ok -cmovo_3 ... ok -cmovo_4 ... ok -cmovp_1 ... ok -cmovp_2 ... ok -cmovp_3 ... ok -cmovp_4 ... ok -cmovs_1 ... ok -cmovs_2 ... ok -cmovs_3 ... ok -cmovs_4 ... ok -cmovz_1 ... ok -cmovz_2 ... ok -cmovz_3 ... ok -cmovz_4 ... ok -cmova_9 ... ok -cmova_10 ... ok -cmova_11 ... ok -cmova_12 ... ok -cmova_13 ... ok -cmova_14 ... ok -cmova_15 ... ok -cmova_16 ... ok -cmovae_5 ... ok -cmovae_6 ... ok -cmovae_7 ... ok -cmovae_8 ... ok -cmovb_5 ... ok -cmovb_6 ... ok -cmovb_7 ... ok -cmovb_8 ... ok -cmovbe_9 ... ok -cmovbe_10 ... ok -cmovbe_11 ... ok -cmovbe_12 ... ok -cmovbe_13 ... ok -cmovbe_14 ... ok -cmovbe_15 ... ok -cmovbe_16 ... ok -cmovc_5 ... ok -cmovc_6 ... ok -cmovc_7 ... ok -cmovc_8 ... ok -cmove_5 ... ok -cmove_6 ... ok -cmove_7 ... ok -cmove_8 ... ok -cmovg_17 ... ok -cmovg_18 ... ok -cmovg_19 ... ok -cmovg_20 ... ok -cmovg_21 ... ok -cmovg_22 ... ok -cmovg_23 ... ok -cmovg_24 ... ok -cmovg_25 ... ok -cmovg_26 ... ok -cmovg_27 ... ok -cmovg_28 ... ok -cmovg_29 ... ok -cmovg_30 ... ok -cmovg_31 ... ok -cmovg_32 ... ok -cmovge_9 ... ok -cmovge_10 ... ok -cmovge_11 ... ok -cmovge_12 ... ok -cmovge_13 ... ok -cmovge_14 ... ok -cmovge_15 ... ok -cmovge_16 ... ok -cmovl_9 ... ok -cmovl_10 ... ok -cmovl_11 ... ok -cmovl_12 ... ok -cmovl_13 ... ok -cmovl_14 ... ok -cmovl_15 ... ok -cmovl_16 ... ok -cmovle_17 ... ok -cmovle_18 ... ok -cmovle_19 ... ok -cmovle_20 ... ok -cmovle_21 ... ok -cmovle_22 ... ok -cmovle_23 ... ok -cmovle_24 ... ok -cmovle_25 ... ok -cmovle_26 ... ok -cmovle_27 ... ok -cmovle_28 ... ok -cmovle_29 ... ok -cmovle_30 ... ok -cmovle_31 ... ok -cmovle_32 ... ok -cmovna_9 ... ok -cmovna_10 ... ok -cmovna_11 ... ok -cmovna_12 ... ok -cmovna_13 ... ok -cmovna_14 ... ok -cmovna_15 ... ok -cmovna_16 ... ok -cmovnae_5 ... ok -cmovnae_6 ... ok -cmovnae_7 ... ok -cmovnae_8 ... ok -cmovnb_5 ... ok -cmovnb_6 ... ok -cmovnb_7 ... ok -cmovnb_8 ... ok -cmovnbe_9 ... ok -cmovnbe_10 ... ok -cmovnbe_11 ... ok -cmovnbe_12 ... ok -cmovnbe_13 ... ok -cmovnbe_14 ... ok -cmovnbe_15 ... ok -cmovnbe_16 ... ok -cmovnc_5 ... ok -cmovnc_6 ... ok -cmovnc_7 ... ok -cmovnc_8 ... ok -cmovne_5 ... ok -cmovne_6 ... ok -cmovne_7 ... ok -cmovne_8 ... ok -cmovng_17 ... ok -cmovng_18 ... ok -cmovng_19 ... ok -cmovng_20 ... ok -cmovng_21 ... ok -cmovng_22 ... ok -cmovng_23 ... ok -cmovng_24 ... ok -cmovng_25 ... ok -cmovng_26 ... ok -cmovng_27 ... ok -cmovng_28 ... ok -cmovng_29 ... ok -cmovng_30 ... ok -cmovng_31 ... ok -cmovng_32 ... ok -cmovnge_9 ... ok -cmovnge_10 ... ok -cmovnge_11 ... ok -cmovnge_12 ... ok -cmovnge_13 ... ok -cmovnge_14 ... ok -cmovnge_15 ... ok -cmovnge_16 ... ok -cmovnl_9 ... ok -cmovnl_10 ... ok -cmovnl_11 ... ok -cmovnl_12 ... ok -cmovnl_13 ... ok -cmovnl_14 ... ok -cmovnl_15 ... ok -cmovnl_16 ... ok -cmovnle_17 ... ok -cmovnle_18 ... ok -cmovnle_19 ... ok -cmovnle_20 ... ok -cmovnle_21 ... ok -cmovnle_22 ... ok -cmovnle_23 ... ok -cmovnle_24 ... ok -cmovnle_25 ... ok -cmovnle_26 ... ok -cmovnle_27 ... ok -cmovnle_28 ... ok -cmovnle_29 ... ok -cmovnle_30 ... ok -cmovnle_31 ... ok -cmovnle_32 ... ok -cmovno_5 ... ok -cmovno_6 ... ok -cmovno_7 ... ok -cmovno_8 ... ok -cmovnp_5 ... ok -cmovnp_6 ... ok -cmovnp_7 ... ok -cmovnp_8 ... ok -cmovns_5 ... ok -cmovns_6 ... ok -cmovns_7 ... ok -cmovns_8 ... ok -cmovnz_5 ... ok -cmovnz_6 ... ok -cmovnz_7 ... ok -cmovnz_8 ... ok -cmovo_5 ... ok -cmovo_6 ... ok -cmovo_7 ... ok -cmovo_8 ... ok -cmovp_5 ... ok -cmovp_6 ... ok -cmovp_7 ... ok -cmovp_8 ... ok -cmovs_5 ... ok -cmovs_6 ... ok -cmovs_7 ... ok -cmovs_8 ... ok -cmovz_5 ... ok -cmovz_6 ... ok -cmovz_7 ... ok -cmovz_8 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_cmov.vgtest b/VEX/head20041019/addrcheck/tests/insn_cmov.vgtest deleted file mode 100644 index 0321a3ca8..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_cmov.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_cmov -cpu_test: cmov diff --git a/VEX/head20041019/addrcheck/tests/insn_fpu.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_fpu.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_fpu.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_fpu.stdout.exp deleted file mode 100644 index 2dbaa07ce..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_fpu.stdout.exp +++ /dev/null @@ -1,452 +0,0 @@ -fabs_1 ... ok -fabs_2 ... ok -fabs_3 ... ok -fabs_4 ... ok -fadds_1 ... ok -fadds_2 ... ok -fadds_3 ... ok -fadds_4 ... ok -faddl_1 ... ok -faddl_2 ... ok -faddl_3 ... ok -faddl_4 ... ok -fadd_1 ... ok -fadd_2 ... ok -fadd_3 ... ok -fadd_4 ... ok -fadd_5 ... ok -fadd_6 ... ok -fadd_7 ... ok -fadd_8 ... ok -fadd_9 ... ok -fadd_10 ... ok -fadd_11 ... ok -fadd_12 ... ok -fadd_13 ... ok -fadd_14 ... ok -fadd_15 ... ok -fadd_16 ... ok -faddp_1 ... ok -faddp_2 ... ok -faddp_3 ... ok -faddp_4 ... ok -faddp_5 ... ok -faddp_6 ... ok -faddp_7 ... ok -faddp_8 ... ok -faddp_9 ... ok -faddp_10 ... ok -faddp_11 ... ok -faddp_12 ... ok -faddp_13 ... ok -faddp_14 ... ok -faddp_15 ... ok -faddp_16 ... ok -fiadds_1 ... ok -fiadds_2 ... ok -fiadds_3 ... ok -fiadds_4 ... ok -fiadds_5 ... ok -fiadds_6 ... ok -fiadds_7 ... ok -fiadds_8 ... ok -fiaddl_1 ... ok -fiaddl_2 ... ok -fiaddl_3 ... ok -fiaddl_4 ... ok -fiaddl_5 ... ok -fiaddl_6 ... ok -fiaddl_7 ... ok -fiaddl_8 ... ok -fcomi_1 ... ok -fcomi_2 ... ok -fcomi_3 ... ok -fcomi_4 ... ok -fcomi_5 ... ok -fcomi_6 ... ok -fcomip_1 ... ok -fcomip_2 ... ok -fcomip_3 ... ok -fcomip_4 ... ok -fcomip_5 ... ok -fcomip_6 ... ok -fucomi_1 ... ok -fucomi_2 ... ok -fucomi_3 ... ok -fucomi_4 ... ok -fucomi_5 ... ok -fucomi_6 ... ok -fucomip_1 ... ok -fucomip_2 ... ok -fucomip_3 ... ok -fucomip_4 ... ok -fucomip_5 ... ok -fucomip_6 ... ok -fchs_1 ... ok -fchs_2 ... ok -fchs_3 ... ok -fchs_4 ... ok -fdivs_1 ... ok -fdivs_2 ... ok -fdivs_3 ... ok -fdivs_4 ... ok -fdivl_1 ... ok -fdivl_2 ... ok -fdivl_3 ... ok -fdivl_4 ... ok -fdiv_1 ... ok -fdiv_2 ... ok -fdiv_3 ... ok -fdiv_4 ... ok -fdiv_5 ... ok -fdiv_6 ... ok -fdiv_7 ... ok -fdiv_8 ... ok -fdiv_9 ... ok -fdiv_10 ... ok -fdiv_11 ... ok -fdiv_12 ... ok -fdiv_13 ... ok -fdiv_14 ... ok -fdiv_15 ... ok -fdiv_16 ... ok -fdivp_1 ... ok -fdivp_2 ... ok -fdivp_3 ... ok -fdivp_4 ... ok -fdivp_5 ... ok -fdivp_6 ... ok -fdivp_7 ... ok -fdivp_8 ... ok -fdivp_9 ... ok -fdivp_10 ... ok -fdivp_11 ... ok -fdivp_12 ... ok -fdivp_13 ... ok -fdivp_14 ... ok -fdivp_15 ... ok -fdivp_16 ... ok -fidivs_1 ... ok -fidivs_2 ... ok -fidivs_3 ... ok -fidivs_4 ... ok -fidivs_5 ... ok -fidivs_6 ... ok -fidivs_7 ... ok -fidivs_8 ... ok -fidivl_1 ... ok -fidivl_2 ... ok -fidivl_3 ... ok -fidivl_4 ... ok -fidivl_5 ... ok -fidivl_6 ... ok -fidivl_7 ... ok -fidivl_8 ... ok -fdivrs_1 ... ok -fdivrs_2 ... ok -fdivrs_3 ... ok -fdivrs_4 ... ok -fdivrl_1 ... ok -fdivrl_2 ... ok -fdivrl_3 ... ok -fdivrl_4 ... ok -fdivr_1 ... ok -fdivr_2 ... ok -fdivr_3 ... ok -fdivr_4 ... ok -fdivr_5 ... ok -fdivr_6 ... ok -fdivr_7 ... ok -fdivr_8 ... ok -fdivr_9 ... ok -fdivr_10 ... ok -fdivr_11 ... ok -fdivr_12 ... ok -fdivr_13 ... ok -fdivr_14 ... ok -fdivr_15 ... ok -fdivr_16 ... ok -fdivrp_1 ... ok -fdivrp_2 ... ok -fdivrp_3 ... ok -fdivrp_4 ... ok -fdivrp_5 ... ok -fdivrp_6 ... ok -fdivrp_7 ... ok -fdivrp_8 ... ok -fdivrp_9 ... ok -fdivrp_10 ... ok -fdivrp_11 ... ok -fdivrp_12 ... ok -fdivrp_13 ... ok -fdivrp_14 ... ok -fdivrp_15 ... ok -fdivrp_16 ... ok -fidivrs_1 ... ok -fidivrs_2 ... ok -fidivrs_3 ... ok -fidivrs_4 ... ok -fidivrs_5 ... ok -fidivrs_6 ... ok -fidivrs_7 ... ok -fidivrs_8 ... ok -fidivrl_1 ... ok -fidivrl_2 ... ok -fidivrl_3 ... ok -fidivrl_4 ... ok -fidivrl_5 ... ok -fidivrl_6 ... ok -fidivrl_7 ... ok -fidivrl_8 ... ok -filds_1 ... ok -filds_2 ... ok -filds_3 ... ok -filds_4 ... ok -fildl_1 ... ok -fildl_2 ... ok -fildl_3 ... ok -fildl_4 ... ok -fildq_1 ... ok -fildq_2 ... ok -fildq_3 ... ok -fildq_4 ... ok -fists_1 ... ok -fists_2 ... ok -fists_3 ... ok -fists_4 ... ok -fists_5 ... ok -fists_6 ... ok -fists_7 ... ok -fists_8 ... ok -fistl_1 ... ok -fistl_2 ... ok -fistl_3 ... ok -fistl_4 ... ok -fistl_5 ... ok -fistl_6 ... ok -fistl_7 ... ok -fistl_8 ... ok -fistps_1 ... ok -fistps_2 ... ok -fistps_3 ... ok -fistps_4 ... ok -fistps_5 ... ok -fistps_6 ... ok -fistps_7 ... ok -fistps_8 ... ok -fistpl_1 ... ok -fistpl_2 ... ok -fistpl_3 ... ok -fistpl_4 ... ok -fistpl_5 ... ok -fistpl_6 ... ok -fistpl_7 ... ok -fistpl_8 ... ok -fistpq_1 ... ok -fistpq_2 ... ok -fistpq_3 ... ok -fistpq_4 ... ok -fistpq_5 ... ok -fistpq_6 ... ok -fistpq_7 ... ok -fistpq_8 ... ok -flds_1 ... ok -flds_2 ... ok -fldl_1 ... ok -fldl_2 ... ok -fld_1 ... ok -fld_2 ... ok -fld_3 ... ok -fld1_1 ... ok -fldl2t_1 ... ok -fldl2e_1 ... ok -fldpi_1 ... ok -fldlg2_1 ... ok -fldln2_1 ... ok -fldz_1 ... ok -fmuls_1 ... ok -fmuls_2 ... ok -fmuls_3 ... ok -fmuls_4 ... ok -fmull_1 ... ok -fmull_2 ... ok -fmull_3 ... ok -fmull_4 ... ok -fmul_1 ... ok -fmul_2 ... ok -fmul_3 ... ok -fmul_4 ... ok -fmul_5 ... ok -fmul_6 ... ok -fmul_7 ... ok -fmul_8 ... ok -fmul_9 ... ok -fmul_10 ... ok -fmul_11 ... ok -fmul_12 ... ok -fmul_13 ... ok -fmul_14 ... ok -fmul_15 ... ok -fmul_16 ... ok -fmulp_1 ... ok -fmulp_2 ... ok -fmulp_3 ... ok -fmulp_4 ... ok -fmulp_5 ... ok -fmulp_6 ... ok -fmulp_7 ... ok -fmulp_8 ... ok -fmulp_9 ... ok -fmulp_10 ... ok -fmulp_11 ... ok -fmulp_12 ... ok -fmulp_13 ... ok -fmulp_14 ... ok -fmulp_15 ... ok -fmulp_16 ... ok -fimuls_1 ... ok -fimuls_2 ... ok -fimuls_3 ... ok -fimuls_4 ... ok -fimuls_5 ... ok -fimuls_6 ... ok -fimuls_7 ... ok -fimuls_8 ... ok -fimull_1 ... ok -fimull_2 ... ok -fimull_3 ... ok -fimull_4 ... ok -fimull_5 ... ok -fimull_6 ... ok -fimull_7 ... ok -fimull_8 ... ok -frndint_1 ... ok -frndint_2 ... ok -frndint_3 ... ok -frndint_4 ... ok -frndint_5 ... ok -frndint_6 ... ok -frndint_7 ... ok -frndint_8 ... ok -frndint_9 ... ok -frndint_10 ... ok -frndint_11 ... ok -frndint_12 ... ok -frndint_13 ... ok -frndint_14 ... ok -frndint_15 ... ok -frndint_16 ... ok -fsubs_1 ... ok -fsubs_2 ... ok -fsubs_3 ... ok -fsubs_4 ... ok -fsubl_1 ... ok -fsubl_2 ... ok -fsubl_3 ... ok -fsubl_4 ... ok -fsub_1 ... ok -fsub_2 ... ok -fsub_3 ... ok -fsub_4 ... ok -fsub_5 ... ok -fsub_6 ... ok -fsub_7 ... ok -fsub_8 ... ok -fsub_9 ... ok -fsub_10 ... ok -fsub_11 ... ok -fsub_12 ... ok -fsub_13 ... ok -fsub_14 ... ok -fsub_15 ... ok -fsub_16 ... ok -fsubp_1 ... ok -fsubp_2 ... ok -fsubp_3 ... ok -fsubp_4 ... ok -fsubp_5 ... ok -fsubp_6 ... ok -fsubp_7 ... ok -fsubp_8 ... ok -fsubp_9 ... ok -fsubp_10 ... ok -fsubp_11 ... ok -fsubp_12 ... ok -fsubp_13 ... ok -fsubp_14 ... ok -fsubp_15 ... ok -fsubp_16 ... ok -fisubs_1 ... ok -fisubs_2 ... ok -fisubs_3 ... ok -fisubs_4 ... ok -fisubs_5 ... ok -fisubs_6 ... ok -fisubs_7 ... ok -fisubs_8 ... ok -fisubl_1 ... ok -fisubl_2 ... ok -fisubl_3 ... ok -fisubl_4 ... ok -fisubl_5 ... ok -fisubl_6 ... ok -fisubl_7 ... ok -fisubl_8 ... ok -fsubrs_1 ... ok -fsubrs_2 ... ok -fsubrs_3 ... ok -fsubrs_4 ... ok -fsubrl_1 ... ok -fsubrl_2 ... ok -fsubrl_3 ... ok -fsubrl_4 ... ok -fsubr_1 ... ok -fsubr_2 ... ok -fsubr_3 ... ok -fsubr_4 ... ok -fsubr_5 ... ok -fsubr_6 ... ok -fsubr_7 ... ok -fsubr_8 ... ok -fsubr_9 ... ok -fsubr_10 ... ok -fsubr_11 ... ok -fsubr_12 ... ok -fsubr_13 ... ok -fsubr_14 ... ok -fsubr_15 ... ok -fsubr_16 ... ok -fsubrp_1 ... ok -fsubrp_2 ... ok -fsubrp_3 ... ok -fsubrp_4 ... ok -fsubrp_5 ... ok -fsubrp_6 ... ok -fsubrp_7 ... ok -fsubrp_8 ... ok -fsubrp_9 ... ok -fsubrp_10 ... ok -fsubrp_11 ... ok -fsubrp_12 ... ok -fsubrp_13 ... ok -fsubrp_14 ... ok -fsubrp_15 ... ok -fsubrp_16 ... ok -fisubrs_1 ... ok -fisubrs_2 ... ok -fisubrs_3 ... ok -fisubrs_4 ... ok -fisubrs_5 ... ok -fisubrs_6 ... ok -fisubrs_7 ... ok -fisubrs_8 ... ok -fisubrl_1 ... ok -fisubrl_2 ... ok -fisubrl_3 ... ok -fisubrl_4 ... ok -fisubrl_5 ... ok -fisubrl_6 ... ok -fisubrl_7 ... ok -fisubrl_8 ... ok -fxch_1 ... ok -fxch_2 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_fpu.vgtest b/VEX/head20041019/addrcheck/tests/insn_fpu.vgtest deleted file mode 100644 index 1b9546f54..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_fpu.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_fpu -cpu_test: fpu diff --git a/VEX/head20041019/addrcheck/tests/insn_mmx.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_mmx.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_mmx.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_mmx.stdout.exp deleted file mode 100644 index 95cbae160..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_mmx.stdout.exp +++ /dev/null @@ -1,103 +0,0 @@ -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movq_1 ... ok -movq_2 ... ok -movq_3 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -por_1 ... ok -por_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_mmx.vgtest b/VEX/head20041019/addrcheck/tests/insn_mmx.vgtest deleted file mode 100644 index ddbb97726..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_mmx.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmx -cpu_test: mmx diff --git a/VEX/head20041019/addrcheck/tests/insn_mmxext.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_mmxext.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_mmxext.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_mmxext.stdout.exp deleted file mode 100644 index 23b2e55ab..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_mmxext.stdout.exp +++ /dev/null @@ -1,29 +0,0 @@ -movntq_1 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -sfence_1 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_mmxext.vgtest b/VEX/head20041019/addrcheck/tests/insn_mmxext.vgtest deleted file mode 100644 index bb667097f..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_mmxext.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmxext -cpu_test: mmxext diff --git a/VEX/head20041019/addrcheck/tests/insn_sse.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_sse.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_sse.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_sse.stdout.exp deleted file mode 100644 index f15bd81f0..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_sse.stdout.exp +++ /dev/null @@ -1,142 +0,0 @@ -addps_1 ... ok -addps_2 ... ok -addss_1 ... ok -addss_2 ... ok -andnps_1 ... ok -andnps_2 ... ok -andps_1 ... ok -andps_2 ... ok -cmpeqps_1 ... ok -cmpeqps_2 ... ok -cmpeqss_1 ... ok -cmpeqss_2 ... ok -cmpleps_1 ... ok -cmpleps_2 ... ok -cmpless_1 ... ok -cmpless_2 ... ok -cmpltps_1 ... ok -cmpltps_2 ... ok -cmpltss_1 ... ok -cmpltss_2 ... ok -cmpneqps_1 ... ok -cmpneqps_2 ... ok -cmpneqss_1 ... ok -cmpneqss_2 ... ok -cmpnleps_1 ... ok -cmpnleps_2 ... ok -cmpnless_1 ... ok -cmpnless_2 ... ok -cmpnltps_1 ... ok -cmpnltps_2 ... ok -cmpnltss_1 ... ok -cmpnltss_2 ... ok -comiss_1 ... ok -comiss_2 ... ok -comiss_3 ... ok -comiss_4 ... ok -comiss_5 ... ok -comiss_6 ... ok -cvtpi2ps_1 ... ok -cvtpi2ps_2 ... ok -cvtps2pi_1 ... ok -cvtps2pi_2 ... ok -cvtsi2ss_1 ... ok -cvtsi2ss_2 ... ok -cvtss2si_1 ... ok -cvtss2si_2 ... ok -cvttps2pi_1 ... ok -cvttps2pi_2 ... ok -cvttss2si_1 ... ok -cvttss2si_2 ... ok -divps_1 ... ok -divps_2 ... ok -divss_1 ... ok -divss_2 ... ok -maxps_1 ... ok -maxps_2 ... ok -maxss_1 ... ok -maxss_2 ... ok -minps_1 ... ok -minps_2 ... ok -minss_1 ... ok -minss_2 ... ok -movaps_1 ... ok -movaps_2 ... ok -movhlps_1 ... ok -movhps_1 ... ok -movhps_2 ... ok -movlhps_1 ... ok -movlps_1 ... ok -movlps_2 ... ok -movmskps_1 ... ok -movntps_1 ... ok -movntq_1 ... ok -movss_1 ... ok -movss_2 ... ok -movss_3 ... ok -movups_1 ... ok -movups_2 ... ok -mulps_1 ... ok -mulps_2 ... ok -mulss_1 ... ok -mulss_2 ... ok -orps_1 ... ok -orps_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -rcpps_1 ... ok -rcpps_2 ... ok -rcpss_1 ... ok -rcpss_2 ... ok -rsqrtps_1 ... ok -rsqrtps_2 ... ok -rsqrtss_1 ... ok -rsqrtss_2 ... ok -sfence_1 ... ok -shufps_1 ... ok -shufps_2 ... ok -sqrtps_1 ... ok -sqrtps_2 ... ok -sqrtss_1 ... ok -sqrtss_2 ... ok -subps_1 ... ok -subps_2 ... ok -subss_1 ... ok -subss_2 ... ok -ucomiss_1 ... ok -ucomiss_2 ... ok -ucomiss_3 ... ok -ucomiss_4 ... ok -ucomiss_5 ... ok -ucomiss_6 ... ok -unpckhps_1 ... ok -unpckhps_2 ... ok -unpcklps_1 ... ok -unpcklps_2 ... ok -xorps_1 ... ok -xorps_2 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_sse.vgtest b/VEX/head20041019/addrcheck/tests/insn_sse.vgtest deleted file mode 100644 index 167c8e290..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_sse.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse -cpu_test: sse diff --git a/VEX/head20041019/addrcheck/tests/insn_sse2.stderr.exp b/VEX/head20041019/addrcheck/tests/insn_sse2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/addrcheck/tests/insn_sse2.stdout.exp b/VEX/head20041019/addrcheck/tests/insn_sse2.stdout.exp deleted file mode 100644 index 9c24f7262..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_sse2.stdout.exp +++ /dev/null @@ -1,294 +0,0 @@ -addpd_1 ... ok -addpd_2 ... ok -addsd_1 ... ok -addsd_2 ... ok -andpd_1 ... ok -andpd_2 ... ok -andnpd_1 ... ok -andnpd_2 ... ok -cmpeqpd_1 ... ok -cmpeqpd_2 ... ok -cmpltpd_1 ... ok -cmpltpd_2 ... ok -cmplepd_1 ... ok -cmplepd_2 ... ok -cmpneqpd_1 ... ok -cmpneqpd_2 ... ok -cmpnltpd_1 ... ok -cmpnltpd_2 ... ok -cmpnlepd_1 ... ok -cmpnlepd_2 ... ok -cmpeqsd_1 ... ok -cmpeqsd_2 ... ok -cmpltsd_1 ... ok -cmpltsd_2 ... ok -cmplesd_1 ... ok -cmplesd_2 ... ok -cmpneqsd_1 ... ok -cmpneqsd_2 ... ok -cmpnltsd_1 ... ok -cmpnltsd_2 ... ok -cmpnlesd_1 ... ok -cmpnlesd_2 ... ok -comisd_1 ... ok -comisd_2 ... ok -comisd_3 ... ok -comisd_4 ... ok -comisd_5 ... ok -comisd_6 ... ok -cvtdq2pd_1 ... ok -cvtdq2pd_2 ... ok -cvtdq2ps_1 ... ok -cvtdq2ps_2 ... ok -cvtpd2dq_1 ... ok -cvtpd2dq_2 ... ok -cvtpd2pi_1 ... ok -cvtpd2pi_2 ... ok -cvtpd2ps_1 ... ok -cvtpd2ps_2 ... ok -cvtpi2pd_1 ... ok -cvtpi2pd_2 ... ok -cvtps2dq_1 ... ok -cvtps2dq_2 ... ok -cvtps2pd_1 ... ok -cvtps2pd_2 ... ok -cvtsd2si_1 ... ok -cvtsd2si_2 ... ok -cvtsd2ss_1 ... ok -cvtsd2ss_2 ... ok -cvtsi2sd_1 ... ok -cvtsi2sd_2 ... ok -cvtss2sd_1 ... ok -cvtss2sd_2 ... ok -cvttpd2pi_1 ... ok -cvttpd2pi_2 ... ok -cvttpd2dq_1 ... ok -cvttpd2dq_2 ... ok -cvttps2dq_1 ... ok -cvttps2dq_2 ... ok -cvttsd2si_1 ... ok -cvttsd2si_2 ... ok -divpd_1 ... ok -divpd_2 ... ok -divsd_1 ... ok -divsd_2 ... ok -lfence_1 ... ok -maxpd_1 ... ok -maxpd_2 ... ok -maxsd_1 ... ok -maxsd_2 ... ok -mfence_1 ... ok -minpd_1 ... ok -minpd_2 ... ok -minsd_1 ... ok -minsd_2 ... ok -movapd_1 ... ok -movapd_2 ... ok -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movdqa_1 ... ok -movdqa_2 ... ok -movdqa_3 ... ok -movdqu_1 ... ok -movdqu_2 ... ok -movdqu_3 ... ok -movdq2q_1 ... ok -movhpd_1 ... ok -movhpd_2 ... ok -movlpd_1 ... ok -movlpd_2 ... ok -movmskpd_1 ... ok -movntdq_1 ... ok -movnti_1 ... ok -movntpd_1 ... ok -movq2dq_1 ... ok -movsd_1 ... ok -movsd_2 ... ok -movsd_3 ... ok -movupd_1 ... ok -movupd_2 ... ok -mulpd_1 ... ok -mulpd_2 ... ok -mulsd_1 ... ok -mulsd_2 ... ok -orpd_1 ... ok -orpd_2 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddq_1 ... ok -paddq_2 ... ok -paddq_3 ... ok -paddq_4 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pextrw_5 ... ok -pextrw_6 ... ok -pextrw_7 ... ok -pextrw_8 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pinsrw_5 ... ok -pinsrw_6 ... ok -pinsrw_7 ... ok -pinsrw_8 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -pmuludq_1 ... ok -pmuludq_2 ... ok -pmuludq_3 ... ok -pmuludq_4 ... ok -por_1 ... ok -por_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufd_1 ... ok -pshufd_2 ... ok -pshufhw_1 ... ok -pshufhw_2 ... ok -pshuflw_1 ... ok -pshuflw_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -pslldq_1 ... ok -pslldq_2 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrldq_1 ... ok -psrldq_2 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubq_1 ... ok -psubq_2 ... ok -psubq_3 ... ok -psubq_4 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhqdq_1 ... ok -punpckhqdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklqdq_1 ... ok -punpcklqdq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok -shufpd_1 ... ok -shufpd_2 ... ok -sqrtpd_1 ... ok -sqrtpd_2 ... ok -sqrtsd_1 ... ok -sqrtsd_2 ... ok -subpd_1 ... ok -subpd_2 ... ok -subsd_1 ... ok -subsd_2 ... ok -ucomisd_1 ... ok -ucomisd_2 ... ok -ucomisd_3 ... ok -ucomisd_4 ... ok -ucomisd_5 ... ok -ucomisd_6 ... ok -unpckhpd_1 ... ok -unpckhpd_2 ... ok -unpcklpd_1 ... ok -unpcklpd_2 ... ok -xorpd_1 ... ok -xorpd_2 ... ok diff --git a/VEX/head20041019/addrcheck/tests/insn_sse2.vgtest b/VEX/head20041019/addrcheck/tests/insn_sse2.vgtest deleted file mode 100644 index 42e82f38d..000000000 --- a/VEX/head20041019/addrcheck/tests/insn_sse2.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse2 -cpu_test: sse2 diff --git a/VEX/head20041019/addrcheck/tests/overlap.stderr.exp b/VEX/head20041019/addrcheck/tests/overlap.stderr.exp deleted file mode 100644 index 6fcbcd1ca..000000000 --- a/VEX/head20041019/addrcheck/tests/overlap.stderr.exp +++ /dev/null @@ -1,27 +0,0 @@ -Source and destination overlap in memcpy(0x........, 0x........, 21) - at 0x........: memcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:40) - -Source and destination overlap in memcpy(0x........, 0x........, 21) - at 0x........: memcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:42) - -Source and destination overlap in strncpy(0x........, 0x........, 21) - at 0x........: strncpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:45) - -Source and destination overlap in strncpy(0x........, 0x........, 21) - at 0x........: strncpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:47) - -Source and destination overlap in strcpy(0x........, 0x........) - at 0x........: strcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:54) - -Source and destination overlap in strncat(0x........, 0x........, 21) - at 0x........: strncat (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:112) - -Source and destination overlap in strncat(0x........, 0x........, 21) - at 0x........: strncat (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:113) diff --git a/VEX/head20041019/addrcheck/tests/overlap.stdout.exp b/VEX/head20041019/addrcheck/tests/overlap.stdout.exp deleted file mode 100644 index 12cb02e54..000000000 --- a/VEX/head20041019/addrcheck/tests/overlap.stdout.exp +++ /dev/null @@ -1,11 +0,0 @@ -`_________________________________________________' -`abcdefghijklmnopqrstuvwxyz' -`abcdefghijklmnopqrstuvwxy________________________' -`abcdefghijklmnopqrstuvwxyz_______________________' -`abcdefghijklmnopqrstuvwxyz' - -`ABCDEFG' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' -`ABCDEFGabcdefghijklmnopqrstuvwxy' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' diff --git a/VEX/head20041019/addrcheck/tests/overlap.vgtest b/VEX/head20041019/addrcheck/tests/overlap.vgtest deleted file mode 100644 index da96655ba..000000000 --- a/VEX/head20041019/addrcheck/tests/overlap.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: ../../memcheck/tests/overlap diff --git a/VEX/head20041019/addrcheck/tests/toobig-allocs.stderr.exp b/VEX/head20041019/addrcheck/tests/toobig-allocs.stderr.exp deleted file mode 100644 index a5ba60a36..000000000 --- a/VEX/head20041019/addrcheck/tests/toobig-allocs.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ - -Attempting too-big malloc()... -Attempting too-big mmap()... - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 1 allocs, 0 frees, 2145386496 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/addrcheck/tests/toobig-allocs.vgtest b/VEX/head20041019/addrcheck/tests/toobig-allocs.vgtest deleted file mode 100644 index 186cf5f90..000000000 --- a/VEX/head20041019/addrcheck/tests/toobig-allocs.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: ../../tests/toobig-allocs diff --git a/VEX/head20041019/autogen.sh b/VEX/head20041019/autogen.sh deleted file mode 100755 index 117462c7f..000000000 --- a/VEX/head20041019/autogen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -run () -{ - echo "running: $*" - eval $* - - if test $? != 0 ; then - echo "error: while running '$*'" - exit 1 - fi -} - -run aclocal -run autoheader -run automake -a -run autoconf diff --git a/VEX/head20041019/auxprogs/.cvsignore b/VEX/head20041019/auxprogs/.cvsignore deleted file mode 100644 index 786212505..000000000 --- a/VEX/head20041019/auxprogs/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile.in -Makefile -valgrind-listener diff --git a/VEX/head20041019/auxprogs/CVS/Entries b/VEX/head20041019/auxprogs/CVS/Entries deleted file mode 100644 index 0f34eaefb..000000000 --- a/VEX/head20041019/auxprogs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Tue Feb 25 01:48:11 2003// -/Makefile.am/1.9/Wed Sep 1 23:20:46 2004// -/valgrind-listener.c/1.13/Wed Sep 1 23:58:13 2004// -D diff --git a/VEX/head20041019/auxprogs/CVS/Repository b/VEX/head20041019/auxprogs/CVS/Repository deleted file mode 100644 index 9f5d9c1b0..000000000 --- a/VEX/head20041019/auxprogs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/auxprogs diff --git a/VEX/head20041019/auxprogs/CVS/Root b/VEX/head20041019/auxprogs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/auxprogs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/auxprogs/CVS/Template b/VEX/head20041019/auxprogs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/auxprogs/Makefile.am b/VEX/head20041019/auxprogs/Makefile.am deleted file mode 100644 index 1e31292ca..000000000 --- a/VEX/head20041019/auxprogs/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include $(top_srcdir)/Makefile.all.am -include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am - -AM_CFLAGS = $(WERROR) -Winline -Wall -O -g - -bin_PROGRAMS = valgrind-listener - -valgrind_listener_SOURCES = valgrind-listener.c - diff --git a/VEX/head20041019/auxprogs/valgrind-listener.c b/VEX/head20041019/auxprogs/valgrind-listener.c deleted file mode 100644 index 1ab139cfe..000000000 --- a/VEX/head20041019/auxprogs/valgrind-listener.c +++ /dev/null @@ -1,400 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A simple program to listen for valgrind logfile data. ---*/ -/*--- valgrind-listener.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - - -/*---------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* For VG_CLO_DEFAULT_LOGPORT and VG_BUGS_TO. */ -#include "core.h" - - -/*---------------------------------------------------------------*/ - -/* The maximum allowable number concurrent connections. */ -#define M_CONNECTIONS 50 - - -/*---------------------------------------------------------------*/ - -__attribute__ ((noreturn)) -static void panic ( Char* str ) -{ - fprintf(stderr, - "\nvalgrind-listener: the " - "`impossible' happened:\n %s\n", str); - fprintf(stderr, - "Please report this bug at: %s\n\n", VG_BUGS_TO); - exit(1); -} - -__attribute__ ((noreturn)) -static void my_assert_fail ( const Char* expr, const Char* file, Int line, const Char* fn ) -{ - fprintf(stderr, - "\nvalgrind-listener: %s:%d (%s): Assertion `%s' failed.\n", - file, line, fn, expr ); - fprintf(stderr, - "Please report this bug at: %s\n\n", VG_BUGS_TO); - exit(1); -} - -#undef assert -#undef VG__STRING - -#define VG__STRING(__str) #__str -#define assert(expr) \ - ((void) ((expr) ? 0 : \ - (my_assert_fail (VG__STRING(expr), \ - __FILE__, __LINE__, \ - __PRETTY_FUNCTION__), 0))) - - -/*---------------------------------------------------------------*/ - -/* holds the fds for connections; zero if slot not in use. */ -int conn_count = 0; -int conn_fd[M_CONNECTIONS]; -struct pollfd conn_pollfd[M_CONNECTIONS]; - - -void set_nonblocking ( int sd ) -{ - int res; - res = fcntl(sd, F_GETFL); - res = fcntl(sd, F_SETFL, res | O_NONBLOCK); - if (res != 0) { - perror("fcntl failed"); - panic("set_nonblocking"); - } -} - -void set_blocking ( int sd ) -{ - int res; - res = fcntl(sd, F_GETFL); - res = fcntl(sd, F_SETFL, res & ~O_NONBLOCK); - if (res != 0) { - perror("fcntl failed"); - panic("set_blocking"); - } -} - - -void copyout ( char* buf, int nbuf ) -{ - int i; - for (i = 0; i < nbuf; i++) { - if (buf[i] == '\n') { - fprintf(stdout, "\n(%d) ", conn_count); - } else { - fwrite(&buf[i], 1, 1, stdout); - } - } - fflush(stdout); -} - -int read_from_sd ( int sd ) -{ - char buf[100]; - int n; - - set_blocking(sd); - n = read(sd, buf, 99); - if (n <= 0) return 0; /* closed */ - copyout(buf, n); - - set_nonblocking(sd); - while (1) { - n = read(sd, buf, 100); - if (n <= 0) return 1; /* not closed */ - copyout(buf, n); - } -} - - -void snooze ( void ) -{ - struct timespec req; - req.tv_sec = 0; - req.tv_nsec = 200 * 1000 * 1000; - nanosleep(&req,NULL); -} - - -/* returns 0 if invalid, else port # */ -int atoi_portno ( char* str ) -{ - int n = 0; - while (1) { - if (*str == 0) - break; - if (*str < '0' || *str > '9') - return 0; - n = 10*n + (int)(*str - '0'); - str++; - if (n >= 65536) - return 0; - } - if (n < 1024) - return 0; - return n; -} - - -void usage ( void ) -{ - fprintf(stderr, - "\n" - "usage is:\n" - "\n" - " valgrind-listener [--exit-at-zero|-e] [port-number]\n" - "\n" - " where --exit-at-zero or -e causes the listener to exit\n" - " when the number of connections falls back to zero\n" - " (the default is to keep listening forever)\n" - "\n" - " port-number is the default port on which to listen for\n" - " connections. It must be between 1024 and 65535.\n" - " Current default is %d.\n" - "\n" - , - VG_CLO_DEFAULT_LOGPORT - ); - exit(1); -} - - -void banner ( char* str ) -{ - time_t t; - t = time(NULL); - printf("valgrind-listener %s at %s", str, ctime(&t)); - fflush(stdout); -} - - -void exit_routine ( void ) -{ - banner("exited"); - exit(0); -} - - -void sigint_handler ( int signo ) -{ - exit_routine(); -} - - -int main (int argc, char** argv) -{ - int i, j, k, res, one; - int main_sd, new_sd, client_len; - struct sockaddr_in client_addr, server_addr; - - char /*bool*/ exit_when_zero = 0; - int port = VG_CLO_DEFAULT_LOGPORT; - - for (i = 1; i < argc; i++) { - if (0==strcmp(argv[i], "--exit-at-zero") - || 0==strcmp(argv[i], "-e")) { - exit_when_zero = 1; - } - else - if (atoi_portno(argv[i]) > 0) { - port = atoi_portno(argv[i]); - } - else - usage(); - } - - banner("started"); - signal(SIGINT, sigint_handler); - - conn_count = 0; - for (i = 0; i < M_CONNECTIONS; i++) - conn_fd[i] = 0; - - /* create socket */ - main_sd = socket(AF_INET, SOCK_STREAM, 0); - if (main_sd < 0) { - perror("cannot open socket "); - panic("main -- create socket"); - } - - /* allow address reuse to avoid "address already in use" errors */ - - one = 1; - if (setsockopt(main_sd, SOL_SOCKET, SO_REUSEADDR, - &one, sizeof(int)) < 0) { - perror("cannot enable address reuse "); - panic("main -- enable address reuse"); - } - - /* bind server port */ - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - server_addr.sin_port = htons(port); - - if (bind(main_sd, (struct sockaddr *) &server_addr, - sizeof(server_addr) ) < 0) { - perror("cannot bind port "); - panic("main -- bind port"); - } - - res = listen(main_sd,M_CONNECTIONS); - if (res != 0) { - perror("listen failed "); - panic("main -- listen"); - } - - while (1) { - - snooze(); - - /* enquire, using poll, whether there is any activity available on - the main socket descriptor. If so, someone is trying to - connect; get the fd and add it to our table thereof. */ - { struct pollfd ufd; - while (1) { - ufd.fd = main_sd; - ufd.events = POLLIN; - ufd.revents = 0; - res = poll(&ufd, 1, 0); - if (res == 0) break; - - /* ok, we have someone waiting to connect. Get the sd. */ - client_len = sizeof(client_addr); - new_sd = accept(main_sd, (struct sockaddr *) &client_addr, - &client_len); - if (new_sd < 0) { - perror("cannot accept connection "); - panic("main -- accept connection"); - } - - /* find a place to put it. */ - assert(new_sd > 0); - for (i = 0; i < M_CONNECTIONS; i++) - if (conn_fd[i] == 0) - break; - - if (i >= M_CONNECTIONS) { - fprintf(stderr, "Too many concurrent connections. " - "Increase M_CONNECTIONS and recompile.\n"); - panic("main -- too many concurrent connections"); - } - - conn_fd[i] = new_sd; - conn_count++; - printf("\n(%d) -------------------- CONNECT " - "--------------------\n(%d)\n(%d) ", - conn_count, conn_count, conn_count); - fflush(stdout); - } /* while (1) */ - } - - /* We've processed all new connect requests. Listen for changes - to the current set of fds. */ - j = 0; - for (i = 0; i < M_CONNECTIONS; i++) { - if (conn_fd[i] == 0) - continue; - conn_pollfd[j].fd = conn_fd[i]; - conn_pollfd[j].events = POLLIN /* | POLLHUP | POLLNVAL */; - conn_pollfd[j].revents = 0; - j++; - } - - res = poll(conn_pollfd, j, 0 /* return immediately. */ ); - if (res < 0) { - perror("poll(main) failed"); - panic("poll(main) failed"); - } - - /* nothing happened. go round again. */ - if (res == 0) { - continue; - } - - /* inspect the fds. */ - for (i = 0; i < j; i++) { - - if (conn_pollfd[i].revents & POLLIN) { - /* data is available on this fd */ - res = read_from_sd(conn_pollfd[i].fd); - - if (res == 0) { - /* the connection has been closed. */ - close(conn_pollfd[i].fd); - /* this fd has been closed or otherwise gone bad; forget - about it. */ - for (k = 0; k < M_CONNECTIONS; k++) - if (conn_fd[k] == conn_pollfd[i].fd) - break; - assert(k < M_CONNECTIONS); - conn_fd[k] = 0; - conn_count--; - printf("\n(%d) ------------------- DISCONNECT " - "-------------------\n(%d)\n(%d) ", - conn_count, conn_count, conn_count); - fflush(stdout); - if (conn_count == 0 && exit_when_zero) { - printf("\n"); - fflush(stdout); - exit_routine(); - } - } - } - - } /* for (i = 0; i < j; i++) */ - - } /* while (1) */ - - /* NOTREACHED */ -} - - -/*--------------------------------------------------------------------*/ -/*--- end valgrind-listener.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/cachegrind/.cvsignore b/VEX/head20041019/cachegrind/.cvsignore deleted file mode 100644 index bc25b8a88..000000000 --- a/VEX/head20041019/cachegrind/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile.in -Makefile -cg_annotate diff --git a/VEX/head20041019/cachegrind/CVS/Entries b/VEX/head20041019/cachegrind/CVS/Entries deleted file mode 100644 index 0a0fb430b..000000000 --- a/VEX/head20041019/cachegrind/CVS/Entries +++ /dev/null @@ -1,9 +0,0 @@ -/.cvsignore/1.2/Mon Sep 23 11:37:05 2002// -/Makefile.am/1.48/Sat Sep 11 18:27:43 2004// -/cg_annotate.in/1.20/Tue Jul 6 21:54:20 2004// -/cg_arch.h/1.1/Sat Sep 11 16:45:25 2004// -/cg_main.c/1.81/Wed Oct 6 13:50:12 2004// -/cg_sim.c/1.1/Sun Jan 4 16:56:57 2004// -D/docs//// -D/tests//// -D/x86//// diff --git a/VEX/head20041019/cachegrind/CVS/Repository b/VEX/head20041019/cachegrind/CVS/Repository deleted file mode 100644 index 2c241ce6c..000000000 --- a/VEX/head20041019/cachegrind/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/cachegrind diff --git a/VEX/head20041019/cachegrind/CVS/Root b/VEX/head20041019/cachegrind/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/cachegrind/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/cachegrind/CVS/Template b/VEX/head20041019/cachegrind/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/Makefile.am b/VEX/head20041019/cachegrind/Makefile.am deleted file mode 100644 index 9d658d54e..000000000 --- a/VEX/head20041019/cachegrind/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -##include $(top_srcdir)/Makefile.tool.am -include $(top_srcdir)/Makefile.all.am -include $(top_srcdir)/Makefile.tool-flags.am -include $(top_srcdir)/Makefile.tool-inplace.am - -SUBDIRS = $(VG_ARCH) . tests docs - -AM_CPPFLAGS += -I$(top_srcdir)/cachegrind/$(VG_ARCH) - -bin_SCRIPTS = cg_annotate - -EXTRA_DIST = cg_sim.c - -noinst_HEADERS = cg_arch.h - -val_PROGRAMS = vgskin_cachegrind.so - -vgskin_cachegrind_so_SOURCES = cg_main.c -vgskin_cachegrind_so_LDFLAGS = -shared -vgskin_cachegrind_so_LDADD = ${VG_ARCH}/libcgarch.a - diff --git a/VEX/head20041019/cachegrind/cg_annotate.in b/VEX/head20041019/cachegrind/cg_annotate.in deleted file mode 100644 index 17d19eea6..000000000 --- a/VEX/head20041019/cachegrind/cg_annotate.in +++ /dev/null @@ -1,891 +0,0 @@ -#! @PERL@ -w - -##--------------------------------------------------------------------## -##--- The cache simulation framework: instrumentation, recording ---## -##--- and results printing. ---## -##--- cg_annotate.in ---## -##--------------------------------------------------------------------## - -# This file is part of Cachegrind, a Valgrind tool for cache -# profiling programs. -# -# Copyright (C) 2002-2004 Nicholas Nethercote -# njn25@cam.ac.uk -# -# 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. -# -# The GNU General Public License is contained in the file COPYING. - -#---------------------------------------------------------------------------- -# Annotator for cachegrind. -# -# File format is described in /docs/techdocs.html. -# -# Performance improvements record, using cachegrind.out for cacheprof, doing no -# source annotation (irrelevant ones removed): -# user time -# 1. turned off warnings in add_hash_a_to_b() 3.81 --> 3.48s -# [now add_array_a_to_b()] -# 6. make line_to_CC() return a ref instead of a hash 3.01 --> 2.77s -# -#10. changed file format to avoid file/fn name repetition 2.40s -# (not sure why higher; maybe due to new '.' entries?) -#11. changed file format to drop unnecessary end-line "."s 2.36s -# (shrunk file by about 37%) -#12. switched from hash CCs to array CCs 1.61s -#13. only adding b[i] to a[i] if b[i] defined (was doing it if -# either a[i] or b[i] was defined, but if b[i] was undefined -# it just added 0) 1.48s -#14. Stopped converting "." entries to undef and then back 1.16s -#15. Using foreach $i (x..y) instead of for ($i = 0...) in -# add_array_a_to_b() 1.11s -# -# Auto-annotating primes: -#16. Finding count lengths by int((length-1)/3), not by -# commifying (halves the number of commify calls) 1.68s --> 1.47s - -use strict; - -#---------------------------------------------------------------------------- -# Overview: the running example in the comments is for: -# - events = A,B,C,D -# - --show=C,A,D -# - --sort=D,C -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Global variables, main data structures -#---------------------------------------------------------------------------- -# CCs are arrays, the counts corresponding to @events, with 'undef' -# representing '.'. This makes things fast (faster than using hashes for CCs) -# but we have to use @sort_order and @show_order below to handle the --sort and -# --show options, which is a bit tricky. -#---------------------------------------------------------------------------- - -# Total counts for summary (an array reference). -my $summary_CC; - -# Totals for each function, for overall summary. -# hash(filename:fn_name => CC array) -my %fn_totals; - -# Individual CCs, organised by filename and line_num for easy annotation. -# hash(filename => hash(line_num => CC array)) -my %all_ind_CCs; - -# Files chosen for annotation on the command line. -# key = basename (trimmed of any directory), value = full filename -my %user_ann_files; - -# Generic description string. -my $desc = ""; - -# Command line of profiled program. -my $cmd; - -# Events in input file, eg. (A,B,C,D) -my @events; - -# Events to show, from command line, eg. (C,A,D) -my @show_events; - -# Map from @show_events indices to @events indices, eg. (2,0,3). Gives the -# order in which we must traverse @events in order to show the @show_events, -# eg. (@events[$show_order[1]], @events[$show_order[2]]...) = @show_events. -# (Might help to think of it like a hash (0 => 2, 1 => 0, 2 => 3).) -my @show_order; - -# Print out the function totals sorted by these events, eg. (D,C). -my @sort_events; - -# Map from @sort_events indices to @events indices, eg. (3,2). Same idea as -# for @show_order. -my @sort_order; - -# Thresholds, one for each sort event (or default to 1 if no sort events -# specified). We print out functions and do auto-annotations until we've -# handled this proportion of all the events thresholded. -my @thresholds; - -my $default_threshold = 99; - -my $single_threshold = $default_threshold; - -# If on, automatically annotates all files that are involved in getting over -# all the threshold counts. -my $auto_annotate = 0; - -# Number of lines to show around each annotated line. -my $context = 8; - -# Directories in which to look for annotation files. -my @include_dirs = (""); - -# Input file name -my $input_file = undef; - -# Version number -my $version = "@VERSION@"; - -# Usage message. -my $usage = < [source-files] - - options for the user, with defaults in [ ], are: - -h --help show this message - -v --version show version - --show=A,B,C only show figures for events A,B,C [all] - --sort=A,B,C sort columns by events A,B,C [event column order] - --threshold=<0--100> percentage of counts (of primary sort event) we - are interested in [$default_threshold%] - --auto=yes|no annotate all source files containing functions - that helped reach the event count threshold [no] - --context=N print N lines of context before and after - annotated lines [8] - -I --include=

add to list of directories to search for - source files - - Cachegrind is Copyright (C) 2002-2004 Nicholas Nethercote. - Both are licensed under the GNU General Public License, version 2. - Bug reports, feedback, admiration, abuse, etc, to: njn25\@cam.ac.uk. - -END -; - -# Used in various places of output. -my $fancy = '-' x 80 . "\n"; - -#----------------------------------------------------------------------------- -# Argument and option handling -#----------------------------------------------------------------------------- -sub process_cmd_line() -{ - for my $arg (@ARGV) { - - # Option handling - if ($arg =~ /^-/) { - - # --version - if ($arg =~ /^-v$|^--version$/) { - die("cg_annotate-$version\n"); - - # --show=A,B,C - } elsif ($arg =~ /^--show=(.*)$/) { - @show_events = split(/,/, $1); - - # --sort=A,B,C - } elsif ($arg =~ /^--sort=(.*)$/) { - @sort_events = split(/,/, $1); - foreach my $i (0 .. scalar @sort_events - 1) { - if ($sort_events[$i] =~#/.*:(\d+)$/) { - /.*:([\d\.]+)%?$/) { - my $th = $1; - ($th >= 0 && $th <= 100) or die($usage); - $sort_events[$i] =~ s/:.*//; - $thresholds[$i] = $th; - } else { - $thresholds[$i] = 0; - } - } - - # --threshold=X (tolerates a trailing '%') - } elsif ($arg =~ /^--threshold=([\d\.]+)%?$/) { - $single_threshold = $1; - ($1 >= 0 && $1 <= 100) or die($usage); - - # --auto=yes|no - } elsif ($arg =~ /^--auto=(yes|no)$/) { - $auto_annotate = 1 if ($1 eq "yes"); - $auto_annotate = 0 if ($1 eq "no"); - - # --context=N - } elsif ($arg =~ /^--context=([\d\.]+)$/) { - $context = $1; - if ($context < 0) { - die($usage); - } - - # --include=A,B,C - } elsif ($arg =~ /^(-I|--include)=(.*)$/) { - my $inc = $2; - $inc =~ s|/$||; # trim trailing '/' - push(@include_dirs, "$inc/"); - - } elsif ($arg =~ /^--(\d+)$/) { - my $pid = $1; - if (not defined $input_file) { - $input_file = "cachegrind.out.$pid"; - } else { - die("One cachegrind.out. file at a time, please\n"); - } - - } else { # -h and --help fall under this case - die($usage); - } - - # Argument handling -- annotation file checking and selection. - # Stick filenames into a hash for quick 'n easy lookup throughout. - } else { - my $readable = 0; - foreach my $include_dir (@include_dirs) { - if (-r $include_dir . $arg) { - $readable = 1; - } - } - $readable or die("File $arg not found in any of: @include_dirs\n"); - $user_ann_files{$arg} = 1; - } - } - - # Must have chosen an input file - if (not defined $input_file) { - die($usage); - } -} - -#----------------------------------------------------------------------------- -# Reading of input file -#----------------------------------------------------------------------------- -sub max ($$) -{ - my ($x, $y) = @_; - return ($x > $y ? $x : $y); -} - -# Add the two arrays; any '.' entries are ignored. Two tricky things: -# 1. If $a2->[$i] is undefined, it defaults to 0 which is what we want; we turn -# off warnings to allow this. This makes things about 10% faster than -# checking for definedness ourselves. -# 2. We don't add an undefined count or a ".", even though it's value is 0, -# because we don't want to make an $a2->[$i] that is undef become 0 -# unnecessarily. -sub add_array_a_to_b ($$) -{ - my ($a1, $a2) = @_; - - my $n = max(scalar @$a1, scalar @$a2); - $^W = 0; - foreach my $i (0 .. $n-1) { - $a2->[$i] += $a1->[$i] if (defined $a1->[$i] && "." ne $a1->[$i]); - } - $^W = 1; -} - -# Add each event count to the CC array. '.' counts become undef, as do -# missing entries (implicitly). -sub line_to_CC ($) -{ - my @CC = (split /\s+/, $_[0]); - (@CC <= @events) or die("Line $.: too many event counts\n"); - return \@CC; -} - -sub read_input_file() -{ - open(INPUTFILE, "< $input_file") || die "File $input_file not opened\n"; - - # Read "desc:" lines. - my $line; - while ($line = ) { - if ($line =~ s/desc:\s+//) { - $desc .= $line; - } else { - last; - } - } - - # Read "cmd:" line (Nb: will already be in $line from "desc:" loop above). - ($line =~ s/cmd:\s+//) or die("Line $.: missing command line\n"); - $cmd = $line; - chomp($cmd); # Remove newline - - # Read "events:" line. We make a temporary hash in which the Nth event's - # value is N, which is useful for handling --show/--sort options below. - $line = ; - (defined $line && $line =~ s/events:\s+//) - or die("Line $.: missing events line\n"); - @events = split(/\s+/, $line); - my %events; - my $n = 0; - foreach my $event (@events) { - $events{$event} = $n; - $n++ - } - - # If no --show arg give, default to showing all events in the file. - # If --show option is used, check all specified events appeared in the - # "events:" line. Then initialise @show_order. - if (@show_events) { - foreach my $show_event (@show_events) { - (defined $events{$show_event}) or - die("--show event `$show_event' did not appear in input\n"); - } - } else { - @show_events = @events; - } - foreach my $show_event (@show_events) { - push(@show_order, $events{$show_event}); - } - - # Do as for --show, but if no --sort arg given, default to sorting by - # column order (ie. first column event is primary sort key, 2nd column is - # 2ndary key, etc). - if (@sort_events) { - foreach my $sort_event (@sort_events) { - (defined $events{$sort_event}) or - die("--sort event `$sort_event' did not appear in input\n"); - } - } else { - @sort_events = @events; - } - foreach my $sort_event (@sort_events) { - push(@sort_order, $events{$sort_event}); - } - - # If multiple threshold args weren't given via --sort, stick in the single - # threshold (either from --threshold if used, or the default otherwise) for - # the primary sort event, and 0% for the rest. - if (not @thresholds) { - foreach my $e (@sort_order) { - push(@thresholds, 0); - } - $thresholds[0] = $single_threshold; - } - - my $curr_file; - my $curr_fn; - my $curr_name; - - my $curr_fn_CC = []; - my $curr_file_ind_CCs = {}; # hash(line_num => CC) - - # Read body of input file. - while () { - s/#.*$//; # remove comments - if (s/^(\d+)\s+//) { - my $line_num = $1; - my $CC = line_to_CC($_); - add_array_a_to_b($CC, $curr_fn_CC); - - # If curr_file is selected, add CC to curr_file list. We look for - # full filename matches; or, if auto-annotating, we have to - # remember everything -- we won't know until the end what's needed. - if ($auto_annotate || defined $user_ann_files{$curr_file}) { - my $tmp = $curr_file_ind_CCs->{$line_num}; - $tmp = [] unless defined $tmp; - add_array_a_to_b($CC, $tmp); - $curr_file_ind_CCs->{$line_num} = $tmp; - } - - } elsif (s/^fn=(.*)$//) { - # Commit result from previous function - $fn_totals{$curr_name} = $curr_fn_CC if (defined $curr_name); - - # Setup new one - $curr_fn = $1; - $curr_name = "$curr_file:$curr_fn"; - $curr_fn_CC = $fn_totals{$curr_name}; - $curr_fn_CC = [] unless (defined $curr_fn_CC); - - } elsif (s/^fl=(.*)$//) { - $all_ind_CCs{$curr_file} = $curr_file_ind_CCs - if (defined $curr_file); - - $curr_file = $1; - $curr_file_ind_CCs = $all_ind_CCs{$curr_file}; - $curr_file_ind_CCs = {} unless (defined $curr_file_ind_CCs); - - } elsif (s/^\s*$//) { - # blank, do nothing - - } elsif (s/^summary:\s+//) { - # Finish up handling final filename/fn_name counts - $fn_totals{"$curr_file:$curr_fn"} = $curr_fn_CC - if (defined $curr_file && defined $curr_fn); - $all_ind_CCs{$curr_file} = - $curr_file_ind_CCs if (defined $curr_file); - - $summary_CC = line_to_CC($_); - (scalar(@$summary_CC) == @events) - or die("Line $.: summary event and total event mismatch\n"); - - } else { - warn("WARNING: line $. malformed, ignoring\n"); - } - } - - # Check if summary line was present - if (not defined $summary_CC) { - die("missing final summary line, aborting\n"); - } - - close(INPUTFILE); -} - -#----------------------------------------------------------------------------- -# Print options used -#----------------------------------------------------------------------------- -sub print_options () -{ - print($fancy); - print($desc); - print("Command: $cmd\n"); - print("Events recorded: @events\n"); - print("Events shown: @show_events\n"); - print("Event sort order: @sort_events\n"); - print("Thresholds: @thresholds\n"); - - my @include_dirs2 = @include_dirs; # copy @include_dirs - shift(@include_dirs2); # remove "" entry, which is always the first - unshift(@include_dirs2, "") if (0 == @include_dirs2); - my $include_dir = shift(@include_dirs2); - print("Include dirs: $include_dir\n"); - foreach my $include_dir (@include_dirs2) { - print(" $include_dir\n"); - } - - my @user_ann_files = keys %user_ann_files; - unshift(@user_ann_files, "") if (0 == @user_ann_files); - my $user_ann_file = shift(@user_ann_files); - print("User annotated: $user_ann_file\n"); - foreach $user_ann_file (@user_ann_files) { - print(" $user_ann_file\n"); - } - - my $is_on = ($auto_annotate ? "on" : "off"); - print("Auto-annotation: $is_on\n"); - print("\n"); -} - -#----------------------------------------------------------------------------- -# Print summary and sorted function totals -#----------------------------------------------------------------------------- -sub mycmp ($$) -{ - my ($c, $d) = @_; - - # Iterate through sort events (eg. 3,2); return result if two are different - foreach my $i (@sort_order) { - my ($x, $y); - $x = $c->[$i]; - $y = $d->[$i]; - $x = -1 unless defined $x; - $y = -1 unless defined $y; - - my $cmp = $y <=> $x; # reverse sort - if (0 != $cmp) { - return $cmp; - } - } - # Exhausted events, equal - return 0; -} - -sub commify ($) { - my ($val) = @_; - 1 while ($val =~ s/^(\d+)(\d{3})/$1,$2/); - return $val; -} - -# Because the counts can get very big, and we don't want to waste screen space -# and make lines too long, we compute exactly how wide each column needs to be -# by finding the widest entry for each one. -sub compute_CC_col_widths (@) -{ - my @CCs = @_; - my $CC_col_widths = []; - - # Initialise with minimum widths (from event names) - foreach my $event (@events) { - push(@$CC_col_widths, length($event)); - } - - # Find maximum width count for each column. @CC_col_width positions - # correspond to @CC positions. - foreach my $CC (@CCs) { - foreach my $i (0 .. scalar(@$CC)-1) { - if (defined $CC->[$i]) { - # Find length, accounting for commas that will be added - my $length = length $CC->[$i]; - my $clength = $length + int(($length - 1) / 3); - $CC_col_widths->[$i] = max($CC_col_widths->[$i], $clength); - } - } - } - return $CC_col_widths; -} - -# Print the CC with each column's size dictated by $CC_col_widths. -sub print_CC ($$) -{ - my ($CC, $CC_col_widths) = @_; - - foreach my $i (@show_order) { - my $count = (defined $CC->[$i] ? commify($CC->[$i]) : "."); - my $space = ' ' x ($CC_col_widths->[$i] - length($count)); - print("$space$count "); - } -} - -sub print_events ($) -{ - my ($CC_col_widths) = @_; - - foreach my $i (@show_order) { - my $event = $events[$i]; - my $event_width = length($event); - my $col_width = $CC_col_widths->[$i]; - my $space = ' ' x ($col_width - $event_width); - print("$space$event "); - } -} - -# Prints summary and function totals (with separate column widths, so that -# function names aren't pushed over unnecessarily by huge summary figures). -# Also returns a hash containing all the files that are involved in getting the -# events count above the thresholds (ie. all the interesting ones). -sub print_summary_and_fn_totals () -{ - my @fn_fullnames = keys %fn_totals; - - # Work out the size of each column for printing (summary and functions - # separately). - my $summary_CC_col_widths = compute_CC_col_widths($summary_CC); - my $fn_CC_col_widths = compute_CC_col_widths(values %fn_totals); - - # Header and counts for summary - print($fancy); - print_events($summary_CC_col_widths); - print("\n"); - print($fancy); - print_CC($summary_CC, $summary_CC_col_widths); - print(" PROGRAM TOTALS\n"); - print("\n"); - - # Header for functions - print($fancy); - print_events($fn_CC_col_widths); - print(" file:function\n"); - print($fancy); - - # Sort function names into order dictated by --sort option. - @fn_fullnames = sort { - mycmp($fn_totals{$a}, $fn_totals{$b}) - } @fn_fullnames; - - - # Assertion - (scalar @sort_order == scalar @thresholds) or - die("sort_order length != thresholds length:\n", - " @sort_order\n @thresholds\n"); - - my $threshold_files = {}; - # @curr_totals has the same shape as @sort_order and @thresholds - my @curr_totals = (); - foreach my $e (@thresholds) { - push(@curr_totals, 0); - } - - # Print functions, stopping when the threshold has been reached. - foreach my $fn_name (@fn_fullnames) { - - # Stop when we've reached all the thresholds - my $reached_all_thresholds = 1; - foreach my $i (0 .. scalar @thresholds - 1) { - my $prop = $curr_totals[$i] * 100 / $summary_CC->[$sort_order[$i]]; - $reached_all_thresholds &&= ($prop >= $thresholds[$i]); - } - last if $reached_all_thresholds; - - # Print function results - my $fn_CC = $fn_totals{$fn_name}; - print_CC($fn_CC, $fn_CC_col_widths); - print(" $fn_name\n"); - - # Update the threshold counts - my $filename = $fn_name; - $filename =~ s/:.+$//; # remove function name - $threshold_files->{$filename} = 1; - foreach my $i (0 .. scalar @sort_order - 1) { - $curr_totals[$i] += $fn_CC->[$sort_order[$i]] - if (defined $fn_CC->[$sort_order[$i]]); - } - } - print("\n"); - - return $threshold_files; -} - -#----------------------------------------------------------------------------- -# Annotate selected files -#----------------------------------------------------------------------------- - -# Issue a warning that the source file is more recent than the input file. -sub warning_on_src_more_recent_than_inputfile ($) -{ - my $src_file = $_[0]; - - my $warning = <{"???"}; - %all_ann_files = (%user_ann_files, %$threshold_files) - } else { - %all_ann_files = %user_ann_files; - } - - # Track if we did any annotations. - my $did_annotations = 0; - - LOOP: - foreach my $src_file (keys %all_ann_files) { - - my $opened_file = ""; - my $full_file_name = ""; - foreach my $include_dir (@include_dirs) { - my $try_name = $include_dir . $src_file; - if (open(INPUTFILE, "< $try_name")) { - $opened_file = $try_name; - $full_file_name = ($include_dir eq "" - ? $src_file - : "$include_dir + $src_file"); - last; - } - } - - if (not $opened_file) { - # Failed to open the file. If chosen on the command line, die. - # If arose from auto-annotation, print a little message. - if (defined $user_ann_files{$src_file}) { - die("File $src_file not opened in any of: @include_dirs\n"); - - } else { - push(@unfound_auto_annotate_files, $src_file); - } - - } else { - # File header (distinguish between user- and auto-selected files). - print("$fancy"); - my $ann_type = - (defined $user_ann_files{$src_file} ? "User" : "Auto"); - print("-- $ann_type-annotated source: $full_file_name\n"); - print("$fancy"); - - # Get file's CCs - my $src_file_CCs = $all_ind_CCs{$src_file}; - if (!defined $src_file_CCs) { - print(" No information has been collected for $src_file\n\n"); - next LOOP; - } - - $did_annotations = 1; - - # Numeric, not lexicographic sort! - my @line_nums = sort {$a <=> $b} keys %$src_file_CCs; - - # If $src_file more recent than cachegrind.out, issue warning - my $src_more_recent_than_inputfile = 0; - if ((stat $opened_file)[9] > (stat $input_file)[9]) { - $src_more_recent_than_inputfile = 1; - warning_on_src_more_recent_than_inputfile($src_file); - } - - # Work out the size of each column for printing - my $CC_col_widths = compute_CC_col_widths(values %$src_file_CCs); - - # Events header - print_events($CC_col_widths); - print("\n\n"); - - # Shift out 0 if it's in the line numbers (from unknown entries, - # likely due to bugs in Valgrind's stabs debug info reader) - shift(@line_nums) if (0 == $line_nums[0]); - - # Finds interesting line ranges -- all lines with a CC, and all - # lines within $context lines of a line with a CC. - my $n = @line_nums; - my @pairs; - for (my $i = 0; $i < $n; $i++) { - push(@pairs, $line_nums[$i] - $context); # lower marker - while ($i < $n-1 && - $line_nums[$i] + 2*$context >= $line_nums[$i+1]) { - $i++; - } - push(@pairs, $line_nums[$i] + $context); # upper marker - } - - # Annotate chosen lines, tracking total counts of lines printed - $pairs[0] = 1 if ($pairs[0] < 1); - while (@pairs) { - my $low = shift @pairs; - my $high = shift @pairs; - while ($. < $low-1) { - my $tmp = ; - last unless (defined $tmp); # hack to detect EOF - } - my $src_line; - # Print line number, unless start of file - print("-- line $low " . '-' x 40 . "\n") if ($low != 1); - while (($. < $high) && ($src_line = )) { - if (defined $line_nums[0] && $. == $line_nums[0]) { - print_CC($src_file_CCs->{$.}, $CC_col_widths); - add_array_a_to_b($src_file_CCs->{$.}, - $printed_totals_CC); - shift(@line_nums); - - } else { - print_CC( [], $CC_col_widths); - } - - print(" $src_line"); - } - # Print line number, unless EOF - if ($src_line) { - print("-- line $high " . '-' x 40 . "\n"); - } else { - last; - } - } - - # If there was info on lines past the end of the file... - if (@line_nums) { - foreach my $line_num (@line_nums) { - print_CC($src_file_CCs->{$line_num}, $CC_col_widths); - print(" \n"); - } - print("\n"); - warning_on_nonexistent_lines($src_more_recent_than_inputfile, - $src_file, \@line_nums); - } - print("\n"); - - # Print summary of counts attributed to file but not to any - # particular line (due to incomplete debug info). - if ($src_file_CCs->{0}) { - print_CC($src_file_CCs->{0}, $CC_col_widths); - print(" \n\n"); - } - - close(INPUTFILE); - } - } - - # Print list of unfound auto-annotate selected files. - if (@unfound_auto_annotate_files) { - print("$fancy"); - print("The following files chosen for auto-annotation could not be found:\n"); - print($fancy); - foreach my $f (@unfound_auto_annotate_files) { - print(" $f\n"); - } - print("\n"); - } - - # If we did any annotating, print what proportion of events were covered by - # annotated lines above. - if ($did_annotations) { - my $percent_printed_CC; - foreach (my $i = 0; $i < @$summary_CC; $i++) { - $percent_printed_CC->[$i] = - sprintf("%.0f", - $printed_totals_CC->[$i] / $summary_CC->[$i] * 100); - } - my $pp_CC_col_widths = compute_CC_col_widths($percent_printed_CC); - print($fancy); - print_events($pp_CC_col_widths); - print("\n"); - print($fancy); - print_CC($percent_printed_CC, $pp_CC_col_widths); - print(" percentage of events annotated\n\n"); - } -} - -#---------------------------------------------------------------------------- -# "main()" -#---------------------------------------------------------------------------- -process_cmd_line(); -read_input_file(); -print_options(); -my $threshold_files = print_summary_and_fn_totals(); -annotate_ann_files($threshold_files); - -##--------------------------------------------------------------------## -##--- end cg_annotate.in ---## -##--------------------------------------------------------------------## - - diff --git a/VEX/head20041019/cachegrind/cg_arch.h b/VEX/head20041019/cachegrind/cg_arch.h deleted file mode 100644 index 71ed2bd84..000000000 --- a/VEX/head20041019/cachegrind/cg_arch.h +++ /dev/null @@ -1,49 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Arch-specific declarations. cg_arch.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Cachegrind, a Valgrind tool for cache - profiling programs. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __CG_ARCH_H -#define __CG_ARCH_H - -// For cache simulation -typedef struct { - int size; // bytes - int assoc; - int line_size; // bytes -} cache_t; - -void VGA_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c, - cache_t* I1_dflt, cache_t* D1_dflt, cache_t* L2_dflt, - Bool all_caches_clo_defined); - -#endif // __CG_ARCH_H - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/cachegrind/cg_main.c b/VEX/head20041019/cachegrind/cg_main.c deleted file mode 100644 index 67be6bb09..000000000 --- a/VEX/head20041019/cachegrind/cg_main.c +++ /dev/null @@ -1,1163 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Cachegrind: every but the simulation itself. ---*/ -/*--- cg_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Cachegrind, a Valgrind tool for cache - profiling programs. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" -//#include "vg_profile.c" - -#include "cg_arch.h" -#include "cg_sim.c" - -/*------------------------------------------------------------*/ -/*--- Constants ---*/ -/*------------------------------------------------------------*/ - -#define MIN_LINE_SIZE 16 -#define FILE_LEN 256 -#define FN_LEN 256 - -/*------------------------------------------------------------*/ -/*--- Profiling events ---*/ -/*------------------------------------------------------------*/ - -typedef - enum { - VgpGetLineCC = VgpFini+1, - VgpCacheSimulate, - VgpCacheResults - } - VgpToolCC; - -/*------------------------------------------------------------*/ -/*--- Types and Data Structures ---*/ -/*------------------------------------------------------------*/ - -typedef struct _CC CC; -struct _CC { - ULong a; - ULong m1; - ULong m2; -}; - -//------------------------------------------------------------ -// Primary data structure #1: CC table -// - Holds the per-source-line hit/miss stats, grouped by file/function/line. -// - hash(file, hash(fn, hash(line+CC))) -// - Each hash table is separately chained. -// - The array sizes below work fairly well for Konqueror. -// - Lookups done by instr_addr, which is converted immediately to a source -// location. -// - Traversed for dumping stats at end in file/func/line hierarchy. - -#define N_FILE_ENTRIES 251 -#define N_FN_ENTRIES 53 -#define N_LINE_ENTRIES 37 - -typedef struct _lineCC lineCC; -struct _lineCC { - Int line; - CC Ir; - CC Dr; - CC Dw; - lineCC* next; -}; - -typedef struct _fnCC fnCC; -struct _fnCC { - Char* fn; - fnCC* next; - lineCC* lines[N_LINE_ENTRIES]; -}; - -typedef struct _fileCC fileCC; -struct _fileCC { - Char* file; - fileCC* next; - fnCC* fns[N_FN_ENTRIES]; -}; - -// Top level of CC table. Auto-zeroed. -static fileCC *CC_table[N_FILE_ENTRIES]; - -//------------------------------------------------------------ -// Primary data structre #2: Instr-info table -// - Holds the cached info about each instr that is used for simulation. -// - table(BB_start_addr, list(instr_info)) -// - For each BB, each instr_info in the list holds info about the -// instruction (instr_size, instr_addr, etc), plus a pointer to its line -// CC. This node is what's passed to the simulation function. -// - When BBs are discarded the relevant list(instr_details) is freed. - -typedef struct _instr_info instr_info; -struct _instr_info { - Addr instr_addr; - UChar instr_size; - UChar data_size; - lineCC* parent; // parent line-CC -}; - -typedef struct _BB_info BB_info; -struct _BB_info { - BB_info* next; // next field - Addr BB_addr; // key - Int n_instrs; - instr_info instrs[0]; -}; - -VgHashTable instr_info_table; // hash(Addr, BB_info) - -//------------------------------------------------------------ -// Stats -static Int distinct_files = 0; -static Int distinct_fns = 0; -static Int distinct_lines = 0; -static Int distinct_instrs = 0; - -static Int full_debug_BBs = 0; -static Int file_line_debug_BBs = 0; -static Int fn_debug_BBs = 0; -static Int no_debug_BBs = 0; - -static Int BB_retranslations = 0; - -/*------------------------------------------------------------*/ -/*--- CC table operations ---*/ -/*------------------------------------------------------------*/ - -static void get_debug_info(Addr instr_addr, Char file[FILE_LEN], - Char fn[FN_LEN], Int* line) -{ - Bool found_file_line = VG_(get_filename_linenum)(instr_addr, file, - FILE_LEN, line); - Bool found_fn = VG_(get_fnname)(instr_addr, fn, FN_LEN); - - if (!found_file_line) { - VG_(strcpy)(file, "???"); - *line = 0; - } - if (!found_fn) { - VG_(strcpy)(fn, "???"); - } - if (found_file_line) { - if (found_fn) full_debug_BBs++; - else file_line_debug_BBs++; - } else { - if (found_fn) fn_debug_BBs++; - else no_debug_BBs++; - } -} - -static UInt hash(Char *s, UInt table_size) -{ - const int hash_constant = 256; - int hash_value = 0; - for ( ; *s; s++) - hash_value = (hash_constant * hash_value + *s) % table_size; - return hash_value; -} - -static __inline__ -fileCC* new_fileCC(Char filename[], fileCC* next) -{ - // Using calloc() zeroes the fns[] array - fileCC* cc = VG_(calloc)(1, sizeof(fileCC)); - cc->file = VG_(strdup)(filename); - cc->next = next; - return cc; -} - -static __inline__ -fnCC* new_fnCC(Char fn[], fnCC* next) -{ - // Using calloc() zeroes the lines[] array - fnCC* cc = VG_(calloc)(1, sizeof(fnCC)); - cc->fn = VG_(strdup)(fn); - cc->next = next; - return cc; -} - -static __inline__ -lineCC* new_lineCC(Int line, lineCC* next) -{ - // Using calloc() zeroes the Ir/Dr/Dw CCs and the instrs[] array - lineCC* cc = VG_(calloc)(1, sizeof(lineCC)); - cc->line = line; - cc->next = next; - return cc; -} - -static __inline__ -instr_info* new_instr_info(Addr instr_addr, lineCC* parent, instr_info* next) -{ - // Using calloc() zeroes instr_size and data_size - instr_info* ii = VG_(calloc)(1, sizeof(instr_info)); - ii->instr_addr = instr_addr; - ii->parent = parent; - return ii; -} - -// Do a three step traversal: by file, then fn, then line. -// In all cases prepends new nodes to their chain. Returns a pointer to the -// line node, creates a new one if necessary. -static lineCC* get_lineCC(Addr orig_addr) -{ - fileCC *curr_fileCC; - fnCC *curr_fnCC; - lineCC *curr_lineCC; - Char file[FILE_LEN], fn[FN_LEN]; - Int line; - UInt file_hash, fn_hash, line_hash; - - get_debug_info(orig_addr, file, fn, &line); - - VGP_PUSHCC(VgpGetLineCC); - - // level 1 - file_hash = hash(file, N_FILE_ENTRIES); - curr_fileCC = CC_table[file_hash]; - while (NULL != curr_fileCC && !VG_STREQ(file, curr_fileCC->file)) { - curr_fileCC = curr_fileCC->next; - } - if (NULL == curr_fileCC) { - CC_table[file_hash] = curr_fileCC = - new_fileCC(file, CC_table[file_hash]); - distinct_files++; - } - - // level 2 - fn_hash = hash(fn, N_FN_ENTRIES); - curr_fnCC = curr_fileCC->fns[fn_hash]; - while (NULL != curr_fnCC && !VG_STREQ(fn, curr_fnCC->fn)) { - curr_fnCC = curr_fnCC->next; - } - if (NULL == curr_fnCC) { - curr_fileCC->fns[fn_hash] = curr_fnCC = - new_fnCC(fn, curr_fileCC->fns[fn_hash]); - distinct_fns++; - } - - // level 3 - line_hash = line % N_LINE_ENTRIES; - curr_lineCC = curr_fnCC->lines[line_hash]; - while (NULL != curr_lineCC && line != curr_lineCC->line) { - curr_lineCC = curr_lineCC->next; - } - if (NULL == curr_lineCC) { - curr_fnCC->lines[line_hash] = curr_lineCC = - new_lineCC(line, curr_fnCC->lines[line_hash]); - distinct_lines++; - } - - VGP_POPCC(VgpGetLineCC); - return curr_lineCC; -} - -/*------------------------------------------------------------*/ -/*--- Cache simulation functions ---*/ -/*------------------------------------------------------------*/ - -static REGPARM(1) -void log_1I_0D_cache_access(instr_info* n) -{ - //VG_(printf)("1I_0D: CCaddr=0x%x, iaddr=0x%x, isize=%u\n", - // n, n->instr_addr, n->instr_size) - VGP_PUSHCC(VgpCacheSimulate); - cachesim_I1_doref(n->instr_addr, n->instr_size, - &n->parent->Ir.m1, &n->parent->Ir.m2); - n->parent->Ir.a++; - VGP_POPCC(VgpCacheSimulate); -} - -static REGPARM(2) -void log_1I_1Dr_cache_access(instr_info* n, Addr data_addr) -{ - //VG_(printf)("1I_1Dr: CCaddr=%p, iaddr=%p, isize=%u, daddr=%p, dsize=%u\n", - // n, n->instr_addr, n->instr_size, data_addr, n->data_size) - VGP_PUSHCC(VgpCacheSimulate); - cachesim_I1_doref(n->instr_addr, n->instr_size, - &n->parent->Ir.m1, &n->parent->Ir.m2); - n->parent->Ir.a++; - - cachesim_D1_doref(data_addr, n->data_size, - &n->parent->Dr.m1, &n->parent->Dr.m2); - n->parent->Dr.a++; - VGP_POPCC(VgpCacheSimulate); -} - -static REGPARM(2) -void log_1I_1Dw_cache_access(instr_info* n, Addr data_addr) -{ - //VG_(printf)("1I_1Dw: CCaddr=%p, iaddr=%p, isize=%u, daddr=%p, dsize=%u\n", - // n, n->instr_addr, n->instr_size, data_addr, n->data_size) - VGP_PUSHCC(VgpCacheSimulate); - cachesim_I1_doref(n->instr_addr, n->instr_size, - &n->parent->Ir.m1, &n->parent->Ir.m2); - n->parent->Ir.a++; - - cachesim_D1_doref(data_addr, n->data_size, - &n->parent->Dw.m1, &n->parent->Dw.m2); - n->parent->Dw.a++; - VGP_POPCC(VgpCacheSimulate); -} - -static REGPARM(3) -void log_1I_2D_cache_access(instr_info* n, Addr data_addr1, Addr data_addr2) -{ - //VG_(printf)("1I_2D: CCaddr=%p, iaddr=%p, isize=%u, daddr1=%p, daddr2=%p, dsize=%u\n", - // n, n->instr_addr, n->instr_size, data_addr1, data_addr2, n->data_size) - VGP_PUSHCC(VgpCacheSimulate); - cachesim_I1_doref(n->instr_addr, n->instr_size, - &n->parent->Ir.m1, &n->parent->Ir.m2); - n->parent->Ir.a++; - - cachesim_D1_doref(data_addr1, n->data_size, - &n->parent->Dr.m1, &n->parent->Dr.m2); - n->parent->Dr.a++; - cachesim_D1_doref(data_addr2, n->data_size, - &n->parent->Dw.m1, &n->parent->Dw.m2); - n->parent->Dw.a++; - VGP_POPCC(VgpCacheSimulate); -} - -/*------------------------------------------------------------*/ -/*--- Instrumentation ---*/ -/*------------------------------------------------------------*/ - -static -BB_info* get_BB_info(UCodeBlock* cb_in, Addr orig_addr, Bool* bb_seen_before) -{ - Int i, n_instrs; - UInstr* u_in; - BB_info* bb_info; - VgHashNode** dummy; - - // Count number of x86 instrs in BB - n_instrs = 1; // start at 1 because last x86 instr has no INCEIP - for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) { - u_in = VG_(get_instr)(cb_in, i); - if (INCEIP == u_in->opcode) n_instrs++; - } - - // Get the BB_info - bb_info = (BB_info*)VG_(HT_get_node)(instr_info_table, orig_addr, &dummy); - *bb_seen_before = ( NULL == bb_info ? False : True ); - if (*bb_seen_before) { - // BB must have been translated before, but flushed from the TT - sk_assert(bb_info->n_instrs == n_instrs ); - BB_retranslations++; - } else { - // BB never translated before (at this address, at least; could have - // been unloaded and then reloaded elsewhere in memory) - bb_info = - VG_(calloc)(1, sizeof(BB_info) + n_instrs*sizeof(instr_info)); - bb_info->BB_addr = orig_addr; - bb_info->n_instrs = n_instrs; - VG_(HT_add_node)( instr_info_table, (VgHashNode*)bb_info ); - distinct_instrs++; - } - return bb_info; -} - -static -void do_details( instr_info* n, Bool bb_seen_before, - Addr instr_addr, Int instr_size, Int data_size ) -{ - lineCC* parent = get_lineCC(instr_addr); - if (bb_seen_before) { - sk_assert( n->instr_addr == instr_addr ); - sk_assert( n->instr_size == instr_size ); - sk_assert( n->data_size == data_size ); - // Don't assert that (n->parent == parent)... it's conceivable that - // the debug info might change; the other asserts should be enough to - // detect anything strange. - } else { - n->instr_addr = instr_addr; - n->instr_size = instr_size; - n->data_size = data_size; - n->parent = parent; - } -} - -static Bool is_valid_data_size(Int data_size) -{ - return (4 == data_size || 2 == data_size || 1 == data_size || - 8 == data_size || 10 == data_size || MIN_LINE_SIZE == data_size); -} - -// Instrumentation for the end of each x86 instruction. -static -void end_of_x86_instr(UCodeBlock* cb, instr_info* i_node, Bool bb_seen_before, - UInt instr_addr, UInt instr_size, UInt data_size, - Int t_read, Int t_read_addr, - Int t_write, Int t_write_addr) -{ - Addr helper; - Int argc; - Int t_CC_addr, - t_data_addr1 = INVALID_TEMPREG, - t_data_addr2 = INVALID_TEMPREG; - - sk_assert(instr_size >= MIN_INSTR_SIZE && - instr_size <= MAX_INSTR_SIZE); - -#define IS_(X) (INVALID_TEMPREG != t_##X##_addr) -#define INV(qqt) (INVALID_TEMPREG == (qqt)) - - // Work out what kind of x86 instruction it is - if (!IS_(read) && !IS_(write)) { - sk_assert( 0 == data_size ); - sk_assert(INV(t_read) && INV(t_write)); - helper = (Addr) & log_1I_0D_cache_access; - argc = 1; - - } else if (IS_(read) && !IS_(write)) { - sk_assert( is_valid_data_size(data_size) ); - sk_assert(!INV(t_read) && INV(t_write)); - helper = (Addr) & log_1I_1Dr_cache_access; - argc = 2; - t_data_addr1 = t_read_addr; - - } else if (!IS_(read) && IS_(write)) { - sk_assert( is_valid_data_size(data_size) ); - sk_assert(INV(t_read) && !INV(t_write)); - helper = (Addr) & log_1I_1Dw_cache_access; - argc = 2; - t_data_addr1 = t_write_addr; - - } else { - sk_assert(IS_(read) && IS_(write)); - sk_assert( is_valid_data_size(data_size) ); - sk_assert(!INV(t_read) && !INV(t_write)); - if (t_read == t_write) { - helper = (Addr) & log_1I_1Dr_cache_access; - argc = 2; - t_data_addr1 = t_read_addr; - } else { - helper = (Addr) & log_1I_2D_cache_access; - argc = 3; - t_data_addr1 = t_read_addr; - t_data_addr2 = t_write_addr; - } - } -#undef IS_ -#undef INV - - // Setup 1st arg: CC addr - do_details( i_node, bb_seen_before, instr_addr, instr_size, data_size ); - t_CC_addr = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_CC_addr); - uLiteral(cb, (Addr)i_node); - - // Call the helper - if (1 == argc) - uInstr1(cb, CCALL, 0, TempReg, t_CC_addr); - else if (2 == argc) - uInstr2(cb, CCALL, 0, TempReg, t_CC_addr, - TempReg, t_data_addr1); - else if (3 == argc) - uInstr3(cb, CCALL, 0, TempReg, t_CC_addr, - TempReg, t_data_addr1, - TempReg, t_data_addr2); - else - VG_(skin_panic)("argc... not 1 or 2 or 3?"); - - uCCall(cb, helper, argc, argc, False); -} - -UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr) -{ - UCodeBlock* cb; - UInstr* u_in; - Int i, bb_info_i; - BB_info* bb_info; - Bool bb_seen_before = False; - Int t_read_addr, t_write_addr, t_read, t_write; - Addr x86_instr_addr = orig_addr; - UInt x86_instr_size, data_size = 0; - Bool instrumented_Jcc = False; - - bb_info = get_BB_info(cb_in, orig_addr, &bb_seen_before); - bb_info_i = 0; - - cb = VG_(setup_UCodeBlock)(cb_in); - - t_read_addr = t_write_addr = t_read = t_write = INVALID_TEMPREG; - - for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) { - u_in = VG_(get_instr)(cb_in, i); - - // We want to instrument each x86 instruction with a call to the - // appropriate simulation function, which depends on whether the - // instruction does memory data reads/writes. x86 instructions can - // end in three ways, and this is how they are instrumented: - // - // 1. UCode, INCEIP --> UCode, Instrumentation, INCEIP - // 2. UCode, JMP --> UCode, Instrumentation, JMP - // 3. UCode, Jcc, JMP --> UCode, Instrumentation, Jcc, JMP - // - // The last UInstr in a BB is always a JMP. Jccs, when they appear, - // are always second last. This is checked with assertions. - // Instrumentation must go before any jumps. (JIFZ is the exception; - // if a JIFZ succeeds, no simulation is done for the instruction.) - // - // x86 instruction sizes are obtained from INCEIPs (for case 1) or - // from .extra4b field of the final JMP (for case 2 & 3). - - if (instrumented_Jcc) sk_assert(u_in->opcode == JMP); - - switch (u_in->opcode) { - - // For memory-ref instrs, copy the data_addr into a temporary to be - // passed to the cachesim_* helper at the end of the instruction. - case LOAD: - case SSE3ag_MemRd_RegWr: - t_read = u_in->val1; - t_read_addr = newTemp(cb); - uInstr2(cb, MOV, 4, TempReg, u_in->val1, TempReg, t_read_addr); - data_size = u_in->size; - VG_(copy_UInstr)(cb, u_in); - break; - - case FPU_R: - case MMX2_MemRd: - t_read = u_in->val2; - t_read_addr = newTemp(cb); - uInstr2(cb, MOV, 4, TempReg, u_in->val2, TempReg, t_read_addr); - data_size = u_in->size; - VG_(copy_UInstr)(cb, u_in); - break; - break; - - case MMX2a1_MemRd: - case SSE2a_MemRd: - case SSE2a1_MemRd: - case SSE3a_MemRd: - case SSE3a1_MemRd: - t_read = u_in->val3; - t_read_addr = newTemp(cb); - uInstr2(cb, MOV, 4, TempReg, u_in->val3, TempReg, t_read_addr); - data_size = u_in->size; - VG_(copy_UInstr)(cb, u_in); - break; - - // Note that we must set t_write_addr even for mod instructions; - // That's how the code above determines whether it does a write. - // Without it, it would think a mod instruction is a read. - // As for the MOV, if it's a mod instruction it's redundant, but it's - // not expensive and mod instructions are rare anyway. */ - case STORE: - case FPU_W: - case MMX2_MemWr: - t_write = u_in->val2; - t_write_addr = newTemp(cb); - uInstr2(cb, MOV, 4, TempReg, u_in->val2, TempReg, t_write_addr); - data_size = u_in->size; - VG_(copy_UInstr)(cb, u_in); - break; - - case SSE2a_MemWr: - case SSE3a_MemWr: - t_write = u_in->val3; - t_write_addr = newTemp(cb); - uInstr2(cb, MOV, 4, TempReg, u_in->val3, TempReg, t_write_addr); - data_size = u_in->size; - VG_(copy_UInstr)(cb, u_in); - break; - - // INCEIP: insert instrumentation - case INCEIP: - x86_instr_size = u_in->val1; - goto instrument_x86_instr; - - // JMP: insert instrumentation if the first JMP - case JMP: - if (instrumented_Jcc) { - sk_assert(CondAlways == u_in->cond); - sk_assert(i+1 == VG_(get_num_instrs)(cb_in)); - VG_(copy_UInstr)(cb, u_in); - instrumented_Jcc = False; // rest - break; - } else { - // The first JMP... instrument. - if (CondAlways != u_in->cond) { - sk_assert(i+2 == VG_(get_num_instrs)(cb_in)); - instrumented_Jcc = True; - } else { - sk_assert(i+1 == VG_(get_num_instrs)(cb_in)); - } - // Get x86 instr size from final JMP. - x86_instr_size = VG_(get_last_instr)(cb_in)->extra4b; - goto instrument_x86_instr; - } - - // Code executed at the end of each x86 instruction. - instrument_x86_instr: - // Large (eg. 28B, 108B, 512B) data-sized instructions will be - // done inaccurately but they're very rare and this avoids - // errors from hitting more than two cache lines in the - // simulation. - if (data_size > MIN_LINE_SIZE) data_size = MIN_LINE_SIZE; - - end_of_x86_instr(cb, &bb_info->instrs[ bb_info_i ], bb_seen_before, - x86_instr_addr, x86_instr_size, data_size, - t_read, t_read_addr, t_write, t_write_addr); - - // Copy original UInstr (INCEIP or JMP) - VG_(copy_UInstr)(cb, u_in); - - // Update loop state for next x86 instr - bb_info_i++; - x86_instr_addr += x86_instr_size; - t_read_addr = t_write_addr = t_read = t_write = INVALID_TEMPREG; - data_size = 0; - break; - - default: - VG_(copy_UInstr)(cb, u_in); - break; - } - } - - // BB address should be the same as the first instruction's address. - sk_assert(bb_info->BB_addr == bb_info->instrs[0].instr_addr ); - sk_assert(bb_info_i == bb_info->n_instrs); - - VG_(free_UCodeBlock)(cb_in); - return cb; - -#undef INVALID_DATA_SIZE -} - -/*------------------------------------------------------------*/ -/*--- Cache configuration ---*/ -/*------------------------------------------------------------*/ - -#define UNDEFINED_CACHE ((cache_t) { -1, -1, -1 }) - -static cache_t clo_I1_cache = UNDEFINED_CACHE; -static cache_t clo_D1_cache = UNDEFINED_CACHE; -static cache_t clo_L2_cache = UNDEFINED_CACHE; - -/* Checks cache config is ok; makes it so if not. */ -static -void check_cache(cache_t* cache, cache_t* dflt, Char *name) -{ - /* First check they're all powers of two */ - if (-1 == VG_(log2)(cache->size)) { - VG_(message)(Vg_UserMsg, - "warning: %s size of %dB not a power of two; " - "defaulting to %dB", name, cache->size, dflt->size); - cache->size = dflt->size; - } - - if (-1 == VG_(log2)(cache->assoc)) { - VG_(message)(Vg_UserMsg, - "warning: %s associativity of %d not a power of two; " - "defaulting to %d-way", name, cache->assoc, dflt->assoc); - cache->assoc = dflt->assoc; - } - - if (-1 == VG_(log2)(cache->line_size)) { - VG_(message)(Vg_UserMsg, - "warning: %s line size of %dB not a power of two; " - "defaulting to %dB", - name, cache->line_size, dflt->line_size); - cache->line_size = dflt->line_size; - } - - /* Then check line size >= 16 -- any smaller and a single instruction could - * straddle three cache lines, which breaks a simulation assertion and is - * stupid anyway. */ - if (cache->line_size < MIN_LINE_SIZE) { - VG_(message)(Vg_UserMsg, - "warning: %s line size of %dB too small; " - "increasing to %dB", name, cache->line_size, MIN_LINE_SIZE); - cache->line_size = MIN_LINE_SIZE; - } - - /* Then check cache size > line size (causes seg faults if not). */ - if (cache->size <= cache->line_size) { - VG_(message)(Vg_UserMsg, - "warning: %s cache size of %dB <= line size of %dB; " - "increasing to %dB", name, cache->size, cache->line_size, - cache->line_size * 2); - cache->size = cache->line_size * 2; - } - - /* Then check assoc <= (size / line size) (seg faults otherwise). */ - if (cache->assoc > (cache->size / cache->line_size)) { - VG_(message)(Vg_UserMsg, - "warning: %s associativity > (size / line size); " - "increasing size to %dB", - name, cache->assoc * cache->line_size); - cache->size = cache->assoc * cache->line_size; - } -} - -static -void configure_caches(cache_t* I1c, cache_t* D1c, cache_t* L2c) -{ -#define DEFINED(L) (-1 != L.size || -1 != L.assoc || -1 != L.line_size) - - Int n_clos = 0; - cache_t I1_dflt, D1_dflt, L2_dflt; - - // Count how many were defined on the command line. - if (DEFINED(clo_I1_cache)) { n_clos++; } - if (DEFINED(clo_D1_cache)) { n_clos++; } - if (DEFINED(clo_L2_cache)) { n_clos++; } - - // Set the default cache config (using auto-detection, if supported by - // current arch) - VGA_(configure_caches)( I1c, D1c, L2c, &I1_dflt, &D1_dflt, &L2_dflt, - (3 == n_clos) ); - - // Then replace with any defined on the command line. - if (DEFINED(clo_I1_cache)) { *I1c = clo_I1_cache; } - if (DEFINED(clo_D1_cache)) { *D1c = clo_D1_cache; } - if (DEFINED(clo_L2_cache)) { *L2c = clo_L2_cache; } - - // Then check values and fix if not acceptable. - check_cache(I1c, &I1_dflt, "I1"); - check_cache(D1c, &D1_dflt, "D1"); - check_cache(L2c, &L2_dflt, "L2"); - - if (VG_(clo_verbosity) > 1) { - VG_(message)(Vg_UserMsg, "Cache configuration used:"); - VG_(message)(Vg_UserMsg, " I1: %dB, %d-way, %dB lines", - I1c->size, I1c->assoc, I1c->line_size); - VG_(message)(Vg_UserMsg, " D1: %dB, %d-way, %dB lines", - D1c->size, D1c->assoc, D1c->line_size); - VG_(message)(Vg_UserMsg, " L2: %dB, %d-way, %dB lines", - L2c->size, L2c->assoc, L2c->line_size); - } -#undef CMD_LINE_DEFINED -} - -/*------------------------------------------------------------*/ -/*--- SK_(fini)() and related function ---*/ -/*------------------------------------------------------------*/ - -// Total reads/writes/misses. Calculated during CC traversal at the end. -// All auto-zeroed. -static CC Ir_total; -static CC Dr_total; -static CC Dw_total; - -static Char* cachegrind_out_file; - -static void file_err ( void ) -{ - VG_(message)(Vg_UserMsg, - "error: can't open cache simulation output file `%s'", - cachegrind_out_file ); - VG_(message)(Vg_UserMsg, - " ... so simulation results will be missing."); -} - -static void fprint_lineCC(Int fd, lineCC* n) -{ - Char buf[512]; - VG_(sprintf)(buf, "%u %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", - n->line, - n->Ir.a, n->Ir.m1, n->Ir.m2, - n->Dr.a, n->Dr.m1, n->Dr.m2, - n->Dw.a, n->Dw.m1, n->Dw.m2); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - - Ir_total.a += n->Ir.a; Ir_total.m1 += n->Ir.m1; Ir_total.m2 += n->Ir.m2; - Dr_total.a += n->Dr.a; Dr_total.m1 += n->Dr.m1; Dr_total.m2 += n->Dr.m2; - Dw_total.a += n->Dw.a; Dw_total.m1 += n->Dw.m1; Dw_total.m2 += n->Dw.m2; -} - -static void fprint_CC_table_and_calc_totals(void) -{ - Int fd; - Char buf[512]; - fileCC *curr_fileCC; - fnCC *curr_fnCC; - lineCC *curr_lineCC; - Int i, j, k; - - VGP_PUSHCC(VgpCacheResults); - - fd = VG_(open)(cachegrind_out_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY, - VKI_S_IRUSR|VKI_S_IWUSR); - if (fd < 0) { - // If the file can't be opened for whatever reason (conflict - // between multiple cachegrinded processes?), give up now. - file_err(); - return; - } - - // "desc:" lines (giving I1/D1/L2 cache configuration). The spaces after - // the 2nd colon makes cg_annotate's output look nicer. - VG_(sprintf)(buf, "desc: I1 cache: %s\n" - "desc: D1 cache: %s\n" - "desc: L2 cache: %s\n", - I1.desc_line, D1.desc_line, L2.desc_line); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - - // "cmd:" line - VG_(strcpy)(buf, "cmd:"); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - for (i = 0; i < VG_(client_argc); i++) { - VG_(write)(fd, " ", 1); - VG_(write)(fd, VG_(client_argv)[i], VG_(strlen)(VG_(client_argv)[i])); - } - // "events:" line - VG_(sprintf)(buf, "\nevents: Ir I1mr I2mr Dr D1mr D2mr Dw D1mw D2mw\n"); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - - // Six loops here: three for the hash table arrays, and three for the - // chains hanging off the hash table arrays. - for (i = 0; i < N_FILE_ENTRIES; i++) { - curr_fileCC = CC_table[i]; - while (curr_fileCC != NULL) { - VG_(sprintf)(buf, "fl=%s\n", curr_fileCC->file); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - - for (j = 0; j < N_FN_ENTRIES; j++) { - curr_fnCC = curr_fileCC->fns[j]; - while (curr_fnCC != NULL) { - VG_(sprintf)(buf, "fn=%s\n", curr_fnCC->fn); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - - for (k = 0; k < N_LINE_ENTRIES; k++) { - curr_lineCC = curr_fnCC->lines[k]; - while (curr_lineCC != NULL) { - fprint_lineCC(fd, curr_lineCC); - curr_lineCC = curr_lineCC->next; - } - } - curr_fnCC = curr_fnCC->next; - } - } - curr_fileCC = curr_fileCC->next; - } - } - - // Summary stats must come after rest of table, since we calculate them - // during traversal. */ - VG_(sprintf)(buf, "summary: " - "%llu %llu %llu %llu %llu %llu %llu %llu %llu\n", - Ir_total.a, Ir_total.m1, Ir_total.m2, - Dr_total.a, Dr_total.m1, Dr_total.m2, - Dw_total.a, Dw_total.m1, Dw_total.m2); - VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); - VG_(close)(fd); -} - -static UInt ULong_width(ULong n) -{ - UInt w = 0; - while (n > 0) { - n = n / 10; - w++; - } - return w + (w-1)/3; // add space for commas -} - -static -void percentify(Int n, Int ex, Int field_width, char buf[]) -{ - int i, len, space; - - VG_(sprintf)(buf, "%d.%d%%", n / ex, n % ex); - len = VG_(strlen)(buf); - space = field_width - len; - if (space < 0) space = 0; /* Allow for v. small field_width */ - i = len; - - /* Right justify in field */ - for ( ; i >= 0; i--) buf[i + space] = buf[i]; - for (i = 0; i < space; i++) buf[i] = ' '; -} - -void SK_(fini)(Int exitcode) -{ - static char buf1[128], buf2[128], buf3[128], fmt [128]; - - CC D_total; - ULong L2_total_m, L2_total_mr, L2_total_mw, - L2_total, L2_total_r, L2_total_w; - Int l1, l2, l3; - Int p; - - fprint_CC_table_and_calc_totals(); - - if (VG_(clo_verbosity) == 0) - return; - - /* I cache results. Use the I_refs value to determine the first column - * width. */ - l1 = ULong_width(Ir_total.a); - l2 = ULong_width(Dr_total.a); - l3 = ULong_width(Dw_total.a); - - /* Make format string, getting width right for numbers */ - VG_(sprintf)(fmt, "%%s %%,%dld", l1); - - VG_(message)(Vg_UserMsg, fmt, "I refs: ", Ir_total.a); - VG_(message)(Vg_UserMsg, fmt, "I1 misses: ", Ir_total.m1); - VG_(message)(Vg_UserMsg, fmt, "L2i misses: ", Ir_total.m2); - - p = 100; - - if (0 == Ir_total.a) Ir_total.a = 1; - percentify(Ir_total.m1 * 100 * p / Ir_total.a, p, l1+1, buf1); - VG_(message)(Vg_UserMsg, "I1 miss rate: %s", buf1); - - percentify(Ir_total.m2 * 100 * p / Ir_total.a, p, l1+1, buf1); - VG_(message)(Vg_UserMsg, "L2i miss rate: %s", buf1); - VG_(message)(Vg_UserMsg, ""); - - /* D cache results. Use the D_refs.rd and D_refs.wr values to determine the - * width of columns 2 & 3. */ - D_total.a = Dr_total.a + Dw_total.a; - D_total.m1 = Dr_total.m1 + Dw_total.m1; - D_total.m2 = Dr_total.m2 + Dw_total.m2; - - /* Make format string, getting width right for numbers */ - VG_(sprintf)(fmt, "%%s %%,%dld (%%,%dld rd + %%,%dld wr)", l1, l2, l3); - - VG_(message)(Vg_UserMsg, fmt, "D refs: ", - D_total.a, Dr_total.a, Dw_total.a); - VG_(message)(Vg_UserMsg, fmt, "D1 misses: ", - D_total.m1, Dr_total.m1, Dw_total.m1); - VG_(message)(Vg_UserMsg, fmt, "L2d misses: ", - D_total.m2, Dr_total.m2, Dw_total.m2); - - p = 10; - - if (0 == D_total.a) D_total.a = 1; - if (0 == Dr_total.a) Dr_total.a = 1; - if (0 == Dw_total.a) Dw_total.a = 1; - percentify( D_total.m1 * 100 * p / D_total.a, p, l1+1, buf1); - percentify(Dr_total.m1 * 100 * p / Dr_total.a, p, l2+1, buf2); - percentify(Dw_total.m1 * 100 * p / Dw_total.a, p, l3+1, buf3); - VG_(message)(Vg_UserMsg, "D1 miss rate: %s (%s + %s )", buf1, buf2,buf3); - - percentify( D_total.m2 * 100 * p / D_total.a, p, l1+1, buf1); - percentify(Dr_total.m2 * 100 * p / Dr_total.a, p, l2+1, buf2); - percentify(Dw_total.m2 * 100 * p / Dw_total.a, p, l3+1, buf3); - VG_(message)(Vg_UserMsg, "L2d miss rate: %s (%s + %s )", buf1, buf2,buf3); - VG_(message)(Vg_UserMsg, ""); - - /* L2 overall results */ - - L2_total = Dr_total.m1 + Dw_total.m1 + Ir_total.m1; - L2_total_r = Dr_total.m1 + Ir_total.m1; - L2_total_w = Dw_total.m1; - VG_(message)(Vg_UserMsg, fmt, "L2 refs: ", - L2_total, L2_total_r, L2_total_w); - - L2_total_m = Dr_total.m2 + Dw_total.m2 + Ir_total.m2; - L2_total_mr = Dr_total.m2 + Ir_total.m2; - L2_total_mw = Dw_total.m2; - VG_(message)(Vg_UserMsg, fmt, "L2 misses: ", - L2_total_m, L2_total_mr, L2_total_mw); - - percentify(L2_total_m * 100 * p / (Ir_total.a + D_total.a), p, l1+1, buf1); - percentify(L2_total_mr * 100 * p / (Ir_total.a + Dr_total.a), p, l2+1, buf2); - percentify(L2_total_mw * 100 * p / Dw_total.a, p, l3+1, buf3); - VG_(message)(Vg_UserMsg, "L2 miss rate: %s (%s + %s )", buf1, buf2,buf3); - - - // Various stats - if (VG_(clo_verbosity) > 1) { - int BB_lookups = full_debug_BBs + fn_debug_BBs + - file_line_debug_BBs + no_debug_BBs; - - VG_(message)(Vg_DebugMsg, ""); - VG_(message)(Vg_DebugMsg, "Distinct files: %d", distinct_files); - VG_(message)(Vg_DebugMsg, "Distinct fns: %d", distinct_fns); - VG_(message)(Vg_DebugMsg, "Distinct lines: %d", distinct_lines); - VG_(message)(Vg_DebugMsg, "Distinct instrs: %d", distinct_instrs); - VG_(message)(Vg_DebugMsg, "BB lookups: %d", BB_lookups); - VG_(message)(Vg_DebugMsg, "With full debug info:%3d%% (%d)", - full_debug_BBs * 100 / BB_lookups, - full_debug_BBs); - VG_(message)(Vg_DebugMsg, "With file/line debug info:%3d%% (%d)", - file_line_debug_BBs * 100 / BB_lookups, - file_line_debug_BBs); - VG_(message)(Vg_DebugMsg, "With fn name debug info:%3d%% (%d)", - fn_debug_BBs * 100 / BB_lookups, - fn_debug_BBs); - VG_(message)(Vg_DebugMsg, "With no debug info:%3d%% (%d)", - no_debug_BBs * 100 / BB_lookups, - no_debug_BBs); - VG_(message)(Vg_DebugMsg, "BBs Retranslated: %d", BB_retranslations); - } - VGP_POPCC(VgpCacheResults); -} - -/*--------------------------------------------------------------------*/ -/*--- Discarding BB info ---*/ -/*--------------------------------------------------------------------*/ - -// Called when a translation is invalidated due to code unloading. -void SK_(discard_basic_block_info) ( Addr a, UInt size ) -{ - VgHashNode** prev_next_ptr; - VgHashNode* bb_info; - - if (0) VG_(printf)( "discard_basic_block_info: %p, %u\n", a, size); - - // Get BB info, remove from table, free BB info. Simple! - bb_info = VG_(HT_get_node)(instr_info_table, a, &prev_next_ptr); - sk_assert(NULL != bb_info); - *prev_next_ptr = bb_info->next; - VG_(free)(bb_info); -} - -/*--------------------------------------------------------------------*/ -/*--- Command line processing ---*/ -/*--------------------------------------------------------------------*/ - -static void parse_cache_opt ( cache_t* cache, char* opt ) -{ - int i = 0, i2, i3; - - // Option argument looks like "65536,2,64". - // Find commas, replace with NULs to make three independent - // strings, then extract numbers, put NULs back. Yuck. - while (VG_(isdigit)(opt[i])) i++; - if (',' == opt[i]) { - opt[i++] = '\0'; - i2 = i; - } else goto bad; - while (VG_(isdigit)(opt[i])) i++; - if (',' == opt[i]) { - opt[i++] = '\0'; - i3 = i; - } else goto bad; - while (VG_(isdigit)(opt[i])) i++; - if ('\0' != opt[i]) goto bad; - - cache->size = (Int)VG_(atoll)(opt); - cache->assoc = (Int)VG_(atoll)(opt + i2); - cache->line_size = (Int)VG_(atoll)(opt + i3); - - opt[i2-1] = ','; - opt[i3-1] = ','; - return; - - bad: - VG_(bad_option)(opt); -} - -Bool SK_(process_cmd_line_option)(Char* arg) -{ - // 5 is length of "--I1=" - if (VG_CLO_STREQN(5, arg, "--I1=")) - parse_cache_opt(&clo_I1_cache, &arg[5]); - else if (VG_CLO_STREQN(5, arg, "--D1=")) - parse_cache_opt(&clo_D1_cache, &arg[5]); - else if (VG_CLO_STREQN(5, arg, "--L2=")) - parse_cache_opt(&clo_L2_cache, &arg[5]); - else - return False; - - return True; -} - -void SK_(print_usage)(void) -{ - VG_(printf)( -" --I1=,, set I1 cache manually\n" -" --D1=,, set D1 cache manually\n" -" --L2=,, set L2 cache manually\n" - ); -} - -void SK_(print_debug_usage)(void) -{ - VG_(printf)( -" (none)\n" - ); -} - -/*--------------------------------------------------------------------*/ -/*--- Setup ---*/ -/*--------------------------------------------------------------------*/ - -void SK_(pre_clo_init)(void) -{ - Char* base_dir = NULL; - - VG_(details_name) ("Cachegrind"); - VG_(details_version) (NULL); - VG_(details_description) ("an I1/D1/L2 cache profiler"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 155 ); - - VG_(needs_basic_block_discards)(); - VG_(needs_command_line_options)(); - - VG_(register_compact_helper)((Addr) & log_1I_0D_cache_access); - VG_(register_compact_helper)((Addr) & log_1I_1Dr_cache_access); - VG_(register_compact_helper)((Addr) & log_1I_1Dw_cache_access); - VG_(register_compact_helper)((Addr) & log_1I_2D_cache_access); - - /* Get working directory */ - sk_assert( VG_(getcwd_alloc)(&base_dir) ); - - /* Block is big enough for dir name + cachegrind.out. */ - cachegrind_out_file = VG_(malloc)((VG_(strlen)(base_dir) + 32)*sizeof(Char)); - VG_(sprintf)(cachegrind_out_file, "%s/cachegrind.out.%d", - base_dir, VG_(getpid)()); - VG_(free)(base_dir); - - instr_info_table = VG_(HT_construct)(); -} - -void SK_(post_clo_init)(void) -{ - cache_t I1c, D1c, L2c; - - configure_caches(&I1c, &D1c, &L2c); - - cachesim_I1_initcache(I1c); - cachesim_D1_initcache(D1c); - cachesim_L2_initcache(L2c); - - VGP_(register_profile_event)(VgpGetLineCC, "get-lineCC"); - VGP_(register_profile_event)(VgpCacheSimulate, "cache-simulate"); - VGP_(register_profile_event)(VgpCacheResults, "cache-results"); -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 0) - -/*--------------------------------------------------------------------*/ -/*--- end cg_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/cachegrind/cg_sim.c b/VEX/head20041019/cachegrind/cg_sim.c deleted file mode 100644 index 5d42c1ba4..000000000 --- a/VEX/head20041019/cachegrind/cg_sim.c +++ /dev/null @@ -1,210 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Cache simulation cg_sim.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Cachegrind, a Valgrind tool for cache - profiling programs. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* Notes: - - simulates a write-allocate cache - - (block --> set) hash function uses simple bit selection - - handling of references straddling two cache blocks: - - counts as only one cache access (not two) - - both blocks hit --> one hit - - one block hits, the other misses --> one miss - - both blocks miss --> one miss (not two) -*/ - -typedef struct { - int size; /* bytes */ - int assoc; - int line_size; /* bytes */ - int sets; - int sets_min_1; - int assoc_bits; - int line_size_bits; - int tag_shift; - char desc_line[128]; - int* tags; -} cache_t2; - -/* By this point, the size/assoc/line_size has been checked. */ -static void cachesim_initcache(cache_t config, cache_t2* c) -{ - int i; - - c->size = config.size; - c->assoc = config.assoc; - c->line_size = config.line_size; - - c->sets = (c->size / c->line_size) / c->assoc; - c->sets_min_1 = c->sets - 1; - c->assoc_bits = VG_(log2)(c->assoc); - c->line_size_bits = VG_(log2)(c->line_size); - c->tag_shift = c->line_size_bits + VG_(log2)(c->sets); - - if (c->assoc == 1) { - VG_(sprintf)(c->desc_line, "%d B, %d B, direct-mapped", - c->size, c->line_size); - } else { - VG_(sprintf)(c->desc_line, "%d B, %d B, %d-way associative", - c->size, c->line_size, c->assoc); - } - - c->tags = VG_(malloc)(sizeof(UInt) * c->sets * c->assoc); - - for (i = 0; i < c->sets * c->assoc; i++) - c->tags[i] = 0; -} - -#if 0 -static void print_cache(cache_t2* c) -{ - UInt set, way, i; - - /* Note initialisation and update of 'i'. */ - for (i = 0, set = 0; set < c->sets; set++) { - for (way = 0; way < c->assoc; way++, i++) { - VG_(printf)("%8x ", c->tags[i]); - } - VG_(printf)("\n"); - } -} -#endif - -/* This is done as a macro rather than by passing in the cache_t2 as an - * arg because it slows things down by a small amount (3-5%) due to all - * that extra indirection. */ - -#define CACHESIM(L, MISS_TREATMENT) \ -/* The cache and associated bits and pieces. */ \ -static cache_t2 L; \ - \ -static void cachesim_##L##_initcache(cache_t config) \ -{ \ - cachesim_initcache(config, &L); \ -} \ - \ -static /* __inline__ */ \ -void cachesim_##L##_doref(Addr a, UChar size, ULong* m1, ULong *m2) \ -{ \ - register UInt set1 = ( a >> L.line_size_bits) & (L.sets_min_1); \ - register UInt set2 = ((a+size-1) >> L.line_size_bits) & (L.sets_min_1); \ - register UInt tag = a >> L.tag_shift; \ - int i, j; \ - Bool is_miss = False; \ - int* set; \ - \ - /* First case: word entirely within line. */ \ - if (set1 == set2) { \ - \ - /* Shifting is a bit faster than multiplying */ \ - set = &(L.tags[set1 << L.assoc_bits]); \ - \ - /* This loop is unrolled for just the first case, which is the most */\ - /* common. We can't unroll any further because it would screw up */\ - /* if we have a direct-mapped (1-way) cache. */\ - if (tag == set[0]) { \ - return; \ - } \ - /* If the tag is one other than the MRU, move it into the MRU spot */\ - /* and shuffle the rest down. */\ - for (i = 1; i < L.assoc; i++) { \ - if (tag == set[i]) { \ - for (j = i; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - return; \ - } \ - } \ - \ - /* A miss; install this tag as MRU, shuffle rest down. */ \ - for (j = L.assoc - 1; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - MISS_TREATMENT; \ - return; \ - \ - /* Second case: word straddles two lines. */ \ - /* Nb: this is a fast way of doing ((set1+1) % L.sets) */ \ - } else if (((set1 + 1) & (L.sets-1)) == set2) { \ - set = &(L.tags[set1 << L.assoc_bits]); \ - if (tag == set[0]) { \ - goto block2; \ - } \ - for (i = 1; i < L.assoc; i++) { \ - if (tag == set[i]) { \ - for (j = i; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - goto block2; \ - } \ - } \ - for (j = L.assoc - 1; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - is_miss = True; \ -block2: \ - set = &(L.tags[set2 << L.assoc_bits]); \ - if (tag == set[0]) { \ - goto miss_treatment; \ - } \ - for (i = 1; i < L.assoc; i++) { \ - if (tag == set[i]) { \ - for (j = i; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - goto miss_treatment; \ - } \ - } \ - for (j = L.assoc - 1; j > 0; j--) { \ - set[j] = set[j - 1]; \ - } \ - set[0] = tag; \ - is_miss = True; \ -miss_treatment: \ - if (is_miss) { MISS_TREATMENT; } \ - \ - } else { \ - VG_(printf)("addr: %x size: %u sets: %d %d", a, size, set1, set2); \ - VG_(skin_panic)("item straddles more than two cache sets"); \ - } \ - return; \ -} - -CACHESIM(L2, (*m2)++ ); -CACHESIM(I1, { (*m1)++; cachesim_L2_doref(a, size, m1, m2); } ); -CACHESIM(D1, { (*m1)++; cachesim_L2_doref(a, size, m1, m2); } ); - -/*--------------------------------------------------------------------*/ -/*--- end cg_sim.c ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/cachegrind/docs/.cvsignore b/VEX/head20041019/cachegrind/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/cachegrind/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/cachegrind/docs/CVS/Entries b/VEX/head20041019/cachegrind/docs/CVS/Entries deleted file mode 100644 index 05ac7ec69..000000000 --- a/VEX/head20041019/cachegrind/docs/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:22 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:04 2004// -/cg_main.html/1.5/Fri Nov 14 17:47:52 2003// -/cg_techdocs.html/1.4/Thu Nov 20 16:20:54 2003// -D diff --git a/VEX/head20041019/cachegrind/docs/CVS/Repository b/VEX/head20041019/cachegrind/docs/CVS/Repository deleted file mode 100644 index a5e96cda3..000000000 --- a/VEX/head20041019/cachegrind/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/cachegrind/docs diff --git a/VEX/head20041019/cachegrind/docs/CVS/Root b/VEX/head20041019/cachegrind/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/cachegrind/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/cachegrind/docs/CVS/Template b/VEX/head20041019/cachegrind/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/docs/Makefile.am b/VEX/head20041019/cachegrind/docs/Makefile.am deleted file mode 100644 index 9657fe59f..000000000 --- a/VEX/head20041019/cachegrind/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = cg_main.html cg_techdocs.html diff --git a/VEX/head20041019/cachegrind/docs/cg_main.html b/VEX/head20041019/cachegrind/docs/cg_main.html deleted file mode 100644 index 545748ae9..000000000 --- a/VEX/head20041019/cachegrind/docs/cg_main.html +++ /dev/null @@ -1,714 +0,0 @@ - - - Cachegrind: a cache-miss profiler - - - - -

Cachegrind: a cache-miss profiler

- -To use this tool, you must specify --tool=cachegrind -on the Valgrind command line. - -

-Detailed technical documentation on how Cachegrind works is available -here. If you want to know how -to use it, you only need to read this page. - - - -

4.1  Cache profiling

-Cachegrind is a tool for doing cache simulations and annotating your source -line-by-line with the number of cache misses. In particular, it records: -
    -
  • L1 instruction cache reads and misses; -
  • L1 data cache reads and read misses, writes and write misses; -
  • L2 unified cache reads and read misses, writes and writes misses. -
-On a modern x86 machine, an L1 miss will typically cost around 10 cycles, -and an L2 miss can cost as much as 200 cycles. Detailed cache profiling can be -very useful for improving the performance of your program.

- -Also, since one instruction cache read is performed per instruction executed, -you can find out how many instructions are executed per line, which can be -useful for traditional profiling and test coverage.

- -Any feedback, bug-fixes, suggestions, etc, welcome. - - -

4.2  Overview

-First off, as for normal Valgrind use, you probably want to compile with -debugging info (the -g flag). But by contrast with normal -Valgrind use, you probably do want to turn optimisation on, since you -should profile your program as it will be normally run. - -The two steps are: -
    -
  1. Run your program with valgrind --tool=cachegrind in front of - the normal command line invocation. When the program finishes, - Cachegrind will print summary cache statistics. It also collects - line-by-line information in a file - cachegrind.out.pid, where pid - is the program's process id. -

    - This step should be done every time you want to collect - information about a new program, a changed program, or about the - same program with different input. -

  2. -

  3. Generate a function-by-function summary, and possibly annotate - source files, using the supplied - cg_annotate program. Source files to annotate can be - specified manually, or manually on the command line, or - "interesting" source files can be annotated automatically with - the --auto=yes option. You can annotate C/C++ - files or assembly language files equally easily. -

    - This step can be performed as many times as you like for each - Step 2. You may want to do multiple annotations showing - different information each time. -

  4. -

- -The steps are described in detail in the following sections. - - -

4.3  Cache simulation specifics

- -Cachegrind uses a simulation for a machine with a split L1 cache and a unified -L2 cache. This configuration is used for all (modern) x86-based machines we -are aware of. Old Cyrix CPUs had a unified I and D L1 cache, but they are -ancient history now.

- -The more specific characteristics of the simulation are as follows. - -

    -
  • Write-allocate: when a write miss occurs, the block written to - is brought into the D1 cache. Most modern caches have this - property.

    -

  • -

    -

  • Bit-selection hash function: the line(s) in the cache to which a - memory block maps is chosen by the middle bits M--(M+N-1) of the - byte address, where: -
      -
    •  line size = 2^M bytes 
    • -
    • (cache size / line size) = 2^N bytes
    • -
    -
  • -

    -

  • Inclusive L2 cache: the L2 cache replicates all the entries of - the L1 cache. This is standard on Pentium chips, but AMD - Athlons use an exclusive L2 cache that only holds blocks evicted - from L1. Ditto AMD Durons and most modern VIAs.
  • -
- -The cache configuration simulated (cache size, associativity and line size) is -determined automagically using the CPUID instruction. If you have an old -machine that (a) doesn't support the CPUID instruction, or (b) supports it in -an early incarnation that doesn't give any cache information, then Cachegrind -will fall back to using a default configuration (that of a model 3/4 Athlon). -Cachegrind will tell you if this happens. You can manually specify one, two or -all three levels (I1/D1/L2) of the cache from the command line using the ---I1, --D1 and --L2 options. - -

-Other noteworthy behaviour: - -

    -
  • References that straddle two cache lines are treated as follows: -
      -
    • If both blocks hit --> counted as one hit
    • -
    • If one block hits, the other misses --> counted as one miss
    • -
    • If both blocks miss --> counted as one miss (not two)
    • -
    -
  • - -
  • Instructions that modify a memory location (eg. inc and - dec) are counted as doing just a read, ie. a single data - reference. This may seem strange, but since the write can never cause a - miss (the read guarantees the block is in the cache) it's not very - interesting. -

    - Thus it measures not the number of times the data cache is accessed, but - the number of times a data cache miss could occur.

    -

  • -
- -If you are interested in simulating a cache with different properties, it is -not particularly hard to write your own cache simulator, or to modify the -existing ones in vg_cachesim_I1.c, vg_cachesim_D1.c, -vg_cachesim_L2.c and vg_cachesim_gen.c. We'd be -interested to hear from anyone who does. - - - -

4.4  Profiling programs

- -To gather cache profiling information about the program ls -l, -invoke Cachegrind like this: - -
valgrind --tool=cachegrind ls -l
- -The program will execute (slowly). Upon completion, summary statistics -that look like this will be printed: - -
-==31751== I   refs:      27,742,716
-==31751== I1  misses:           276
-==31751== L2  misses:           275
-==31751== I1  miss rate:        0.0%
-==31751== L2i miss rate:        0.0%
-==31751== 
-==31751== D   refs:      15,430,290  (10,955,517 rd + 4,474,773 wr)
-==31751== D1  misses:        41,185  (    21,905 rd +    19,280 wr)
-==31751== L2  misses:        23,085  (     3,987 rd +    19,098 wr)
-==31751== D1  miss rate:        0.2% (       0.1%   +       0.4%)
-==31751== L2d miss rate:        0.1% (       0.0%   +       0.4%)
-==31751== 
-==31751== L2 misses:         23,360  (     4,262 rd +    19,098 wr)
-==31751== L2 miss rate:         0.0% (       0.0%   +       0.4%)
-
- -Cache accesses for instruction fetches are summarised first, giving the -number of fetches made (this is the number of instructions executed, which -can be useful to know in its own right), the number of I1 misses, and the -number of L2 instruction (L2i) misses. -

-Cache accesses for data follow. The information is similar to that of the -instruction fetches, except that the values are also shown split between reads -and writes (note each row's rd and wr values add up -to the row's total). -

-Combined instruction and data figures for the L2 cache follow that. - - -

4.5  Output file

- -As well as printing summary information, Cachegrind also writes -line-by-line cache profiling information to a file named -cachegrind.out.pid. This file is human-readable, but is -best interpreted by the accompanying program cg_annotate, -described in the next section. -

-Things to note about the cachegrind.out.pid file: -

    -
  • It is written every time Cachegrind - is run, and will overwrite any existing - cachegrind.out.pid in the current directory (but - that won't happen very often because it takes some time for process ids - to be recycled).
  • -

  • It can be huge: ls -l generates a file of about - 350KB. Browsing a few files and web pages with a Konqueror - built with full debugging information generates a file - of around 15 MB.
  • -
- -Note that older versions of Cachegrind used a log file named -cachegrind.out (i.e. no .pid suffix). -The suffix serves two purposes. Firstly, it means you don't have to -rename old log files that you don't want to overwrite. Secondly, and -more importantly, it allows correct profiling with the ---trace-children=yes option of programs that spawn child -processes. - - - -

4.6  Cachegrind options

- -Cache-simulation specific options are: - -
    -
  • --I1=<size>,<associativity>,<line_size>
    - --D1=<size>,<associativity>,<line_size>
    - --L2=<size>,<associativity>,<line_size>

    - [default: uses CPUID for automagic cache configuration]

    - - Manually specifies the I1/D1/L2 cache configuration, where - size and line_size are measured in bytes. The - three items must be comma-separated, but with no spaces, eg: - -

    - valgrind --tool=cachegrind --I1=65535,2,64 -
    - - You can specify one, two or three of the I1/D1/L2 caches. Any level not - manually specified will be simulated using the configuration found in the - normal way (via the CPUID instruction, or failing that, via defaults). -
- - - -

4.7  Annotating C/C++ programs

- -Before using cg_annotate, it is worth widening your -window to be at least 120-characters wide if possible, as the output -lines can be quite long. -

-To get a function-by-function summary, run cg_annotate ---pid in a directory containing a -cachegrind.out.pid file. The --pid -is required so that cg_annotate knows which log file to use when -several are present. -

-The output looks like this: - -

---------------------------------------------------------------------------------
-I1 cache:              65536 B, 64 B, 2-way associative
-D1 cache:              65536 B, 64 B, 2-way associative
-L2 cache:              262144 B, 64 B, 8-way associative
-Command:               concord vg_to_ucode.c
-Events recorded:       Ir I1mr I2mr Dr D1mr D2mr Dw D1mw D2mw
-Events shown:          Ir I1mr I2mr Dr D1mr D2mr Dw D1mw D2mw
-Event sort order:      Ir I1mr I2mr Dr D1mr D2mr Dw D1mw D2mw
-Threshold:             99%
-Chosen for annotation:
-Auto-annotation:       on
-
---------------------------------------------------------------------------------
-Ir         I1mr I2mr Dr         D1mr   D2mr  Dw        D1mw   D2mw
---------------------------------------------------------------------------------
-27,742,716  276  275 10,955,517 21,905 3,987 4,474,773 19,280 19,098  PROGRAM TOTALS
-
---------------------------------------------------------------------------------
-Ir        I1mr I2mr Dr        D1mr  D2mr  Dw        D1mw   D2mw    file:function
---------------------------------------------------------------------------------
-8,821,482    5    5 2,242,702 1,621    73 1,794,230      0      0  getc.c:_IO_getc
-5,222,023    4    4 2,276,334    16    12   875,959      1      1  concord.c:get_word
-2,649,248    2    2 1,344,810 7,326 1,385         .      .      .  vg_main.c:strcmp
-2,521,927    2    2   591,215     0     0   179,398      0      0  concord.c:hash
-2,242,740    2    2 1,046,612   568    22   448,548      0      0  ctype.c:tolower
-1,496,937    4    4   630,874 9,000 1,400   279,388      0      0  concord.c:insert
-  897,991   51   51   897,831    95    30        62      1      1  ???:???
-  598,068    1    1   299,034     0     0   149,517      0      0  ../sysdeps/generic/lockfile.c:__flockfile
-  598,068    0    0   299,034     0     0   149,517      0      0  ../sysdeps/generic/lockfile.c:__funlockfile
-  598,024    4    4   213,580    35    16   149,506      0      0  vg_clientmalloc.c:malloc
-  446,587    1    1   215,973 2,167   430   129,948 14,057 13,957  concord.c:add_existing
-  341,760    2    2   128,160     0     0   128,160      0      0  vg_clientmalloc.c:vg_trap_here_WRAPPER
-  320,782    4    4   150,711   276     0    56,027     53     53  concord.c:init_hash_table
-  298,998    1    1   106,785     0     0    64,071      1      1  concord.c:create
-  149,518    0    0   149,516     0     0         1      0      0  ???:tolower@@GLIBC_2.0
-  149,518    0    0   149,516     0     0         1      0      0  ???:fgetc@@GLIBC_2.0
-   95,983    4    4    38,031     0     0    34,409  3,152  3,150  concord.c:new_word_node
-   85,440    0    0    42,720     0     0    21,360      0      0  vg_clientmalloc.c:vg_bogus_epilogue
-
- -First up is a summary of the annotation options: - -
    -
  • I1 cache, D1 cache, L2 cache: cache configuration. So you know the - configuration with which these results were obtained.
  • - -

  • Command: the command line invocation of the program under - examination.
  • - -

  • Events recorded: event abbreviations are:

    -

      -
    • Ir : I cache reads (ie. instructions executed)
    • -
    • I1mr: I1 cache read misses
    • -
    • I2mr: L2 cache instruction read misses
    • -
    • Dr : D cache reads (ie. memory reads)
    • -
    • D1mr: D1 cache read misses
    • -
    • D2mr: L2 cache data read misses
    • -
    • Dw : D cache writes (ie. memory writes)
    • -
    • D1mw: D1 cache write misses
    • -
    • D2mw: L2 cache data write misses
    • -

    - Note that D1 total accesses is given by D1mr + - D1mw, and that L2 total accesses is given by - I2mr + D2mr + D2mw.

  • - -

  • Events shown: the events shown (a subset of events gathered). This can - be adjusted with the --show option.
  • - -

  • Event sort order: the sort order in which functions are shown. For - example, in this case the functions are sorted from highest - Ir counts to lowest. If two functions have identical - Ir counts, they will then be sorted by I1mr - counts, and so on. This order can be adjusted with the - --sort option.

    - - Note that this dictates the order the functions appear. It is not - the order in which the columns appear; that is dictated by the "events - shown" line (and can be changed with the --show option). -

  • - -

  • Threshold: cg_annotate by default omits functions - that cause very low numbers of misses to avoid drowning you in - information. In this case, cg_annotate shows summaries the - functions that account for 99% of the Ir counts; - Ir is chosen as the threshold event since it is the - primary sort event. The threshold can be adjusted with the - --threshold option.
  • - -

  • Chosen for annotation: names of files specified manually for annotation; - in this case none.
  • - -

  • Auto-annotation: whether auto-annotation was requested via the - --auto=yes option. In this case no.
  • -

- -Then follows summary statistics for the whole program. These are similar -to the summary provided when running valgrind --tool=cachegrind.

- -Then follows function-by-function statistics. Each function is -identified by a file_name:function_name pair. If a column -contains only a dot it means the function never performs -that event (eg. the third row shows that strcmp() -contains no instructions that write to memory). The name -??? is used if the the file name and/or function name -could not be determined from debugging information. If most of the -entries have the form ???:??? the program probably wasn't -compiled with -g. If any code was invalidated (either due to -self-modifying code or unloading of shared objects) its counts are aggregated -into a single cost centre written as (discarded):(discarded).

- -It is worth noting that functions will come from three types of source files: -

    -
  1. From the profiled program (concord.c in this example).
  2. -
  3. From libraries (eg. getc.c)
  4. -
  5. From Valgrind's implementation of some libc functions (eg. - vg_clientmalloc.c:malloc). These are recognisable because - the filename begins with vg_, and is probably one of - vg_main.c, vg_clientmalloc.c or - vg_mylibc.c. -
  6. -
- -There are two ways to annotate source files -- by choosing them -manually, or with the --auto=yes option. To do it -manually, just specify the filenames as arguments to -cg_annotate. For example, the output from running -cg_annotate concord.c for our example produces the same -output as above followed by an annotated version of -concord.c, a section of which looks like: - -
---------------------------------------------------------------------------------
--- User-annotated source: concord.c
---------------------------------------------------------------------------------
-Ir        I1mr I2mr Dr      D1mr  D2mr  Dw      D1mw   D2mw
-
-[snip]
-
-        .    .    .       .     .     .       .      .      .  void init_hash_table(char *file_name, Word_Node *table[])
-        3    1    1       .     .     .       1      0      0  {
-        .    .    .       .     .     .       .      .      .      FILE *file_ptr;
-        .    .    .       .     .     .       .      .      .      Word_Info *data;
-        1    0    0       .     .     .       1      1      1      int line = 1, i;
-        .    .    .       .     .     .       .      .      .
-        5    0    0       .     .     .       3      0      0      data = (Word_Info *) create(sizeof(Word_Info));
-        .    .    .       .     .     .       .      .      .
-    4,991    0    0   1,995     0     0     998      0      0      for (i = 0; i < TABLE_SIZE; i++)
-    3,988    1    1   1,994     0     0     997     53     52          table[i] = NULL;
-        .    .    .       .     .     .       .      .      .
-        .    .    .       .     .     .       .      .      .      /* Open file, check it. */
-        6    0    0       1     0     0       4      0      0      file_ptr = fopen(file_name, "r");
-        2    0    0       1     0     0       .      .      .      if (!(file_ptr)) {
-        .    .    .       .     .     .       .      .      .          fprintf(stderr, "Couldn't open '%s'.\n", file_name);
-        1    1    1       .     .     .       .      .      .          exit(EXIT_FAILURE);
-        .    .    .       .     .     .       .      .      .      }
-        .    .    .       .     .     .       .      .      .
-  165,062    1    1  73,360     0     0  91,700      0      0      while ((line = get_word(data, line, file_ptr)) != EOF)
-  146,712    0    0  73,356     0     0  73,356      0      0          insert(data->;word, data->line, table);
-        .    .    .       .     .     .       .      .      .
-        4    0    0       1     0     0       2      0      0      free(data);
-        4    0    0       1     0     0       2      0      0      fclose(file_ptr);
-        3    0    0       2     0     0       .      .      .  }
-
- -(Although column widths are automatically minimised, a wide terminal is clearly -useful.)

- -Each source file is clearly marked (User-annotated source) as -having been chosen manually for annotation. If the file was found in one of -the directories specified with the -I/--include -option, the directory and file are both given.

- -Each line is annotated with its event counts. Events not applicable for a line -are represented by a `.'; this is useful for distinguishing between an event -which cannot happen, and one which can but did not.

- -Sometimes only a small section of a source file is executed. To minimise -uninteresting output, Valgrind only shows annotated lines and lines within a -small distance of annotated lines. Gaps are marked with the line numbers so -you know which part of a file the shown code comes from, eg: - -

-(figures and code for line 704)
--- line 704 ----------------------------------------
--- line 878 ----------------------------------------
-(figures and code for line 878)
-
- -The amount of context to show around annotated lines is controlled by the ---context option.

- -To get automatic annotation, run cg_annotate --auto=yes. -cg_annotate will automatically annotate every source file it can find that is -mentioned in the function-by-function summary. Therefore, the files chosen for -auto-annotation are affected by the --sort and ---threshold options. Each source file is clearly marked -(Auto-annotated source) as being chosen automatically. Any files -that could not be found are mentioned at the end of the output, eg: - -

---------------------------------------------------------------------------------
-The following files chosen for auto-annotation could not be found:
---------------------------------------------------------------------------------
-  getc.c
-  ctype.c
-  ../sysdeps/generic/lockfile.c
-
- -This is quite common for library files, since libraries are usually compiled -with debugging information, but the source files are often not present on a -system. If a file is chosen for annotation both manually and -automatically, it is marked as User-annotated source. - -Use the -I/--include option to tell Valgrind where to look for -source files if the filenames found from the debugging information aren't -specific enough. - -Beware that cg_annotate can take some time to digest large -cachegrind.out.pid files, e.g. 30 seconds or more. Also -beware that auto-annotation can produce a lot of output if your program is -large! - - -

4.8  Annotating assembler programs

- -Valgrind can annotate assembler programs too, or annotate the -assembler generated for your C program. Sometimes this is useful for -understanding what is really happening when an interesting line of C -code is translated into multiple instructions.

- -To do this, you just need to assemble your .s files with -assembler-level debug information. gcc doesn't do this, but you can -use the GNU assembler with the --gstabs option to -generate object files with this information, eg: - -

as --gstabs foo.s
- -You can then profile and annotate source files in the same way as for C/C++ -programs. - - -

4.9  cg_annotate options

-
    -
  • --pid
  • - - Indicates which cachegrind.out.pid file to read. - Not actually an option -- it is required. - -

  • -h, --help
  • -

  • -v, --version

    - - Help and version, as usual.

  • - -
  • --sort=A,B,C [default: order in - cachegrind.out.pid]

    - Specifies the events upon which the sorting of the function-by-function - entries will be based. Useful if you want to concentrate on eg. I cache - misses (--sort=I1mr,I2mr), or D cache misses - (--sort=D1mr,D2mr), or L2 misses - (--sort=D2mr,I2mr).

  • - -

  • --show=A,B,C [default: all, using order in - cachegrind.out.pid]

    - Specifies which events to show (and the column order). Default is to use - all present in the cachegrind.out.pid file (and use - the order in the file).

  • - -

  • --threshold=X [default: 99%]

    - Sets the threshold for the function-by-function summary. Functions are - shown that account for more than X% of the primary sort event. If - auto-annotating, also affects which files are annotated. - - Note: thresholds can be set for more than one of the events by appending - any events for the --sort option with a colon and a number - (no spaces, though). E.g. if you want to see the functions that cover - 99% of L2 read misses and 99% of L2 write misses, use this option: - -

    --sort=D2mr:99,D2mw:99
    -
  • - -

  • --auto=no [default]
    - --auto=yes

    - When enabled, automatically annotates every file that is mentioned in the - function-by-function summary that can be found. Also gives a list of - those that couldn't be found. - -

  • --context=N [default: 8]

    - Print N lines of context before and after each annotated line. Avoids - printing large sections of source files that were not executed. Use a - large number (eg. 10,000) to show all source lines. -

  • - -

  • -I=<dir>, --include=<dir> - [default: empty string]

    - Adds a directory to the list in which to search for files. Multiple - -I/--include options can be given to add multiple directories. -

- - -

4.10  Warnings

-There are a couple of situations in which cg_annotate issues warnings. - -
    -
  • If a source file is more recent than the - cachegrind.out.pid file. This is because the - information in cachegrind.out.pid is only recorded - with line numbers, so if the line numbers change at all in the source - (eg. lines added, deleted, swapped), any annotations will be - incorrect.

    - -

  • If information is recorded about line numbers past the end of a file. - This can be caused by the above problem, ie. shortening the source file - while using an old cachegrind.out.pid file. If this - happens, the figures for the bogus lines are printed anyway (clearly - marked as bogus) in case they are important.
  • -

- - -

4.11  Things to watch out for

-Some odd things that can occur during annotation: - -
    -
  • If annotating at the assembler level, you might see something like this: - -
    -      1    0    0  .    .    .  .    .    .          leal -12(%ebp),%eax
    -      1    0    0  .    .    .  1    0    0          movl %eax,84(%ebx)
    -      2    0    0  0    0    0  1    0    0          movl $1,-20(%ebp)
    -      .    .    .  .    .    .  .    .    .          .align 4,0x90
    -      1    0    0  .    .    .  .    .    .          movl $.LnrB,%eax
    -      1    0    0  .    .    .  1    0    0          movl %eax,-16(%ebp)
    -      
    - - How can the third instruction be executed twice when the others are - executed only once? As it turns out, it isn't. Here's a dump of the - executable, using objdump -d: - -
    -      8048f25:       8d 45 f4                lea    0xfffffff4(%ebp),%eax
    -      8048f28:       89 43 54                mov    %eax,0x54(%ebx)
    -      8048f2b:       c7 45 ec 01 00 00 00    movl   $0x1,0xffffffec(%ebp)
    -      8048f32:       89 f6                   mov    %esi,%esi
    -      8048f34:       b8 08 8b 07 08          mov    $0x8078b08,%eax
    -      8048f39:       89 45 f0                mov    %eax,0xfffffff0(%ebp)
    -      
    - - Notice the extra mov %esi,%esi instruction. Where did this - come from? The GNU assembler inserted it to serve as the two bytes of - padding needed to align the movl $.LnrB,%eax instruction on - a four-byte boundary, but pretended it didn't exist when adding debug - information. Thus when Valgrind reads the debug info it thinks that the - movl $0x1,0xffffffec(%ebp) instruction covers the address - range 0x8048f2b--0x804833 by itself, and attributes the counts for the - mov %esi,%esi to it.

    -

  • - -
  • Inlined functions can cause strange results in the function-by-function - summary. If a function inline_me() is defined in - foo.h and inlined in the functions f1(), - f2() and f3() in bar.c, there will - not be a foo.h:inline_me() function entry. Instead, there - will be separate function entries for each inlining site, ie. - foo.h:f1(), foo.h:f2() and - foo.h:f3(). To find the total counts for - foo.h:inline_me(), add up the counts from each entry.

    - - The reason for this is that although the debug info output by gcc - indicates the switch from bar.c to foo.h, it - doesn't indicate the name of the function in foo.h, so - Valgrind keeps using the old one.

    - -

  • Sometimes, the same filename might be represented with a relative name - and with an absolute name in different parts of the debug info, eg: - /home/user/proj/proj.h and ../proj.h. In this - case, if you use auto-annotation, the file will be annotated twice with - the counts split between the two.

    -

  • - -
  • Files with more than 65,535 lines cause difficulties for the stabs debug - info reader. This is because the line number in the struct - nlist defined in a.out.h under Linux is only a 16-bit - value. Valgrind can handle some files with more than 65,535 lines - correctly by making some guesses to identify line number overflows. But - some cases are beyond it, in which case you'll get a warning message - explaining that annotations for the file might be incorrect.

    -

  • - -
  • If you compile some files with -g and some without, some - events that take place in a file without debug info could be attributed - to the last line of a file with debug info (whichever one gets placed - before the non-debug-info file in the executable).

    -

  • -
- -This list looks long, but these cases should be fairly rare.

- -Note: stabs is not an easy format to read. If you come across bizarre -annotations that look like might be caused by a bug in the stabs reader, -please let us know.

- - -

4.12  Accuracy

-Valgrind's cache profiling has a number of shortcomings: - -
    -
  • It doesn't account for kernel activity -- the effect of system calls on - the cache contents is ignored.
  • - -

  • It doesn't account for other process activity (although this is probably - desirable when considering a single program).
  • - -

  • It doesn't account for virtual-to-physical address mappings; hence the - entire simulation is not a true representation of what's happening in the - cache.
  • - -

  • It doesn't account for cache misses not visible at the instruction level, - eg. those arising from TLB misses, or speculative execution.
  • - -

  • Valgrind's custom threads implementation will schedule threads - differently to the standard one. This could warp the results for - threaded programs. -
  • - -

  • The instructions bts, btr and btc - will incorrectly be counted as doing a data read if both the arguments - are registers, eg: - -
    btsl %eax, %edx
    - - This should only happen rarely. -
  • - -

  • FPU instructions with data sizes of 28 and 108 bytes (e.g. - fsave) are treated as though they only access 16 bytes. - These instructions seem to be rare so hopefully this won't affect - accuracy much. -
  • -

- -Another thing worth nothing is that results are very sensitive. Changing the -size of the valgrind.so file, the size of the program being -profiled, or even the length of its name can perturb the results. Variations -will be small, but don't expect perfectly repeatable results if your program -changes at all.

- -While these factors mean you shouldn't trust the results to be super-accurate, -hopefully they should be close enough to be useful.

- - -

4.13  Todo

-
    -
  • Program start-up/shut-down calls a lot of functions that aren't - interesting and just complicate the output. Would be nice to exclude - these somehow.
  • -

    -

- - - diff --git a/VEX/head20041019/cachegrind/docs/cg_techdocs.html b/VEX/head20041019/cachegrind/docs/cg_techdocs.html deleted file mode 100644 index 0ac5b6759..000000000 --- a/VEX/head20041019/cachegrind/docs/cg_techdocs.html +++ /dev/null @@ -1,458 +0,0 @@ - - - - How Cachegrind works - - - - -  -

How Cachegrind works

- -
-Detailed technical notes for hackers, maintainers and the -overly-curious
-

-njn25@cam.ac.uk
-http://valgrind.kde.org
-

-Copyright © 2001-2003 Nick Nethercote -

-

- -

- - - - -


- -

Cache profiling

-Valgrind is a very nice platform for doing cache profiling and other kinds of -simulation, because it converts horrible x86 instructions into nice clean -RISC-like UCode. For example, for cache profiling we are interested in -instructions that read and write memory; in UCode there are only four -instructions that do this: LOAD, STORE, -FPU_R and FPU_W. By contrast, because of the x86 -addressing modes, almost every instruction can read or write memory.

- -Most of the cache profiling machinery is in the file -vg_cachesim.c.

- -These notes are a somewhat haphazard guide to how Valgrind's cache profiling -works.

- -

Cost centres

-Valgrind gathers cache profiling about every instruction executed, -individually. Each instruction has a cost centre associated with it. -There are two kinds of cost centre: one for instructions that don't reference -memory (iCC), and one for instructions that do -(idCC): - -
-typedef struct _CC {
-   ULong a;
-   ULong m1;
-   ULong m2;
-} CC;
-
-typedef struct _iCC {
-   /* word 1 */
-   UChar tag;
-   UChar instr_size;
-
-   /* words 2+ */
-   Addr instr_addr;
-   CC I;
-} iCC;
-   
-typedef struct _idCC {
-   /* word 1 */
-   UChar tag;
-   UChar instr_size;
-   UChar data_size;
-
-   /* words 2+ */
-   Addr instr_addr;
-   CC I; 
-   CC D; 
-} idCC; 
-
- -Each CC has three fields a, m1, -m2 for recording references, level 1 misses and level 2 misses. -Each of these is a 64-bit ULong -- the numbers can get very large, -ie. greater than 4.2 billion allowed by a 32-bit unsigned int.

- -A iCC has one CC for instruction cache accesses. A -idCC has two, one for instruction cache accesses, and one for data -cache accesses.

- -The iCC and dCC structs also store unchanging -information about the instruction: -

    -
  • An instruction-type identification tag (explained below)
  • -

  • Instruction size
  • -

  • Data reference size (idCC only)
  • -

  • Instruction address
  • -

- -Note that data address is not one of the fields for idCC. This is -because for many memory-referencing instructions the data address can change -each time it's executed (eg. if it uses register-offset addressing). We have -to give this item to the cache simulation in a different way (see -Instrumentation section below). Some memory-referencing instructions do always -reference the same address, but we don't try to treat them specialy in order to -keep things simple.

- -Also note that there is only room for recording info about one data cache -access in an idCC. So what about instructions that do a read then -a write, such as: - -

inc %(esi)
- -In a write-allocate cache, as simulated by Valgrind, the write cannot miss, -since it immediately follows the read which will drag the block into the cache -if it's not already there. So the write access isn't really interesting, and -Valgrind doesn't record it. This means that Valgrind doesn't measure -memory references, but rather memory references that could miss in the cache. -This behaviour is the same as that used by the AMD Athlon hardware counters. -It also has the benefit of simplifying the implementation -- instructions that -read and write memory can be treated like instructions that read memory.

- -

Storing cost-centres

-Cost centres are stored in a way that makes them very cheap to lookup, which is -important since one is looked up for every original x86 instruction -executed.

- -Valgrind does JIT translations at the basic block level, and cost centres are -also setup and stored at the basic block level. By doing things carefully, we -store all the cost centres for a basic block in a contiguous array, and lookup -comes almost for free.

- -Consider this part of a basic block (for exposition purposes, pretend it's an -entire basic block): - -

-movl $0x0,%eax
-movl $0x99, -4(%ebp)
-
- -The translation to UCode looks like this: - -
-MOVL      $0x0, t20
-PUTL      t20, %EAX
-INCEIPo   $5
-
-LEA1L     -4(t4), t14
-MOVL      $0x99, t18
-STL       t18, (t14)
-INCEIPo   $7
-
- -The first step is to allocate the cost centres. This requires a preliminary -pass to count how many x86 instructions were in the basic block, and their -types (and thus sizes). UCode translations for single x86 instructions are -delimited by the INCEIPo instruction, the argument of which gives -the byte size of the instruction (note that lazy INCEIP updating is turned off -to allow this).

- -We can tell if an x86 instruction references memory by looking for -LDL and STL UCode instructions, and thus what kind of -cost centre is required. From this we can determine how many cost centres we -need for the basic block, and their sizes. We can then allocate them in a -single array.

- -Consider the example code above. After the preliminary pass, we know we need -two cost centres, one iCC and one dCC. So we -allocate an array to store these which looks like this: - -

-|(uninit)|      tag         (1 byte)
-|(uninit)|      instr_size  (1 bytes)
-|(uninit)|      (padding)   (2 bytes)
-|(uninit)|      instr_addr  (4 bytes)
-|(uninit)|      I.a         (8 bytes)
-|(uninit)|      I.m1        (8 bytes)
-|(uninit)|      I.m2        (8 bytes)
-
-|(uninit)|      tag         (1 byte)
-|(uninit)|      instr_size  (1 byte)
-|(uninit)|      data_size   (1 byte)
-|(uninit)|      (padding)   (1 byte)
-|(uninit)|      instr_addr  (4 bytes)
-|(uninit)|      I.a         (8 bytes)
-|(uninit)|      I.m1        (8 bytes)
-|(uninit)|      I.m2        (8 bytes)
-|(uninit)|      D.a         (8 bytes)
-|(uninit)|      D.m1        (8 bytes)
-|(uninit)|      D.m2        (8 bytes)
-
- -(We can see now why we need tags to distinguish between the two types of cost -centres.)

- -We also record the size of the array. We look up the debug info of the first -instruction in the basic block, and then stick the array into a table indexed -by filename and function name. This makes it easy to dump the information -quickly to file at the end.

- -

Instrumentation

-The instrumentation pass has two main jobs: - -
    -
  1. Fill in the gaps in the allocated cost centres.
  2. -

  3. Add UCode to call the cache simulator for each instruction.
  4. -

- -The instrumentation pass steps through the UCode and the cost centres in -tandem. As each original x86 instruction's UCode is processed, the appropriate -gaps in the instructions cost centre are filled in, for example: - -
-|INSTR_CC|      tag         (1 byte)
-|5       |      instr_size  (1 bytes)
-|(uninit)|      (padding)   (2 bytes)
-|i_addr1 |      instr_addr  (4 bytes)
-|0       |      I.a         (8 bytes)
-|0       |      I.m1        (8 bytes)
-|0       |      I.m2        (8 bytes)
-
-|WRITE_CC|      tag         (1 byte)
-|7       |      instr_size  (1 byte)
-|4       |      data_size   (1 byte)
-|(uninit)|      (padding)   (1 byte)
-|i_addr2 |      instr_addr  (4 bytes)
-|0       |      I.a         (8 bytes)
-|0       |      I.m1        (8 bytes)
-|0       |      I.m2        (8 bytes)
-|0       |      D.a         (8 bytes)
-|0       |      D.m1        (8 bytes)
-|0       |      D.m2        (8 bytes)
-
- -(Note that this step is not performed if a basic block is re-translated; see -here for more information.)

- -GCC inserts padding before the instr_size field so that it is word -aligned.

- -The instrumentation added to call the cache simulation function looks like this -(instrumentation is indented to distinguish it from the original UCode): - -

-MOVL      $0x0, t20
-PUTL      t20, %EAX
-  PUSHL     %eax
-  PUSHL     %ecx
-  PUSHL     %edx
-  MOVL      $0x4091F8A4, t46  # address of 1st CC
-  PUSHL     t46
-  CALLMo    $0x12             # second cachesim function
-  CLEARo    $0x4
-  POPL      %edx
-  POPL      %ecx
-  POPL      %eax
-INCEIPo   $5
-
-LEA1L     -4(t4), t14
-MOVL      $0x99, t18
-  MOVL      t14, t42
-STL       t18, (t14)
-  PUSHL     %eax
-  PUSHL     %ecx
-  PUSHL     %edx
-  PUSHL     t42
-  MOVL      $0x4091F8C4, t44  # address of 2nd CC
-  PUSHL     t44
-  CALLMo    $0x13             # second cachesim function
-  CLEARo    $0x8
-  POPL      %edx
-  POPL      %ecx
-  POPL      %eax
-INCEIPo   $7
-
- -Consider the first instruction's UCode. Each call is surrounded by three -PUSHL and POPL instructions to save and restore the -caller-save registers. Then the address of the instruction's cost centre is -pushed onto the stack, to be the first argument to the cache simulation -function. The address is known at this point because we are doing a -simultaneous pass through the cost centre array. This means the cost centre -lookup for each instruction is almost free (just the cost of pushing an -argument for a function call). Then the call to the cache simulation function -for non-memory-reference instructions is made (note that the -CALLMo UInstruction takes an offset into a table of predefined -functions; it is not an absolute address), and the single argument is -CLEARed from the stack.

- -The second instruction's UCode is similar. The only difference is that, as -mentioned before, we have to pass the address of the data item referenced to -the cache simulation function too. This explains the MOVL t14, -t42 and PUSHL t42 UInstructions. (Note that the seemingly -redundant MOVing will probably be optimised away during register -allocation.)

- -Note that instead of storing unchanging information about each instruction -(instruction size, data size, etc) in its cost centre, we could have passed in -these arguments to the simulation function. But this would slow the calls down -(two or three extra arguments pushed onto the stack). Also it would bloat the -UCode instrumentation by amounts similar to the space required for them in the -cost centre; bloated UCode would also fill the translation cache more quickly, -requiring more translations for large programs and slowing them down more.

- - -

Handling basic block retranslations

-The above description ignores one complication. Valgrind has a limited size -cache for basic block translations; if it fills up, old translations are -discarded. If a discarded basic block is executed again, it must be -re-translated.

- -However, we can't use this approach for profiling -- we can't throw away cost -centres for instructions in the middle of execution! So when a basic block is -translated, we first look for its cost centre array in the hash table. If -there is no cost centre array, it must be the first translation, so we proceed -as described above. But if there is a cost centre array already, it must be a -retranslation. In this case, we skip the cost centre allocation and -initialisation steps, but still do the UCode instrumentation step.

- -

The cache simulation

-The cache simulation is fairly straightforward. It just tracks which memory -blocks are in the cache at the moment (it doesn't track the contents, since -that is irrelevant).

- -The interface to the simulation is quite clean. The functions called from the -UCode contain calls to the simulation functions in the files -vg_cachesim_{I1,D1,L2}.c; these calls are inlined so that only -one function call is done per simulated x86 instruction. The file -vg_cachesim.c simply #includes the three files -containing the simulation, which makes plugging in new cache simulations is -very easy -- you just replace the three files and recompile.

- -

Output

-Output is fairly straightforward, basically printing the cost centre for every -instruction, grouped by files and functions. Total counts (eg. total cache -accesses, total L1 misses) are calculated when traversing this structure rather -than during execution, to save time; the cache simulation functions are called -so often that even one or two extra adds can make a sizeable difference.

- -Input file has the following format: - -

-file         ::= desc_line* cmd_line events_line data_line+ summary_line
-desc_line    ::= "desc:" ws? non_nl_string
-cmd_line     ::= "cmd:" ws? cmd
-events_line  ::= "events:" ws? (event ws)+
-data_line    ::= file_line | fn_line | count_line
-file_line    ::= ("fl=" | "fi=" | "fe=") filename
-fn_line      ::= "fn=" fn_name
-count_line   ::= line_num ws? (count ws)+
-summary_line ::= "summary:" ws? (count ws)+
-count        ::= num | "."
-
- -Where: - -
    -
  • non_nl_string is any string not containing a newline.
  • -

  • cmd is a command line invocation.
  • -

  • filename and fn_name can be anything.
  • -

  • num and line_num are decimal numbers.
  • -

  • ws is whitespace.
  • -

  • nl is a newline.
  • -

- -The contents of the "desc:" lines is printed out at the top of the summary. -This is a generic way of providing simulation specific information, eg. for -giving the cache configuration for cache simulation.

- -Counts can be "." to represent "N/A", eg. the number of write misses for an -instruction that doesn't write to memory.

- -The number of counts in each line and the -summary_line should not exceed the number of events in the -event_line. If the number in each line is less, -cg_annotate treats those missing as though they were a "." entry.

- -A file_line changes the current file name. A fn_line -changes the current function name. A count_line contains counts -that pertain to the current filename/fn_name. A "fn=" file_line -and a fn_line must appear before any count_lines to -give the context of the first count_lines.

- -Each file_line should be immediately followed by a -fn_line. "fi=" file_lines are used to switch -filenames for inlined functions; "fe=" file_lines are similar, but -are put at the end of a basic block in which the file name hasn't been switched -back to the original file name. (fi and fe lines behave the same, they are -only distinguished to help debugging.)

- - -

Summary of performance features

-Quite a lot of work has gone into making the profiling as fast as possible. -This is a summary of the important features: - -
    -
  • The basic block-level cost centre storage allows almost free cost centre - lookup.
  • - -

  • Only one function call is made per instruction simulated; even this - accounts for a sizeable percentage of execution time, but it seems - unavoidable if we want flexibility in the cache simulator.
  • - -

  • Unchanging information about an instruction is stored in its cost centre, - avoiding unnecessary argument pushing, and minimising UCode - instrumentation bloat.
  • - -

  • Summary counts are calculated at the end, rather than during - execution.
  • - -

  • The cachegrind.out output files can contain huge amounts of - information; file format was carefully chosen to minimise file - sizes.
  • -

- - -

Annotation

-Annotation is done by cg_annotate. It is a fairly straightforward Perl script -that slurps up all the cost centres, and then runs through all the chosen -source files, printing out cost centres with them. It too has been carefully -optimised. - - -

Similar work, extensions

-It would be relatively straightforward to do other simulations and obtain -line-by-line information about interesting events. A good example would be -branch prediction -- all branches could be instrumented to interact with a -branch prediction simulator, using very similar techniques to those described -above.

- -In particular, cg_annotate would not need to change -- the file format is such -that it is not specific to the cache simulation, but could be used for any kind -of line-by-line information. The only part of cg_annotate that is specific to -the cache simulation is the name of the input file -(cachegrind.out), although it would be very simple to add an -option to control this.

- - - diff --git a/VEX/head20041019/cachegrind/tests/.cvsignore b/VEX/head20041019/cachegrind/tests/.cvsignore deleted file mode 100644 index 768ce5ccf..000000000 --- a/VEX/head20041019/cachegrind/tests/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -Makefile.in -Makefile -chdir -dlclose -fpu-28-108 -cachegrind.out -cachegrind.out.* -*.stdout.diff -*.stderr.diff -*.stdout.out -*.stderr.out diff --git a/VEX/head20041019/cachegrind/tests/CVS/Entries b/VEX/head20041019/cachegrind/tests/CVS/Entries deleted file mode 100644 index 243e8762e..000000000 --- a/VEX/head20041019/cachegrind/tests/CVS/Entries +++ /dev/null @@ -1,37 +0,0 @@ -/.cvsignore/1.2/Wed May 28 01:02:46 2003// -/Makefile.am/1.12/Sat Mar 27 18:02:36 2004// -/chdir.c/1.1/Wed Apr 30 20:23:56 2003// -/chdir.stderr.exp/1.1/Wed Apr 30 20:23:58 2003// -/chdir.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/dlclose.c/1.2/Mon Sep 23 09:36:24 2002// -/dlclose.stderr.exp/1.5/Wed Nov 19 20:09:53 2003// -/dlclose.stdout.exp/1.2/Mon Sep 23 09:36:24 2002// -/dlclose.vgtest/1.5/Sat Apr 17 17:25:08 2004// -/filter_cachesim_discards/1.4/Mon May 5 16:18:50 2003// -/filter_stderr/1.4/Mon May 5 16:18:51 2003// -/fpu-28-108.S/1.2/Mon Sep 23 09:36:24 2002// -/fpu-28-108.stderr.exp/1.2/Mon Sep 23 09:36:24 2002// -/fpu-28-108.vgtest/1.5/Sat Apr 17 17:25:08 2004// -/insn_basic.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_cmov.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_fpu.stderr.exp/1.1/Sat Mar 27 18:02:36 2004// -/insn_fpu.stdout.exp/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_mmx.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_mmxext.stderr.exp/1.2/Tue Mar 9 08:50:02 2004// -/insn_mmxext.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_mmxext.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_sse.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_sse.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/insn_sse2.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stdout.exp/1.2/Sun Jul 25 15:18:20 2004// -/insn_sse2.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/myprint.c/1.2/Mon Sep 23 09:36:24 2002// -D diff --git a/VEX/head20041019/cachegrind/tests/CVS/Repository b/VEX/head20041019/cachegrind/tests/CVS/Repository deleted file mode 100644 index ca8962341..000000000 --- a/VEX/head20041019/cachegrind/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/cachegrind/tests diff --git a/VEX/head20041019/cachegrind/tests/CVS/Root b/VEX/head20041019/cachegrind/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/cachegrind/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/cachegrind/tests/CVS/Template b/VEX/head20041019/cachegrind/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/Makefile.am b/VEX/head20041019/cachegrind/tests/Makefile.am deleted file mode 100644 index cb3115d7e..000000000 --- a/VEX/head20041019/cachegrind/tests/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -noinst_SCRIPTS = filter_stderr filter_cachesim_discards - -INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2 - -EXTRA_DIST = $(noinst_SCRIPTS) \ - chdir.vgtest chdir.stderr.exp \ - dlclose.vgtest dlclose.stderr.exp dlclose.stdout.exp \ - fpu-28-108.vgtest fpu-28-108.stderr.exp \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ - $(addsuffix .stdout.exp,$(INSN_TESTS)) \ - $(addsuffix .vgtest,$(INSN_TESTS)) - -check_PROGRAMS = \ - chdir dlclose fpu-28-108 myprint.so - -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -AM_CXXFLAGS = $(AM_CFLAGS) -AM_CCASFLAGS = $(AM_CFLAGS) - -# C ones -chdir_SOURCES = chdir.c -dlclose_SOURCES = dlclose.c -dlclose_LDADD = -ldl -myprint_so_SOURCES = myprint.c -myprint_so_LDFLAGS = -shared - -fpu_28_108_SOURCES = fpu-28-108.S diff --git a/VEX/head20041019/cachegrind/tests/chdir.c b/VEX/head20041019/cachegrind/tests/chdir.c deleted file mode 100644 index 9b681cfc4..000000000 --- a/VEX/head20041019/cachegrind/tests/chdir.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -// Before the bug was fixed, if a program changed working directory, things -// would break and the cachegrind.out. file wouldn't get written. -int main(void) -{ - chdir(".."); - - return 0; -} diff --git a/VEX/head20041019/cachegrind/tests/chdir.stderr.exp b/VEX/head20041019/cachegrind/tests/chdir.stderr.exp deleted file mode 100644 index 8eaf65446..000000000 --- a/VEX/head20041019/cachegrind/tests/chdir.stderr.exp +++ /dev/null @@ -1,17 +0,0 @@ - - -I refs: -I1 misses: -L2i misses: -I1 miss rate: -L2i miss rate: - -D refs: -D1 misses: -L2d misses: -D1 miss rate: -L2d miss rate: - -L2 refs: -L2 misses: -L2 miss rate: diff --git a/VEX/head20041019/cachegrind/tests/chdir.vgtest b/VEX/head20041019/cachegrind/tests/chdir.vgtest deleted file mode 100644 index c91b4b673..000000000 --- a/VEX/head20041019/cachegrind/tests/chdir.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: chdir -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/dlclose.c b/VEX/head20041019/cachegrind/tests/dlclose.c deleted file mode 100644 index 9fee03088..000000000 --- a/VEX/head20041019/cachegrind/tests/dlclose.c +++ /dev/null @@ -1,38 +0,0 @@ -/* This exercises the code that was causing this bug: - - valgrind: vg_cachesim.c:389 (get_BBCC): Assertion `((Bool)0) == remove' - failed. - - in Cachegrind 1.0.0 and 1.0.1, that was caused by unloading symbols before - invalidating translations. -*/ - -#include -#include -#include - -int main(int argc, char **argv) { - void *handle; - void (*myprint)(void); - char *error; - - handle = dlopen ("./myprint.so", RTLD_LAZY); - if (!handle) { - fputs (dlerror(), stderr); - exit(1); - } - - myprint = dlsym(handle, "myprint"); - if ((error = dlerror()) != NULL) { - fprintf (stderr, "%s\n", error); - exit(1); - } - - (*myprint)(); - - /* Assertion failure was happening here */ - dlclose(handle); - - return 0; -} - diff --git a/VEX/head20041019/cachegrind/tests/dlclose.stderr.exp b/VEX/head20041019/cachegrind/tests/dlclose.stderr.exp deleted file mode 100644 index 8eaf65446..000000000 --- a/VEX/head20041019/cachegrind/tests/dlclose.stderr.exp +++ /dev/null @@ -1,17 +0,0 @@ - - -I refs: -I1 misses: -L2i misses: -I1 miss rate: -L2i miss rate: - -D refs: -D1 misses: -L2d misses: -D1 miss rate: -L2d miss rate: - -L2 refs: -L2 misses: -L2 miss rate: diff --git a/VEX/head20041019/cachegrind/tests/dlclose.stdout.exp b/VEX/head20041019/cachegrind/tests/dlclose.stdout.exp deleted file mode 100644 index 890082f48..000000000 --- a/VEX/head20041019/cachegrind/tests/dlclose.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -This is myprint! diff --git a/VEX/head20041019/cachegrind/tests/dlclose.vgtest b/VEX/head20041019/cachegrind/tests/dlclose.vgtest deleted file mode 100644 index 353a3243a..000000000 --- a/VEX/head20041019/cachegrind/tests/dlclose.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: dlclose -stderr_filter: filter_cachesim_discards -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/filter_cachesim_discards b/VEX/head20041019/cachegrind/tests/filter_cachesim_discards deleted file mode 100755 index d184c4f0b..000000000 --- a/VEX/head20041019/cachegrind/tests/filter_cachesim_discards +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/filter_stderr | - -# Anonymise paths like "/local/foo/bar/tests/baz/quux" (note "tests" is there) -sed "s/\/.*\/tests\//\/...\/tests\//" diff --git a/VEX/head20041019/cachegrind/tests/filter_stderr b/VEX/head20041019/cachegrind/tests/filter_stderr deleted file mode 100755 index 1dad41acf..000000000 --- a/VEX/head20041019/cachegrind/tests/filter_stderr +++ /dev/null @@ -1,16 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | - -# Remove numbers from I/D/L2 "refs:" lines -sed "s/\(\(I\|D\|L2\) *refs:\)[ 0-9,()+rdw]*$/\1/" | - -# Remove numbers from I1/D1/L2/L2i/L2d "misses:" and "miss rates:" lines -sed "s/\(\(I1\|D1\|L2\|L2i\|L2d\) *\(misses\|miss rate\):\)[ 0-9,()+rdw%\.]*$/\1/" | - -# Remove warnings lines for P4s: -sed "/warning: Pentium with 12 K micro-op instruction trace cache/d" | -sed "/Simulating a 16 KB cache with 32 B lines/d" - diff --git a/VEX/head20041019/cachegrind/tests/fpu-28-108.S b/VEX/head20041019/cachegrind/tests/fpu-28-108.S deleted file mode 100644 index f655c00f7..000000000 --- a/VEX/head20041019/cachegrind/tests/fpu-28-108.S +++ /dev/null @@ -1,24 +0,0 @@ -/* Test 28 and 108 byte loads and stores. (Just make sure program - runs without any assertion failures from V.) */ - -/* Useful listing: - gcc -o tests/fpu_28_108 tests/fpu_28_108.S -Wa,-a */ - -.data -fooble: - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -bar: - -.text -.globl main -main: - fstsw fooble - fsave fooble - frstor fooble - fstenv fooble - fldenv fooble - movl $0, %eax - ret - diff --git a/VEX/head20041019/cachegrind/tests/fpu-28-108.stderr.exp b/VEX/head20041019/cachegrind/tests/fpu-28-108.stderr.exp deleted file mode 100644 index 8eaf65446..000000000 --- a/VEX/head20041019/cachegrind/tests/fpu-28-108.stderr.exp +++ /dev/null @@ -1,17 +0,0 @@ - - -I refs: -I1 misses: -L2i misses: -I1 miss rate: -L2i miss rate: - -D refs: -D1 misses: -L2d misses: -D1 miss rate: -L2d miss rate: - -L2 refs: -L2 misses: -L2 miss rate: diff --git a/VEX/head20041019/cachegrind/tests/fpu-28-108.vgtest b/VEX/head20041019/cachegrind/tests/fpu-28-108.vgtest deleted file mode 100644 index 48cc454c8..000000000 --- a/VEX/head20041019/cachegrind/tests/fpu-28-108.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: fpu-28-108 -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_basic.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_basic.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_basic.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_basic.stdout.exp deleted file mode 100644 index 40cabbcd0..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_basic.stdout.exp +++ /dev/null @@ -1,1083 +0,0 @@ -aaa_1 ... ok -aaa_2 ... ok -aaa_3 ... ok -aaa_4 ... ok -aaa_5 ... ok -aaa_6 ... ok -aaa_7 ... ok -aaa_8 ... ok -aad_1 ... ok -aad_2 ... ok -aam_1 ... ok -aam_2 ... ok -aas_1 ... ok -aas_2 ... ok -aas_3 ... ok -aas_4 ... ok -aas_5 ... ok -aas_6 ... ok -aas_7 ... ok -aas_8 ... ok -adcb_1 ... ok -adcb_2 ... ok -adcb_3 ... ok -adcb_4 ... ok -adcb_5 ... ok -adcb_6 ... ok -adcb_7 ... ok -adcb_8 ... ok -adcb_9 ... ok -adcb_10 ... ok -adcb_11 ... ok -adcb_12 ... ok -adcw_1 ... ok -adcw_2 ... ok -adcw_3 ... ok -adcw_4 ... ok -adcw_5 ... ok -adcw_6 ... ok -adcw_7 ... ok -adcw_8 ... ok -adcw_9 ... ok -adcw_10 ... ok -adcw_11 ... ok -adcw_12 ... ok -adcw_13 ... ok -adcw_14 ... ok -adcl_1 ... ok -adcl_2 ... ok -adcl_3 ... ok -adcl_4 ... ok -adcl_5 ... ok -adcl_6 ... ok -adcl_7 ... ok -adcl_8 ... ok -adcl_9 ... ok -adcl_10 ... ok -adcl_11 ... ok -adcl_12 ... ok -adcl_13 ... ok -adcl_14 ... ok -addb_1 ... ok -addb_2 ... ok -addb_3 ... ok -addb_4 ... ok -addb_5 ... ok -addb_6 ... ok -addw_1 ... ok -addw_2 ... ok -addw_3 ... ok -addw_4 ... ok -addw_5 ... ok -addw_6 ... ok -addw_7 ... ok -addl_1 ... ok -addl_2 ... ok -addl_3 ... ok -addl_4 ... ok -addl_5 ... ok -addl_6 ... ok -addl_7 ... ok -andb_1 ... ok -andb_2 ... ok -andb_3 ... ok -andb_4 ... ok -andb_5 ... ok -andb_6 ... ok -andw_1 ... ok -andw_2 ... ok -andw_3 ... ok -andw_4 ... ok -andw_5 ... ok -andw_6 ... ok -andw_7 ... ok -andl_1 ... ok -andl_2 ... ok -andl_3 ... ok -andl_4 ... ok -andl_5 ... ok -andl_6 ... ok -andl_7 ... ok -bsfw_1 ... ok -bsfw_2 ... ok -bsfl_1 ... ok -bsfl_2 ... ok -bsrw_1 ... ok -bsrw_2 ... ok -bsrl_1 ... ok -bsrl_2 ... ok -bswapl_1 ... ok -btw_1 ... ok -btw_2 ... ok -btw_3 ... ok -btw_4 ... ok -btw_5 ... ok -btw_6 ... ok -btw_7 ... ok -btw_8 ... ok -btl_1 ... ok -btl_2 ... ok -btl_3 ... ok -btl_4 ... ok -btl_5 ... ok -btl_6 ... ok -btl_7 ... ok -btl_8 ... ok -btcw_1 ... ok -btcw_2 ... ok -btcw_3 ... ok -btcw_4 ... ok -btcw_5 ... ok -btcw_6 ... ok -btcw_7 ... ok -btcw_8 ... ok -btcl_1 ... ok -btcl_2 ... ok -btcl_3 ... ok -btcl_4 ... ok -btcl_5 ... ok -btcl_6 ... ok -btcl_7 ... ok -btcl_8 ... ok -btrw_1 ... ok -btrw_2 ... ok -btrw_3 ... ok -btrw_4 ... ok -btrw_5 ... ok -btrw_6 ... ok -btrw_7 ... ok -btrw_8 ... ok -btrl_1 ... ok -btrl_2 ... ok -btrl_3 ... ok -btrl_4 ... ok -btrl_5 ... ok -btrl_6 ... ok -btrl_7 ... ok -btrl_8 ... ok -btsw_1 ... ok -btsw_2 ... ok -btsw_3 ... ok -btsw_4 ... ok -btsw_5 ... ok -btsw_6 ... ok -btsw_7 ... ok -btsw_8 ... ok -btsl_1 ... ok -btsl_2 ... ok -btsl_3 ... ok -btsl_4 ... ok -btsl_5 ... ok -btsl_6 ... ok -btsl_7 ... ok -btsl_8 ... ok -cbw_1 ... ok -cbw_2 ... ok -cdq_1 ... ok -cdq_2 ... ok -clc_1 ... ok -clc_2 ... ok -cld_1 ... ok -cld_2 ... ok -cmc_1 ... ok -cmc_2 ... ok -cmpb_1 ... ok -cmpb_2 ... ok -cmpb_3 ... ok -cmpb_4 ... ok -cmpb_5 ... ok -cmpb_6 ... ok -cmpb_7 ... ok -cmpb_8 ... ok -cmpb_9 ... ok -cmpb_10 ... ok -cmpb_11 ... ok -cmpb_12 ... ok -cmpb_13 ... ok -cmpb_14 ... ok -cmpb_15 ... ok -cmpb_16 ... ok -cmpb_17 ... ok -cmpb_18 ... ok -cmpb_19 ... ok -cmpb_20 ... ok -cmpb_21 ... ok -cmpb_22 ... ok -cmpb_23 ... ok -cmpb_24 ... ok -cmpb_25 ... ok -cmpb_26 ... ok -cmpb_27 ... ok -cmpb_28 ... ok -cmpb_29 ... ok -cmpb_30 ... ok -cmpb_31 ... ok -cmpb_32 ... ok -cmpb_33 ... ok -cmpb_34 ... ok -cmpb_35 ... ok -cmpb_36 ... ok -cmpb_37 ... ok -cmpb_38 ... ok -cmpb_39 ... ok -cmpb_40 ... ok -cmpb_41 ... ok -cmpb_42 ... ok -cmpb_43 ... ok -cmpb_44 ... ok -cmpb_45 ... ok -cmpb_46 ... ok -cmpb_47 ... ok -cmpb_48 ... ok -cmpb_49 ... ok -cmpb_50 ... ok -cmpb_51 ... ok -cmpb_52 ... ok -cmpb_53 ... ok -cmpb_54 ... ok -cmpb_55 ... ok -cmpb_56 ... ok -cmpb_57 ... ok -cmpb_58 ... ok -cmpb_59 ... ok -cmpb_60 ... ok -cmpw_1 ... ok -cmpw_2 ... ok -cmpw_3 ... ok -cmpw_4 ... ok -cmpw_5 ... ok -cmpw_6 ... ok -cmpw_7 ... ok -cmpw_8 ... ok -cmpw_9 ... ok -cmpw_10 ... ok -cmpw_11 ... ok -cmpw_12 ... ok -cmpw_13 ... ok -cmpw_14 ... ok -cmpw_15 ... ok -cmpw_16 ... ok -cmpw_17 ... ok -cmpw_18 ... ok -cmpw_19 ... ok -cmpw_20 ... ok -cmpw_21 ... ok -cmpw_22 ... ok -cmpw_23 ... ok -cmpw_24 ... ok -cmpw_25 ... ok -cmpw_26 ... ok -cmpw_27 ... ok -cmpw_28 ... ok -cmpw_29 ... ok -cmpw_30 ... ok -cmpw_31 ... ok -cmpw_32 ... ok -cmpw_33 ... ok -cmpw_34 ... ok -cmpw_35 ... ok -cmpw_36 ... ok -cmpw_37 ... ok -cmpw_38 ... ok -cmpw_39 ... ok -cmpw_40 ... ok -cmpw_41 ... ok -cmpw_42 ... ok -cmpw_43 ... ok -cmpw_44 ... ok -cmpw_45 ... ok -cmpw_46 ... ok -cmpw_47 ... ok -cmpw_48 ... ok -cmpw_49 ... ok -cmpw_50 ... ok -cmpw_51 ... ok -cmpw_52 ... ok -cmpw_53 ... ok -cmpw_54 ... ok -cmpw_55 ... ok -cmpw_56 ... ok -cmpw_57 ... ok -cmpw_58 ... ok -cmpw_59 ... ok -cmpw_60 ... ok -cmpw_61 ... ok -cmpw_62 ... ok -cmpw_63 ... ok -cmpw_64 ... ok -cmpw_65 ... ok -cmpw_66 ... ok -cmpw_67 ... ok -cmpw_68 ... ok -cmpw_69 ... ok -cmpw_70 ... ok -cmpw_71 ... ok -cmpw_72 ... ok -cmpw_73 ... ok -cmpw_74 ... ok -cmpw_75 ... ok -cmpw_76 ... ok -cmpw_77 ... ok -cmpw_78 ... ok -cmpw_79 ... ok -cmpw_80 ... ok -cmpl_1 ... ok -cmpl_2 ... ok -cmpl_3 ... ok -cmpl_4 ... ok -cmpl_5 ... ok -cmpl_6 ... ok -cmpl_7 ... ok -cmpl_8 ... ok -cmpl_9 ... ok -cmpl_10 ... ok -cmpl_11 ... ok -cmpl_12 ... ok -cmpl_13 ... ok -cmpl_14 ... ok -cmpl_15 ... ok -cmpl_16 ... ok -cmpl_17 ... ok -cmpl_18 ... ok -cmpl_19 ... ok -cmpl_20 ... ok -cmpl_21 ... ok -cmpl_22 ... ok -cmpl_23 ... ok -cmpl_24 ... ok -cmpl_25 ... ok -cmpl_26 ... ok -cmpl_27 ... ok -cmpl_28 ... ok -cmpl_29 ... ok -cmpl_30 ... ok -cmpl_31 ... ok -cmpl_32 ... ok -cmpl_33 ... ok -cmpl_34 ... ok -cmpl_35 ... ok -cmpl_36 ... ok -cmpl_37 ... ok -cmpl_38 ... ok -cmpl_39 ... ok -cmpl_40 ... ok -cmpl_41 ... ok -cmpl_42 ... ok -cmpl_43 ... ok -cmpl_44 ... ok -cmpl_45 ... ok -cmpl_46 ... ok -cmpl_47 ... ok -cmpl_48 ... ok -cmpl_49 ... ok -cmpl_50 ... ok -cmpl_51 ... ok -cmpl_52 ... ok -cmpl_53 ... ok -cmpl_54 ... ok -cmpl_55 ... ok -cmpl_56 ... ok -cmpl_57 ... ok -cmpl_58 ... ok -cmpl_59 ... ok -cmpl_60 ... ok -cmpl_61 ... ok -cmpl_62 ... ok -cmpl_63 ... ok -cmpl_64 ... ok -cmpl_65 ... ok -cmpl_66 ... ok -cmpl_67 ... ok -cmpl_68 ... ok -cmpl_69 ... ok -cmpl_70 ... ok -cmpl_71 ... ok -cmpl_72 ... ok -cmpl_73 ... ok -cmpl_74 ... ok -cmpl_75 ... ok -cmpl_76 ... ok -cmpl_77 ... ok -cmpl_78 ... ok -cmpl_79 ... ok -cmpl_80 ... ok -cmpxchgb_1 ... ok -cmpxchgb_2 ... ok -cmpxchgb_3 ... ok -cmpxchgb_4 ... ok -cmpxchgw_1 ... ok -cmpxchgw_2 ... ok -cmpxchgw_3 ... ok -cmpxchgw_4 ... ok -cmpxchgl_1 ... ok -cmpxchgl_2 ... ok -cmpxchgl_3 ... ok -cmpxchgl_4 ... ok -cwd_1 ... ok -cwd_2 ... ok -cwde_1 ... ok -cwde_2 ... ok -daa_1 ... ok -daa_2 ... ok -das_1 ... ok -decb_1 ... ok -decb_2 ... ok -decw_1 ... ok -decw_2 ... ok -decl_1 ... ok -decl_2 ... ok -divb_1 ... ok -divb_2 ... ok -divw_1 ... ok -divw_2 ... ok -divl_1 ... ok -divl_2 ... ok -idivb_1 ... ok -idivb_2 ... ok -idivw_1 ... ok -idivw_2 ... ok -idivl_1 ... ok -idivl_2 ... ok -imulb_1 ... ok -imulb_2 ... ok -imulw_1 ... ok -imulw_2 ... ok -imull_1 ... ok -imull_2 ... ok -imulw_3 ... ok -imulw_4 ... ok -imulw_5 ... ok -imulw_6 ... ok -imulw_7 ... ok -imulw_8 ... ok -imulw_9 ... ok -imulw_10 ... ok -imull_3 ... ok -imull_4 ... ok -imull_5 ... ok -imull_6 ... ok -imull_7 ... ok -imull_8 ... ok -imull_9 ... ok -imull_10 ... ok -incb_1 ... ok -incb_2 ... ok -incw_1 ... ok -incw_2 ... ok -incl_1 ... ok -incl_2 ... ok -lahf_1 ... ok -lahf_2 ... ok -movb_1 ... ok -movb_2 ... ok -movb_3 ... ok -movb_4 ... ok -movb_5 ... ok -movw_1 ... ok -movw_2 ... ok -movw_3 ... ok -movw_4 ... ok -movw_5 ... ok -movl_1 ... ok -movl_2 ... ok -movl_3 ... ok -movl_4 ... ok -movl_5 ... ok -movsbw_1 ... ok -movsbw_2 ... ok -movsbl_1 ... ok -movsbl_2 ... ok -movswl_1 ... ok -movswl_2 ... ok -movzbw_1 ... ok -movzbw_2 ... ok -movzbl_1 ... ok -movzbl_2 ... ok -movzwl_1 ... ok -movzwl_2 ... ok -mulb_1 ... ok -mulb_2 ... ok -mulw_1 ... ok -mulw_2 ... ok -mull_1 ... ok -mull_2 ... ok -negb_1 ... ok -negb_2 ... ok -negw_1 ... ok -negw_2 ... ok -negl_1 ... ok -negl_2 ... ok -notb_1 ... ok -notb_2 ... ok -notw_1 ... ok -notw_2 ... ok -notl_1 ... ok -notl_2 ... ok -orb_1 ... ok -orb_2 ... ok -orb_3 ... ok -orb_4 ... ok -orb_5 ... ok -orb_6 ... ok -orw_1 ... ok -orw_2 ... ok -orw_3 ... ok -orw_4 ... ok -orw_5 ... ok -orw_6 ... ok -orw_7 ... ok -orl_1 ... ok -orl_2 ... ok -orl_3 ... ok -orl_4 ... ok -orl_5 ... ok -orl_6 ... ok -orl_7 ... ok -rclb_1 ... ok -rclb_2 ... ok -rclb_3 ... ok -rclb_4 ... ok -rclb_5 ... ok -rclb_6 ... ok -rclw_1 ... ok -rclw_2 ... ok -rclw_3 ... ok -rclw_4 ... ok -rclw_5 ... ok -rclw_6 ... ok -rcll_1 ... ok -rcll_2 ... ok -rcll_3 ... ok -rcll_4 ... ok -rcll_5 ... ok -rcll_6 ... ok -rcrb_1 ... ok -rcrb_2 ... ok -rcrb_3 ... ok -rcrb_4 ... ok -rcrb_5 ... ok -rcrb_6 ... ok -rcrw_1 ... ok -rcrw_2 ... ok -rcrw_3 ... ok -rcrw_4 ... ok -rcrw_5 ... ok -rcrw_6 ... ok -rcrl_1 ... ok -rcrl_2 ... ok -rcrl_3 ... ok -rcrl_4 ... ok -rcrl_5 ... ok -rcrl_6 ... ok -rolb_1 ... ok -rolb_2 ... ok -rolb_3 ... ok -rolb_4 ... ok -rolb_5 ... ok -rolb_6 ... ok -rolw_1 ... ok -rolw_2 ... ok -rolw_3 ... ok -rolw_4 ... ok -rolw_5 ... ok -rolw_6 ... ok -roll_1 ... ok -roll_2 ... ok -roll_3 ... ok -roll_4 ... ok -roll_5 ... ok -roll_6 ... ok -rorb_1 ... ok -rorb_2 ... ok -rorb_3 ... ok -rorb_4 ... ok -rorb_5 ... ok -rorb_6 ... ok -rorw_1 ... ok -rorw_2 ... ok -rorw_3 ... ok -rorw_4 ... ok -rorw_5 ... ok -rorw_6 ... ok -rorl_1 ... ok -rorl_2 ... ok -rorl_3 ... ok -rorl_4 ... ok -rorl_5 ... ok -rorl_6 ... ok -sahf_1 ... ok -sahf_2 ... ok -salb_1 ... ok -salb_2 ... ok -salb_3 ... ok -salb_4 ... ok -salb_5 ... ok -salb_6 ... ok -salw_1 ... ok -salw_2 ... ok -salw_3 ... ok -salw_4 ... ok -salw_5 ... ok -salw_6 ... ok -sall_1 ... ok -sall_2 ... ok -sall_3 ... ok -sall_4 ... ok -sall_5 ... ok -sall_6 ... ok -sarb_1 ... ok -sarb_2 ... ok -sarb_3 ... ok -sarb_4 ... ok -sarb_5 ... ok -sarb_6 ... ok -sarw_1 ... ok -sarw_2 ... ok -sarw_3 ... ok -sarw_4 ... ok -sarw_5 ... ok -sarw_6 ... ok -sarl_1 ... ok -sarl_2 ... ok -sarl_3 ... ok -sarl_4 ... ok -sarl_5 ... ok -sarl_6 ... ok -sbbb_1 ... ok -sbbb_2 ... ok -sbbb_3 ... ok -sbbb_4 ... ok -sbbb_5 ... ok -sbbb_6 ... ok -sbbb_7 ... ok -sbbb_8 ... ok -sbbb_9 ... ok -sbbb_10 ... ok -sbbb_11 ... ok -sbbb_12 ... ok -sbbw_1 ... ok -sbbw_2 ... ok -sbbw_3 ... ok -sbbw_4 ... ok -sbbw_5 ... ok -sbbw_6 ... ok -sbbw_7 ... ok -sbbw_8 ... ok -sbbw_9 ... ok -sbbw_10 ... ok -sbbw_11 ... ok -sbbw_12 ... ok -sbbw_13 ... ok -sbbw_14 ... ok -sbbl_1 ... ok -sbbl_2 ... ok -sbbl_3 ... ok -sbbl_4 ... ok -sbbl_5 ... ok -sbbl_6 ... ok -sbbl_7 ... ok -sbbl_8 ... ok -sbbl_9 ... ok -sbbl_10 ... ok -sbbl_11 ... ok -sbbl_12 ... ok -sbbl_13 ... ok -sbbl_14 ... ok -seta_1 ... ok -seta_2 ... ok -seta_3 ... ok -seta_4 ... ok -seta_5 ... ok -seta_6 ... ok -seta_7 ... ok -seta_8 ... ok -setae_1 ... ok -setae_2 ... ok -setae_3 ... ok -setae_4 ... ok -setb_1 ... ok -setb_2 ... ok -setb_3 ... ok -setb_4 ... ok -setbe_1 ... ok -setbe_2 ... ok -setbe_3 ... ok -setbe_4 ... ok -setbe_5 ... ok -setbe_6 ... ok -setbe_7 ... ok -setbe_8 ... ok -setc_1 ... ok -setc_2 ... ok -setc_3 ... ok -setc_4 ... ok -sete_1 ... ok -sete_2 ... ok -sete_3 ... ok -sete_4 ... ok -setg_1 ... ok -setg_2 ... ok -setg_3 ... ok -setg_4 ... ok -setg_5 ... ok -setg_6 ... ok -setg_7 ... ok -setg_8 ... ok -setg_9 ... ok -setg_10 ... ok -setg_11 ... ok -setg_12 ... ok -setg_13 ... ok -setg_14 ... ok -setg_15 ... ok -setg_16 ... ok -setge_1 ... ok -setge_2 ... ok -setge_3 ... ok -setge_4 ... ok -setge_5 ... ok -setge_6 ... ok -setge_7 ... ok -setge_8 ... ok -setl_1 ... ok -setl_2 ... ok -setl_3 ... ok -setl_4 ... ok -setl_5 ... ok -setl_6 ... ok -setl_7 ... ok -setl_8 ... ok -setle_1 ... ok -setle_2 ... ok -setle_3 ... ok -setle_4 ... ok -setle_5 ... ok -setle_6 ... ok -setle_7 ... ok -setle_8 ... ok -setle_9 ... ok -setle_10 ... ok -setle_11 ... ok -setle_12 ... ok -setle_13 ... ok -setle_14 ... ok -setle_15 ... ok -setle_16 ... ok -setna_1 ... ok -setna_2 ... ok -setna_3 ... ok -setna_4 ... ok -setna_5 ... ok -setna_6 ... ok -setna_7 ... ok -setna_8 ... ok -setnae_1 ... ok -setnae_2 ... ok -setnae_3 ... ok -setnae_4 ... ok -setnb_1 ... ok -setnb_2 ... ok -setnb_3 ... ok -setnb_4 ... ok -setnbe_1 ... ok -setnbe_2 ... ok -setnbe_3 ... ok -setnbe_4 ... ok -setnbe_5 ... ok -setnbe_6 ... ok -setnbe_7 ... ok -setnbe_8 ... ok -setnc_1 ... ok -setnc_2 ... ok -setnc_3 ... ok -setnc_4 ... ok -setne_1 ... ok -setne_2 ... ok -setne_3 ... ok -setne_4 ... ok -setng_1 ... ok -setng_2 ... ok -setng_3 ... ok -setng_4 ... ok -setng_5 ... ok -setng_6 ... ok -setng_7 ... ok -setng_8 ... ok -setng_9 ... ok -setng_10 ... ok -setng_11 ... ok -setng_12 ... ok -setng_13 ... ok -setng_14 ... ok -setng_15 ... ok -setng_16 ... ok -setnge_1 ... ok -setnge_2 ... ok -setnge_3 ... ok -setnge_4 ... ok -setnge_5 ... ok -setnge_6 ... ok -setnge_7 ... ok -setnge_8 ... ok -setnl_1 ... ok -setnl_2 ... ok -setnl_3 ... ok -setnl_4 ... ok -setnl_5 ... ok -setnl_6 ... ok -setnl_7 ... ok -setnl_8 ... ok -setnle_1 ... ok -setnle_2 ... ok -setnle_3 ... ok -setnle_4 ... ok -setnle_5 ... ok -setnle_6 ... ok -setnle_7 ... ok -setnle_8 ... ok -setnle_9 ... ok -setnle_10 ... ok -setnle_11 ... ok -setnle_12 ... ok -setnle_13 ... ok -setnle_14 ... ok -setnle_15 ... ok -setnle_16 ... ok -setno_1 ... ok -setno_2 ... ok -setno_3 ... ok -setno_4 ... ok -setnp_1 ... ok -setnp_2 ... ok -setnp_3 ... ok -setnp_4 ... ok -setns_1 ... ok -setns_2 ... ok -setns_3 ... ok -setns_4 ... ok -setnz_1 ... ok -setnz_2 ... ok -setnz_3 ... ok -setnz_4 ... ok -seto_1 ... ok -seto_2 ... ok -seto_3 ... ok -seto_4 ... ok -setp_1 ... ok -setp_2 ... ok -setp_3 ... ok -setp_4 ... ok -sets_1 ... ok -sets_2 ... ok -sets_3 ... ok -sets_4 ... ok -setz_1 ... ok -setz_2 ... ok -setz_3 ... ok -setz_4 ... ok -shlb_1 ... ok -shlb_2 ... ok -shlb_3 ... ok -shlb_4 ... ok -shlb_5 ... ok -shlb_6 ... ok -shlw_1 ... ok -shlw_2 ... ok -shlw_3 ... ok -shlw_4 ... ok -shlw_5 ... ok -shlw_6 ... ok -shll_1 ... ok -shll_2 ... ok -shll_3 ... ok -shll_4 ... ok -shll_5 ... ok -shll_6 ... ok -shrb_1 ... ok -shrb_2 ... ok -shrb_3 ... ok -shrb_4 ... ok -shrb_5 ... ok -shrb_6 ... ok -shrw_1 ... ok -shrw_2 ... ok -shrw_3 ... ok -shrw_4 ... ok -shrw_5 ... ok -shrw_6 ... ok -shrl_1 ... ok -shrl_2 ... ok -shrl_3 ... ok -shrl_4 ... ok -shrl_5 ... ok -shrl_6 ... ok -shldw_1 ... ok -shldw_2 ... ok -shldw_3 ... ok -shldw_4 ... ok -shldw_5 ... ok -shldw_6 ... ok -shldw_7 ... ok -shldw_8 ... ok -shldl_1 ... ok -shldl_2 ... ok -shldl_3 ... ok -shldl_4 ... ok -shldl_5 ... ok -shldl_6 ... ok -shldl_7 ... ok -shldl_8 ... ok -shrdw_1 ... ok -shrdw_2 ... ok -shrdw_3 ... ok -shrdw_4 ... ok -shrdw_5 ... ok -shrdw_6 ... ok -shrdw_7 ... ok -shrdw_8 ... ok -shrdl_1 ... ok -shrdl_2 ... ok -shrdl_3 ... ok -shrdl_4 ... ok -shrdl_5 ... ok -shrdl_6 ... ok -shrdl_7 ... ok -shrdl_8 ... ok -stc_1 ... ok -stc_2 ... ok -std_1 ... ok -std_2 ... ok -subb_1 ... ok -subb_2 ... ok -subb_3 ... ok -subb_4 ... ok -subb_5 ... ok -subb_6 ... ok -subw_1 ... ok -subw_2 ... ok -subw_3 ... ok -subw_4 ... ok -subw_5 ... ok -subw_6 ... ok -subw_7 ... ok -subl_1 ... ok -subl_2 ... ok -subl_3 ... ok -subl_4 ... ok -subl_5 ... ok -subl_6 ... ok -subl_7 ... ok -testb_1 ... ok -testb_2 ... ok -testb_3 ... ok -testb_4 ... ok -testb_5 ... ok -testb_6 ... ok -testb_7 ... ok -testb_8 ... ok -testb_9 ... ok -testb_10 ... ok -testb_11 ... ok -testb_12 ... ok -testb_13 ... ok -testb_14 ... ok -testb_15 ... ok -testb_16 ... ok -testb_17 ... ok -testb_18 ... ok -testb_19 ... ok -testb_20 ... ok -testb_21 ... ok -testb_22 ... ok -testb_23 ... ok -testb_24 ... ok -testb_25 ... ok -testw_1 ... ok -testw_2 ... ok -testw_3 ... ok -testw_4 ... ok -testw_5 ... ok -testw_6 ... ok -testw_7 ... ok -testw_8 ... ok -testw_9 ... ok -testw_10 ... ok -testw_11 ... ok -testw_12 ... ok -testw_13 ... ok -testw_14 ... ok -testw_15 ... ok -testw_16 ... ok -testw_17 ... ok -testw_18 ... ok -testw_19 ... ok -testw_20 ... ok -testw_21 ... ok -testw_22 ... ok -testw_23 ... ok -testw_24 ... ok -testw_25 ... ok -testl_1 ... ok -testl_2 ... ok -testl_3 ... ok -testl_4 ... ok -testl_5 ... ok -testl_6 ... ok -testl_7 ... ok -testl_8 ... ok -testl_9 ... ok -testl_10 ... ok -testl_11 ... ok -testl_12 ... ok -testl_13 ... ok -testl_14 ... ok -testl_15 ... ok -testl_16 ... ok -testl_17 ... ok -testl_18 ... ok -testl_19 ... ok -testl_20 ... ok -testl_21 ... ok -testl_22 ... ok -testl_23 ... ok -testl_24 ... ok -testl_25 ... ok -xaddb_1 ... ok -xaddb_2 ... ok -xaddw_1 ... ok -xaddw_2 ... ok -xaddl_1 ... ok -xaddl_2 ... ok -xchgb_1 ... ok -xchgb_2 ... ok -xchgb_3 ... ok -xchgw_1 ... ok -xchgw_2 ... ok -xchgw_3 ... ok -xchgw_4 ... ok -xchgw_5 ... ok -xchgl_1 ... ok -xchgl_2 ... ok -xchgl_3 ... ok -xchgl_4 ... ok -xchgl_5 ... ok -xorb_1 ... ok -xorb_2 ... ok -xorb_3 ... ok -xorb_4 ... ok -xorb_5 ... ok -xorb_6 ... ok -xorw_1 ... ok -xorw_2 ... ok -xorw_3 ... ok -xorw_4 ... ok -xorw_5 ... ok -xorw_6 ... ok -xorw_7 ... ok -xorl_1 ... ok -xorl_2 ... ok -xorl_3 ... ok -xorl_4 ... ok -xorl_5 ... ok -xorl_6 ... ok -xorl_7 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_basic.vgtest b/VEX/head20041019/cachegrind/tests/insn_basic.vgtest deleted file mode 100644 index a6efda61c..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_basic.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_basic -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_cmov.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_cmov.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_cmov.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_cmov.stdout.exp deleted file mode 100644 index 31ac17204..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_cmov.stdout.exp +++ /dev/null @@ -1,384 +0,0 @@ -cmova_1 ... ok -cmova_2 ... ok -cmova_3 ... ok -cmova_4 ... ok -cmova_5 ... ok -cmova_6 ... ok -cmova_7 ... ok -cmova_8 ... ok -cmovae_1 ... ok -cmovae_2 ... ok -cmovae_3 ... ok -cmovae_4 ... ok -cmovb_1 ... ok -cmovb_2 ... ok -cmovb_3 ... ok -cmovb_4 ... ok -cmovbe_1 ... ok -cmovbe_2 ... ok -cmovbe_3 ... ok -cmovbe_4 ... ok -cmovbe_5 ... ok -cmovbe_6 ... ok -cmovbe_7 ... ok -cmovbe_8 ... ok -cmovc_1 ... ok -cmovc_2 ... ok -cmovc_3 ... ok -cmovc_4 ... ok -cmove_1 ... ok -cmove_2 ... ok -cmove_3 ... ok -cmove_4 ... ok -cmovg_1 ... ok -cmovg_2 ... ok -cmovg_3 ... ok -cmovg_4 ... ok -cmovg_5 ... ok -cmovg_6 ... ok -cmovg_7 ... ok -cmovg_8 ... ok -cmovg_9 ... ok -cmovg_10 ... ok -cmovg_11 ... ok -cmovg_12 ... ok -cmovg_13 ... ok -cmovg_14 ... ok -cmovg_15 ... ok -cmovg_16 ... ok -cmovge_1 ... ok -cmovge_2 ... ok -cmovge_3 ... ok -cmovge_4 ... ok -cmovge_5 ... ok -cmovge_6 ... ok -cmovge_7 ... ok -cmovge_8 ... ok -cmovl_1 ... ok -cmovl_2 ... ok -cmovl_3 ... ok -cmovl_4 ... ok -cmovl_5 ... ok -cmovl_6 ... ok -cmovl_7 ... ok -cmovl_8 ... ok -cmovle_1 ... ok -cmovle_2 ... ok -cmovle_3 ... ok -cmovle_4 ... ok -cmovle_5 ... ok -cmovle_6 ... ok -cmovle_7 ... ok -cmovle_8 ... ok -cmovle_9 ... ok -cmovle_10 ... ok -cmovle_11 ... ok -cmovle_12 ... ok -cmovle_13 ... ok -cmovle_14 ... ok -cmovle_15 ... ok -cmovle_16 ... ok -cmovna_1 ... ok -cmovna_2 ... ok -cmovna_3 ... ok -cmovna_4 ... ok -cmovna_5 ... ok -cmovna_6 ... ok -cmovna_7 ... ok -cmovna_8 ... ok -cmovnae_1 ... ok -cmovnae_2 ... ok -cmovnae_3 ... ok -cmovnae_4 ... ok -cmovnb_1 ... ok -cmovnb_2 ... ok -cmovnb_3 ... ok -cmovnb_4 ... ok -cmovnbe_1 ... ok -cmovnbe_2 ... ok -cmovnbe_3 ... ok -cmovnbe_4 ... ok -cmovnbe_5 ... ok -cmovnbe_6 ... ok -cmovnbe_7 ... ok -cmovnbe_8 ... ok -cmovnc_1 ... ok -cmovnc_2 ... ok -cmovnc_3 ... ok -cmovnc_4 ... ok -cmovne_1 ... ok -cmovne_2 ... ok -cmovne_3 ... ok -cmovne_4 ... ok -cmovng_1 ... ok -cmovng_2 ... ok -cmovng_3 ... ok -cmovng_4 ... ok -cmovng_5 ... ok -cmovng_6 ... ok -cmovng_7 ... ok -cmovng_8 ... ok -cmovng_9 ... ok -cmovng_10 ... ok -cmovng_11 ... ok -cmovng_12 ... ok -cmovng_13 ... ok -cmovng_14 ... ok -cmovng_15 ... ok -cmovng_16 ... ok -cmovnge_1 ... ok -cmovnge_2 ... ok -cmovnge_3 ... ok -cmovnge_4 ... ok -cmovnge_5 ... ok -cmovnge_6 ... ok -cmovnge_7 ... ok -cmovnge_8 ... ok -cmovnl_1 ... ok -cmovnl_2 ... ok -cmovnl_3 ... ok -cmovnl_4 ... ok -cmovnl_5 ... ok -cmovnl_6 ... ok -cmovnl_7 ... ok -cmovnl_8 ... ok -cmovnle_1 ... ok -cmovnle_2 ... ok -cmovnle_3 ... ok -cmovnle_4 ... ok -cmovnle_5 ... ok -cmovnle_6 ... ok -cmovnle_7 ... ok -cmovnle_8 ... ok -cmovnle_9 ... ok -cmovnle_10 ... ok -cmovnle_11 ... ok -cmovnle_12 ... ok -cmovnle_13 ... ok -cmovnle_14 ... ok -cmovnle_15 ... ok -cmovnle_16 ... ok -cmovno_1 ... ok -cmovno_2 ... ok -cmovno_3 ... ok -cmovno_4 ... ok -cmovnp_1 ... ok -cmovnp_2 ... ok -cmovnp_3 ... ok -cmovnp_4 ... ok -cmovns_1 ... ok -cmovns_2 ... ok -cmovns_3 ... ok -cmovns_4 ... ok -cmovnz_1 ... ok -cmovnz_2 ... ok -cmovnz_3 ... ok -cmovnz_4 ... ok -cmovo_1 ... ok -cmovo_2 ... ok -cmovo_3 ... ok -cmovo_4 ... ok -cmovp_1 ... ok -cmovp_2 ... ok -cmovp_3 ... ok -cmovp_4 ... ok -cmovs_1 ... ok -cmovs_2 ... ok -cmovs_3 ... ok -cmovs_4 ... ok -cmovz_1 ... ok -cmovz_2 ... ok -cmovz_3 ... ok -cmovz_4 ... ok -cmova_9 ... ok -cmova_10 ... ok -cmova_11 ... ok -cmova_12 ... ok -cmova_13 ... ok -cmova_14 ... ok -cmova_15 ... ok -cmova_16 ... ok -cmovae_5 ... ok -cmovae_6 ... ok -cmovae_7 ... ok -cmovae_8 ... ok -cmovb_5 ... ok -cmovb_6 ... ok -cmovb_7 ... ok -cmovb_8 ... ok -cmovbe_9 ... ok -cmovbe_10 ... ok -cmovbe_11 ... ok -cmovbe_12 ... ok -cmovbe_13 ... ok -cmovbe_14 ... ok -cmovbe_15 ... ok -cmovbe_16 ... ok -cmovc_5 ... ok -cmovc_6 ... ok -cmovc_7 ... ok -cmovc_8 ... ok -cmove_5 ... ok -cmove_6 ... ok -cmove_7 ... ok -cmove_8 ... ok -cmovg_17 ... ok -cmovg_18 ... ok -cmovg_19 ... ok -cmovg_20 ... ok -cmovg_21 ... ok -cmovg_22 ... ok -cmovg_23 ... ok -cmovg_24 ... ok -cmovg_25 ... ok -cmovg_26 ... ok -cmovg_27 ... ok -cmovg_28 ... ok -cmovg_29 ... ok -cmovg_30 ... ok -cmovg_31 ... ok -cmovg_32 ... ok -cmovge_9 ... ok -cmovge_10 ... ok -cmovge_11 ... ok -cmovge_12 ... ok -cmovge_13 ... ok -cmovge_14 ... ok -cmovge_15 ... ok -cmovge_16 ... ok -cmovl_9 ... ok -cmovl_10 ... ok -cmovl_11 ... ok -cmovl_12 ... ok -cmovl_13 ... ok -cmovl_14 ... ok -cmovl_15 ... ok -cmovl_16 ... ok -cmovle_17 ... ok -cmovle_18 ... ok -cmovle_19 ... ok -cmovle_20 ... ok -cmovle_21 ... ok -cmovle_22 ... ok -cmovle_23 ... ok -cmovle_24 ... ok -cmovle_25 ... ok -cmovle_26 ... ok -cmovle_27 ... ok -cmovle_28 ... ok -cmovle_29 ... ok -cmovle_30 ... ok -cmovle_31 ... ok -cmovle_32 ... ok -cmovna_9 ... ok -cmovna_10 ... ok -cmovna_11 ... ok -cmovna_12 ... ok -cmovna_13 ... ok -cmovna_14 ... ok -cmovna_15 ... ok -cmovna_16 ... ok -cmovnae_5 ... ok -cmovnae_6 ... ok -cmovnae_7 ... ok -cmovnae_8 ... ok -cmovnb_5 ... ok -cmovnb_6 ... ok -cmovnb_7 ... ok -cmovnb_8 ... ok -cmovnbe_9 ... ok -cmovnbe_10 ... ok -cmovnbe_11 ... ok -cmovnbe_12 ... ok -cmovnbe_13 ... ok -cmovnbe_14 ... ok -cmovnbe_15 ... ok -cmovnbe_16 ... ok -cmovnc_5 ... ok -cmovnc_6 ... ok -cmovnc_7 ... ok -cmovnc_8 ... ok -cmovne_5 ... ok -cmovne_6 ... ok -cmovne_7 ... ok -cmovne_8 ... ok -cmovng_17 ... ok -cmovng_18 ... ok -cmovng_19 ... ok -cmovng_20 ... ok -cmovng_21 ... ok -cmovng_22 ... ok -cmovng_23 ... ok -cmovng_24 ... ok -cmovng_25 ... ok -cmovng_26 ... ok -cmovng_27 ... ok -cmovng_28 ... ok -cmovng_29 ... ok -cmovng_30 ... ok -cmovng_31 ... ok -cmovng_32 ... ok -cmovnge_9 ... ok -cmovnge_10 ... ok -cmovnge_11 ... ok -cmovnge_12 ... ok -cmovnge_13 ... ok -cmovnge_14 ... ok -cmovnge_15 ... ok -cmovnge_16 ... ok -cmovnl_9 ... ok -cmovnl_10 ... ok -cmovnl_11 ... ok -cmovnl_12 ... ok -cmovnl_13 ... ok -cmovnl_14 ... ok -cmovnl_15 ... ok -cmovnl_16 ... ok -cmovnle_17 ... ok -cmovnle_18 ... ok -cmovnle_19 ... ok -cmovnle_20 ... ok -cmovnle_21 ... ok -cmovnle_22 ... ok -cmovnle_23 ... ok -cmovnle_24 ... ok -cmovnle_25 ... ok -cmovnle_26 ... ok -cmovnle_27 ... ok -cmovnle_28 ... ok -cmovnle_29 ... ok -cmovnle_30 ... ok -cmovnle_31 ... ok -cmovnle_32 ... ok -cmovno_5 ... ok -cmovno_6 ... ok -cmovno_7 ... ok -cmovno_8 ... ok -cmovnp_5 ... ok -cmovnp_6 ... ok -cmovnp_7 ... ok -cmovnp_8 ... ok -cmovns_5 ... ok -cmovns_6 ... ok -cmovns_7 ... ok -cmovns_8 ... ok -cmovnz_5 ... ok -cmovnz_6 ... ok -cmovnz_7 ... ok -cmovnz_8 ... ok -cmovo_5 ... ok -cmovo_6 ... ok -cmovo_7 ... ok -cmovo_8 ... ok -cmovp_5 ... ok -cmovp_6 ... ok -cmovp_7 ... ok -cmovp_8 ... ok -cmovs_5 ... ok -cmovs_6 ... ok -cmovs_7 ... ok -cmovs_8 ... ok -cmovz_5 ... ok -cmovz_6 ... ok -cmovz_7 ... ok -cmovz_8 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_cmov.vgtest b/VEX/head20041019/cachegrind/tests/insn_cmov.vgtest deleted file mode 100644 index c020cbf47..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_cmov.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_cmov -cpu_test: cmov -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_fpu.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_fpu.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_fpu.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_fpu.stdout.exp deleted file mode 100644 index 2dbaa07ce..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_fpu.stdout.exp +++ /dev/null @@ -1,452 +0,0 @@ -fabs_1 ... ok -fabs_2 ... ok -fabs_3 ... ok -fabs_4 ... ok -fadds_1 ... ok -fadds_2 ... ok -fadds_3 ... ok -fadds_4 ... ok -faddl_1 ... ok -faddl_2 ... ok -faddl_3 ... ok -faddl_4 ... ok -fadd_1 ... ok -fadd_2 ... ok -fadd_3 ... ok -fadd_4 ... ok -fadd_5 ... ok -fadd_6 ... ok -fadd_7 ... ok -fadd_8 ... ok -fadd_9 ... ok -fadd_10 ... ok -fadd_11 ... ok -fadd_12 ... ok -fadd_13 ... ok -fadd_14 ... ok -fadd_15 ... ok -fadd_16 ... ok -faddp_1 ... ok -faddp_2 ... ok -faddp_3 ... ok -faddp_4 ... ok -faddp_5 ... ok -faddp_6 ... ok -faddp_7 ... ok -faddp_8 ... ok -faddp_9 ... ok -faddp_10 ... ok -faddp_11 ... ok -faddp_12 ... ok -faddp_13 ... ok -faddp_14 ... ok -faddp_15 ... ok -faddp_16 ... ok -fiadds_1 ... ok -fiadds_2 ... ok -fiadds_3 ... ok -fiadds_4 ... ok -fiadds_5 ... ok -fiadds_6 ... ok -fiadds_7 ... ok -fiadds_8 ... ok -fiaddl_1 ... ok -fiaddl_2 ... ok -fiaddl_3 ... ok -fiaddl_4 ... ok -fiaddl_5 ... ok -fiaddl_6 ... ok -fiaddl_7 ... ok -fiaddl_8 ... ok -fcomi_1 ... ok -fcomi_2 ... ok -fcomi_3 ... ok -fcomi_4 ... ok -fcomi_5 ... ok -fcomi_6 ... ok -fcomip_1 ... ok -fcomip_2 ... ok -fcomip_3 ... ok -fcomip_4 ... ok -fcomip_5 ... ok -fcomip_6 ... ok -fucomi_1 ... ok -fucomi_2 ... ok -fucomi_3 ... ok -fucomi_4 ... ok -fucomi_5 ... ok -fucomi_6 ... ok -fucomip_1 ... ok -fucomip_2 ... ok -fucomip_3 ... ok -fucomip_4 ... ok -fucomip_5 ... ok -fucomip_6 ... ok -fchs_1 ... ok -fchs_2 ... ok -fchs_3 ... ok -fchs_4 ... ok -fdivs_1 ... ok -fdivs_2 ... ok -fdivs_3 ... ok -fdivs_4 ... ok -fdivl_1 ... ok -fdivl_2 ... ok -fdivl_3 ... ok -fdivl_4 ... ok -fdiv_1 ... ok -fdiv_2 ... ok -fdiv_3 ... ok -fdiv_4 ... ok -fdiv_5 ... ok -fdiv_6 ... ok -fdiv_7 ... ok -fdiv_8 ... ok -fdiv_9 ... ok -fdiv_10 ... ok -fdiv_11 ... ok -fdiv_12 ... ok -fdiv_13 ... ok -fdiv_14 ... ok -fdiv_15 ... ok -fdiv_16 ... ok -fdivp_1 ... ok -fdivp_2 ... ok -fdivp_3 ... ok -fdivp_4 ... ok -fdivp_5 ... ok -fdivp_6 ... ok -fdivp_7 ... ok -fdivp_8 ... ok -fdivp_9 ... ok -fdivp_10 ... ok -fdivp_11 ... ok -fdivp_12 ... ok -fdivp_13 ... ok -fdivp_14 ... ok -fdivp_15 ... ok -fdivp_16 ... ok -fidivs_1 ... ok -fidivs_2 ... ok -fidivs_3 ... ok -fidivs_4 ... ok -fidivs_5 ... ok -fidivs_6 ... ok -fidivs_7 ... ok -fidivs_8 ... ok -fidivl_1 ... ok -fidivl_2 ... ok -fidivl_3 ... ok -fidivl_4 ... ok -fidivl_5 ... ok -fidivl_6 ... ok -fidivl_7 ... ok -fidivl_8 ... ok -fdivrs_1 ... ok -fdivrs_2 ... ok -fdivrs_3 ... ok -fdivrs_4 ... ok -fdivrl_1 ... ok -fdivrl_2 ... ok -fdivrl_3 ... ok -fdivrl_4 ... ok -fdivr_1 ... ok -fdivr_2 ... ok -fdivr_3 ... ok -fdivr_4 ... ok -fdivr_5 ... ok -fdivr_6 ... ok -fdivr_7 ... ok -fdivr_8 ... ok -fdivr_9 ... ok -fdivr_10 ... ok -fdivr_11 ... ok -fdivr_12 ... ok -fdivr_13 ... ok -fdivr_14 ... ok -fdivr_15 ... ok -fdivr_16 ... ok -fdivrp_1 ... ok -fdivrp_2 ... ok -fdivrp_3 ... ok -fdivrp_4 ... ok -fdivrp_5 ... ok -fdivrp_6 ... ok -fdivrp_7 ... ok -fdivrp_8 ... ok -fdivrp_9 ... ok -fdivrp_10 ... ok -fdivrp_11 ... ok -fdivrp_12 ... ok -fdivrp_13 ... ok -fdivrp_14 ... ok -fdivrp_15 ... ok -fdivrp_16 ... ok -fidivrs_1 ... ok -fidivrs_2 ... ok -fidivrs_3 ... ok -fidivrs_4 ... ok -fidivrs_5 ... ok -fidivrs_6 ... ok -fidivrs_7 ... ok -fidivrs_8 ... ok -fidivrl_1 ... ok -fidivrl_2 ... ok -fidivrl_3 ... ok -fidivrl_4 ... ok -fidivrl_5 ... ok -fidivrl_6 ... ok -fidivrl_7 ... ok -fidivrl_8 ... ok -filds_1 ... ok -filds_2 ... ok -filds_3 ... ok -filds_4 ... ok -fildl_1 ... ok -fildl_2 ... ok -fildl_3 ... ok -fildl_4 ... ok -fildq_1 ... ok -fildq_2 ... ok -fildq_3 ... ok -fildq_4 ... ok -fists_1 ... ok -fists_2 ... ok -fists_3 ... ok -fists_4 ... ok -fists_5 ... ok -fists_6 ... ok -fists_7 ... ok -fists_8 ... ok -fistl_1 ... ok -fistl_2 ... ok -fistl_3 ... ok -fistl_4 ... ok -fistl_5 ... ok -fistl_6 ... ok -fistl_7 ... ok -fistl_8 ... ok -fistps_1 ... ok -fistps_2 ... ok -fistps_3 ... ok -fistps_4 ... ok -fistps_5 ... ok -fistps_6 ... ok -fistps_7 ... ok -fistps_8 ... ok -fistpl_1 ... ok -fistpl_2 ... ok -fistpl_3 ... ok -fistpl_4 ... ok -fistpl_5 ... ok -fistpl_6 ... ok -fistpl_7 ... ok -fistpl_8 ... ok -fistpq_1 ... ok -fistpq_2 ... ok -fistpq_3 ... ok -fistpq_4 ... ok -fistpq_5 ... ok -fistpq_6 ... ok -fistpq_7 ... ok -fistpq_8 ... ok -flds_1 ... ok -flds_2 ... ok -fldl_1 ... ok -fldl_2 ... ok -fld_1 ... ok -fld_2 ... ok -fld_3 ... ok -fld1_1 ... ok -fldl2t_1 ... ok -fldl2e_1 ... ok -fldpi_1 ... ok -fldlg2_1 ... ok -fldln2_1 ... ok -fldz_1 ... ok -fmuls_1 ... ok -fmuls_2 ... ok -fmuls_3 ... ok -fmuls_4 ... ok -fmull_1 ... ok -fmull_2 ... ok -fmull_3 ... ok -fmull_4 ... ok -fmul_1 ... ok -fmul_2 ... ok -fmul_3 ... ok -fmul_4 ... ok -fmul_5 ... ok -fmul_6 ... ok -fmul_7 ... ok -fmul_8 ... ok -fmul_9 ... ok -fmul_10 ... ok -fmul_11 ... ok -fmul_12 ... ok -fmul_13 ... ok -fmul_14 ... ok -fmul_15 ... ok -fmul_16 ... ok -fmulp_1 ... ok -fmulp_2 ... ok -fmulp_3 ... ok -fmulp_4 ... ok -fmulp_5 ... ok -fmulp_6 ... ok -fmulp_7 ... ok -fmulp_8 ... ok -fmulp_9 ... ok -fmulp_10 ... ok -fmulp_11 ... ok -fmulp_12 ... ok -fmulp_13 ... ok -fmulp_14 ... ok -fmulp_15 ... ok -fmulp_16 ... ok -fimuls_1 ... ok -fimuls_2 ... ok -fimuls_3 ... ok -fimuls_4 ... ok -fimuls_5 ... ok -fimuls_6 ... ok -fimuls_7 ... ok -fimuls_8 ... ok -fimull_1 ... ok -fimull_2 ... ok -fimull_3 ... ok -fimull_4 ... ok -fimull_5 ... ok -fimull_6 ... ok -fimull_7 ... ok -fimull_8 ... ok -frndint_1 ... ok -frndint_2 ... ok -frndint_3 ... ok -frndint_4 ... ok -frndint_5 ... ok -frndint_6 ... ok -frndint_7 ... ok -frndint_8 ... ok -frndint_9 ... ok -frndint_10 ... ok -frndint_11 ... ok -frndint_12 ... ok -frndint_13 ... ok -frndint_14 ... ok -frndint_15 ... ok -frndint_16 ... ok -fsubs_1 ... ok -fsubs_2 ... ok -fsubs_3 ... ok -fsubs_4 ... ok -fsubl_1 ... ok -fsubl_2 ... ok -fsubl_3 ... ok -fsubl_4 ... ok -fsub_1 ... ok -fsub_2 ... ok -fsub_3 ... ok -fsub_4 ... ok -fsub_5 ... ok -fsub_6 ... ok -fsub_7 ... ok -fsub_8 ... ok -fsub_9 ... ok -fsub_10 ... ok -fsub_11 ... ok -fsub_12 ... ok -fsub_13 ... ok -fsub_14 ... ok -fsub_15 ... ok -fsub_16 ... ok -fsubp_1 ... ok -fsubp_2 ... ok -fsubp_3 ... ok -fsubp_4 ... ok -fsubp_5 ... ok -fsubp_6 ... ok -fsubp_7 ... ok -fsubp_8 ... ok -fsubp_9 ... ok -fsubp_10 ... ok -fsubp_11 ... ok -fsubp_12 ... ok -fsubp_13 ... ok -fsubp_14 ... ok -fsubp_15 ... ok -fsubp_16 ... ok -fisubs_1 ... ok -fisubs_2 ... ok -fisubs_3 ... ok -fisubs_4 ... ok -fisubs_5 ... ok -fisubs_6 ... ok -fisubs_7 ... ok -fisubs_8 ... ok -fisubl_1 ... ok -fisubl_2 ... ok -fisubl_3 ... ok -fisubl_4 ... ok -fisubl_5 ... ok -fisubl_6 ... ok -fisubl_7 ... ok -fisubl_8 ... ok -fsubrs_1 ... ok -fsubrs_2 ... ok -fsubrs_3 ... ok -fsubrs_4 ... ok -fsubrl_1 ... ok -fsubrl_2 ... ok -fsubrl_3 ... ok -fsubrl_4 ... ok -fsubr_1 ... ok -fsubr_2 ... ok -fsubr_3 ... ok -fsubr_4 ... ok -fsubr_5 ... ok -fsubr_6 ... ok -fsubr_7 ... ok -fsubr_8 ... ok -fsubr_9 ... ok -fsubr_10 ... ok -fsubr_11 ... ok -fsubr_12 ... ok -fsubr_13 ... ok -fsubr_14 ... ok -fsubr_15 ... ok -fsubr_16 ... ok -fsubrp_1 ... ok -fsubrp_2 ... ok -fsubrp_3 ... ok -fsubrp_4 ... ok -fsubrp_5 ... ok -fsubrp_6 ... ok -fsubrp_7 ... ok -fsubrp_8 ... ok -fsubrp_9 ... ok -fsubrp_10 ... ok -fsubrp_11 ... ok -fsubrp_12 ... ok -fsubrp_13 ... ok -fsubrp_14 ... ok -fsubrp_15 ... ok -fsubrp_16 ... ok -fisubrs_1 ... ok -fisubrs_2 ... ok -fisubrs_3 ... ok -fisubrs_4 ... ok -fisubrs_5 ... ok -fisubrs_6 ... ok -fisubrs_7 ... ok -fisubrs_8 ... ok -fisubrl_1 ... ok -fisubrl_2 ... ok -fisubrl_3 ... ok -fisubrl_4 ... ok -fisubrl_5 ... ok -fisubrl_6 ... ok -fisubrl_7 ... ok -fisubrl_8 ... ok -fxch_1 ... ok -fxch_2 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_fpu.vgtest b/VEX/head20041019/cachegrind/tests/insn_fpu.vgtest deleted file mode 100644 index eb7c9ac4f..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_fpu.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_fpu -cpu_test: fpu -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_mmx.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_mmx.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_mmx.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_mmx.stdout.exp deleted file mode 100644 index 95cbae160..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_mmx.stdout.exp +++ /dev/null @@ -1,103 +0,0 @@ -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movq_1 ... ok -movq_2 ... ok -movq_3 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -por_1 ... ok -por_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_mmx.vgtest b/VEX/head20041019/cachegrind/tests/insn_mmx.vgtest deleted file mode 100644 index 504558cf6..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_mmx.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmx -cpu_test: mmx -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_mmxext.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_mmxext.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_mmxext.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_mmxext.stdout.exp deleted file mode 100644 index 23b2e55ab..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_mmxext.stdout.exp +++ /dev/null @@ -1,29 +0,0 @@ -movntq_1 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -sfence_1 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_mmxext.vgtest b/VEX/head20041019/cachegrind/tests/insn_mmxext.vgtest deleted file mode 100644 index 30a705f33..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_mmxext.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmxext -cpu_test: mmxext -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_sse.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_sse.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_sse.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_sse.stdout.exp deleted file mode 100644 index f15bd81f0..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_sse.stdout.exp +++ /dev/null @@ -1,142 +0,0 @@ -addps_1 ... ok -addps_2 ... ok -addss_1 ... ok -addss_2 ... ok -andnps_1 ... ok -andnps_2 ... ok -andps_1 ... ok -andps_2 ... ok -cmpeqps_1 ... ok -cmpeqps_2 ... ok -cmpeqss_1 ... ok -cmpeqss_2 ... ok -cmpleps_1 ... ok -cmpleps_2 ... ok -cmpless_1 ... ok -cmpless_2 ... ok -cmpltps_1 ... ok -cmpltps_2 ... ok -cmpltss_1 ... ok -cmpltss_2 ... ok -cmpneqps_1 ... ok -cmpneqps_2 ... ok -cmpneqss_1 ... ok -cmpneqss_2 ... ok -cmpnleps_1 ... ok -cmpnleps_2 ... ok -cmpnless_1 ... ok -cmpnless_2 ... ok -cmpnltps_1 ... ok -cmpnltps_2 ... ok -cmpnltss_1 ... ok -cmpnltss_2 ... ok -comiss_1 ... ok -comiss_2 ... ok -comiss_3 ... ok -comiss_4 ... ok -comiss_5 ... ok -comiss_6 ... ok -cvtpi2ps_1 ... ok -cvtpi2ps_2 ... ok -cvtps2pi_1 ... ok -cvtps2pi_2 ... ok -cvtsi2ss_1 ... ok -cvtsi2ss_2 ... ok -cvtss2si_1 ... ok -cvtss2si_2 ... ok -cvttps2pi_1 ... ok -cvttps2pi_2 ... ok -cvttss2si_1 ... ok -cvttss2si_2 ... ok -divps_1 ... ok -divps_2 ... ok -divss_1 ... ok -divss_2 ... ok -maxps_1 ... ok -maxps_2 ... ok -maxss_1 ... ok -maxss_2 ... ok -minps_1 ... ok -minps_2 ... ok -minss_1 ... ok -minss_2 ... ok -movaps_1 ... ok -movaps_2 ... ok -movhlps_1 ... ok -movhps_1 ... ok -movhps_2 ... ok -movlhps_1 ... ok -movlps_1 ... ok -movlps_2 ... ok -movmskps_1 ... ok -movntps_1 ... ok -movntq_1 ... ok -movss_1 ... ok -movss_2 ... ok -movss_3 ... ok -movups_1 ... ok -movups_2 ... ok -mulps_1 ... ok -mulps_2 ... ok -mulss_1 ... ok -mulss_2 ... ok -orps_1 ... ok -orps_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -rcpps_1 ... ok -rcpps_2 ... ok -rcpss_1 ... ok -rcpss_2 ... ok -rsqrtps_1 ... ok -rsqrtps_2 ... ok -rsqrtss_1 ... ok -rsqrtss_2 ... ok -sfence_1 ... ok -shufps_1 ... ok -shufps_2 ... ok -sqrtps_1 ... ok -sqrtps_2 ... ok -sqrtss_1 ... ok -sqrtss_2 ... ok -subps_1 ... ok -subps_2 ... ok -subss_1 ... ok -subss_2 ... ok -ucomiss_1 ... ok -ucomiss_2 ... ok -ucomiss_3 ... ok -ucomiss_4 ... ok -ucomiss_5 ... ok -ucomiss_6 ... ok -unpckhps_1 ... ok -unpckhps_2 ... ok -unpcklps_1 ... ok -unpcklps_2 ... ok -xorps_1 ... ok -xorps_2 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_sse.vgtest b/VEX/head20041019/cachegrind/tests/insn_sse.vgtest deleted file mode 100644 index 8dded750a..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_sse.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse -cpu_test: sse -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/insn_sse2.stderr.exp b/VEX/head20041019/cachegrind/tests/insn_sse2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/tests/insn_sse2.stdout.exp b/VEX/head20041019/cachegrind/tests/insn_sse2.stdout.exp deleted file mode 100644 index 9c24f7262..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_sse2.stdout.exp +++ /dev/null @@ -1,294 +0,0 @@ -addpd_1 ... ok -addpd_2 ... ok -addsd_1 ... ok -addsd_2 ... ok -andpd_1 ... ok -andpd_2 ... ok -andnpd_1 ... ok -andnpd_2 ... ok -cmpeqpd_1 ... ok -cmpeqpd_2 ... ok -cmpltpd_1 ... ok -cmpltpd_2 ... ok -cmplepd_1 ... ok -cmplepd_2 ... ok -cmpneqpd_1 ... ok -cmpneqpd_2 ... ok -cmpnltpd_1 ... ok -cmpnltpd_2 ... ok -cmpnlepd_1 ... ok -cmpnlepd_2 ... ok -cmpeqsd_1 ... ok -cmpeqsd_2 ... ok -cmpltsd_1 ... ok -cmpltsd_2 ... ok -cmplesd_1 ... ok -cmplesd_2 ... ok -cmpneqsd_1 ... ok -cmpneqsd_2 ... ok -cmpnltsd_1 ... ok -cmpnltsd_2 ... ok -cmpnlesd_1 ... ok -cmpnlesd_2 ... ok -comisd_1 ... ok -comisd_2 ... ok -comisd_3 ... ok -comisd_4 ... ok -comisd_5 ... ok -comisd_6 ... ok -cvtdq2pd_1 ... ok -cvtdq2pd_2 ... ok -cvtdq2ps_1 ... ok -cvtdq2ps_2 ... ok -cvtpd2dq_1 ... ok -cvtpd2dq_2 ... ok -cvtpd2pi_1 ... ok -cvtpd2pi_2 ... ok -cvtpd2ps_1 ... ok -cvtpd2ps_2 ... ok -cvtpi2pd_1 ... ok -cvtpi2pd_2 ... ok -cvtps2dq_1 ... ok -cvtps2dq_2 ... ok -cvtps2pd_1 ... ok -cvtps2pd_2 ... ok -cvtsd2si_1 ... ok -cvtsd2si_2 ... ok -cvtsd2ss_1 ... ok -cvtsd2ss_2 ... ok -cvtsi2sd_1 ... ok -cvtsi2sd_2 ... ok -cvtss2sd_1 ... ok -cvtss2sd_2 ... ok -cvttpd2pi_1 ... ok -cvttpd2pi_2 ... ok -cvttpd2dq_1 ... ok -cvttpd2dq_2 ... ok -cvttps2dq_1 ... ok -cvttps2dq_2 ... ok -cvttsd2si_1 ... ok -cvttsd2si_2 ... ok -divpd_1 ... ok -divpd_2 ... ok -divsd_1 ... ok -divsd_2 ... ok -lfence_1 ... ok -maxpd_1 ... ok -maxpd_2 ... ok -maxsd_1 ... ok -maxsd_2 ... ok -mfence_1 ... ok -minpd_1 ... ok -minpd_2 ... ok -minsd_1 ... ok -minsd_2 ... ok -movapd_1 ... ok -movapd_2 ... ok -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movdqa_1 ... ok -movdqa_2 ... ok -movdqa_3 ... ok -movdqu_1 ... ok -movdqu_2 ... ok -movdqu_3 ... ok -movdq2q_1 ... ok -movhpd_1 ... ok -movhpd_2 ... ok -movlpd_1 ... ok -movlpd_2 ... ok -movmskpd_1 ... ok -movntdq_1 ... ok -movnti_1 ... ok -movntpd_1 ... ok -movq2dq_1 ... ok -movsd_1 ... ok -movsd_2 ... ok -movsd_3 ... ok -movupd_1 ... ok -movupd_2 ... ok -mulpd_1 ... ok -mulpd_2 ... ok -mulsd_1 ... ok -mulsd_2 ... ok -orpd_1 ... ok -orpd_2 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddq_1 ... ok -paddq_2 ... ok -paddq_3 ... ok -paddq_4 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pextrw_5 ... ok -pextrw_6 ... ok -pextrw_7 ... ok -pextrw_8 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pinsrw_5 ... ok -pinsrw_6 ... ok -pinsrw_7 ... ok -pinsrw_8 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -pmuludq_1 ... ok -pmuludq_2 ... ok -pmuludq_3 ... ok -pmuludq_4 ... ok -por_1 ... ok -por_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufd_1 ... ok -pshufd_2 ... ok -pshufhw_1 ... ok -pshufhw_2 ... ok -pshuflw_1 ... ok -pshuflw_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -pslldq_1 ... ok -pslldq_2 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrldq_1 ... ok -psrldq_2 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubq_1 ... ok -psubq_2 ... ok -psubq_3 ... ok -psubq_4 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhqdq_1 ... ok -punpckhqdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklqdq_1 ... ok -punpcklqdq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok -shufpd_1 ... ok -shufpd_2 ... ok -sqrtpd_1 ... ok -sqrtpd_2 ... ok -sqrtsd_1 ... ok -sqrtsd_2 ... ok -subpd_1 ... ok -subpd_2 ... ok -subsd_1 ... ok -subsd_2 ... ok -ucomisd_1 ... ok -ucomisd_2 ... ok -ucomisd_3 ... ok -ucomisd_4 ... ok -ucomisd_5 ... ok -ucomisd_6 ... ok -unpckhpd_1 ... ok -unpckhpd_2 ... ok -unpcklpd_1 ... ok -unpcklpd_2 ... ok -xorpd_1 ... ok -xorpd_2 ... ok diff --git a/VEX/head20041019/cachegrind/tests/insn_sse2.vgtest b/VEX/head20041019/cachegrind/tests/insn_sse2.vgtest deleted file mode 100644 index 594a3fd2a..000000000 --- a/VEX/head20041019/cachegrind/tests/insn_sse2.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse2 -cpu_test: sse2 -delete: cachegrind.out.* diff --git a/VEX/head20041019/cachegrind/tests/myprint.c b/VEX/head20041019/cachegrind/tests/myprint.c deleted file mode 100644 index e22ae87a2..000000000 --- a/VEX/head20041019/cachegrind/tests/myprint.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void myprint(void) -{ - puts("This is myprint!"); -} diff --git a/VEX/head20041019/cachegrind/x86/.cvsignore b/VEX/head20041019/cachegrind/x86/.cvsignore deleted file mode 100644 index 282522db0..000000000 --- a/VEX/head20041019/cachegrind/x86/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/VEX/head20041019/cachegrind/x86/CVS/Entries b/VEX/head20041019/cachegrind/x86/CVS/Entries deleted file mode 100644 index 1cdf18446..000000000 --- a/VEX/head20041019/cachegrind/x86/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Sat Sep 11 16:45:27 2004// -/Makefile.am/1.2/Sat Sep 11 18:27:43 2004// -/cg_arch.c/1.2/Wed Oct 13 11:30:14 2004// -D diff --git a/VEX/head20041019/cachegrind/x86/CVS/Repository b/VEX/head20041019/cachegrind/x86/CVS/Repository deleted file mode 100644 index 0bd1c8fb4..000000000 --- a/VEX/head20041019/cachegrind/x86/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/cachegrind/x86 diff --git a/VEX/head20041019/cachegrind/x86/CVS/Root b/VEX/head20041019/cachegrind/x86/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/cachegrind/x86/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/cachegrind/x86/CVS/Template b/VEX/head20041019/cachegrind/x86/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/cachegrind/x86/Makefile.am b/VEX/head20041019/cachegrind/x86/Makefile.am deleted file mode 100644 index 5c07f3961..000000000 --- a/VEX/head20041019/cachegrind/x86/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/Makefile.tool-flags.am - -AM_CPPFLAGS += -I$(top_srcdir)/cachegrind - -noinst_LIBRARIES = libcgarch.a - -libcgarch_a_SOURCES = cg_arch.c - diff --git a/VEX/head20041019/cachegrind/x86/cg_arch.c b/VEX/head20041019/cachegrind/x86/cg_arch.c deleted file mode 100644 index 29cc28380..000000000 --- a/VEX/head20041019/cachegrind/x86/cg_arch.c +++ /dev/null @@ -1,360 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Arch-specific definitions. x86/cg_arch.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Cachegrind, a Valgrind tool for cache - profiling programs. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" -#include "cg_arch.h" - -// All CPUID info taken from sandpile.org/a32/cpuid.htm */ -// Probably only works for Intel and AMD chips, and probably only for some of -// them. - -static void micro_ops_warn(Int actual_size, Int used_size, Int line_size) -{ - VG_(message)(Vg_DebugMsg, - "warning: Pentium with %d K micro-op instruction trace cache", - actual_size); - VG_(message)(Vg_DebugMsg, - " Simulating a %d KB cache with %d B lines", - used_size, line_size); -} - -/* Intel method is truly wretched. We have to do an insane indexing into an - * array of pre-defined configurations for various parts of the memory - * hierarchy. - */ -static -Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c) -{ - UChar info[16]; - Int i, trials; - Bool L2_found = False; - - if (level < 2) { - VG_(message)(Vg_DebugMsg, - "warning: CPUID level < 2 for Intel processor (%d)", - level); - return -1; - } - - VG_(cpuid)(2, (Int*)&info[0], (Int*)&info[4], - (Int*)&info[8], (Int*)&info[12]); - trials = info[0] - 1; /* AL register - bits 0..7 of %eax */ - info[0] = 0x0; /* reset AL */ - - if (0 != trials) { - VG_(message)(Vg_DebugMsg, - "warning: non-zero CPUID trials for Intel processor (%d)", - trials); - return -1; - } - - for (i = 0; i < 16; i++) { - - switch (info[i]) { - - case 0x0: /* ignore zeros */ - break; - - /* TLB info, ignore */ - case 0x01: case 0x02: case 0x03: case 0x04: - case 0x50: case 0x51: case 0x52: case 0x5b: case 0x5c: case 0x5d: - case 0xb0: case 0xb3: - break; - - case 0x06: *I1c = (cache_t) { 8, 4, 32 }; break; - case 0x08: *I1c = (cache_t) { 16, 4, 32 }; break; - case 0x30: *I1c = (cache_t) { 32, 8, 64 }; break; - - case 0x0a: *D1c = (cache_t) { 8, 2, 32 }; break; - case 0x0c: *D1c = (cache_t) { 16, 4, 32 }; break; - case 0x2c: *D1c = (cache_t) { 32, 8, 64 }; break; - - /* IA-64 info -- panic! */ - case 0x10: case 0x15: case 0x1a: - case 0x88: case 0x89: case 0x8a: case 0x8d: - case 0x90: case 0x96: case 0x9b: - VG_(skin_panic)("IA-64 cache detected?!"); - - case 0x22: case 0x23: case 0x25: case 0x29: - VG_(message)(Vg_DebugMsg, - "warning: L3 cache detected but ignored\n"); - break; - - /* These are sectored, whatever that means */ - case 0x39: *L2c = (cache_t) { 128, 4, 64 }; L2_found = True; break; - case 0x3c: *L2c = (cache_t) { 256, 4, 64 }; L2_found = True; break; - - /* If a P6 core, this means "no L2 cache". - If a P4 core, this means "no L3 cache". - We don't know what core it is, so don't issue a warning. To detect - a missing L2 cache, we use 'L2_found'. */ - case 0x40: - break; - - case 0x41: *L2c = (cache_t) { 128, 4, 32 }; L2_found = True; break; - case 0x42: *L2c = (cache_t) { 256, 4, 32 }; L2_found = True; break; - case 0x43: *L2c = (cache_t) { 512, 4, 32 }; L2_found = True; break; - case 0x44: *L2c = (cache_t) { 1024, 4, 32 }; L2_found = True; break; - case 0x45: *L2c = (cache_t) { 2048, 4, 32 }; L2_found = True; break; - - /* These are sectored, whatever that means */ - case 0x60: *D1c = (cache_t) { 16, 8, 64 }; break; /* sectored */ - case 0x66: *D1c = (cache_t) { 8, 4, 64 }; break; /* sectored */ - case 0x67: *D1c = (cache_t) { 16, 4, 64 }; break; /* sectored */ - case 0x68: *D1c = (cache_t) { 32, 4, 64 }; break; /* sectored */ - - /* HACK ALERT: Instruction trace cache -- capacity is micro-ops based. - * conversion to byte size is a total guess; treat the 12K and 16K - * cases the same since the cache byte size must be a power of two for - * everything to work!. Also guessing 32 bytes for the line size... - */ - case 0x70: /* 12K micro-ops, 8-way */ - *I1c = (cache_t) { 16, 8, 32 }; - micro_ops_warn(12, 16, 32); - break; - case 0x71: /* 16K micro-ops, 8-way */ - *I1c = (cache_t) { 16, 8, 32 }; - micro_ops_warn(16, 16, 32); - break; - case 0x72: /* 32K micro-ops, 8-way */ - *I1c = (cache_t) { 32, 8, 32 }; - micro_ops_warn(32, 32, 32); - break; - - /* These are sectored, whatever that means */ - case 0x79: *L2c = (cache_t) { 128, 8, 64 }; L2_found = True; break; - case 0x7a: *L2c = (cache_t) { 256, 8, 64 }; L2_found = True; break; - case 0x7b: *L2c = (cache_t) { 512, 8, 64 }; L2_found = True; break; - case 0x7c: *L2c = (cache_t) { 1024, 8, 64 }; L2_found = True; break; - case 0x7e: *L2c = (cache_t) { 256, 8, 128 }; L2_found = True; break; - - case 0x81: *L2c = (cache_t) { 128, 8, 32 }; L2_found = True; break; - case 0x82: *L2c = (cache_t) { 256, 8, 32 }; L2_found = True; break; - case 0x83: *L2c = (cache_t) { 512, 8, 32 }; L2_found = True; break; - case 0x84: *L2c = (cache_t) { 1024, 8, 32 }; L2_found = True; break; - case 0x85: *L2c = (cache_t) { 2048, 8, 32 }; L2_found = True; break; - case 0x86: *L2c = (cache_t) { 512, 4, 64 }; L2_found = True; break; - case 0x87: *L2c = (cache_t) { 1024, 8, 64 }; L2_found = True; break; - - default: - VG_(message)(Vg_DebugMsg, - "warning: Unknown Intel cache config value " - "(0x%x), ignoring", info[i]); - break; - } - } - - if (!L2_found) - VG_(message)(Vg_DebugMsg, - "warning: L2 cache not installed, ignore L2 results."); - - return 0; -} - -/* AMD method is straightforward, just extract appropriate bits from the - * result registers. - * - * Bits, for D1 and I1: - * 31..24 data L1 cache size in KBs - * 23..16 data L1 cache associativity (FFh=full) - * 15.. 8 data L1 cache lines per tag - * 7.. 0 data L1 cache line size in bytes - * - * Bits, for L2: - * 31..16 unified L2 cache size in KBs - * 15..12 unified L2 cache associativity (0=off, FFh=full) - * 11.. 8 unified L2 cache lines per tag - * 7.. 0 unified L2 cache line size in bytes - * - * #3 The AMD K7 processor's L2 cache must be configured prior to relying - * upon this information. (Whatever that means -- njn) - * - * Also, according to Cyrille Chepelov, Duron stepping A0 processors (model - * 0x630) have a bug and misreport their L2 size as 1KB (it's really 64KB), - * so we detect that. - * - * Returns 0 on success, non-zero on failure. - */ -static -Int AMD_cache_info(cache_t* I1c, cache_t* D1c, cache_t* L2c) -{ - UInt ext_level; - UInt dummy, model; - UInt I1i, D1i, L2i; - - VG_(cpuid)(0x80000000, &ext_level, &dummy, &dummy, &dummy); - - if (0 == (ext_level & 0x80000000) || ext_level < 0x80000006) { - VG_(message)(Vg_UserMsg, - "warning: ext_level < 0x80000006 for AMD processor (0x%x)", - ext_level); - return -1; - } - - VG_(cpuid)(0x80000005, &dummy, &dummy, &D1i, &I1i); - VG_(cpuid)(0x80000006, &dummy, &dummy, &L2i, &dummy); - - VG_(cpuid)(0x1, &model, &dummy, &dummy, &dummy); - - /* Check for Duron bug */ - if (model == 0x630) { - VG_(message)(Vg_UserMsg, - "Buggy Duron stepping A0. Assuming L2 size=65536 bytes"); - L2i = (64 << 16) | (L2i & 0xffff); - } - - D1c->size = (D1i >> 24) & 0xff; - D1c->assoc = (D1i >> 16) & 0xff; - D1c->line_size = (D1i >> 0) & 0xff; - - I1c->size = (I1i >> 24) & 0xff; - I1c->assoc = (I1i >> 16) & 0xff; - I1c->line_size = (I1i >> 0) & 0xff; - - L2c->size = (L2i >> 16) & 0xffff; /* Nb: different bits used for L2 */ - L2c->assoc = (L2i >> 12) & 0xf; - L2c->line_size = (L2i >> 0) & 0xff; - - return 0; -} - -static jmp_buf cpuid_jmpbuf; - -static -void cpuid_SIGILL_handler(int signum) -{ - __builtin_longjmp(cpuid_jmpbuf, 1); -} - -static -Int get_caches_from_CPUID(cache_t* I1c, cache_t* D1c, cache_t* L2c) -{ - Int level, res, ret; - Char vendor_id[13]; - vki_ksigaction sigill_new, sigill_saved; - - /* Install own SIGILL handler */ - sigill_new.ksa_handler = cpuid_SIGILL_handler; - sigill_new.ksa_flags = 0; - sigill_new.ksa_restorer = NULL; - res = VG_(ksigemptyset)( &sigill_new.ksa_mask ); - sk_assert(res == 0); - - res = VG_(ksigaction)( VKI_SIGILL, &sigill_new, &sigill_saved ); - sk_assert(res == 0); - - /* Trap for illegal instruction, in case it's a really old processor that - * doesn't support CPUID. */ - if (__builtin_setjmp(cpuid_jmpbuf) == 0) { - VG_(cpuid)(0, &level, (int*)&vendor_id[0], - (int*)&vendor_id[8], (int*)&vendor_id[4]); - vendor_id[12] = '\0'; - - /* Restore old SIGILL handler */ - res = VG_(ksigaction)( VKI_SIGILL, &sigill_saved, NULL ); - sk_assert(res == 0); - - } else { - VG_(message)(Vg_DebugMsg, "CPUID instruction not supported"); - - /* Restore old SIGILL handler */ - res = VG_(ksigaction)( VKI_SIGILL, &sigill_saved, NULL ); - sk_assert(res == 0); - return -1; - } - - if (0 == level) { - VG_(message)(Vg_DebugMsg, "CPUID level is 0, early Pentium?\n"); - return -1; - } - - /* Only handling Intel and AMD chips... no Cyrix, Transmeta, etc */ - if (0 == VG_(strcmp)(vendor_id, "GenuineIntel")) { - ret = Intel_cache_info(level, I1c, D1c, L2c); - - } else if (0 == VG_(strcmp)(vendor_id, "AuthenticAMD")) { - ret = AMD_cache_info(I1c, D1c, L2c); - - } else if (0 == VG_(strcmp)(vendor_id, "CentaurHauls")) { - /* Total kludge. Pretend to be a VIA Nehemiah. */ - D1c->size = 64; - D1c->assoc = 16; - D1c->line_size = 16; - I1c->size = 64; - I1c->assoc = 4; - I1c->line_size = 16; - L2c->size = 64; - L2c->assoc = 16; - L2c->line_size = 16; - ret = 0; - - } else { - VG_(message)(Vg_DebugMsg, "CPU vendor ID not recognised (%s)", - vendor_id); - return -1; - } - - /* Successful! Convert sizes from KB to bytes */ - I1c->size *= 1024; - D1c->size *= 1024; - L2c->size *= 1024; - - return ret; -} - - -void VGA_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c, - cache_t* I1_dflt, cache_t* D1_dflt, cache_t* L2_dflt, - Bool all_caches_clo_defined) -{ - Int res; - - // Set caches to default. - *I1_dflt = (cache_t) { 65536, 2, 64 }; - *D1_dflt = (cache_t) { 65536, 2, 64 }; - *L2_dflt = (cache_t) { 262144, 8, 64 }; - *I1c = *I1_dflt; - *D1c = *D1_dflt; - *L2c = *L2_dflt; - - // Then replace with any info we can get from CPUID. - res = get_caches_from_CPUID(I1c, D1c, L2c); - - // Warn if CPUID failed and config not completely specified from cmd line. - if (res != 0 && !all_caches_clo_defined) { - VG_(message)(Vg_DebugMsg, - "Warning: Couldn't auto-detect cache config, using one " - "or more defaults "); - } -} - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/configure.in b/VEX/head20041019/configure.in deleted file mode 100644 index 7ce44c545..000000000 --- a/VEX/head20041019/configure.in +++ /dev/null @@ -1,454 +0,0 @@ -# Process this file with autoconf to produce a configure script. -AC_INIT(Valgrind, 2.3.0.CVS, valgrind-users@lists.sourceforge.net) -AC_CONFIG_SRCDIR(coregrind/vg_main.c) -AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE - -AM_MAINTAINER_MODE - -# Checks for programs. -CFLAGS="" - -AC_PROG_LN_S -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_RANLIB - -# Check for the compiler support -if test "${GCC}" != "yes" ; then - AC_MSG_ERROR([Valgrind relies on GCC to be compiled]) -fi - -# figure out where perl lives -AC_PATH_PROG(PERL, perl) - -# figure out where gdb lives -AC_PATH_PROG(GDB, gdb) -# autoheader tries to execute the 3rd string or something; I get warnings when -# it's defined. So just leave it undefined. --njn 2002-Apr-18 -AC_DEFINE_UNQUOTED(GDB_PATH, "$GDB", "") - -# some older automake's don't have it so try something on our own -ifdef([AM_PROG_AS],[AM_PROG_AS], -[ -AS="${CC}" -AC_SUBST(AS) - -ASFLAGS="" -AC_SUBST(ASFLAGS) -]) - -# This variable will collect the individual suppression files -# depending on the results of autoconf - -DEFAULT_SUPP="" - - -# We don't want gcc 2.7 -AC_MSG_CHECKING([for a supported version of gcc]) - -gcc_version=`${CC} --version | head -n 1` - -case "${gcc_version}" in - gcc-2.7.*) - AC_MSG_RESULT([no (${gcc_version})]) - AC_MSG_ERROR([please use a recent (>= gcc-2.95) version of gcc]) - ;; - - *) - AC_MSG_RESULT([ok (${gcc_version})]) - ;; -esac - - -# Checks for the platform -AC_CANONICAL_HOST - -AC_MSG_CHECKING([for a supported CPU]) -AC_SUBST(VG_ARCH) - -case "${host_cpu}" in - i?86) - AC_MSG_RESULT([ok (${host_cpu})]) - VG_ARCH="x86" - ;; - - powerpc*) - AC_MSG_RESULT([no (${host_cpu})]) - VG_ARCH="powerpc" - AC_MSG_ERROR([PowerPC not supported. Sorry]) - ;; - - *) - AC_MSG_RESULT([no (${host_cpu})]) - AC_MSG_ERROR([Unsupported host architecture. Sorry]) - ;; -esac - -AC_MSG_CHECKING([for a supported OS]) -AC_SUBST(VG_OS) - -case "${host_os}" in - *linux*) - AC_MSG_RESULT([ok (${host_os})]) - VG_OS="linux" - - # Ok, this is linux. Check the kernel version - AC_MSG_CHECKING([for the kernel version]) - - kernel=`uname -r` - - case "${kernel}" in - 2.6.*) - AC_MSG_RESULT([2.6 family (${kernel})]) - AC_DEFINE([KERNEL_2_6], 1, [Define to 1 if you're using Linux 2.6.x]) - ;; - - 2.4.*) - AC_MSG_RESULT([2.4 family (${kernel})]) - AC_DEFINE([KERNEL_2_4], 1, [Define to 1 if you're using Linux 2.4.x]) - ;; - - 2.2.*) - AC_MSG_RESULT([2.2 family (${kernel})]) - AC_DEFINE([KERNEL_2_2], 1, [Define to 1 if you're using Linux 2.2.x]) - ;; - - *) - AC_MSG_RESULT([unsupported (${kernel})]) - AC_MSG_ERROR([Valgrind works on kernels 2.2, 2.4, 2.6]) - ;; - esac - - ;; - - *freebsd*) - AC_MSG_RESULT([ok (${host_os})]) - VG_OS="freebsd" - ;; - - *) - AC_MSG_RESULT([no (${host_os})]) - AC_MSG_ERROR([Valgrind is operating system specific. Sorry. Please consider doing a port.]) - ;; -esac - -AC_MSG_CHECKING([for a supported CPU/OS combination]) -AC_SUBST(VG_PLATFORM) - -VG_PLATFORM="$VG_ARCH-$VG_OS" - -case $VG_PLATFORM in - x86-linux) - AC_MSG_RESULT([ok (${host_cpu}-${host_os})]) - ;; - - *) - AC_MSG_RESULT([no (${host_cpu}-${host_os})]) - AC_MSG_ERROR([Valgrind is platform specific. Sorry. Please consider doin -g a port.]) - ;; -esac - -AC_SUBST(DEFAULT_SUPP) - -glibc="" - -AC_EGREP_CPP([GLIBC_21], [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 1) - GLIBC_21 - #endif -#endif -], -glibc="2.1") - -AC_EGREP_CPP([GLIBC_22], [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2) - GLIBC_22 - #endif -#endif -], -glibc="2.2") - -AC_EGREP_CPP([GLIBC_23], [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 3) - GLIBC_23 - #endif -#endif -], -glibc="2.3") - -# Ok, this is linux. Check the kernel version -AC_MSG_CHECKING([the glibc version]) - -case "${glibc}" in - 2.1) - AC_MSG_RESULT(2.1 family) - AC_DEFINE([GLIBC_2_1], 1, [Define to 1 if you're using glibc 2.1.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} glibc-2.1.supp" - ;; - - 2.2) - AC_MSG_RESULT(2.2 family) - AC_DEFINE([GLIBC_2_2], 1, [Define to 1 if you're using glibc 2.2.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} glibc-2.2.supp" - ;; - - 2.3) - AC_MSG_RESULT(2.3 family) - AC_DEFINE([GLIBC_2_3], 1, [Define to 1 if you're using glibc 2.3.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} glibc-2.3.supp" - ;; - - *) - AC_MSG_RESULT(unsupported version) - AC_MSG_ERROR([Valgrind requires the glibc version 2.1, 2.2 or 2.3]) - ;; -esac - -# APIs introduced in recent glibc versions - -AC_MSG_CHECKING([whether sched_param has a sched_priority member]) -AC_CACHE_VAL(vg_have_sched_priority, -[ -AC_TRY_COMPILE([#include ],[ -struct sched_param p; p.sched_priority=1;], -vg_have_sched_priority=yes, -vg_have_sched_priority=no) -]) -AC_MSG_RESULT($vg_have_sched_priority) -if test "$vg_have_sched_priority" = yes; then -AC_DEFINE([HAVE_SCHED_PRIORITY], 1, [pthread / sched_priority exists]) -fi - -AC_MSG_CHECKING([whether nfds_t is defined]) -AC_CACHE_VAL(vg_have_nfds_t, -[ -AC_TRY_COMPILE([#include ],[ -nfds_t i=0;], -vg_have_nfds_t=yes, -vg_have_nfds_t=no) -]) -AC_MSG_RESULT($vg_have_nfds_t) -if test "$vg_have_nfds_t" = yes; then -AC_DEFINE([HAVE_NFDS_T], 1, [nfds_t exists]) -fi - -# try to detect the XFree version -# JRS 2002-06-17: this is completely bogus because it -# detects the server version, whereas we need to know the -# client library version. So what follows is hacked to -# use all the X supp files regardless of what is detected. -# This is really stoooopid and should be fixed properly. - -AC_PATH_X - -if test "${no_x}" != 'yes' ; then - - AC_MSG_CHECKING([X version]) - - cat< conftest.c -#include - -int main (int argc, char * argv []) -{ - Display * display = XOpenDisplay (NULL); - - if (display) { - printf ("%s version=%d\n", ServerVendor (display), VendorRelease (display)); - } - - return 0; -} -EOF - - ${CC} -o conftest conftest.c -I${x_includes} -L${x_libraries} -lX11 >&5 2>&1 - - if test "$?" != 0 ; then - AC_MSG_RESULT([cannot compile test program]) - else - xfree=`./conftest` - - case "${xfree}" in - *XFree86*) - case "${xfree}" in - *version=4*) - AC_MSG_RESULT([XFree 4.x family]) - AC_DEFINE([XFREE_4], 1, [Define to 1 if you're using XFree 4.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp" - # haaaaaaack! - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp" - ;; - - *version=3*) - AC_MSG_RESULT([XFree 3.x family]) - AC_DEFINE([XFREE_3], 1, [Define to 1 if you're using XFree86 3.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp" - # haaaaaaack! - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp" - ;; - - *) AC_MSG_RESULT([unknown XFree86 server (${xfree})]) - # haaaaaaack! - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp" - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp" - ;; - esac - ;; - *X.Org*) - case "${xfree}" in - *version=6*) - AC_MSG_RESULT([X.Org 6.x family]) - AC_DEFINE([XFREE_4], 1, [Define to 1 if you're using XFree 4.x]) - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-4.supp" - # haaaaaaack! - DEFAULT_SUPP="${DEFAULT_SUPP} xfree-3.supp" - ;; - esac - ;; - *) AC_MSG_RESULT([not a XFree86 server]) - ;; - esac - - fi - - rm -f conftest conftest.c -fi - - -# check if the GNU as supports CFI directives -AC_MSG_CHECKING([if gas accepts .cfi]) -AC_TRY_LINK(, [ - -__asm__ __volatile__ (".cfi_startproc\n" - ".cfi_adjust_cfa_offset 0x0\n" - ".cfi_endproc\n"); -], -[ - AC_DEFINE_UNQUOTED([HAVE_GAS_CFI], 1, [Define if your GNU as supports .cfi]) - AC_MSG_RESULT(yes) -], - AC_MSG_RESULT(no) -) - -# does this compiler support -mpreferred-stack-boundary=2 ? -AC_MSG_CHECKING([if gcc accepts -mpreferred-stack-boundary]) - -safe_CFLAGS=$CFLAGS -CFLAGS="-mpreferred-stack-boundary=2" - -AC_TRY_COMPILE(, [ - -int main () { return 0 ; } - -], -[ -PREFERRED_STACK_BOUNDARY="-mpreferred-stack-boundary=2" -AC_MSG_RESULT([yes]) -], [ -PREFERRED_STACK_BOUNDARY="" -AC_MSG_RESULT([no]) -]) -CFLAGS=$safe_CFLAGS - -AC_SUBST(PREFERRED_STACK_BOUNDARY) - - - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/statfs.h sys/time.h sys/endian.h endian.h termios.h unistd.h utime.h linux/fb.h mqueue.h linux/compiler.h]) - -AH_TEMPLATE([HAVE_LINUX_MII_H], []) -AC_MSG_CHECKING([for linux/mii.h]) -AC_PREPROC_IFELSE([#include ], - [AC_DEFINE([HAVE_LINUX_MII_H]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_TYPE_UID_T -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_HEADER_TIME -AC_CHECK_TYPES(__pthread_unwind_buf_t,,,[#include ]) -AC_CHECK_TYPES(u16,,,[#include ]) - -# Checks for library functions. -AC_FUNC_MEMCMP -AC_FUNC_MMAP -AC_TYPE_SIGNAL - -AC_CHECK_FUNCS([floor memchr memset mkdir strchr strdup strpbrk strrchr strstr semtimedop]) - -AC_OUTPUT( - Makefile - valgrind.spec - valgrind.pc - docs/Makefile - tests/Makefile - tests/vg_regtest - tests/unused/Makefile - include/valgrind.h - include/Makefile - include/x86/Makefile - auxprogs/Makefile - coregrind/Makefile - coregrind/demangle/Makefile - coregrind/docs/Makefile - coregrind/x86/Makefile - coregrind/x86-linux/Makefile - addrcheck/Makefile - addrcheck/tests/Makefile - addrcheck/docs/Makefile - memcheck/Makefile - memcheck/tests/Makefile - memcheck/docs/Makefile - cachegrind/Makefile - cachegrind/x86/Makefile - cachegrind/tests/Makefile - cachegrind/docs/Makefile - cachegrind/cg_annotate - helgrind/Makefile - helgrind/tests/Makefile - helgrind/docs/Makefile - massif/Makefile - massif/hp2ps/Makefile - massif/tests/Makefile - massif/docs/Makefile - corecheck/Makefile - corecheck/tests/Makefile - corecheck/docs/Makefile - lackey/Makefile - lackey/tests/Makefile - lackey/docs/Makefile - none/Makefile - none/tests/Makefile - none/docs/Makefile -) - -cat< default.supp -# This is a generated file, composed of the following suppression rules: -# -# ${DEFAULT_SUPP} -# - -EOF - -for file in ${DEFAULT_SUPP} ; do - cat ${srcdir}/$file >> default.supp -done diff --git a/VEX/head20041019/corecheck/.cvsignore b/VEX/head20041019/corecheck/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/corecheck/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/corecheck/CVS/Entries b/VEX/head20041019/corecheck/CVS/Entries deleted file mode 100644 index 47bfa5675..000000000 --- a/VEX/head20041019/corecheck/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:30 2002// -/Makefile.am/1.45/Wed Sep 1 23:20:47 2004// -/cc_main.c/1.20/Thu Sep 2 08:51:40 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/corecheck/CVS/Repository b/VEX/head20041019/corecheck/CVS/Repository deleted file mode 100644 index d55fa87d1..000000000 --- a/VEX/head20041019/corecheck/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/corecheck diff --git a/VEX/head20041019/corecheck/CVS/Root b/VEX/head20041019/corecheck/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/corecheck/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/corecheck/CVS/Template b/VEX/head20041019/corecheck/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/corecheck/Makefile.am b/VEX/head20041019/corecheck/Makefile.am deleted file mode 100644 index 9e4c37b7d..000000000 --- a/VEX/head20041019/corecheck/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -val_PROGRAMS = vgskin_corecheck.so - -vgskin_corecheck_so_SOURCES = cc_main.c -vgskin_corecheck_so_LDFLAGS = -shared - diff --git a/VEX/head20041019/corecheck/cc_main.c b/VEX/head20041019/corecheck/cc_main.c deleted file mode 100644 index fc3e1c7d0..000000000 --- a/VEX/head20041019/corecheck/cc_main.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- CoreCheck: a tool reporting errors detected in core. ---*/ -/*--- cc_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of CoreCheck, a rudimentary Valgrind tool for - detecting certain basic program errors. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" - -void SK_(pre_clo_init)(void) -{ - VG_(details_name) ("Coregrind"); - VG_(details_version) (NULL); - VG_(details_description) ("a rudimentary error detector"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - - VG_(needs_core_errors)(); - - /* No core events to track */ -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 0) - -void SK_(post_clo_init)(void) -{ -} - -UCodeBlock* SK_(instrument)(UCodeBlock* cb, Addr a) -{ - return cb; -} - -void SK_(fini)(Int exitcode) -{ -} - -/*--------------------------------------------------------------------*/ -/*--- end cc_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/corecheck/docs/.cvsignore b/VEX/head20041019/corecheck/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/corecheck/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/corecheck/docs/CVS/Entries b/VEX/head20041019/corecheck/docs/CVS/Entries deleted file mode 100644 index 0e2fffb41..000000000 --- a/VEX/head20041019/corecheck/docs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Thu Oct 3 10:07:33 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:05 2004// -/cc_main.html/1.4/Sun Jan 4 16:43:19 2004// -D diff --git a/VEX/head20041019/corecheck/docs/CVS/Repository b/VEX/head20041019/corecheck/docs/CVS/Repository deleted file mode 100644 index 9af3e69a2..000000000 --- a/VEX/head20041019/corecheck/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/corecheck/docs diff --git a/VEX/head20041019/corecheck/docs/CVS/Root b/VEX/head20041019/corecheck/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/corecheck/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/corecheck/docs/CVS/Template b/VEX/head20041019/corecheck/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/corecheck/docs/Makefile.am b/VEX/head20041019/corecheck/docs/Makefile.am deleted file mode 100644 index 4e4da803f..000000000 --- a/VEX/head20041019/corecheck/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = cc_main.html diff --git a/VEX/head20041019/corecheck/docs/cc_main.html b/VEX/head20041019/corecheck/docs/cc_main.html deleted file mode 100644 index 3a374a403..000000000 --- a/VEX/head20041019/corecheck/docs/cc_main.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - Cachegrind - - - - - -

CoreCheck

-
This manual was last updated on 2002-10-03
-

- -

-njn25@cam.ac.uk
-Copyright © 2000-2004 Nicholas Nethercote -

-CoreCheck is licensed under the GNU General Public License, -version 2
-CoreCheck is a Valgrind tool that does very basic error checking. -

- -

- -

1  CoreCheck

- -CoreCheck is a very simple tool for Valgrind. It adds no instrumentation to -the program's code, and only reports the few kinds of errors detected by -Valgrind's core. It is mainly of use for Valgrind's developers for debugging -and regression testing. -

-The errors detected are those found by the core when -VG_(needs).core_errors is set. These include: - -

    -
  • Pthread API errors (many; eg. unlocking a non-locked mutex)

    -

  • Silly arguments to malloc() et al (eg. negative size)

    -

  • Invalid file descriptors to blocking syscalls read() and - write()

    -

  • Bad signal numbers passed to sigaction()

    -

  • Attempts to install signal handler for SIGKILL or - SIGSTOP

    -

- -
- - - diff --git a/VEX/head20041019/corecheck/tests/.cvsignore b/VEX/head20041019/corecheck/tests/.cvsignore deleted file mode 100644 index bcb560cb6..000000000 --- a/VEX/head20041019/corecheck/tests/.cvsignore +++ /dev/null @@ -1,33 +0,0 @@ -Makefile.in -Makefile -erringfds -malloc3 -sigkill -pth_atfork1 -pth_cancel1 -pth_cancel2 -pth_cvsimple -pth_empty -pth_mutexspeed -pth_once -pth_rwlock -res_search -.ktemp -*.stdout.diff -*.stderr.diff* -*.stdout.out -*.stderr.out -fdleak_cmsg -fdleak_creat -fdleak_dup -fdleak_dup2 -fdleak_fcntl -fdleak_ipv4 -fdleak_open -fdleak_pipe -fdleak_socketpair -pth_exit -pth_exit2 -vgprintf -as_shm -as_mmap diff --git a/VEX/head20041019/corecheck/tests/CVS/Entries b/VEX/head20041019/corecheck/tests/CVS/Entries deleted file mode 100644 index 5ea0f8344..000000000 --- a/VEX/head20041019/corecheck/tests/CVS/Entries +++ /dev/null @@ -1,92 +0,0 @@ -/.cvsignore/1.9/Sat Oct 16 14:49:53 2004// -/Makefile.am/1.22/Sat Oct 16 14:49:53 2004// -/as_mmap.c/1.1/Tue Dec 16 02:14:00 2003// -/as_mmap.stderr.exp/1.1/Tue Dec 16 02:14:00 2003// -/as_mmap.stderr.exp2/1.1/Wed Oct 13 16:48:20 2004// -/as_mmap.vgtest/1.1/Tue Dec 16 02:14:00 2003// -/as_shm.c/1.3/Fri Jan 9 16:15:06 2004// -/as_shm.stderr.exp/1.1/Tue Dec 16 02:14:00 2003// -/as_shm.stdout.exp/1.2/Fri Jan 9 16:15:06 2004// -/as_shm.vgtest/1.1/Tue Dec 16 02:14:00 2003// -/erringfds.c/1.2/Mon Sep 23 09:36:24 2002// -/erringfds.stderr.exp/1.4/Sun Dec 14 06:50:36 2003// -/erringfds.stdout.exp/1.2/Mon Sep 23 09:36:24 2002// -/erringfds.vgtest/1.2/Mon Sep 23 09:36:24 2002// -/fdleak_cmsg.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_cmsg.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_cmsg.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_creat.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_creat.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_creat.stderr.exp2/1.1/Sun Mar 7 19:40:33 2004// -/fdleak_creat.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_dup.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_dup.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_dup.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_dup2.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_dup2.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_dup2.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_fcntl.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_fcntl.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_fcntl.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_ipv4.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_ipv4.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_ipv4.stdout.exp/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_ipv4.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_open.c/1.2/Thu Dec 4 16:12:21 2003// -/fdleak_open.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_open.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_pipe.c/1.1/Mon Nov 17 17:44:59 2003// -/fdleak_pipe.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_pipe.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/fdleak_socketpair.c/1.2/Thu Dec 4 16:12:21 2003// -/fdleak_socketpair.stderr.exp/1.4/Sun Feb 29 12:02:32 2004// -/fdleak_socketpair.vgtest/1.2/Sun Feb 29 12:02:32 2004// -/filter_fdleak/1.3/Tue Mar 9 09:59:26 2004// -/filter_stderr/1.3/Mon Sep 23 11:21:45 2002// -/pth_atfork1.c/1.3/Mon May 5 11:04:37 2003// -/pth_atfork1.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_atfork1.stdout.exp/1.4/Mon May 5 11:04:37 2003// -/pth_atfork1.vgtest/1.2/Mon Sep 23 09:36:24 2002// -/pth_cancel1.c/1.1/Sat Jun 12 12:58:21 2004// -/pth_cancel1.stderr.exp/1.1/Sat Jun 12 12:58:21 2004// -/pth_cancel1.stdout.exp/1.1/Sat Jun 12 12:58:21 2004// -/pth_cancel1.vgtest/1.1/Sat Jun 12 12:58:21 2004// -/pth_cancel2.c/1.3/Sat Oct 5 15:28:29 2002// -/pth_cancel2.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_cancel2.vgtest/1.2/Mon Sep 23 09:36:24 2002// -/pth_cvsimple.c/1.2/Mon Sep 23 09:36:24 2002// -/pth_cvsimple.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_cvsimple.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/pth_cvsimple.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_empty.c/1.2/Mon Sep 23 09:36:25 2002// -/pth_empty.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_empty.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_exit.c/1.1/Mon Oct 13 22:26:54 2003// -/pth_exit.stderr.exp/1.1/Mon Oct 13 22:26:54 2003// -/pth_exit.vgtest/1.1/Mon Oct 13 22:26:54 2003// -/pth_exit2.c/1.1/Sat Aug 14 15:37:59 2004// -/pth_exit2.stderr.exp/1.1/Sat Aug 14 15:37:59 2004// -/pth_exit2.vgtest/1.1/Sat Aug 14 15:37:59 2004// -/pth_mutexspeed.c/1.2/Mon Sep 23 09:36:25 2002// -/pth_mutexspeed.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_mutexspeed.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/pth_mutexspeed.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_once.c/1.2/Mon Sep 23 09:36:25 2002// -/pth_once.stderr.exp/1.3/Mon Nov 18 11:33:37 2002// -/pth_once.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/pth_once.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_rwlock.c/1.1/Sat Oct 16 14:49:53 2004// -/pth_rwlock.stderr.exp/1.1/Sat Oct 16 14:49:53 2004// -/pth_rwlock.vgtest/1.1/Sat Oct 16 14:49:53 2004// -/res_search.c/1.3/Wed Jul 9 21:53:32 2003// -/res_search.stderr.exp/1.1/Fri Jul 4 16:16:51 2003// -/res_search.stdout.exp/1.1/Fri Jul 4 16:16:51 2003// -/res_search.vgtest/1.3/Fri Jul 11 00:17:54 2003// -/sigkill.c/1.4/Sun Feb 22 17:24:01 2004// -/sigkill.stderr.exp/1.5/Sun Feb 22 17:24:01 2004// -/sigkill.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/vgprintf.c/1.2/Sat Dec 13 03:07:40 2003// -/vgprintf.stderr.exp/1.1/Fri Oct 31 18:52:18 2003// -/vgprintf.stdout.exp/1.1/Fri Oct 31 18:52:18 2003// -/vgprintf.vgtest/1.1/Fri Oct 31 18:52:18 2003// -D diff --git a/VEX/head20041019/corecheck/tests/CVS/Repository b/VEX/head20041019/corecheck/tests/CVS/Repository deleted file mode 100644 index 5604db7c5..000000000 --- a/VEX/head20041019/corecheck/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/corecheck/tests diff --git a/VEX/head20041019/corecheck/tests/CVS/Root b/VEX/head20041019/corecheck/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/corecheck/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/corecheck/tests/CVS/Template b/VEX/head20041019/corecheck/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/corecheck/tests/Makefile.am b/VEX/head20041019/corecheck/tests/Makefile.am deleted file mode 100644 index 90658326f..000000000 --- a/VEX/head20041019/corecheck/tests/Makefile.am +++ /dev/null @@ -1,90 +0,0 @@ -##--------------------------------------------------------------------------- -## These test core error checking, eg. "silly values" for malloc/calloc, -## pthread errors (and suppressions), signal handling errors, invalid fds for -## blocking syscalls, etc. -##--------------------------------------------------------------------------- - -noinst_SCRIPTS = filter_stderr filter_fdleak - -EXTRA_DIST = $(noinst_SCRIPTS) \ - as_mmap.stderr.exp as_mmap.stderr.exp2 as_mmap.vgtest \ - erringfds.stderr.exp erringfds.stdout.exp erringfds.vgtest \ - fdleak_cmsg.stderr.exp fdleak_cmsg.vgtest \ - fdleak_creat.stderr.exp fdleak_creat.vgtest \ - fdleak_dup.stderr.exp fdleak_dup.vgtest \ - fdleak_dup2.stderr.exp fdleak_dup2.vgtest \ - fdleak_fcntl.stderr.exp fdleak_fcntl.vgtest \ - fdleak_ipv4.stderr.exp fdleak_ipv4.stdout.exp fdleak_ipv4.vgtest \ - fdleak_open.stderr.exp fdleak_open.vgtest \ - fdleak_pipe.stderr.exp fdleak_pipe.vgtest \ - fdleak_socketpair.stderr.exp fdleak_socketpair.vgtest \ - pth_atfork1.stderr.exp pth_atfork1.stdout.exp pth_atfork1.vgtest \ - pth_cancel1.stderr.exp pth_cancel1.stdout.exp pth_cancel1.vgtest \ - pth_cancel2.stderr.exp pth_cancel2.vgtest \ - pth_cvsimple.stderr.exp pth_cvsimple.stdout.exp pth_cvsimple.vgtest \ - pth_empty.stderr.exp pth_empty.vgtest \ - pth_exit.stderr.exp pth_exit.vgtest \ - pth_exit2.stderr.exp pth_exit2.vgtest \ - pth_mutexspeed.stderr.exp \ - pth_mutexspeed.stdout.exp pth_mutexspeed.vgtest \ - pth_once.stderr.exp pth_once.stdout.exp pth_once.vgtest \ - pth_rwlock.stderr.exp pth_rwlock.vgtest \ - sigkill.stderr.exp sigkill.vgtest \ - res_search.stderr.exp res_search.stdout.exp res_search.vgtest \ - vgprintf.stderr.exp vgprintf.stdout.exp vgprintf.vgtest - -check_PROGRAMS = \ - erringfds fdleak_cmsg fdleak_creat fdleak_dup fdleak_dup2 \ - fdleak_fcntl fdleak_ipv4 fdleak_open fdleak_pipe \ - fdleak_socketpair sigkill res_search \ - pth_atfork1 pth_cancel1 pth_cancel2 pth_cvsimple pth_empty \ - pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \ - as_mmap as_shm \ - vgprintf - -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -O0 -I$(top_srcdir)/include -AM_CXXFLAGS = $(AM_CFLAGS) - -vgprintf_SOURCES = vgprintf.c - -# Client address space checks -as_mmap_SOURCES = as_mmap.c -as_shm_SOURCES = as_shm.c - -# Leak tests -fdleak_cmsg_SOURCES = fdleak_cmsg.c -fdleak_creat_SOURCES = fdleak_creat.c -fdleak_dup_SOURCES = fdleak_dup.c -fdleak_dup2_SOURCES = fdleak_dup2.c -fdleak_fcntl_SOURCES = fdleak_fcntl.c -fdleak_ipv4_SOURCES = fdleak_ipv4.c -fdleak_open_SOURCES = fdleak_open.c -fdleak_pipe_SOURCES = fdleak_pipe.c -fdleak_socketpair_SOURCES = fdleak_socketpair.c -sigkill_SOURCES = sigkill.c - -# Pthread ones -pth_atfork1_SOURCES = pth_atfork1.c -pth_atfork1_LDADD = -lpthread -pth_cancel1_SOURCES = pth_cancel1.c -pth_cancel1_LDADD = -lpthread -pth_cancel2_SOURCES = pth_cancel2.c -pth_cancel2_LDADD = -lpthread -pth_cvsimple_SOURCES = pth_cvsimple.c -pth_cvsimple_LDADD = -lpthread -pth_empty_SOURCES = pth_empty.c -pth_empty_LDADD = -lpthread -pth_exit_SOURCES = pth_exit.c -pth_exit_LDADD = -lpthread -pth_exit2_SOURCES = pth_exit2.c -pth_exit2_LDADD = -lpthread -pth_mutexspeed_SOURCES = pth_mutexspeed.c -pth_mutexspeed_LDADD = -lpthread -pth_once_SOURCES = pth_once.c -pth_once_LDADD = -lpthread -pth_rwlock_SOURCES = pth_rwlock.c -pth_rwlock_LDADD = -lpthread -res_search_SOURCES = res_search.c -res_search_LDADD = -lresolv -lpthread - - diff --git a/VEX/head20041019/corecheck/tests/as_mmap.c b/VEX/head20041019/corecheck/tests/as_mmap.c deleted file mode 100644 index da40a8612..000000000 --- a/VEX/head20041019/corecheck/tests/as_mmap.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -int main() -{ - char local; - char *top = (char *)(((unsigned long)&local + 0x0fffffff) & ~0x0fffffff); - - if (mmap((void *)0x00000000, 0x10000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) - perror("mmap @ 0x00000000"); - if (mmap((void *)0x00010000, 0x10000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) - perror("mmap @ 0x00010000"); - if (mmap((void *)0x50000000, 0x10000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) - perror("mmap @ 0x50000000"); - if (mmap(top, 0x10000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) - perror("mmap @ top"); - if (mmap(top+0x08000000, 0x10000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) - perror("mmap @ top+.5G"); - - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp b/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp deleted file mode 100644 index e5314c8de..000000000 --- a/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ - -Warning: client syscall mmap2 tried to modify addresses 0x0-0x10000 -mmap @ 0x00000000: Cannot allocate memory -Warning: client syscall mmap2 tried to modify addresses 0xB0000000-0xB0010000 -mmap @ top: Cannot allocate memory -Warning: client syscall mmap2 tried to modify addresses 0xB8000000-0xB8010000 -mmap @ top+.5G: Cannot allocate memory - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp2 b/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp2 deleted file mode 100644 index d40015196..000000000 --- a/VEX/head20041019/corecheck/tests/as_mmap.stderr.exp2 +++ /dev/null @@ -1,9 +0,0 @@ - -Warning: client syscall mmap tried to modify addresses 0x0-0x10000 -mmap @ 0x00000000: Cannot allocate memory -Warning: client syscall mmap tried to modify addresses 0xB0000000-0xB0010000 -mmap @ top: Cannot allocate memory -Warning: client syscall mmap tried to modify addresses 0xB8000000-0xB8010000 -mmap @ top+.5G: Cannot allocate memory - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/as_mmap.vgtest b/VEX/head20041019/corecheck/tests/as_mmap.vgtest deleted file mode 100644 index 13cb4513c..000000000 --- a/VEX/head20041019/corecheck/tests/as_mmap.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: as_mmap diff --git a/VEX/head20041019/corecheck/tests/as_shm.c b/VEX/head20041019/corecheck/tests/as_shm.c deleted file mode 100644 index 005c725fa..000000000 --- a/VEX/head20041019/corecheck/tests/as_shm.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include - -int main() -{ - int shmid = shmget(IPC_PRIVATE, 0x10000, IPC_CREAT|IPC_EXCL|0777); - void *addr; - char local; - char *top = (char *)(((unsigned long)&local + 0x0fffffff) & ~0x0fffffff); - - if (shmid == -1) - perror("shmget"); - - addr = shmat(shmid, 0, 0); - - if (addr == (void *)-1) - perror("shmat @ 0"); - else - printf("shmat 0: addr=...\n"); - - addr = shmat(shmid, top, 0); - - if (addr == (void *)-1) - perror("shmat @ top"); - else - printf("shmat 2: addr=...\n"); - - shmctl(shmid, IPC_RMID, NULL); - - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/as_shm.stderr.exp b/VEX/head20041019/corecheck/tests/as_shm.stderr.exp deleted file mode 100644 index ee51d4381..000000000 --- a/VEX/head20041019/corecheck/tests/as_shm.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ - -Warning: client syscall shmat tried to modify addresses 0xB0000000-0xB0010000 -shmat @ top: Invalid argument - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/as_shm.stdout.exp b/VEX/head20041019/corecheck/tests/as_shm.stdout.exp deleted file mode 100644 index 5c3a150d2..000000000 --- a/VEX/head20041019/corecheck/tests/as_shm.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -shmat 0: addr=... diff --git a/VEX/head20041019/corecheck/tests/as_shm.vgtest b/VEX/head20041019/corecheck/tests/as_shm.vgtest deleted file mode 100644 index 1263cea7d..000000000 --- a/VEX/head20041019/corecheck/tests/as_shm.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: as_shm diff --git a/VEX/head20041019/corecheck/tests/erringfds.c b/VEX/head20041019/corecheck/tests/erringfds.c deleted file mode 100644 index 0f1afe5de..000000000 --- a/VEX/head20041019/corecheck/tests/erringfds.c +++ /dev/null @@ -1,17 +0,0 @@ - -#include -#include -#include -#include -#include - -int main ( void ) -{ - int fd, n; - char buf[10]; - fd = open("foo/bar/xyzzy", O_RDONLY); /* fails */ - printf("fd = %d\n", fd); - n = read ( fd, buf, 10 ); - printf ("n = %d\n", n); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/erringfds.stderr.exp b/VEX/head20041019/corecheck/tests/erringfds.stderr.exp deleted file mode 100644 index b6a487d38..000000000 --- a/VEX/head20041019/corecheck/tests/erringfds.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ - -Warning: invalid file descriptor -1 in syscall read() - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/erringfds.stdout.exp b/VEX/head20041019/corecheck/tests/erringfds.stdout.exp deleted file mode 100644 index bcc1770f1..000000000 --- a/VEX/head20041019/corecheck/tests/erringfds.stdout.exp +++ /dev/null @@ -1,2 +0,0 @@ -fd = -1 -n = -1 diff --git a/VEX/head20041019/corecheck/tests/erringfds.vgtest b/VEX/head20041019/corecheck/tests/erringfds.vgtest deleted file mode 100644 index 5a8ede4c3..000000000 --- a/VEX/head20041019/corecheck/tests/erringfds.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: erringfds diff --git a/VEX/head20041019/corecheck/tests/fdleak_cmsg.c b/VEX/head20041019/corecheck/tests/fdleak_cmsg.c deleted file mode 100644 index a6dccb102..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_cmsg.c +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -char filea[24]; -char fileb[24]; -char sock[24]; - -void -server () -{ - int s, fd1, fd2; - struct sockaddr_un addr; - - fd1 = open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750); - if(fd1 == -1) { - perror("open"); - exit(1); - } - - fd2 = open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750); - if(fd2 == -1) { - perror("open"); - exit(1); - } - - s = socket(PF_UNIX, SOCK_STREAM, 0); - if(s == -1) { - perror("socket"); - exit(1); - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - sprintf(addr.sun_path, sock); - - unlink(addr.sun_path); - if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - perror("bind"); - exit(1); - } - - if(listen(s, 5) == -1) { - perror("listen"); - exit(1); - } - - { - int x; - int baddrsize = 0; - struct sockaddr_un baddr; - struct msghdr msg = {NULL, 0, NULL, 0, 0, 0, 0}; - struct cmsghdr *cmsg; - char buf[CMSG_SPACE(sizeof(int) * 2)]; - struct iovec iov[1]; - - memset(&baddr, 0, sizeof(baddr)); - x = accept(s, (struct sockaddr *)&baddr, &baddrsize); - if(x == -1) { - perror("accept"); - exit(1); - } - - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 2); - ((int *)CMSG_DATA(cmsg))[0] = fd1; - ((int *)CMSG_DATA(cmsg))[1] = fd2; - - iov[0].iov_base = "hello"; - iov[0].iov_len = 6; - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - if(sendmsg(x, &msg, 0) == -1) { - perror("sendmsg"); - exit(1); - } - } -} - -void -client () -{ - int s, fd1 = -1, fd2 = -1, size, count = 0, ret; - struct sockaddr_un addr; - struct iovec iov[1]; - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(int) * 2)]; - } control_un; - struct msghdr msg = { NULL, 0, iov, 1, control_un.control, - sizeof(control_un), 0 }; - struct cmsghdr *cmsg = &control_un.cm; - char buf[1024]; - - iov[0].iov_base = buf; - iov[0].iov_len = sizeof(buf); - - s = socket(PF_UNIX, SOCK_STREAM, 0); - if(s == -1) { - perror("socket"); - exit(1); - } - - addr.sun_family = AF_UNIX; - sprintf(addr.sun_path, sock); - - do { - count++; - ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); - if(ret == -1) sleep(1); - } while (count < 10 && ret == -1); - - if(ret == -1) { - perror("connect"); - exit(1); - } - - if((size = recvmsg(s, &msg, 0)) == -1) { - perror("recvmsg"); - exit(1); - } - - - cmsg = CMSG_FIRSTHDR(&msg); - while(cmsg) { - if(cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS && - cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) { - fd1 = ((int *)CMSG_DATA(cmsg))[0]; - fd2 = ((int *)CMSG_DATA(cmsg))[1]; - } - - cmsg = CMSG_NXTHDR(&msg, cmsg); - } - - if(fd1 != -1) write(fd1, "Yeah 1\n", 8); - if(fd2 != -1) write(fd2, "Yeah 2\n", 8); -} - - -int -main (int argc, char **argv) -{ - int pid, status; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - pid = getpid(); - sprintf(filea, "/tmp/data1.%d", pid); - sprintf(fileb, "/tmp/data2.%d", pid); - sprintf(sock, "/tmp/sock.%d", pid); - - if((pid = fork()) == 0) { - server(); - return 0; - } - - client(); - - wait(&status); - - unlink(filea); - unlink(fileb); - unlink(sock); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_cmsg.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_cmsg.stderr.exp deleted file mode 100644 index d4ad19209..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_cmsg.stderr.exp +++ /dev/null @@ -1,55 +0,0 @@ - - -FILE DESCRIPTORS: 7 open at exit. -Open AF_UNIX socket .: /tmp/sock - at 0x........: accept (in /...libc...) - by 0x........: main (fdleak_cmsg.c:170) - -Open AF_UNIX socket .: /tmp/sock - at 0x........: socket (in /...libc...) - by 0x........: main (fdleak_cmsg.c:170) - -Open file descriptor .: /tmp/data2 - at 0x........: open (in /...libc...) - by 0x........: main (fdleak_cmsg.c:170) - -Open file descriptor .: /tmp/data1 - at 0x........: open (in /...libc...) - by 0x........: main (fdleak_cmsg.c:170) - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) - -FILE DESCRIPTORS: 6 open at exit. -Open file descriptor .: /tmp/data2 - at 0x........: recvmsg (in /...libc...) - by 0x........: main (fdleak_cmsg.c:174) - -Open file descriptor .: /tmp/data1 - at 0x........: recvmsg (in /...libc...) - by 0x........: main (fdleak_cmsg.c:174) - -Open AF_UNIX socket .: - at 0x........: socket (in /...libc...) - by 0x........: main (fdleak_cmsg.c:174) - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_cmsg.vgtest b/VEX/head20041019/corecheck/tests/fdleak_cmsg.vgtest deleted file mode 100644 index 508332044..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_cmsg.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_cmsg -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_creat.c b/VEX/head20041019/corecheck/tests/fdleak_creat.c deleted file mode 100644 index 9a2aaf1e1..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_creat.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -int -main (int argc, char **argv) -{ - char filename[24]; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - sprintf(filename, "/tmp/file.%d\n", getpid()); - creat(filename, 0); - unlink(filename); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp deleted file mode 100644 index 66e60362a..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp +++ /dev/null @@ -1,20 +0,0 @@ - - -FILE DESCRIPTORS: 4 open at exit. -Open file descriptor .: /tmp/file - - at 0x........: creat (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp2 b/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp2 deleted file mode 100644 index c29fd9699..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_creat.stderr.exp2 +++ /dev/null @@ -1,19 +0,0 @@ - - -FILE DESCRIPTORS: 4 open at exit. -Open file descriptor .: /tmp/file - - at 0x........: open (in /...libc...) - by 0x........: main (fdleak_creat.c:18) - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_creat.vgtest b/VEX/head20041019/corecheck/tests/fdleak_creat.vgtest deleted file mode 100644 index ffa412a45..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_creat.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_creat -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup.c b/VEX/head20041019/corecheck/tests/fdleak_dup.c deleted file mode 100644 index db8a28746..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -int -main (int argc, char **argv) -{ - int s; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - s = open("/dev/null", O_RDONLY); - dup(s); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_dup.stderr.exp deleted file mode 100644 index 0c54be6b0..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup.stderr.exp +++ /dev/null @@ -1,24 +0,0 @@ - - -FILE DESCRIPTORS: 5 open at exit. -Open file descriptor .: /dev/null - at 0x........: dup (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: /dev/null - at 0x........: open (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup.vgtest b/VEX/head20041019/corecheck/tests/fdleak_dup.vgtest deleted file mode 100644 index d150dfef0..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_dup -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup2.c b/VEX/head20041019/corecheck/tests/fdleak_dup2.c deleted file mode 100644 index bcc8ff4a1..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup2.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -int -main (int argc, char **argv) -{ - int s1; - int s2; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - s1 = open("/dev/null", O_RDONLY); - s2 = open("/dev/null", O_RDONLY); - - dup2(s1, 20); - dup2(s1, s2); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup2.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_dup2.stderr.exp deleted file mode 100644 index 612b352e0..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup2.stderr.exp +++ /dev/null @@ -1,29 +0,0 @@ - - -FILE DESCRIPTORS: 6 open at exit. -Open file descriptor .: /dev/null - at 0x........: dup2 (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: /dev/null - at 0x........: dup2 (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: /dev/null - at 0x........: open (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_dup2.vgtest b/VEX/head20041019/corecheck/tests/fdleak_dup2.vgtest deleted file mode 100644 index 7b0d95eea..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_dup2.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_dup2 -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_fcntl.c b/VEX/head20041019/corecheck/tests/fdleak_fcntl.c deleted file mode 100644 index e2ea4f4a0..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_fcntl.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include - -int -main (int argc, char **argv) -{ - int s1; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - s1 = open("/dev/null", O_RDONLY); - if(fcntl(s1, F_DUPFD, s1) == -1) perror("fcntl"); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_fcntl.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_fcntl.stderr.exp deleted file mode 100644 index 89f059e0e..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_fcntl.stderr.exp +++ /dev/null @@ -1,23 +0,0 @@ - - -FILE DESCRIPTORS: 5 open at exit. -Open file descriptor .: /dev/null - at 0x........: fcntl (in /...libc...) - by 0x........: main (fdleak_fcntl.c:18) - -Open file descriptor .: /dev/null - at 0x........: open (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_fcntl.vgtest b/VEX/head20041019/corecheck/tests/fdleak_fcntl.vgtest deleted file mode 100644 index 5b506eaaf..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_fcntl.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_fcntl -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_ipv4.c b/VEX/head20041019/corecheck/tests/fdleak_ipv4.c deleted file mode 100644 index 98d28aee2..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_ipv4.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void -server () -{ - int s, x; - struct sockaddr_in baddr; - struct sockaddr_in addr; - int baddrsize = sizeof(baddr); - int one = 1; - - s = socket(PF_INET, SOCK_STREAM, 0); - if(s == -1) { - perror("socket"); - exit(1); - } - - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = 12321; - - if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - perror("bind"); - exit(1); - } - - if(listen(s, 5) == -1) { - perror("listen"); - exit(1); - } - - memset(&baddr, 0, sizeof(baddr)); - x = accept(s, (struct sockaddr *)&baddr, &baddrsize); - if(x == -1) { - perror("accept"); - exit(1); - } - - write(x, "hello", 6); -} - -void -client () -{ - int s, count = 0, ret; - struct sockaddr_in addr; - char buf[1024]; - - s = socket(PF_INET, SOCK_STREAM, 0); - if(s == -1) { - perror("socket"); - exit(1); - } - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = 12321; - - do { - count++; - ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); - if(ret == -1) sleep(1); - } while (count < 10 && ret == -1); - - if(ret == -1) { - perror("connect"); - exit(1); - } - - read(s, buf, sizeof(buf)); - - printf("%s\n", buf); -} - - -int -main (int argc, char **argv) -{ - int pid, status; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - if((pid = fork()) == 0) { - server(); - return 0; - } - - client(); - - wait(&status); - - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_ipv4.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_ipv4.stderr.exp deleted file mode 100644 index cfe029ed4..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_ipv4.stderr.exp +++ /dev/null @@ -1,39 +0,0 @@ - - -FILE DESCRIPTORS: 5 open at exit. -Open AF_INET socket 4: 127.0.0.1:... <-> 127.0.0.1:... - at 0x........: accept (in /...libc...) - by 0x........: main (fdleak_ipv4.c:100) - -Open AF_INET socket 3: 127.0.0.1:... <-> unbound - at 0x........: socket (in /...libc...) - by 0x........: main (fdleak_ipv4.c:100) - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) - -FILE DESCRIPTORS: 4 open at exit. -Open AF_INET socket 3: 127.0.0.1:... <-> 127.0.0.1:... - at 0x........: socket (in /...libc...) - by 0x........: main (fdleak_ipv4.c:104) - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_ipv4.stdout.exp b/VEX/head20041019/corecheck/tests/fdleak_ipv4.stdout.exp deleted file mode 100644 index ce0136250..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_ipv4.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -hello diff --git a/VEX/head20041019/corecheck/tests/fdleak_ipv4.vgtest b/VEX/head20041019/corecheck/tests/fdleak_ipv4.vgtest deleted file mode 100644 index 7d664a1ab..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_ipv4.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_ipv4 -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_open.c b/VEX/head20041019/corecheck/tests/fdleak_open.c deleted file mode 100644 index 22b4228d8..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_open.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -int -main (int argc, char **argv) -{ - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - open("/dev/null", O_RDONLY); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_open.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_open.stderr.exp deleted file mode 100644 index 6fda89512..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_open.stderr.exp +++ /dev/null @@ -1,19 +0,0 @@ - - -FILE DESCRIPTORS: 4 open at exit. -Open file descriptor .: /dev/null - at 0x........: open (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_open.vgtest b/VEX/head20041019/corecheck/tests/fdleak_open.vgtest deleted file mode 100644 index 8b9bef573..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_open.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_open -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_pipe.c b/VEX/head20041019/corecheck/tests/fdleak_pipe.c deleted file mode 100644 index 6c2d566d1..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_pipe.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -int -main (int argc, char **argv) -{ - int fds[2]; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - pipe(fds); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_pipe.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_pipe.stderr.exp deleted file mode 100644 index 0ba67334f..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_pipe.stderr.exp +++ /dev/null @@ -1,24 +0,0 @@ - - -FILE DESCRIPTORS: 5 open at exit. -Open file descriptor .: - at 0x........: pipe (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: - at 0x........: pipe (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_pipe.vgtest b/VEX/head20041019/corecheck/tests/fdleak_pipe.vgtest deleted file mode 100644 index 242c12753..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_pipe.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_pipe -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/fdleak_socketpair.c b/VEX/head20041019/corecheck/tests/fdleak_socketpair.c deleted file mode 100644 index da3e91204..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_socketpair.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -int -main (int argc, char **argv) -{ - int fds[2]; - - /* - * Fedora Core 1's Perl opens /dev/pts/2 as fd 10. Let's close it - * now to get consistent results across different releases. - */ - - close(10); - - socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX, fds); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/fdleak_socketpair.stderr.exp b/VEX/head20041019/corecheck/tests/fdleak_socketpair.stderr.exp deleted file mode 100644 index 87192dad1..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_socketpair.stderr.exp +++ /dev/null @@ -1,24 +0,0 @@ - - -FILE DESCRIPTORS: 5 open at exit. -Open AF_UNIX socket .: - at 0x........: socketpair (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open AF_UNIX socket .: - at 0x........: socketpair (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -Open file descriptor .: . - - -Open file descriptor .: . - - -Open file descriptor .: /dev/null - - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/fdleak_socketpair.vgtest b/VEX/head20041019/corecheck/tests/fdleak_socketpair.vgtest deleted file mode 100644 index 9903dc2f7..000000000 --- a/VEX/head20041019/corecheck/tests/fdleak_socketpair.vgtest +++ /dev/null @@ -1,4 +0,0 @@ -prog: fdleak_socketpair -vgopts: --track-fds=yes -stderr_filter: filter_fdleak -args: < /dev/null diff --git a/VEX/head20041019/corecheck/tests/filter_fdleak b/VEX/head20041019/corecheck/tests/filter_fdleak deleted file mode 100755 index b33fb2d73..000000000 --- a/VEX/head20041019/corecheck/tests/filter_fdleak +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | - -# Anonymise addresses -$dir/../../tests/filter_addresses | - -# Anonymise line numbers in mac_replace_strmem.c -sed "s/mac_replace_strmem.c:[0-9]*/mac_replace_strmem.c:.../" | - -$dir/../../tests/filter_test_paths | - -# Anonymise paths like "(in /foo/bar/libc-baz.so)" -sed "s/(in \/.*libc.*)$/(in \/...libc...)/" | - -# Anonymise paths like "xxx (../sysdeps/unix/sysv/linux/quux.c:129)" -sed "s/(\.\.\/sysdeps\/unix\/sysv\/linux\/.*\.c:[0-9]*)$/(in \/...libc...)/" | - -# Anonymise paths like "__libc_start_main (../foo/bar/libc-quux.c:129)" -sed "s/__libc_\(.*\) (.*)$/__libc_\1 (...libc...)/" | - -sed s/"^Open AF_UNIX socket [0-9]*: /Open AF_UNIX socket .: /" | -sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/dev\/null/Open \\1 .: \/dev\/null/" | -sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/tmp\/\(sock\|data1\|data2\|file\)\.[0-9]*/Open \\1 .: \/tmp\/\\2/" | -sed s/"^Open file descriptor [0-9]*: .*/Open file descriptor .: ./" | -sed s/"^Open file descriptor [0-9]*:$/Open file descriptor .:/" | -sed s/"127.0.0.1:[0-9]*/127.0.0.1:.../g" diff --git a/VEX/head20041019/corecheck/tests/filter_stderr b/VEX/head20041019/corecheck/tests/filter_stderr deleted file mode 100755 index 76189819f..000000000 --- a/VEX/head20041019/corecheck/tests/filter_stderr +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic diff --git a/VEX/head20041019/corecheck/tests/pth_atfork1.c b/VEX/head20041019/corecheck/tests/pth_atfork1.c deleted file mode 100644 index b9305808c..000000000 --- a/VEX/head20041019/corecheck/tests/pth_atfork1.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Tests for fork in multi-threaded environment. - Copyright (C) 2000 Free Software Foundation, Inc. - Contributed by Ulrich Drepper , 2000. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#include -#include -#include -#include - -enum -{ - PREPARE_BIT = 1, - PARENT_BIT = 2, - CHILD_BIT = 4 -}; - -static int var; - -static void -prepare (void) -{ - var |= PREPARE_BIT; -} - -static void -parent (void) -{ - var |= PARENT_BIT; -} - -static void -child (void) -{ - var |= CHILD_BIT; -} - - -static void *thread (void *arg); - - -int -main (void) -{ - pthread_t th; - void *res; - - pthread_atfork (prepare, parent, child); - - if (pthread_create (&th, NULL, thread, NULL) != 0) - error (EXIT_FAILURE, 0, "cannot create thread"); - - pthread_join (th, &res); - - if ( ( int ) ( long int ) res != 0 ) - error(EXIT_FAILURE, 0, "pthread_join res != 0" ); - - printf ( "all ok\n" ); - return 0; -} - - -static void * -thread (void *arg) -{ - int status; - pid_t pid; - - pid = fork (); - if (pid == 0) - { - /* We check whether the `prepare' and `child' function ran. */ - exit (var != (PREPARE_BIT | CHILD_BIT)); - } - else if (pid == (pid_t) -1) - error (EXIT_FAILURE, errno, "cannot fork"); - - if (waitpid (pid, &status, 0) != pid) - error (EXIT_FAILURE, errno, "wrong child"); - - if (WTERMSIG (status) != 0) - error (EXIT_FAILURE, 0, "Child terminated incorrectly"); - status = WEXITSTATUS (status); - - if (status == 0) - status = var != (PREPARE_BIT | PARENT_BIT); - - return (void *) (long int) status; -} diff --git a/VEX/head20041019/corecheck/tests/pth_atfork1.stderr.exp b/VEX/head20041019/corecheck/tests/pth_atfork1.stderr.exp deleted file mode 100644 index 4201442c2..000000000 --- a/VEX/head20041019/corecheck/tests/pth_atfork1.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_atfork1.stdout.exp b/VEX/head20041019/corecheck/tests/pth_atfork1.stdout.exp deleted file mode 100644 index d48ce7299..000000000 --- a/VEX/head20041019/corecheck/tests/pth_atfork1.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -all ok diff --git a/VEX/head20041019/corecheck/tests/pth_atfork1.vgtest b/VEX/head20041019/corecheck/tests/pth_atfork1.vgtest deleted file mode 100644 index 237ff87d7..000000000 --- a/VEX/head20041019/corecheck/tests/pth_atfork1.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_atfork1 diff --git a/VEX/head20041019/corecheck/tests/pth_cancel1.c b/VEX/head20041019/corecheck/tests/pth_cancel1.c deleted file mode 100644 index d1b93e34b..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel1.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include - -static void thread_cleanup(void *arg) -{ - printf("cleaning up %p\n", arg); - - return; -} - -static void *thread_main(void *arg) -{ - pthread_cleanup_push(thread_cleanup, (void *)0x1234); - pthread_cleanup_push(thread_cleanup, (void *)0x5678); - - if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0) - { - perror("pthread_setcanceltype"); - return NULL; - } - - if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) - { - perror("pthread_setcancelstate"); - return NULL; - } - - pause(); - - pthread_cleanup_pop(0); - pthread_cleanup_pop(0); - - return NULL; -} - -int main(int argc, char **argv) -{ - pthread_t tid; - void *result; - - if (pthread_create(&tid, NULL, thread_main, NULL) != 0) - { - perror("pthread_create"); - exit(1); - } - - sleep(1); - - if (pthread_cancel(tid) != 0) - { - perror("pthread_cancel"); - exit(1); - } - - if (pthread_join(tid, &result) != 0) - { - perror("pthread_join"); - exit(1); - } - - printf("result = %p\n", result); - - exit(0); -} diff --git a/VEX/head20041019/corecheck/tests/pth_cancel1.stderr.exp b/VEX/head20041019/corecheck/tests/pth_cancel1.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel1.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_cancel1.stdout.exp b/VEX/head20041019/corecheck/tests/pth_cancel1.stdout.exp deleted file mode 100644 index f0e1e4e3a..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel1.stdout.exp +++ /dev/null @@ -1,3 +0,0 @@ -cleaning up 0x5678 -cleaning up 0x1234 -result = 0xffffffff diff --git a/VEX/head20041019/corecheck/tests/pth_cancel1.vgtest b/VEX/head20041019/corecheck/tests/pth_cancel1.vgtest deleted file mode 100644 index f224af427..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel1.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_cancel1 diff --git a/VEX/head20041019/corecheck/tests/pth_cancel2.c b/VEX/head20041019/corecheck/tests/pth_cancel2.c deleted file mode 100644 index 63fd75a3f..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel2.c +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************** - * An example source module to accompany... - * - * "Using POSIX Threads: Programming with Pthreads" - * by Brad nichols, Dick Buttlar, Jackie Farrell - * O'Reilly & Associates, Inc. - * - ******************************************************** - * async_safe -- - * - * Example showing macro wrappers for calling non-async - * safe routines when the caller has asynchronous - * cancellation turned on - */ - -#include -#include -#include -#include -#include -#include - -#include - - -#define async_cancel_safe_read(fd,buf,amt) \ - { \ - int oldtype; \ - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \ - if (read(fd,buf,amt) < 0) \ - perror("read"),exit(1); \ - pthread_setcanceltype(oldtype,NULL); \ - pthread_testcancel(); \ - } - - -#define async_cancel_safe_write(fd,buf,amt) \ - { \ - int oldtype; \ - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \ - if (write(fd,buf,amt) < 0) \ - perror("write"), exit(1); \ - pthread_setcanceltype(oldtype,NULL); \ - pthread_testcancel(); \ - } - - -static int fd; - -void *io(void *arg) -{ - int *fd2=(int *)arg; - char buf[20]="String"; - int amt=20; - - for (;;) { - async_cancel_safe_write(*fd2,buf,amt); - async_cancel_safe_read(*fd2,buf,amt); - } - return(NULL); -} - -void *killer(void *arg) -{ - pthread_t * target = (pthread_t *)arg; - sleep(1); - pthread_cancel(*target); - return(NULL); -} - -extern int -main(void) -{ - pthread_t io_thread, killer_thread; - - // extern void *io(void *); - // extern void *killer(void *); - - if ((fd = open(".ktemp",O_CREAT | O_RDWR, 0666)) < 0) - perror("open"), exit(1); - - pthread_create(&io_thread, - NULL, - io, - (void *)&fd); - pthread_create(&killer_thread, - NULL, - killer, - (void *)&io_thread); - - pthread_join(io_thread, NULL); - - pthread_join(killer_thread,NULL); - - if ((close(fd)) < 0) - perror("close"),exit(1); - if ((unlink(".ktemp")) < 0) - perror("unlink"),exit(1); - - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/pth_cancel2.stderr.exp b/VEX/head20041019/corecheck/tests/pth_cancel2.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel2.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_cancel2.vgtest b/VEX/head20041019/corecheck/tests/pth_cancel2.vgtest deleted file mode 100644 index 7bb8e1b71..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cancel2.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_cancel2 diff --git a/VEX/head20041019/corecheck/tests/pth_cvsimple.c b/VEX/head20041019/corecheck/tests/pth_cvsimple.c deleted file mode 100644 index 3bb5085f8..000000000 --- a/VEX/head20041019/corecheck/tests/pth_cvsimple.c +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************** - * An example source module to accompany... - * - * "Using POSIX Threads: Programming with Pthreads" - * by Brad nichols, Dick Buttlar, Jackie Farrell - * O'Reilly & Associates, Inc. - * - ******************************************************** - * - * cvsimple.c - * - * Demonstrates pthread cancellation. - * - */ - -#include -#include - -#define NUM_THREADS 3 -#define TCOUNT 10 -#define COUNT_THRES 12 - -int count = 0; -int thread_ids[3] = {0,1,2}; -pthread_mutex_t count_lock=PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t count_hit_threshold=PTHREAD_COND_INITIALIZER; - -void *inc_count(void *idp) -{ - int i=0; - int *my_id = idp; - - for (i=0; i -#include - -static void *th(void *v) -{ - sleep(1); - pthread_exit(0); -} - -int main() -{ - pthread_t a; - - pthread_create(&a, NULL, th, NULL); - pthread_create(&a, NULL, th, NULL); - pthread_create(&a, NULL, th, NULL); - pthread_create(&a, NULL, th, NULL); - - pthread_exit(0); -} diff --git a/VEX/head20041019/corecheck/tests/pth_exit.stderr.exp b/VEX/head20041019/corecheck/tests/pth_exit.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_exit.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_exit.vgtest b/VEX/head20041019/corecheck/tests/pth_exit.vgtest deleted file mode 100644 index 07cde7606..000000000 --- a/VEX/head20041019/corecheck/tests/pth_exit.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_exit diff --git a/VEX/head20041019/corecheck/tests/pth_exit2.c b/VEX/head20041019/corecheck/tests/pth_exit2.c deleted file mode 100644 index e1b9e7ee0..000000000 --- a/VEX/head20041019/corecheck/tests/pth_exit2.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() -{ - pthread_exit(0); -} diff --git a/VEX/head20041019/corecheck/tests/pth_exit2.stderr.exp b/VEX/head20041019/corecheck/tests/pth_exit2.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_exit2.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_exit2.vgtest b/VEX/head20041019/corecheck/tests/pth_exit2.vgtest deleted file mode 100644 index 1a5457904..000000000 --- a/VEX/head20041019/corecheck/tests/pth_exit2.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_exit2 diff --git a/VEX/head20041019/corecheck/tests/pth_mutexspeed.c b/VEX/head20041019/corecheck/tests/pth_mutexspeed.c deleted file mode 100644 index ad263e193..000000000 --- a/VEX/head20041019/corecheck/tests/pth_mutexspeed.c +++ /dev/null @@ -1,19 +0,0 @@ - -#include -#include -#include - -int main ( void ) -{ - const int n = 100000; - int i, r; - pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; - printf("begin %d lock--unlocks\n", n); - for (i = 0; i < n; i++) { - r = pthread_mutex_lock(&mx); - r |= pthread_mutex_unlock(&mx); - assert(r == 0); - } - printf("done %d lock--unlocks\n", n); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/pth_mutexspeed.stderr.exp b/VEX/head20041019/corecheck/tests/pth_mutexspeed.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_mutexspeed.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_mutexspeed.stdout.exp b/VEX/head20041019/corecheck/tests/pth_mutexspeed.stdout.exp deleted file mode 100644 index 820816844..000000000 --- a/VEX/head20041019/corecheck/tests/pth_mutexspeed.stdout.exp +++ /dev/null @@ -1,2 +0,0 @@ -begin 100000 lock--unlocks -done 100000 lock--unlocks diff --git a/VEX/head20041019/corecheck/tests/pth_mutexspeed.vgtest b/VEX/head20041019/corecheck/tests/pth_mutexspeed.vgtest deleted file mode 100644 index 3daee3a75..000000000 --- a/VEX/head20041019/corecheck/tests/pth_mutexspeed.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_mutexspeed diff --git a/VEX/head20041019/corecheck/tests/pth_once.c b/VEX/head20041019/corecheck/tests/pth_once.c deleted file mode 100644 index 75f6a1f31..000000000 --- a/VEX/head20041019/corecheck/tests/pth_once.c +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************** - * An example source module to accompany... - * - * "Using POSIX Threads: Programming with Pthreads" - * by Brad nichols, Dick Buttlar, Jackie Farrell - * O'Reilly & Associates, Inc. - * - ******************************************************** - * once_exam.c - * - * An example of using the pthreads_once() call to execute an - * initialization procedure. - * - * A program spawns multiple threads and each one tries to - * execute the routine welcome() using the once call. Only - * the first thread into the once routine will actually - * execute welcome(). - * - * The program's main thread synchronizes its exit with the - * exit of the threads using the pthread_join() operation. - * -*/ - -#include -#include -#include -#include - -#include - -#define NUM_THREADS 10 - -static pthread_once_t welcome_once_block = PTHREAD_ONCE_INIT; - -void welcome(void) -{ - printf("welcome: Welcome\n"); -} - -void *identify_yourself(void *arg) -{ - int *pid=(int *)arg; - int rtn; - - if ((rtn = pthread_once(&welcome_once_block, - welcome)) != 0) { - fprintf(stderr, "pthread_once failed with %d",rtn); - pthread_exit((void *)NULL); - } - printf("identify_yourself: Hi, I'm thread # %d\n",*pid); - return(NULL); -} - -extern int -main(void) -{ - int *id_arg, thread_num, rtn; - pthread_t threads[NUM_THREADS]; - - id_arg = (int *)malloc(NUM_THREADS*sizeof(int)); - - for (thread_num = 0; thread_num < NUM_THREADS; (thread_num)++) { - - id_arg[thread_num] = thread_num; - - if (( rtn = pthread_create(&threads[thread_num], - NULL, - identify_yourself, - (void *) &(id_arg[thread_num]))) - != 0) { - fprintf(stderr, "pthread_create failed with %d",rtn); - exit(1); - } - } - - for (thread_num = 0; thread_num < NUM_THREADS; thread_num++) { - pthread_join(threads[thread_num], NULL); - printf("main: joined to thread %d\n", thread_num); - } - printf("main: Goodbye\n"); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/pth_once.stderr.exp b/VEX/head20041019/corecheck/tests/pth_once.stderr.exp deleted file mode 100644 index d18786f80..000000000 --- a/VEX/head20041019/corecheck/tests/pth_once.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_once.stdout.exp b/VEX/head20041019/corecheck/tests/pth_once.stdout.exp deleted file mode 100644 index 97e25d16c..000000000 --- a/VEX/head20041019/corecheck/tests/pth_once.stdout.exp +++ /dev/null @@ -1,22 +0,0 @@ -welcome: Welcome -identify_yourself: Hi, I'm thread # 0 -identify_yourself: Hi, I'm thread # 1 -identify_yourself: Hi, I'm thread # 2 -identify_yourself: Hi, I'm thread # 3 -identify_yourself: Hi, I'm thread # 4 -identify_yourself: Hi, I'm thread # 5 -identify_yourself: Hi, I'm thread # 6 -identify_yourself: Hi, I'm thread # 7 -identify_yourself: Hi, I'm thread # 8 -identify_yourself: Hi, I'm thread # 9 -main: joined to thread 0 -main: joined to thread 1 -main: joined to thread 2 -main: joined to thread 3 -main: joined to thread 4 -main: joined to thread 5 -main: joined to thread 6 -main: joined to thread 7 -main: joined to thread 8 -main: joined to thread 9 -main: Goodbye diff --git a/VEX/head20041019/corecheck/tests/pth_once.vgtest b/VEX/head20041019/corecheck/tests/pth_once.vgtest deleted file mode 100644 index 50bc5b4eb..000000000 --- a/VEX/head20041019/corecheck/tests/pth_once.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_once diff --git a/VEX/head20041019/corecheck/tests/pth_rwlock.c b/VEX/head20041019/corecheck/tests/pth_rwlock.c deleted file mode 100644 index 75486ea98..000000000 --- a/VEX/head20041019/corecheck/tests/pth_rwlock.c +++ /dev/null @@ -1,31 +0,0 @@ -#define _XOPEN_SOURCE 600 - -#include -#include -#include -#include - -#define LOCKS 2000 - -int main(int argc, char **argv) -{ - pthread_rwlock_t locks[LOCKS]; - int n; - int e; - - for (n = 0; n < LOCKS; n++) { - if ((e = pthread_rwlock_init(locks + n, NULL)) != 0) { - fprintf(stderr, "pthread_rwlock_init[%d]: %s\n", n, strerror(e)); - exit(1); - } - } - - for (n = 0; n < LOCKS; n++) { - if ((e = pthread_rwlock_destroy(locks + n)) != 0) { - fprintf(stderr, "pthread_rwlock_destroy[%d]: %s\n", n, strerror(e)); - exit(1); - } - } - - exit(0); -} diff --git a/VEX/head20041019/corecheck/tests/pth_rwlock.stderr.exp b/VEX/head20041019/corecheck/tests/pth_rwlock.stderr.exp deleted file mode 100644 index 67c7b3864..000000000 --- a/VEX/head20041019/corecheck/tests/pth_rwlock.stderr.exp +++ /dev/null @@ -1,12 +0,0 @@ - -warning: Valgrind's pthread_cond_destroy is incomplete - (it doesn't check if the cond is waited on) - your program may misbehave as a result -warning: Valgrind's pthread_cond_destroy is incomplete - (it doesn't check if the cond is waited on) - your program may misbehave as a result -warning: Valgrind's pthread_cond_destroy is incomplete - (it doesn't check if the cond is waited on) - your program may misbehave as a result - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/pth_rwlock.vgtest b/VEX/head20041019/corecheck/tests/pth_rwlock.vgtest deleted file mode 100644 index 3a6647349..000000000 --- a/VEX/head20041019/corecheck/tests/pth_rwlock.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: pth_rwlock diff --git a/VEX/head20041019/corecheck/tests/res_search.c b/VEX/head20041019/corecheck/tests/res_search.c deleted file mode 100644 index b4ac82bd1..000000000 --- a/VEX/head20041019/corecheck/tests/res_search.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void* fn(void* arg) -{ - char* dn = (char*)arg; - - unsigned char buff[8000]; - - if(-1 == res_search(dn, 1, 1, buff, 8000)) - { - printf("Error: res_search()\n"); - } - else - { - printf("Success!\n"); - } - return 0; -} - -int main(int argc, char** argv) -{ - pthread_t pid; - if(2 != argc) - { - printf("Usage: %s \n", argv[0]); - return 1; - } - - _res.options |= RES_DEBUG; - if(0 != res_init()) - { - printf("Error: res_init()\n"); - return(1); - } -#if 1 - /* Test it in a different thread -- the failure case */ - if(0 != pthread_create(&pid, 0, fn, (void*)argv[1])) - { - printf("Failed to create thread.\n"); - return 1; - } - - pthread_join(pid, 0); -#else - { - unsigned char buff[8000]; - - if(-1 == res_search(argv[1], 1, 1, buff, 8000)) - { - printf("Error: res_search()\n"); - } - else - { - printf("Success!\n"); - } - } -#endif - return 0; -} - - diff --git a/VEX/head20041019/corecheck/tests/res_search.stderr.exp b/VEX/head20041019/corecheck/tests/res_search.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/corecheck/tests/res_search.stdout.exp b/VEX/head20041019/corecheck/tests/res_search.stdout.exp deleted file mode 100644 index f985b46af..000000000 --- a/VEX/head20041019/corecheck/tests/res_search.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -Success! diff --git a/VEX/head20041019/corecheck/tests/res_search.vgtest b/VEX/head20041019/corecheck/tests/res_search.vgtest deleted file mode 100644 index 879ce278b..000000000 --- a/VEX/head20041019/corecheck/tests/res_search.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: res_search -args: www.yahoo.com -vgopts: -q diff --git a/VEX/head20041019/corecheck/tests/sigkill.c b/VEX/head20041019/corecheck/tests/sigkill.c deleted file mode 100644 index 4fefed377..000000000 --- a/VEX/head20041019/corecheck/tests/sigkill.c +++ /dev/null @@ -1,42 +0,0 @@ - -#include -#include -#include -#include - -static void -abend (int sig) -{ - printf ("Abended on signal %d\n", sig); - exit (2); -} - -int -main (void) -{ - struct sigaction sa; - - int i; - int rc; - for (i = 1; i <= 65; i++) { - // skip signals 32 and 33: some systems say "warning, ignored attempt - // to catch 32 because it's used internally by Valgrind", others say - // "invalid argument". - if (i == 32 || i == 33) { - continue; - } // different systems - sa.sa_flags = 0; - sigemptyset( &sa.sa_mask ); - sa.sa_handler = abend; - fprintf(stderr,"setting signal %d: ", i); - rc = sigaction (i /*SIGKILL*/, &sa, NULL); - if (rc) perror (""); - else fprintf(stderr,"Success\n"); - fprintf(stderr,"getting signal %d: ", i); - rc = sigaction (i /*SIGKILL*/, NULL, &sa); - if (rc) perror (""); - else fprintf(stderr,"Success\n"); - fprintf(stderr,"\n"); - } - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/sigkill.stderr.exp b/VEX/head20041019/corecheck/tests/sigkill.stderr.exp deleted file mode 100644 index 839d09bdb..000000000 --- a/VEX/head20041019/corecheck/tests/sigkill.stderr.exp +++ /dev/null @@ -1,198 +0,0 @@ - -setting signal 1: Success -getting signal 1: Success - -setting signal 2: Success -getting signal 2: Success - -setting signal 3: Success -getting signal 3: Success - -setting signal 4: Success -getting signal 4: Success - -setting signal 5: Success -getting signal 5: Success - -setting signal 6: Success -getting signal 6: Success - -setting signal 7: Success -getting signal 7: Success - -setting signal 8: Success -getting signal 8: Success - -setting signal 9: Warning: ignored attempt to set SIGKILL handler in sigaction(); - the SIGKILL signal is uncatchable -Invalid argument -getting signal 9: Success - -setting signal 10: Success -getting signal 10: Success - -setting signal 11: Success -getting signal 11: Success - -setting signal 12: Success -getting signal 12: Success - -setting signal 13: Success -getting signal 13: Success - -setting signal 14: Success -getting signal 14: Success - -setting signal 15: Success -getting signal 15: Success - -setting signal 16: Success -getting signal 16: Success - -setting signal 17: Success -getting signal 17: Success - -setting signal 18: Success -getting signal 18: Success - -setting signal 19: Warning: ignored attempt to set SIGSTOP handler in sigaction(); - the SIGSTOP signal is uncatchable -Invalid argument -getting signal 19: Success - -setting signal 20: Success -getting signal 20: Success - -setting signal 21: Success -getting signal 21: Success - -setting signal 22: Success -getting signal 22: Success - -setting signal 23: Success -getting signal 23: Success - -setting signal 24: Success -getting signal 24: Success - -setting signal 25: Success -getting signal 25: Success - -setting signal 26: Success -getting signal 26: Success - -setting signal 27: Success -getting signal 27: Success - -setting signal 28: Success -getting signal 28: Success - -setting signal 29: Success -getting signal 29: Success - -setting signal 30: Success -getting signal 30: Success - -setting signal 31: Success -getting signal 31: Success - -setting signal 34: Success -getting signal 34: Success - -setting signal 35: Success -getting signal 35: Success - -setting signal 36: Success -getting signal 36: Success - -setting signal 37: Success -getting signal 37: Success - -setting signal 38: Success -getting signal 38: Success - -setting signal 39: Success -getting signal 39: Success - -setting signal 40: Success -getting signal 40: Success - -setting signal 41: Success -getting signal 41: Success - -setting signal 42: Success -getting signal 42: Success - -setting signal 43: Success -getting signal 43: Success - -setting signal 44: Success -getting signal 44: Success - -setting signal 45: Success -getting signal 45: Success - -setting signal 46: Success -getting signal 46: Success - -setting signal 47: Success -getting signal 47: Success - -setting signal 48: Success -getting signal 48: Success - -setting signal 49: Success -getting signal 49: Success - -setting signal 50: Success -getting signal 50: Success - -setting signal 51: Success -getting signal 51: Success - -setting signal 52: Success -getting signal 52: Success - -setting signal 53: Success -getting signal 53: Success - -setting signal 54: Success -getting signal 54: Success - -setting signal 55: Success -getting signal 55: Success - -setting signal 56: Success -getting signal 56: Success - -setting signal 57: Success -getting signal 57: Success - -setting signal 58: Success -getting signal 58: Success - -setting signal 59: Success -getting signal 59: Success - -setting signal 60: Success -getting signal 60: Success - -setting signal 61: Success -getting signal 61: Success - -setting signal 62: Success -getting signal 62: Success - -setting signal 63: Success -getting signal 63: Success - -setting signal 64: Success -getting signal 64: Success - -setting signal 65: Warning: bad signal number 65 in sigaction() -Invalid argument -getting signal 65: Warning: bad signal number 65 in sigaction() -Invalid argument - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/sigkill.vgtest b/VEX/head20041019/corecheck/tests/sigkill.vgtest deleted file mode 100644 index a68143011..000000000 --- a/VEX/head20041019/corecheck/tests/sigkill.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: sigkill diff --git a/VEX/head20041019/corecheck/tests/vgprintf.c b/VEX/head20041019/corecheck/tests/vgprintf.c deleted file mode 100644 index 0a023fb53..000000000 --- a/VEX/head20041019/corecheck/tests/vgprintf.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "valgrind.h" -#include - -int -main (int argc, char **argv) -{ - int x = VALGRIND_PRINTF("Yo"); - printf ("%d\n", x); - return 0; -} diff --git a/VEX/head20041019/corecheck/tests/vgprintf.stderr.exp b/VEX/head20041019/corecheck/tests/vgprintf.stderr.exp deleted file mode 100644 index a9e6b58c1..000000000 --- a/VEX/head20041019/corecheck/tests/vgprintf.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ - -Yo - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/VEX/head20041019/corecheck/tests/vgprintf.stdout.exp b/VEX/head20041019/corecheck/tests/vgprintf.stdout.exp deleted file mode 100644 index 9c558e357..000000000 --- a/VEX/head20041019/corecheck/tests/vgprintf.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -. diff --git a/VEX/head20041019/corecheck/tests/vgprintf.vgtest b/VEX/head20041019/corecheck/tests/vgprintf.vgtest deleted file mode 100644 index a8bb288f2..000000000 --- a/VEX/head20041019/corecheck/tests/vgprintf.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: vgprintf -stdout_filter: ../../tests/filter_numbers diff --git a/VEX/head20041019/coregrind/.cvsignore b/VEX/head20041019/coregrind/.cvsignore deleted file mode 100644 index 2f1b6d163..000000000 --- a/VEX/head20041019/coregrind/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -Makefile.in -Makefile -valgrind -stage2 -vg_toolint.h -vg_toolint.c -vg_intercept.c -vg_replace_malloc.c diff --git a/VEX/head20041019/coregrind/CVS/Entries b/VEX/head20041019/coregrind/CVS/Entries deleted file mode 100644 index ff96db643..000000000 --- a/VEX/head20041019/coregrind/CVS/Entries +++ /dev/null @@ -1,55 +0,0 @@ -/.cvsignore/1.4/Tue Jun 15 10:54:38 2004// -/Makefile.am/1.90/Mon Oct 18 11:52:17 2004// -/core.h/1.42/Mon Oct 18 17:41:36 2004// -/core_asm.h/1.3/Sun Sep 5 20:39:51 2004// -/dosyms/1.2/Sun Dec 15 02:05:02 2002// -/gen_intercepts.pl/1.1/Fri Apr 16 23:02:28 2004// -/gen_toolint.pl/1.5/Thu Sep 2 08:51:40 2004// -/stage1.c/1.25/Mon Oct 18 15:34:13 2004// -/toolfuncs.def/1.4/Sat Sep 11 15:11:47 2004// -/ume.c/1.31/Wed Oct 13 17:55:30 2004// -/ume.h/1.13/Mon Oct 18 11:52:17 2004// -/valgrind.vs/1.5/Fri Sep 3 13:45:27 2004// -/vg_cpuid.S/1.4/Fri Sep 10 14:23:58 2004// -/vg_default.c/1.24/Wed Sep 1 23:58:14 2004// -/vg_demangle.c/1.8/Wed Sep 1 23:58:14 2004// -/vg_dispatch.S/1.18/Thu Sep 2 15:37:38 2004// -/vg_dummy_profile.c/1.10/Wed Sep 1 23:58:14 2004// -/vg_dwarf.c/1.5/Wed Sep 1 23:58:14 2004// -/vg_errcontext.c/1.63/Mon Oct 18 15:47:18 2004// -/vg_execontext.c/1.19/Sun Sep 5 21:32:36 2004// -/vg_from_ucode.c/1.84/Fri Sep 3 13:45:27 2004// -/vg_hashtable.c/1.10/Wed Sep 1 23:58:14 2004// -/vg_helpers.S/1.34/Thu Sep 2 15:37:38 2004// -/vg_instrument.c/1.14/Thu Sep 2 08:51:40 2004// -/vg_intercept.c.base/1.2/Thu Sep 2 00:31:02 2004// -/vg_libpthread.c/1.173/Tue Oct 19 11:38:48 2004// -/vg_libpthread.vs/1.10/Mon Aug 23 18:05:51 2004// -/vg_libpthread_unimp.c/1.49/Sun Oct 17 15:00:20 2004// -/vg_main.c/1.217/Mon Oct 18 11:52:17 2004// -/vg_malloc2.c/1.32/Wed Sep 1 23:58:14 2004// -/vg_memory.c/1.70/Thu Oct 14 13:41:28 2004// -/vg_messages.c/1.15/Wed Sep 1 23:58:14 2004// -/vg_mylibc.c/1.95/Mon Oct 18 18:56:25 2004// -/vg_needs.c/1.20/Sat Oct 9 18:50:16 2004// -/vg_procselfmaps.c/1.13/Tue Sep 7 10:17:01 2004// -/vg_proxylwp.c/1.25/Mon Oct 18 17:41:36 2004// -/vg_replace_malloc.c.base/1.8/Mon Oct 18 17:35:35 2004// -/vg_scheduler.c/1.191/Sun Oct 17 15:18:22 2004// -/vg_signals.c/1.96/Mon Oct 18 14:08:16 2004// -/vg_skiplist.c/1.6/Wed Sep 1 23:58:14 2004// -/vg_stabs.c/1.20/Thu Oct 7 08:33:29 2004// -/vg_symtab2.c/1.91/Mon Oct 18 15:47:18 2004// -/vg_symtab2.h/1.8/Thu Sep 2 08:51:40 2004// -/vg_symtypes.c/1.9/Thu Oct 7 08:21:38 2004// -/vg_symtypes.h/1.3/Sun Jan 4 16:43:20 2004// -/vg_syscall.S/1.15/Fri Sep 10 14:23:58 2004// -/vg_syscalls.c/1.147/Mon Oct 18 17:00:29 2004// -/vg_to_ucode.c/1.148/Mon Oct 18 15:47:18 2004// -/vg_translate.c/1.91/Wed Oct 13 09:47:23 2004// -/vg_transtab.c/1.33/Thu Oct 14 13:41:28 2004// -/vg_unsafe.h/1.36/Thu Oct 14 11:18:26 2004// -D/demangle//// -D/docs//// -D/x86//// -D/x86-linux//// diff --git a/VEX/head20041019/coregrind/CVS/Repository b/VEX/head20041019/coregrind/CVS/Repository deleted file mode 100644 index 4f04ba05d..000000000 --- a/VEX/head20041019/coregrind/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/coregrind diff --git a/VEX/head20041019/coregrind/CVS/Root b/VEX/head20041019/coregrind/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/coregrind/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/coregrind/CVS/Template b/VEX/head20041019/coregrind/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/coregrind/Makefile.am b/VEX/head20041019/coregrind/Makefile.am deleted file mode 100644 index 90466633e..000000000 --- a/VEX/head20041019/coregrind/Makefile.am +++ /dev/null @@ -1,160 +0,0 @@ -include $(top_srcdir)/Makefile.all.am -include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am - -SUBDIRS = $(VG_ARCH) $(VG_PLATFORM) demangle . docs - -AM_CPPFLAGS += -DVG_LIBDIR="\"$(valdir)"\" -I$(srcdir)/demangle \ - -DKICKSTART_BASE=$(KICKSTART_BASE) \ - -DVG_PLATFORM="\"$(VG_PLATFORM)"\" -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fno-omit-frame-pointer \ - @PREFERRED_STACK_BOUNDARY@ -g -DELFSZ=32 -AM_CCASFLAGS = $(add_includes) -I.. - -default.supp: $(SUPP_FILES) - -bin_PROGRAMS = \ - valgrind - -val_PROGRAMS = \ - stage2 \ - libpthread.so \ - vg_inject.so - -EXTRA_DIST = \ - vg_libpthread.vs valgrind.vs \ - gen_toolint.pl toolfuncs.def \ - gen_intercepts.pl vg_replace_malloc.c.base vg_intercept.c.base - -BUILT_SOURCES = vg_toolint.c vg_toolint.h -CLEANFILES = vg_toolint.c vg_toolint.h vg_replace_malloc.c vg_intercept.c - -valgrind_SOURCES = \ - ume.c \ - \ - stage1.c \ - ${VG_ARCH}/jmp_with_stack.c -valgrind_DEPENDENCIES = -valgrind_LDFLAGS=-static -g -valgrind_LDADD= - -# Where stage2 will be put. -# Nb: Hard-wiring this sucks. A configure-time test would be better. A -# load-time test would be even better, but would require building stage2 in -# a position-independent way... -KICKSTART_BASE=0xb0000000 - -stage2_SOURCES = \ - ume.c \ - \ - vg_scheduler.c \ - vg_default.c \ - vg_demangle.c \ - vg_dispatch.S \ - vg_errcontext.c \ - vg_execontext.c \ - vg_from_ucode.c \ - vg_hashtable.c \ - vg_helpers.S \ - vg_instrument.c \ - vg_main.c \ - vg_malloc2.c \ - vg_memory.c \ - vg_messages.c \ - vg_mylibc.c \ - vg_needs.c \ - vg_procselfmaps.c \ - vg_proxylwp.c \ - vg_dummy_profile.c \ - vg_signals.c \ - vg_symtab2.c \ - vg_dwarf.c \ - vg_stabs.c \ - vg_skiplist.c \ - vg_symtypes.c \ - vg_syscalls.c \ - vg_syscall.S \ - vg_to_ucode.c \ - vg_toolint.c \ - vg_translate.c \ - vg_transtab.c \ - vg_cpuid.S -stage2_DEPENDENCIES = $(srcdir)/valgrind.vs ${VG_ARCH}/stage2.lds -stage2_LDFLAGS=-Wl,--export-dynamic -g \ - -Wl,-defsym,kickstart_base=$(KICKSTART_BASE) \ - -Wl,-T,${VG_ARCH}/stage2.lds \ - -Wl,-version-script $(srcdir)/valgrind.vs -stage2_LDADD= \ - demangle/cp-demangle.o \ - demangle/cplus-dem.o \ - demangle/dyn-string.o \ - demangle/safe-ctype.o \ - ${VG_ARCH}/libarch.a \ - ${VG_PLATFORM}/libplatform.a \ - ../../libvex.a \ - -ldl - -vg_intercept.c: $(srcdir)/gen_intercepts.pl $(srcdir)/vg_intercept.c.base - rm -f $@ - $(PERL) $(srcdir)/gen_intercepts.pl < $(srcdir)/vg_intercept.c.base > $@ - -vg_replace_malloc.c: $(srcdir)/gen_intercepts.pl $(srcdir)/vg_replace_malloc.c.base - rm -f $@ - $(PERL) $(srcdir)/gen_intercepts.pl < $(srcdir)/vg_replace_malloc.c.base > $@ - -vg_toolint.c: $(srcdir)/gen_toolint.pl $(srcdir)/toolfuncs.def ./Makefile - rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl callwrap < $(srcdir)/toolfuncs.def > $@ || rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl missingfuncs < $(srcdir)/toolfuncs.def >> $@ || rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl initfunc < $(srcdir)/toolfuncs.def >> $@ || rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl initdlsym < $(srcdir)/toolfuncs.def >> $@ || rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl structdef < $(srcdir)/toolfuncs.def >> $@ || rm -f $@ - -vg_toolint.h: $(srcdir)/gen_toolint.pl $(srcdir)/toolfuncs.def ./Makefile - rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl proto < $(srcdir)/toolfuncs.def > $@ || rm -f $@ - $(PERL) $(srcdir)/gen_toolint.pl struct < $(srcdir)/toolfuncs.def >> $@ || rm -f $@ - -libpthread_so_SOURCES = \ - vg_libpthread.c \ - vg_libpthread_unimp.c \ - vg_syscall.S -libpthread_so_DEPENDENCIES = $(srcdir)/vg_libpthread.vs -libpthread_so_LDFLAGS = -Werror -fno-omit-frame-pointer -UVG_LIBDIR \ - -shared -fpic -ldl \ - -Wl,-version-script $(srcdir)/vg_libpthread.vs \ - -Wl,-z,nodelete \ - -Wl,--soname=libpthread.so.0 - -vg_inject_so_SOURCES = \ - vg_intercept.c - -# Not really true, but we need to build vg_replace_malloc.o somehow -vg_inject_so_DEPENDENCIES = \ - vg_replace_malloc.o - -vg_inject_so_LDFLAGS = \ - -shared \ - -Wl,--soname,vg_inject.so \ - -Wl,-z,initfirst - -noinst_HEADERS = \ - core.h \ - core_asm.h \ - ume.h \ - vg_symtab2.h \ - vg_symtypes.h \ - vg_toolint.h \ - vg_unsafe.h - -MANUAL_DEPS = $(noinst_HEADERS) $(include_HEADERS) $(inplacedir)/libpthread.so.0 - -vg_replace_malloc.o vg_intercept.o vg_libpthread.o: CFLAGS += -fno-omit-frame-pointer -g -fpic - -all-local: - mkdir -p $(inplacedir) - for i in $(val_PROGRAMS); do \ - to=$(inplacedir)/$$(echo $$i | sed 's,libpthread.so,libpthread.so.0,'); \ - rm -f $$$to; \ - ln -sf ../$(subdir)/$$i $$to; \ - done - diff --git a/VEX/head20041019/coregrind/core.h b/VEX/head20041019/coregrind/core.h deleted file mode 100644 index bf07db67d..000000000 --- a/VEX/head20041019/coregrind/core.h +++ /dev/null @@ -1,1560 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A header file for all private parts of Valgrind's core. ---*/ -/*--- Include no other! (more or less...) ---*/ -/*--- core.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __CORE_H -#define __CORE_H - -/* - Header hierarchy: - - - core C files include core.h - - core asm files include core_asm.h - - tool C files include tool.h - - tool asm files include tool_asm.h - - - The hierarchy of the header files themselves is based around the - following rules: - - - core headers include tool headers - - generic headers include arch/OS/platform headers - - C headers include asm headers - - This gives the following hierarchy (only showing 'arch' headers, not - 'os' or 'platform' headers), where arrows indicate inclusion, and - $VG_ARCH==x86: - - - (include/x86/tool_arch_asm.h?) <----- coregrind/x86/core_arch_asm.h - ^ ^ ^ ^ - / \ / \ - / \ / \ - / \ / \ - include/tool_asm.h <-\---- coregrind/core_asm.h \ - ^ \ ^ \ - \ include/x86/tool_arch.h <--------coregrind/x86/core_arch.h - \ ^ \ ^ - \ / \ / - \ / \ / - \ / \ / - include/tool.h <------------ coregrind/core.h - - - Note that core.h contains the *declarations* of arch-specific functions - and variables, which can be used by the core_arch.h file of any - architecture. (The functions/variables are *defined* within arch/.) - However, arch-specific macros and types cannot go into core.h, because - there is no separation between declaration and definition for - macros/types, so they instead go into $VG_ARCH/core_arch.h. - - The tool-specific headers are all in include/ so they can be seen by any - external tools. -*/ - - -/* For system call numbers __NR_... */ -#include "vki_unistd.h" - -#include "core_asm.h" // asm stuff -#include "tool.h" // tool stuff -#include "core_arch.h" // arch-specific stuff, eg. x86/core_arch.h -#include "core_platform.h" // platform-specific stuff, - // eg. x86-linux/core_platform.h - -#include "valgrind.h" - -#include "../../pub/libvex.h" - -#undef SK_ -#define SK_(x) vgSkinInternal_##x - - -/* --------------------------------------------------------------------- - Build options and table sizes. You should be able to change these - options or sizes, recompile, and still have a working system. - ------------------------------------------------------------------ */ - -/* Constants for the slow translation lookup cache. */ -#define VG_TRANSTAB_SLOW_BITS 11 -#define VG_TRANSTAB_SLOW_SIZE (1 << VG_TRANSTAB_SLOW_BITS) -#define VG_TRANSTAB_SLOW_MASK ((VG_TRANSTAB_SLOW_SIZE) - 1) - -/* Size of a buffer used for creating messages. */ -#define M_VG_MSGBUF 10000 - -/* Size of a smallish table used to read /proc/self/map entries. */ -#define M_PROCMAP_BUF 50000 - -/* Max length of pathname to a .so/executable file. */ -#define M_VG_LIBNAMESTR 100 - -/* Max length of a text fragment used to construct error messages. */ -#define M_VG_ERRTXT 4096 - -/* Max length of the string copied from env var VG_ARGS at startup. */ -#define M_VG_CMDLINE_STRLEN 1000 - -/* Max number of options for Valgrind which we can handle. */ -#define M_VG_CMDLINE_OPTS 100 - -/* After this many different unsuppressed errors have been observed, - be more conservative about collecting new ones. */ -#define M_VG_COLLECT_ERRORS_SLOWLY_AFTER 50 - -/* After this many different unsuppressed errors have been observed, - stop collecting errors at all, and tell the user their program is - evidently a steaming pile of camel dung. */ -#define M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN 300 - -/* After this many total errors have been observed, stop collecting - errors at all. Counterpart to M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN. */ -#define M_VG_COLLECT_NO_ERRORS_AFTER_FOUND 30000 - -/* The maximum number of calls we're prepared to save in a - backtrace. */ -#define VG_DEEPEST_BACKTRACE 50 - -/* Number of lists in which we keep track of ExeContexts. Should be - prime. */ -#define VG_N_EC_LISTS 4999 /* a prime number */ - -/* Defines the thread-scheduling timeslice, in terms of the number of - basic blocks we attempt to run each thread for. Smaller values - give finer interleaving but much increased scheduling overheads. */ -#define VG_SCHEDULING_QUANTUM 50000 - -/* Number of file descriptors that Valgrind tries to reserve for - it's own use - two per thread plues a small number of extras. */ -#define VG_N_RESERVED_FDS (VG_N_THREADS*2 + 4) - -/* Stack size for a thread. We try and check that they do not go - beyond it. */ -#define VG_PTHREAD_STACK_SIZE (1 << 20) - -/* Number of entries in each thread's cleanup stack. */ -#define VG_N_CLEANUPSTACK 16 - -/* Number of entries in each thread's fork-handler stack. */ -#define VG_N_FORKHANDLERSTACK 4 - -/* Max number of callers for context in a suppression. */ -#define VG_N_SUPP_CALLERS 4 - -/* Numer of entries in each thread's signal queue. */ -#define VG_N_SIGNALQUEUE 8 - -/* Useful macros */ -/* a - alignment - must be a power of 2 */ -#define ROUNDDN(p, a) ((Addr)(p) & ~((a)-1)) -#define ROUNDUP(p, a) ROUNDDN((p)+(a)-1, (a)) -#define PGROUNDDN(p) ROUNDDN(p, VKI_BYTES_PER_PAGE) -#define PGROUNDUP(p) ROUNDUP(p, VKI_BYTES_PER_PAGE) - -/* --------------------------------------------------------------------- - Environment variables - ------------------------------------------------------------------ */ - -/* The directory we look for all our auxillary files in */ -#define VALGRINDLIB "VALGRINDLIB" - -/* Additional command-line arguments; they are overridden by actual - command-line option. Each argument is separated by spaces. There - is no quoting mechanism. - */ -#define VALGRINDOPTS "VALGRIND_OPTS" - -/* If this variable is present in the environment, then valgrind will - not parse the command line for options at all; all options come - from this variable. Arguments are terminated by ^A (\001). There - is no quoting mechanism. - - This variable is not expected to be set by anything other than - Valgrind itself, as part of its handling of execve with - --trace-children=yes. This variable should not be present in the - client environment. - */ -#define VALGRINDCLO "_VALGRIND_CLO" - - -/* --------------------------------------------------------------------- - Command-line-settable options - ------------------------------------------------------------------ */ - -/* Default destination port to be used in logging over a network, if - none specified. */ -#define VG_CLO_DEFAULT_LOGPORT 1500 - -/* The max number of suppression files. */ -#define VG_CLO_MAX_SFILES 10 - -/* Default debugger command. */ -#define VG_CLO_DEFAULT_DBCOMMAND GDB_PATH " -nw %f %p" - -/* Describes where logging output is to be sent. */ -typedef - enum { - VgLogTo_Fd, - VgLogTo_File, - VgLogTo_Socket - } VgLogTo; - -/* pid of main process */ -extern Int VG_(main_pid); - -/* pgrp of process (global to all threads) */ -extern Int VG_(main_pgrp); - -/* Application-visible file descriptor limits */ -extern Int VG_(fd_soft_limit); -extern Int VG_(fd_hard_limit); - -/* Vex iropt control */ -extern VexControl VG_(clo_vex_control); -/* Should we stop collecting errors if too many appear? default: YES */ -extern Bool VG_(clo_error_limit); -/* Enquire about whether to attach to a debugger at errors? default: NO */ -extern Bool VG_(clo_db_attach); -/* The debugger command? default: whatever gdb ./configure found */ -extern Char* VG_(clo_db_command); -/* Enquire about generating a suppression for each error? default: NO */ -extern Bool VG_(clo_gen_suppressions); -/* Sanity-check level: 0 = none, 1 (default), > 1 = expensive. */ -extern Int VG_(clo_sanity_level); -/* Automatically attempt to demangle C++ names? default: YES */ -extern Bool VG_(clo_demangle); -/* Simulate child processes? default: NO */ -extern Bool VG_(clo_trace_children); - -/* Where logging output is to be sent to. - - When log_to == VgLogTo_Fd, clo_log_fd holds the file id, and is - taken from the command line. clo_log_name is irrelevant. - - When log_to == VgLogTo_File, clo_log_name holds the log-file - name, and is taken from the command line. clo_log_fd is then - made to hold the relevant file id, by opening clo_log_name - (concatenated with the process ID) for writing. - - When log_to == VgLogTo_Socket, clo_log_name holds the - hostname:portnumber pair, and is taken from the command line. - clo_log_fd is then made to hold the relevant file handle, by - opening a connection to said hostname:portnumber pair. - - Global default is to set log_to == VgLogTo_Fd and log_fd == 2 - (stderr). */ -extern VgLogTo VG_(clo_log_to); -extern Int VG_(clo_log_fd); -extern Char* VG_(clo_log_name); - -/* Add timestamps to log messages? default: NO */ -extern Bool VG_(clo_time_stamp); - -/* The file descriptor to read for input. default: 0 == stdin */ -extern Int VG_(clo_input_fd); -/* The number of suppression files specified. */ -extern Int VG_(clo_n_suppressions); -/* The names of the suppression files. */ -extern Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES]; - -/* Single stepping? default: NO */ -extern Bool VG_(clo_single_step); -/* Code improvement? default: YES */ -extern Bool VG_(clo_optimise); -/* DEBUG: print generated code? default: 00000 ( == NO ) */ -extern Bool VG_(clo_trace_codegen); -/* DEBUG: print system calls? default: NO */ -extern Bool VG_(clo_trace_syscalls); -/* DEBUG: print signal details? default: NO */ -extern Bool VG_(clo_trace_signals); -/* DEBUG: print symtab details? default: NO */ -extern Bool VG_(clo_trace_symtab); -/* DEBUG: print thread scheduling events? default: NO */ -extern Bool VG_(clo_trace_sched); -/* DEBUG: print pthread (mutex etc) events? default: 0 (none), 1 - (some), 2 (all) */ -extern Int VG_(clo_trace_pthread_level); -/* Display gory details for the k'th most popular error. default: - Infinity. */ -extern Int VG_(clo_dump_error); -/* Number of parents of a backtrace. Default: 8. */ -extern Int VG_(clo_backtrace_size); -/* Engage miscellaneous weird hacks needed for some progs. */ -extern Char* VG_(clo_weird_hacks); -/* How often we should poll for signals, assuming we need to poll for - signals. */ -extern Int VG_(clo_signal_polltime); - -/* Low latency syscalls and signals */ -extern Bool VG_(clo_lowlat_syscalls); -extern Bool VG_(clo_lowlat_signals); - -/* Track open file descriptors? */ -extern Bool VG_(clo_track_fds); - -/* Should we run __libc_freeres at exit? Sometimes causes crashes. - Default: YES. Note this is subservient to VG_(needs).libc_freeres; - if the latter says False, then the setting of VG_(clo_weird_hacks) - is ignored. Ie if a tool says no, I don't want this to run, that - cannot be overridden from the command line. */ -extern Bool VG_(clo_run_libc_freeres); -/* Use the basic-block chaining optimisation? Default: YES */ -extern Bool VG_(clo_chain_bb); -/* Generate branch-prediction hints? */ -extern Bool VG_(clo_branchpred); -/* Continue stack traces below main()? Default: NO */ -extern Bool VG_(clo_show_below_main); -/* Test each client pointer dereference to check it's within the - client address space bounds */ -extern Bool VG_(clo_pointercheck); - -/* Set up the libc freeres wrapper */ -extern void VG_(intercept_libc_freeres_wrapper)(Addr); - -/* --------------------------------------------------------------------- - Profiling stuff - ------------------------------------------------------------------ */ - -extern void VGP_(init_profiling) ( void ); -extern void VGP_(done_profiling) ( void ); - -#undef VGP_PUSHCC -#undef VGP_POPCC -#define VGP_PUSHCC(x) if (VG_(clo_profile)) VGP_(pushcc)(x) -#define VGP_POPCC(x) if (VG_(clo_profile)) VGP_(popcc)(x) - -/* --------------------------------------------------------------------- - Tool-related types - ------------------------------------------------------------------ */ -/* These structs are not exposed to tools to mitigate possibility of - binary-incompatibilities when the core/tool interface changes. Instead, - set functions are provided (see include/tool.h). */ -typedef - struct { - Char* name; - Char* version; - Char* description; - Char* copyright_author; - Char* bug_reports_to; - UInt avg_translation_sizeB; - } - VgDetails; - -extern VgDetails VG_(details); - -/* If new fields are added to this type, update: - * - vg_main.c:initialisation of VG_(needs) - * - vg_main.c:sanity_check_needs() - * - * If the name of this type or any of its fields change, update: - * - dependent comments (just search for "VG_(needs)"). - */ -typedef - struct { - Bool libc_freeres; - Bool core_errors; - Bool skin_errors; - Bool basic_block_discards; - Bool shadow_regs; - Bool command_line_options; - Bool client_requests; - Bool extended_UCode; - Bool syscall_wrapper; - Bool sanity_checks; - Bool data_syms; - Bool shadow_memory; - } - VgNeeds; - -extern VgNeeds VG_(needs); - -extern void VG_(tool_init_dlsym)(void *dlhandle); - -#include "vg_toolint.h" - -/* --------------------------------------------------------------------- - Exports of vg_needs.c - ------------------------------------------------------------------ */ - -void VG_(sanity_check_needs)(void); - -/* --------------------------------------------------------------------- - Exports of vg_malloc2.c - ------------------------------------------------------------------ */ - -/* Allocation arenas. - - CORE for the core's general use. - TOOL for the tool to use (and the only one it uses). - SYMTAB for Valgrind's symbol table storage. - JITTER for small storage during translation. - CLIENT for the client's mallocs/frees, if the tool replaces glibc's - malloc() et al -- redzone size is chosen by the tool. - DEMANGLE for the C++ demangler. - EXECTXT for storing ExeContexts. - ERRORS for storing CoreErrors. - TRANSIENT for very short-term use. It should be empty in between uses. - - When adding a new arena, remember also to add it to ensure_mm_init(). -*/ -typedef Int ArenaId; - -#define VG_N_ARENAS 9 - -#define VG_AR_CORE 0 -#define VG_AR_TOOL 1 -#define VG_AR_SYMTAB 2 -#define VG_AR_JITTER 3 -#define VG_AR_CLIENT 4 -#define VG_AR_DEMANGLE 5 -#define VG_AR_EXECTXT 6 -#define VG_AR_ERRORS 7 -#define VG_AR_TRANSIENT 8 - -// This is both the minimum payload size of a malloc'd block, and its -// minimum alignment. Must be a power of 2 greater than 4, and should be -// greater than 8. -#define VG_MIN_MALLOC_SZB 8 - -// Round-up size for --sloppy-malloc=yes. -#define VG_SLOPPY_MALLOC_SZB 4 - -extern void* VG_(arena_malloc) ( ArenaId arena, Int nbytes ); -extern void VG_(arena_free) ( ArenaId arena, void* ptr ); -extern void* VG_(arena_calloc) ( ArenaId arena, Int alignment, - Int nmemb, Int nbytes ); -extern void* VG_(arena_realloc) ( ArenaId arena, void* ptr, Int alignment, - Int size ); -extern void* VG_(arena_malloc_aligned) ( ArenaId aid, Int req_alignB, - Int req_pszB ); - -extern Int VG_(arena_payload_szB) ( ArenaId aid, void* payload ); - -extern void VG_(sanity_check_malloc_all) ( void ); - -extern void VG_(print_all_arena_stats) ( void ); - -extern Bool VG_(is_empty_arena) ( ArenaId aid ); - -/* --------------------------------------------------------------------- - Exports of vg_intercept.c - ------------------------------------------------------------------ */ - -/* This doesn't export code or data that valgrind.so needs to link - against. However, the scheduler does need to know the following - request codes. A few, publically-visible, request codes are also - defined in valgrind.h, and similar headers for some tools. */ - -#define VG_USERREQ__MALLOC 0x2001 -#define VG_USERREQ__FREE 0x2002 - -/* (Fn, Arg): Create a new thread and run Fn applied to Arg in it. Fn - MUST NOT return -- ever. Eventually it will do either __QUIT or - __WAIT_JOINER. */ -#define VG_USERREQ__APPLY_IN_NEW_THREAD 0x3001 - -/* ( no-args ): calling thread disappears from the system forever. - Reclaim resources. */ -#define VG_USERREQ__QUIT 0x3002 - -/* ( void* ): calling thread waits for joiner and returns the void* to - it. */ -#define VG_USERREQ__WAIT_JOINER 0x3003 - -/* ( ThreadId, void** ): wait to join a thread. */ -#define VG_USERREQ__PTHREAD_JOIN 0x3004 - -/* Set cancellation state and type for this thread. */ -#define VG_USERREQ__SET_CANCELSTATE 0x3005 -#define VG_USERREQ__SET_CANCELTYPE 0x3006 - -/* ( no-args ): Test if we are at a cancellation point. */ -#define VG_USERREQ__TESTCANCEL 0x3007 - -/* ( ThreadId, &thread_exit_wrapper is the only allowable arg ): call - with this arg to indicate that a cancel is now pending for the - specified thread. */ -#define VG_USERREQ__SET_CANCELPEND 0x3008 - -/* Set/get detach state for this thread. */ -#define VG_USERREQ__SET_OR_GET_DETACH 0x3009 - -#define VG_USERREQ__PTHREAD_GET_THREADID 0x300A -#define VG_USERREQ__PTHREAD_MUTEX_LOCK 0x300B -#define VG_USERREQ__PTHREAD_MUTEX_TIMEDLOCK 0x300C -#define VG_USERREQ__PTHREAD_MUTEX_TRYLOCK 0x300D -#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK 0x300E -#define VG_USERREQ__PTHREAD_COND_WAIT 0x300F -#define VG_USERREQ__PTHREAD_COND_TIMEDWAIT 0x3010 -#define VG_USERREQ__PTHREAD_COND_SIGNAL 0x3011 -#define VG_USERREQ__PTHREAD_COND_BROADCAST 0x3012 -#define VG_USERREQ__PTHREAD_KEY_CREATE 0x3013 -#define VG_USERREQ__PTHREAD_KEY_DELETE 0x3014 -#define VG_USERREQ__PTHREAD_SETSPECIFIC_PTR 0x3015 -#define VG_USERREQ__PTHREAD_GETSPECIFIC_PTR 0x3016 -#define VG_USERREQ__READ_MILLISECOND_TIMER 0x3017 -#define VG_USERREQ__PTHREAD_SIGMASK 0x3018 -#define VG_USERREQ__SIGWAIT 0x3019 /* unused */ -#define VG_USERREQ__PTHREAD_KILL 0x301A -#define VG_USERREQ__PTHREAD_YIELD 0x301B -#define VG_USERREQ__PTHREAD_KEY_VALIDATE 0x301C - -#define VG_USERREQ__CLEANUP_PUSH 0x3020 -#define VG_USERREQ__CLEANUP_POP 0x3021 -#define VG_USERREQ__GET_KEY_D_AND_S 0x3022 - -#define VG_USERREQ__NUKE_OTHER_THREADS 0x3023 - -/* Ask how many signal handler returns have happened to this - thread. */ -#define VG_USERREQ__GET_N_SIGS_RETURNED 0x3024 /* unused */ - -/* Get/set entries for a thread's pthread_atfork stack. */ -#define VG_USERREQ__SET_FHSTACK_USED 0x3025 -#define VG_USERREQ__GET_FHSTACK_USED 0x3026 -#define VG_USERREQ__SET_FHSTACK_ENTRY 0x3027 -#define VG_USERREQ__GET_FHSTACK_ENTRY 0x3028 - -/* Denote the finish of __libc_freeres_wrapper(). */ -#define VG_USERREQ__LIBC_FREERES_DONE 0x3029 - -/* Allocate RT signals */ -#define VG_USERREQ__GET_SIGRT_MIN 0x302B -#define VG_USERREQ__GET_SIGRT_MAX 0x302C -#define VG_USERREQ__ALLOC_RTSIG 0x302D - -/* Hook for replace_malloc.o to get malloc functions */ -#define VG_USERREQ__GET_MALLOCFUNCS 0x3030 - -/* Get stack information for a thread. */ -#define VG_USERREQ__GET_STACK_INFO 0x3033 - -/* Cosmetic ... */ -#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101 -/* Log a pthread error from client-space. Cosmetic. */ -#define VG_USERREQ__PTHREAD_ERROR 0x3102 -/* Internal equivalent of VALGRIND_PRINTF . */ -#define VG_USERREQ__INTERNAL_PRINTF 0x3103 -/* Internal equivalent of VALGRIND_PRINTF_BACKTRACE . */ -#define VG_USERREQ__INTERNAL_PRINTF_BACKTRACE 0x3104 - -/* -In core_asm.h: -#define VG_USERREQ__SIGNAL_RETURNS 0x4001 -*/ - -#define VG_INTERCEPT_PREFIX "_vgi__" -#define VG_INTERCEPT_PREFIX_LEN 6 -#define VG_INTERCEPT(name) _vgi__##name -#define VG_INTERCEPT_ALIAS(name) "_vgi__" #name - -#define VG_WRAPPER_PREFIX "_vgw__" -#define VG_WRAPPER_PREFIX_LEN 6 -#define VG_WRAPPER(name) _vgw__##name -#define VG_WRAPPER_ALIAS(name) "_vgw__" #name - - -struct vg_mallocfunc_info { - /* things vg_replace_malloc.o needs to know about */ - Addr sk_malloc; - Addr sk_calloc; - Addr sk_realloc; - Addr sk_memalign; - Addr sk___builtin_new; - Addr sk___builtin_vec_new; - Addr sk_free; - Addr sk___builtin_delete; - Addr sk___builtin_vec_delete; - - Addr arena_payload_szB; - - Bool clo_sloppy_malloc; - Bool clo_trace_malloc; -}; - -/* --------------------------------------------------------------------- - Exports of vg_defaults.c - ------------------------------------------------------------------ */ - -extern Bool VG_(sk_malloc_called_by_scheduler); - -/* --------------------------------------------------------------------- - Exports of vg_libpthread.c - ------------------------------------------------------------------ */ - -/* Replacements for pthread types, shared between vg_libpthread.c and - vg_scheduler.c. See comment in vg_libpthread.c above the other - vg_pthread_*_t types for a description of how these are used. */ - -struct _vg_pthread_fastlock -{ - long int __vg_status; /* "Free" or "taken" or head of waiting list */ - int __vg_spinlock; /* Used by compare_and_swap emulation. Also, - adaptive SMP lock stores spin count here. */ -}; - -typedef struct -{ - int __vg_m_reserved; /* Reserved for future use */ - int __vg_m_count; /* Depth of recursive locking */ - /*_pthread_descr*/ void* __vg_m_owner; /* Owner thread (if recursive or errcheck) */ - int __vg_m_kind; /* Mutex kind: fast, recursive or errcheck */ - struct _vg_pthread_fastlock __vg_m_lock; /* Underlying fast lock */ -} vg_pthread_mutex_t; - -typedef struct -{ - struct _vg_pthread_fastlock __vg_c_lock; /* Protect against concurrent access */ - /*_pthread_descr*/ void* __vg_c_waiting; /* Threads waiting on this condition */ - - // Nb: the following padding removed because it was missing from an - // earlier glibc, so the size test in the CONVERT macro was failing. - // --njn - - // Padding ensures the size is 48 bytes - /*char __vg_padding[48 - sizeof(struct _vg_pthread_fastlock) - - sizeof(void*) - sizeof(long long)]; - long long __vg_align;*/ -} vg_pthread_cond_t; - - -/* --------------------------------------------------------------------- - Exports of vg_scheduler.c - ------------------------------------------------------------------ */ - -typedef - enum ThreadStatus { - VgTs_Empty, /* this slot is not in use */ - VgTs_Runnable, /* waiting to be scheduled */ - VgTs_WaitJoiner, /* waiting for someone to do join on me */ - VgTs_WaitJoinee, /* waiting for the thread I did join on */ - VgTs_WaitMX, /* waiting on a mutex */ - VgTs_WaitCV, /* waiting on a condition variable */ - VgTs_WaitSys, /* waiting for a syscall to complete */ - VgTs_Sleeping, /* sleeping for a while */ - } - ThreadStatus; - -typedef - enum CleanupType { - VgCt_None, /* this cleanup entry is not initialised */ - VgCt_Function, /* an old-style function pointer cleanup */ - VgCt_Longjmp /* a new-style longjmp based cleanup */ - } - CleanupType; - -/* Information on a thread's stack. */ -typedef - struct { - Addr base; - UInt size; - UInt guardsize; - } - StackInfo; - -/* An entry in a threads's cleanup stack. */ -typedef - struct { - CleanupType type; - union { - struct { - void (*fn)(void*); - void* arg; - } function; - struct { - void *ub; - int ctype; - } longjmp; - } data; - } - CleanupEntry; - -/* An entry in a thread's fork-handler stack. */ -typedef - struct { - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); - } - ForkHandlerEntry; - -typedef struct ProxyLWP ProxyLWP; - -typedef - struct _ThreadState { - /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED. - The thread identity is simply the index in vg_threads[]. - ThreadId == 1 is the root thread and has the special property - that we don't try and allocate or deallocate its stack. For - convenience of generating error message, we also put the - ThreadId in this tid field, but be aware that it should - ALWAYS == the index in vg_threads[]. */ - ThreadId tid; - - /* Current scheduling status. - - Complications: whenever this is set to VgTs_WaitMX, you - should also set .m_edx to whatever the required return value - is for pthread_mutex_lock / pthread_cond_timedwait for when - the mutex finally gets unblocked. */ - ThreadStatus status; - - /* When .status == WaitMX, points to the mutex I am waiting for. - When .status == WaitCV, points to the mutex associated with - the condition variable indicated by the .associated_cv field. - In all other cases, should be NULL. */ - vg_pthread_mutex_t* associated_mx; - - /* When .status == WaitCV, points to the condition variable I am - waiting for. In all other cases, should be NULL. */ - void* /*pthread_cond_t* */ associated_cv; - - /* If VgTs_Sleeping, this is when we should wake up, measured in - milliseconds as supplied by VG_(read_millisecond_timer). - - If VgTs_WaitCV, this indicates the time at which - pthread_cond_timedwait should wake up. If == 0xFFFFFFFF, - this means infinitely far in the future, viz, - pthread_cond_wait. */ - UInt awaken_at; - - /* If VgTs_WaitJoiner, return value, as generated by joinees. */ - void* joinee_retval; - - /* If VgTs_WaitJoinee, place to copy the return value to, and - the identity of the thread we're waiting for. */ - void** joiner_thread_return; - ThreadId joiner_jee_tid; - - /* If VgTs_WaitSys, this is the result of the pre-syscall check */ - void *sys_pre_res; - - /* If VgTs_WaitSys, this is the syscall we're currently running */ - Int syscallno; - - /* If VgTs_WaitSys, this is the syscall flags */ - UInt sys_flags; - - /* Details about this thread's proxy LWP */ - ProxyLWP *proxy; - - /* Whether or not detached. */ - Bool detached; - - /* Cancelability state and type. */ - Bool cancel_st; /* False==PTH_CANCEL_DISABLE; True==.._ENABLE */ - Bool cancel_ty; /* False==PTH_CANC_ASYNCH; True==..._DEFERRED */ - - /* Pointer to fn to call to do cancellation. Indicates whether - or not cancellation is pending. If NULL, not pending. Else - should be &thread_exit_wrapper(), indicating that - cancallation is pending. */ - void (*cancel_pend)(void*); - - /* The cleanup stack. */ - Int custack_used; - CleanupEntry custack[VG_N_CLEANUPSTACK]; - - /* A pointer to the thread's-specific-data. This is handled almost - entirely from vg_libpthread.c. We just provide hooks to get and - set this ptr. This is either NULL, indicating the thread has - read/written none of its specifics so far, OR points to a - void*[VG_N_THREAD_KEYS], allocated and deallocated in - vg_libpthread.c. */ - void** specifics_ptr; - - /* This thread's blocked-signals mask. Semantics is that for a - signal to be delivered to this thread, the signal must not be - blocked by this signal mask. If more than one thread accepts a - signal, then it will be delivered to one at random. If all - threads block the signal, it will remain pending until either a - thread unblocks it or someone uses sigwaitsig/sigtimedwait. - - sig_mask reflects what the client told us its signal mask should - be, but isn't necessarily the current signal mask of the proxy - LWP: it may have more signals blocked because of signal - handling, or it may be different because of sigsuspend. - */ - vki_ksigset_t sig_mask; - - /* Effective signal mask. This is the mask which currently - applies; it may be different from sig_mask while a signal - handler is running. - */ - vki_ksigset_t eff_sig_mask; - - /* Signal queue. This is used when the kernel doesn't route - signals properly in order to remember the signal information - while we are routing the signal. It is a circular queue with - insertions performed at the head and removals at the tail. - */ - vki_ksiginfo_t sigqueue[VG_N_SIGNALQUEUE]; - Int sigqueue_head; - Int sigqueue_tail; - - /* Stacks. When a thread slot is freed, we don't deallocate its - stack; we just leave it lying around for the next use of the - slot. If the next use of the slot requires a larger stack, - only then is the old one deallocated and a new one - allocated. - - For the main thread (threadid == 0), this mechanism doesn't - apply. We don't know the size of the stack since we didn't - allocate it, and furthermore we never reallocate it. */ - - /* The allocated size of this thread's stack (permanently zero - if this is ThreadId == 0, since we didn't allocate its stack) */ - UInt stack_size; - - /* Address of the lowest word in this thread's stack. NULL means - not allocated yet. - */ - Addr stack_base; - - /* The allocated size of this thread's stack's guard area (permanently - zero if this is ThreadId == 0, since we didn't allocate its stack) */ - UInt stack_guard_size; - - /* Address of the highest legitimate word in this stack. This is - used for error messages only -- not critical for execution - correctness. Is is set for all stacks, specifically including - ThreadId == 0 (the main thread). */ - Addr stack_highest_word; - - /* Alternate signal stack */ - vki_kstack_t altstack; - - /* Architecture-specific thread state */ - arch_thread_t arch; -} -ThreadState; - - -/* The thread table. */ -extern ThreadState VG_(threads)[VG_N_THREADS]; - -/* Check that tid is in range and denotes a non-Empty thread. */ -extern Bool VG_(is_valid_tid) ( ThreadId tid ); - -/* Determine if 'tid' is that of the current running thread (Nb: returns - False if no thread is currently running. */ -extern Bool VG_(is_running_thread)(ThreadId tid); - -/* Get the ThreadState for a particular thread */ -extern ThreadState *VG_(get_ThreadState)(ThreadId tid); - -/* Similarly ... */ -extern ThreadId VG_(get_current_tid) ( void ); - -/* Nuke all threads except tid. */ -extern void VG_(nuke_all_threads_except) ( ThreadId me ); - -/* Give a hint to the scheduler that it may be a good time to find a - new runnable thread. If prefer_sched != VG_INVALID_THREADID, then - try to schedule that thread. -*/ -extern void VG_(need_resched) ( ThreadId prefer_sched ); - -/* Return codes from the scheduler. */ -typedef - enum { - VgSrc_Deadlock, /* no runnable threads and no prospect of any - even if we wait for a long time */ - VgSrc_ExitSyscall, /* client called exit(). This is the normal - route out. */ - VgSrc_FatalSig /* Killed by the default action of a fatal - signal */ - } - VgSchedReturnCode; - - -// The scheduler. 'fatal_sigNo' is only set if VgSrc_FatalSig is returned. -extern VgSchedReturnCode VG_(scheduler) - ( Int* exit_code, ThreadId* last_run_thread, Int* fatal_sigNo ); - -extern void VG_(scheduler_init) ( void ); - -extern void VG_(pp_sched_status) ( void ); - -// Longjmp back to the scheduler and thus enter the sighandler immediately. -extern void VG_(resume_scheduler) ( Int sigNo, vki_ksiginfo_t *info ); - -// Longjmp, ending the scheduler, when a fatal signal occurs in the client. -extern void VG_(scheduler_handle_fatal_signal)( Int sigNo ); - -/* The red-zone size which we put at the bottom (highest address) of - thread stacks, for paranoia reasons. This can be arbitrary, and - doesn't really need to be set at compile time. */ -#define VG_AR_CLIENT_STACKBASE_REDZONE_SZB 16 - -// Write a value to a client's thread register, and shadow (if necessary). -// Note that there are some further similar macros in the arch- and -// platform-specific parts; these ones are the totally generic ones. -#define SET_THREAD_REG( zztid, zzval, zzGETREG, zzREG, zzevent, zzargs... ) \ - do { zzGETREG(VG_(threads)[zztid].arch) = (zzval); \ - VG_TRACK( zzevent, zztid, zzREG, ##zzargs ); \ - } while (0) - -#define SET_CLREQ_RETVAL(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \ - post_reg_write_clientreq_return) - -#define SET_CLCALL_RETVAL(zztid, zzval, f) \ - SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \ - post_reg_write_clientcall_return, f) - -#define SET_PTHREQ_ESP(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \ - post_reg_write_pthread_return) - -#define SET_PTHREQ_RETVAL(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_PTHREQ_RET, R_PTHREQ_RET, \ - post_reg_write_pthread_return) - - -/* --------------------------------------------------------------------- - Exports of vg_signals.c - ------------------------------------------------------------------ */ - -extern Bool VG_(do_signal_routing); /* whether scheduler LWP has to route signals */ - -/* RT signal allocation */ -extern Int VG_(sig_rtmin); -extern Int VG_(sig_rtmax); -extern Int VG_(sig_alloc_rtsig) ( Int high ); - -extern void VG_(sigstartup_actions) ( void ); - -extern void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *, Bool async ); -extern void VG_(unblock_host_signal) ( Int sigNo ); - -extern Bool VG_(is_sig_ign) ( Int sigNo ); - -/* Route pending signals from the scheduler LWP to the appropriate - thread LWP. */ -extern void VG_(route_signals) ( void ); - -/* Fake system calls for signal handling. */ -extern void VG_(do__NR_sigaltstack) ( ThreadId tid ); -extern void VG_(do__NR_sigaction) ( ThreadId tid ); -extern void VG_(do__NR_sigprocmask) ( ThreadId tid, Int how, - vki_ksigset_t* set, - vki_ksigset_t* oldset ); -extern void VG_(do_pthread_sigmask_SCSS_upd) ( ThreadId tid, Int how, - vki_ksigset_t* set, - vki_ksigset_t* oldset ); - -/* Modify the current thread's state once we have detected it is - returning from a signal handler. */ -extern Bool VG_(signal_returns) ( ThreadId tid ); - -/* Handy utilities to block/restore all host signals. */ -extern void VG_(block_all_host_signals) - ( /* OUT */ vki_ksigset_t* saved_mask ); -extern void VG_(restore_all_host_signals) - ( /* IN */ vki_ksigset_t* saved_mask ); - -extern void VG_(kill_self)(Int sigNo); - -/* These function synthesize a fault, as if the running instruction - had had a fault. These functions do not return - they longjmp back - into the scheduler so the signal can be delivered. */ -extern void VG_(synth_fault) (ThreadId tid); -extern void VG_(synth_fault_mapping)(ThreadId tid, Addr addr); -extern void VG_(synth_fault_perms) (ThreadId tid, Addr addr); - -extern void VG_(get_sigstack_bounds)( Addr* low, Addr* high ); - -/* --------------------------------------------------------------------- - Exports of vg_mylibc.c - ------------------------------------------------------------------ */ - -#define vg_assert(expr) \ - ((void) ((expr) ? 0 : \ - (VG_(core_assert_fail) (VG__STRING(expr), \ - __FILE__, __LINE__, \ - __PRETTY_FUNCTION__), 0))) -__attribute__ ((__noreturn__)) -extern void VG_(core_assert_fail) ( const Char* expr, const Char* file, - Int line, const Char* fn ); -__attribute__ ((__noreturn__)) -extern void VG_(core_panic) ( Char* str ); -__attribute__ ((__noreturn__)) -extern void VG_(core_panic_at) ( Char* str, ExeContext *ec ); - -/* Tools use VG_(strdup)() which doesn't expose ArenaId */ -extern Char* VG_(arena_strdup) ( ArenaId aid, const Char* s); - -extern Int VG_(fcntl) ( Int fd, Int cmd, Int arg ); -extern Int VG_(poll)( struct vki_pollfd *, UInt nfds, Int timeout); - -/* system/mman.h */ -extern void* VG_(mmap)( void* start, UInt length, UInt prot, UInt flags, - UInt sf_flags, UInt fd, UInt offset ); -extern Int VG_(munmap)( void* start, Int length ); -extern Int VG_(mprotect)( void *start, Int length, UInt prot ); - - -/* Move an fd into the Valgrind-safe range */ -Int VG_(safe_fd)(Int oldfd); - -extern Int VG_(write_socket)( Int sd, void *msg, Int count ); - -/* --- Connecting over the network --- */ -extern Int VG_(connect_via_socket)( UChar* str ); - -/* Environment manipulations */ -extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname, - const Char *val ); -extern void VG_(env_unsetenv) ( Char **env, const Char *varname ); -extern void VG_(env_remove_valgrind_env_stuff) ( Char** env ); - -/* --------------------------------------------------------------------- - Exports of vg_message.c - ------------------------------------------------------------------ */ - -/* Low-level -- send bytes directly to the message sink. Do not - use. */ -extern void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes ); - -// Functions for printing from code within Valgrind, but which runs on the -// sim'd CPU. Defined here because needed for vg_libpthread.c, -// vg_replace_malloc.c, plus the rest of the core. The weak attribute -// ensures the multiple definitions are not a problem. They must be functions -// rather than macros so that va_list can be used. - -__attribute__((weak)) -int -VALGRIND_INTERNAL_PRINTF(char *format, ...) -{ - unsigned int _qzz_res = 0; - va_list vargs; - va_start(vargs, format); - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF, - (unsigned int)format, (unsigned int)vargs, 0, 0); - va_end(vargs); - return _qzz_res; -} - -__attribute__((weak)) -int -VALGRIND_INTERNAL_PRINTF_BACKTRACE(char *format, ...) -{ - unsigned int _qzz_res = 0; - va_list vargs; - va_start(vargs, format); - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF_BACKTRACE, - (unsigned int)format, (unsigned int)vargs, 0, 0); - va_end(vargs); - return _qzz_res; -} - - -/* --------------------------------------------------------------------- - Exports of vg_demangle.c - ------------------------------------------------------------------ */ - -extern void VG_(demangle) ( Char* orig, Char* result, Int result_size ); - -/* --------------------------------------------------------------------- - Exports of vg_from_ucode.c - ------------------------------------------------------------------ */ - -extern UChar* VG_(emit_code) ( UCodeBlock* cb, Int* nbytes, UShort jumps[VG_MAX_JUMPS] ); - -extern void VG_(print_ccall_stats) ( void ); -extern void VG_(print_UInstr_histogram) ( void ); - -extern void VG_(unchain_jumpsite) ( Addr jumpsite ); -extern Addr VG_(get_jmp_dest) ( Addr jumpsite ); - -/* --------------------------------------------------------------------- - Exports of vg_to_ucode.c - ------------------------------------------------------------------ */ - -Bool VG_(cpu_has_feature)(UInt feat); - -extern Int VG_(disBB) ( UCodeBlock* cb, Addr eip0 ); - -/* --------------------------------------------------------------------- - Exports of vg_translate.c - ------------------------------------------------------------------ */ - -/* Expandable arrays of uinstrs. */ -struct _UCodeBlock { - Addr orig_eip; - Int used; - Int size; - UInstr* instrs; - Int nextTemp; -}; - -extern Bool VG_(translate) ( ThreadId tid, Addr orig_addr, Bool debugging ); - -extern void VG_(sanity_check_UInstr) ( UInt n, UInstr* u ); - -extern void VG_(print_reg_alloc_stats) ( void ); - -/* --------------------------------------------------------------------- - Exports of vg_execontext.c. - ------------------------------------------------------------------ */ - -/* Records the PC and a bit of the call chain. The first 4 %eip - values are used in comparisons do remove duplicate errors, and for - comparing against suppression specifications. The rest are purely - informational (but often important). */ - -struct _ExeContext { - struct _ExeContext * next; - /* Variable-length array. The size is VG_(clo_backtrace_size); at - least 1, at most VG_DEEPEST_BACKTRACE. [0] is the current IP, - [1] is its caller, [2] is the caller of [1], etc. */ - Addr ips[0]; -}; - - -/* Print stats (informational only). */ -extern void VG_(print_ExeContext_stats) ( void ); - -/* Like VG_(get_ExeContext), but with a slightly different type */ -extern ExeContext* VG_(get_ExeContext2) ( Addr ip, Addr fp, - Addr fp_min, Addr fp_max ); - - -/* --------------------------------------------------------------------- - Exports of vg_errcontext.c. - ------------------------------------------------------------------ */ - -extern void VG_(load_suppressions) ( void ); - -extern void VG_(record_pthread_error) ( ThreadId tid, Char* msg ); - -extern void VG_(show_all_errors) ( void ); - -extern Bool VG_(is_action_requested) ( Char* action, Bool* clo ); - -extern UInt VG_(get_n_errs_found) ( void ); - -/* --------------------------------------------------------------------- - Exports of vg_procselfmaps.c - ------------------------------------------------------------------ */ - -/* Reads /proc/self/maps into a static buffer which can be parsed by - VG_(parse_procselfmaps)(). */ -extern void VG_(read_procselfmaps) ( void ); - -/* Parses /proc/self/maps, calling `record_mapping' for each entry. If - `read_from_file' is True, /proc/self/maps is read directly, otherwise - it's read from the buffer filled by VG_(read_procselfmaps_contents)(). */ -extern -void VG_(parse_procselfmaps) ( - void (*record_mapping)( Addr addr, UInt len, Char rr, Char ww, Char xx, - UInt dev, UInt ino, ULong foff, - const UChar *filename ) ); - - -/* --------------------------------------------------------------------- - Exports of vg_symtab2.c - ------------------------------------------------------------------ */ - -typedef struct _Segment Segment; - -extern Bool VG_(is_object_file) ( const void *hdr ); -extern void VG_(mini_stack_dump) ( Addr eips[], UInt n_eips ); -extern SegInfo * VG_(read_seg_symbols) ( Segment *seg ); -extern void VG_(symtab_incref) ( SegInfo * ); -extern void VG_(symtab_decref) ( SegInfo *, Addr a, UInt len ); - -extern Bool VG_(get_fnname_nodemangle)( Addr a, Char* fnname, Int n_fnname ); - -/* Set up some default redirects */ -extern void VG_(setup_code_redirect_table) ( void ); - -/* Redirection machinery */ -extern Addr VG_(code_redirect) ( Addr orig ); - -/* --------------------------------------------------------------------- - Exports of vg_main.c - ------------------------------------------------------------------ */ - -/* Is this a SSE/SSE2-capable CPU? If so, we had better save/restore - the SSE state all over the place. This is set up very early, in - main(). We have to determine it early since we can't even - correctly snapshot the startup machine state without it. */ -extern Bool VG_(have_ssestate); - -/* Tell the logging mechanism whether we are logging to a file - descriptor or a socket descriptor. */ -extern Bool VG_(logging_to_filedes); - -/* Sanity checks which may be done at any time. The scheduler decides when. */ -extern void VG_(sanity_check_general) ( Bool force_expensive ); - -/* Address space */ -extern Addr VG_(client_base); /* client address space limits */ -extern Addr VG_(client_end); -extern Addr VG_(client_mapbase); /* base of mappings */ -extern Addr VG_(clstk_base); /* client stack range */ -extern Addr VG_(clstk_end); -extern Addr VG_(client_trampoline_code); - -extern Addr VG_(brk_base); /* start of brk */ -extern Addr VG_(brk_limit); /* current brk */ -extern Addr VG_(shadow_base); /* tool's shadow memory */ -extern Addr VG_(shadow_end); -extern Addr VG_(valgrind_base); /* valgrind's address range */ -extern Addr VG_(valgrind_last); // Nb: last byte, rather than one past the end - -extern vki_rlimit VG_(client_rlimit_data); /* client's original rlimit data */ -extern vki_rlimit VG_(client_rlimit_stack); /* client's original rlimit stack */ - -/* client executable file descriptor */ -extern Int VG_(clexecfd); - -// Help set up the child used when doing execve() with --trace-children=yes -Char* VG_(build_child_VALGRINDCLO) ( Char* exename ); -Char* VG_(build_child_exename) ( void ); - -/* Determine if %esp adjustment must be noted */ -extern Bool VG_(need_to_handle_esp_assignment) ( void ); - -/* Called when some unhandleable client behaviour is detected. - Prints a msg and aborts. */ -extern void VG_(unimplemented) ( Char* msg ) - __attribute__((__noreturn__)); - -/* Something of a function looking for a home ... start up debugger. */ -extern void VG_(start_debugger) ( Int tid ); - -/* Counts downwards in vg_run_innerloop. */ -extern UInt VG_(dispatch_ctr); - -/* --- Counters, for informational purposes only. --- */ - -// These counters must be declared here because they're maintained by -// vg_dispatch.S. -extern UInt VG_(bb_enchain_count); // Counts of chain operations done -extern UInt VG_(bb_dechain_count); // Counts of unchain operations done -extern UInt VG_(unchained_jumps_done); // Number of unchained jumps performed - -extern void VG_(print_scheduler_stats) ( void ); - -extern Int VG_(alloc_BaB)( Int ); // Allocate slots in baseBlock -extern void VG_(align_BaB)( UInt ); // Align baseBlock offset -extern Int VG_(alloc_BaB_1_set)( Addr ); // Allocate & init baseBlock slot - -/* --------------------------------------------------------------------- - Exports of vg_memory.c - ------------------------------------------------------------------ */ - -/* A Segment is mapped piece of client memory. This covers all kinds - of mapped memory (exe, brk, mmap, .so, shm, stack, etc) - - We try to encode everything we know about a particular segment here. -*/ -#define SF_FIXED (1 << 0) // client asked for MAP_FIXED -#define SF_SHARED (1 << 1) // shared -#define SF_SHM (1 << 2) // SYSV SHM (also SF_SHARED) -#define SF_MMAP (1 << 3) // mmap memory -#define SF_FILE (1 << 4) // mapping is backed by a file -#define SF_STACK (1 << 5) // is a stack -#define SF_GROWDOWN (1 << 6) // segment grows down -#define SF_GROWUP (1 << 7) // segment grows up -#define SF_EXEC (1 << 8) // segment created by exec -#define SF_DYNLIB (1 << 9) // mapped from dynamic library -#define SF_NOSYMS (1 << 10) // don't load syms, even if present -#define SF_BRK (1 << 11) // brk segment -#define SF_CORE (1 << 12) // allocated by core on behalf of the client -#define SF_VALGRIND (1 << 13) // a valgrind-internal mapping - not in client -#define SF_CODE (1 << 14) // segment contains cached code - -struct _Segment { - UInt prot; /* VKI_PROT_* */ - UInt flags; /* SF_* */ - - Addr addr; /* mapped addr (page aligned) */ - UInt len; /* size of mapping (page aligned) */ - - /* These are valid if (flags & SF_FILE) */ - ULong offset; /* file offset */ - const Char *filename; /* filename (NULL if unknown) */ - UInt dev; /* device */ - UInt ino; /* inode */ - - SegInfo *symtab; /* symbol table */ -}; - -/* segment mapped from a file descriptor */ -extern void VG_(map_fd_segment) (Addr addr, UInt len, UInt prot, UInt flags, - Int fd, ULong off, const Char *filename); - -/* segment mapped from a file */ -extern void VG_(map_file_segment)(Addr addr, UInt len, UInt prot, UInt flags, - UInt dev, UInt ino, ULong off, const Char *filename); - -/* simple segment */ -extern void VG_(map_segment) (Addr addr, UInt len, UInt prot, UInt flags); - -extern void VG_(unmap_range) (Addr addr, UInt len); -extern void VG_(mprotect_range)(Addr addr, UInt len, UInt prot); -extern Addr VG_(find_map_space)(Addr base, UInt len, Bool for_client); - -extern Segment *VG_(find_segment)(Addr a); -extern Segment *VG_(first_segment)(void); -extern Segment *VG_(next_segment)(Segment *); - -extern Bool VG_(seg_contains)(const Segment *s, Addr ptr, UInt size); -extern Bool VG_(seg_overlaps)(const Segment *s, Addr ptr, UInt size); - -extern void VG_(pad_address_space)(void); -extern void VG_(unpad_address_space)(void); - -extern REGPARM(1) - void VG_(unknown_esp_update) ( Addr new_ESP ); - -/* --------------------------------------------------------------------- - Exports of vg_proxylwp.c - ------------------------------------------------------------------ */ - -enum PXState -{ - PXS_BAD = -1, - PXS_WaitReq, /* waiting for a request */ - PXS_RunSyscall, /* running a syscall */ - PXS_IntReply, /* request interrupted - need to send reply */ - PXS_SysDone, /* small window between syscall - complete and results written out */ - PXS_SigACK, /* waiting for a signal ACK */ -}; - - -/* Issue a syscall for thread tid */ -extern Int VG_(sys_issue)(int tid); - -extern void VG_(proxy_init) ( void ); -extern void VG_(proxy_create) ( ThreadId tid ); -extern void VG_(proxy_delete) ( ThreadId tid, Bool force ); -extern void VG_(proxy_results) ( void ); -extern void VG_(proxy_sendsig) ( ThreadId tid, Int signo ); -extern void VG_(proxy_setsigmask)(ThreadId tid); -extern void VG_(proxy_sigack) ( ThreadId tid, const vki_ksigset_t *); -extern void VG_(proxy_abort_syscall) ( ThreadId tid ); -extern void VG_(proxy_waitsig) ( void ); -extern void VG_(proxy_wait_sys) (ThreadId tid, Bool restart); - -extern void VG_(proxy_shutdown) ( void ); // shut down the syscall workers -extern Int VG_(proxy_resfd) ( void ); // FD something can select on to know - // a syscall finished - -/* Sanity-check the whole proxy-LWP machinery */ -void VG_(sanity_check_proxy)(void); - -/* Send a signal from a thread's proxy to the thread. This longjmps - back into the proxy's main loop, so it doesn't return. */ -__attribute__ ((__noreturn__)) -extern void VG_(proxy_handlesig)( const vki_ksiginfo_t *siginfo, - Addr ip, Int sysnum ); - -/* --------------------------------------------------------------------- - Exports of vg_syscalls.c - ------------------------------------------------------------------ */ - -extern Char *VG_(resolve_filename)(Int fd); - -extern Bool VG_(pre_syscall) ( ThreadId tid ); -extern void VG_(post_syscall)( ThreadId tid, Bool restart ); - -extern Bool VG_(is_kerror) ( Int res ); - -/* Internal atfork handlers */ -typedef void (*vg_atfork_t)(ThreadId); -extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child); - -/* fd leakage calls. */ -extern void VG_(init_preopened_fds) ( void ); -extern void VG_(show_open_fds) ( void ); - -/* --------------------------------------------------------------------- - Exports of vg_transtab.c - ------------------------------------------------------------------ */ - -/* The fast-cache for tt-lookup. */ -extern Addr VG_(tt_fast)[VG_TT_FAST_SIZE]; - -extern void VG_(init_tt_tc) ( void ); -extern void VG_(add_to_trans_tab) ( Addr orig_addr, Int orig_size, - Addr trans_addr, Int trans_size ); -extern Addr VG_(search_transtab) ( Addr original_addr ); - -extern void VG_(invalidate_translations) ( Addr start, UInt range, - Bool unchain_blocks ); - -extern void VG_(sanity_check_tt_tc) ( void ); - -extern void VG_(print_tt_tc_stats) ( void ); - -extern Int VG_(get_bbs_translated) ( void ); - -/* --------------------------------------------------------------------- - Exports of vg_syscall.S - ------------------------------------------------------------------ */ - -extern Int VG_(do_syscall) ( UInt, ... ); -extern Int VG_(clone) ( Int (*fn)(void *), void *stack, Int flags, void *arg, - Int *child_tid, Int *parent_tid); -extern void VG_(sigreturn)(void); - -/* --------------------------------------------------------------------- - Exports of vg_dispatch.S - ------------------------------------------------------------------ */ - -/* Run a thread for a (very short) while, until some event happens - which means we need to defer to the scheduler. */ -extern UInt VG_(run_innerloop) ( void ); - -/* The patching routing called when a BB wants to chain itself to - another. */ -extern UInt VG_(patch_me); - -/* --------------------------------------------------------------------- - Exports of vg_helpers.S - ------------------------------------------------------------------ */ - -extern void VG_(helper_undefined_instruction); - -/* Information about trampoline code (for signal return and syscalls) */ -extern const Char VG_(trampoline_code_start); -extern const Int VG_(trampoline_code_length); -extern const Int VG_(tramp_sigreturn_offset); -extern const Int VG_(tramp_syscall_offset); - -/* --------------------------------------------------------------------- - Things relating to the used tool - ------------------------------------------------------------------ */ - -#define VG_TRACK(fn, args...) \ - do { \ - if (VG_(defined_##fn)()) \ - SK_(fn)(args); \ - } while(0) - -__attribute__ ((noreturn)) -extern void VG_(missing_tool_func) ( const Char* fn ); - -/* --------------------------------------------------------------------- - The baseBlock -- arch-neutral bits - ------------------------------------------------------------------ */ - -#define INVALID_OFFSET (-1) - -/* An array of words. In generated code, %ebp always points to the - start of this array. Useful stuff, like the simulated CPU state, - and the addresses of helper functions, can then be found by - indexing off %ebp. The following declares variables which, at - startup time, are given values denoting offsets into baseBlock. - These offsets are in *words* from the start of baseBlock. */ - -#define VG_BASEBLOCK_WORDS 288 - -extern UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS]; - -// --------------------------------------------------------------------- -// Architecture-specific things defined in eg. x86/*.c -// --------------------------------------------------------------------- - -// For setting up the baseBlock -extern void VGA_(init_low_baseBlock) ( Addr client_eip, Addr esp_at_startup ); -extern void VGA_(init_high_baseBlock) ( Addr client_eip, Addr esp_at_startup ); - -// Register state moving -extern void VGA_(load_state) ( arch_thread_t*, ThreadId tid ); -extern void VGA_(save_state) ( arch_thread_t*, ThreadId tid ); - -// Thread stuff -extern void VGA_(clear_thread) ( arch_thread_t* ); -extern void VGA_(init_thread) ( arch_thread_t* ); -extern void VGA_(cleanup_thread) ( arch_thread_t* ); -extern void VGA_(setup_child) ( arch_thread_t*, arch_thread_t* ); - -extern void VGA_(set_arg_and_bogus_ret) ( ThreadId tid, UWord arg, Addr ret ); -extern void VGA_(thread_initial_stack) ( ThreadId tid, UWord arg, Addr ret ); - -// Symtab stuff -extern UInt* VGA_(reg_addr_from_BB) ( Int reg ); -extern UInt* VGA_(reg_addr_from_tst) ( Int reg, arch_thread_t* ); - -// Pointercheck -extern Bool VGA_(setup_pointercheck) ( void ); - -// For attaching the debugger -extern Int VGA_(ptrace_setregs_from_BB) ( Int pid ); -extern Int VGA_(ptrace_setregs_from_tst) ( Int pid, arch_thread_t* arch ); - -// Making coredumps -extern void VGA_(fill_elfregs_from_BB) ( struct user_regs_struct* regs ); -extern void VGA_(fill_elfregs_from_tst) ( struct user_regs_struct* regs, - arch_thread_t* arch ); -extern void VGA_(fill_elffpregs_from_BB) ( elf_fpregset_t* fpu ); -extern void VGA_(fill_elffpregs_from_tst) ( elf_fpregset_t* fpu, - const arch_thread_t* arch ); -extern void VGA_(fill_elffpxregs_from_BB) ( elf_fpxregset_t* xfpu ); -extern void VGA_(fill_elffpxregs_from_tst) ( elf_fpxregset_t* xfpu, - const arch_thread_t* arch ); - -// Signal stuff -extern void VGA_(push_signal_frame) ( ThreadId tid, Addr esp_top_of_frame, - const vki_ksiginfo_t *siginfo, - void *handler, UInt flags, - const vki_ksigset_t *mask); -extern Int VGA_(pop_signal_frame) ( ThreadId tid ); - -// --------------------------------------------------------------------- -// Platform-specific things defined in eg. x86/*.c -// --------------------------------------------------------------------- - -extern const Addr vga_sys_before, vga_sys_restarted, - vga_sys_after, vga_sys_done; - -extern void VGA_(restart_syscall)(arch_thread_t* arch); - -extern void VGA_(thread_syscall)(Int syscallno, arch_thread_t* arch, - enum PXState* state, enum PXState poststate); - -/* --------------------------------------------------------------------- - Finally - autoconf-generated settings - ------------------------------------------------------------------ */ - -#include "config.h" - -#endif /* ndef __CORE_H */ - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/core_asm.h b/VEX/head20041019/coregrind/core_asm.h deleted file mode 100644 index dc8ae40c5..000000000 --- a/VEX/head20041019/coregrind/core_asm.h +++ /dev/null @@ -1,159 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Asm-specific core stuff. core_asm.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __CORE_ASM_H -#define __CORE_ASM_H - -#include "tool_asm.h" // tool asm stuff -#include "core_arch_asm.h" // arch-specific asm stuff - -/* This file is included in all Valgrind source files, including - assembly ones. */ - -/* Magic values that %ebp might be set to when returning to the - dispatcher. The only other legitimate value is to point to the - start of VG_(baseBlock). These also are return values from - VG_(run_innerloop) to the scheduler. - - EBP means %ebp can legitimately have this value when a basic block - returns to the dispatch loop. TRC means that this value is a valid - thread return code, which the dispatch loop may return to the - scheduler. */ -#define VG_TRC_EBP_JMP_SYSCALL 19 /* EBP and TRC */ -#define VG_TRC_EBP_JMP_CLIENTREQ 23 /* EBP and TRC */ -#define VG_TRC_EBP_JMP_YIELD 27 /* EBP and TRC */ - -#define VG_TRC_INNER_FASTMISS 31 /* TRC only; means fast-cache miss. */ -#define VG_TRC_INNER_COUNTERZERO 29 /* TRC only; means bb ctr == 0 */ -#define VG_TRC_UNRESUMABLE_SIGNAL 37 /* TRC only; got sigsegv/sigbus */ - -/* maximum number of normal jumps which can appear in a basic block */ -#define VG_MAX_JUMPS 2 - -/* Offset of code in a TCEntry */ -#define VG_CODE_OFFSET (8 + VG_MAX_JUMPS * 2) - -/* Client address space segment limit descriptor entry */ -#define VG_POINTERCHECK_SEGIDX 1 - -/* Debugging hack for assembly code ... sigh. */ -#if 0 -#define OYNK(nnn) pushal; pushl $nnn; call VG_(oynk) ; addl $4,%esp; popal -#else -#define OYNK(nnn) -#endif - -#if 0 -#define OYNNK(nnn) pushal; pushl $nnn; call VG_(oynk) ; addl $4,%esp; popal -#else -#define OYNNK(nnn) -#endif - - -/* Constants for the fast translation lookup cache. */ -#define VG_TT_FAST_BITS 16 -#define VG_TT_FAST_SIZE (1 << VG_TT_FAST_BITS) -#define VG_TT_FAST_MASK ((VG_TT_FAST_SIZE) - 1) - -/* Constants for the fast original-code-write check cache. */ - - -/* Assembly code stubs make this request */ -#define VG_USERREQ__SIGNAL_RETURNS 0x4001 - -/* - 0 - standard feature flags - 1 - Intel extended flags - 2 - Valgrind internal flags - 3 - AMD-specific flags - */ -#define VG_N_FEATURE_WORDS 4 - -#define VG_X86_FEAT 0 -#define VG_EXT_FEAT 1 -#define VG_INT_FEAT 2 -#define VG_AMD_FEAT 3 - -/* CPU features (generic) */ -#define VG_X86_FEAT_FPU (VG_X86_FEAT*32 + 0) -#define VG_X86_FEAT_VME (VG_X86_FEAT*32 + 1) -#define VG_X86_FEAT_DE (VG_X86_FEAT*32 + 2) -#define VG_X86_FEAT_PSE (VG_X86_FEAT*32 + 3) -#define VG_X86_FEAT_TSC (VG_X86_FEAT*32 + 4) -#define VG_X86_FEAT_MSR (VG_X86_FEAT*32 + 5) -#define VG_X86_FEAT_PAE (VG_X86_FEAT*32 + 6) -#define VG_X86_FEAT_MCE (VG_X86_FEAT*32 + 7) -#define VG_X86_FEAT_CX8 (VG_X86_FEAT*32 + 8) -#define VG_X86_FEAT_APIC (VG_X86_FEAT*32 + 9) -#define VG_X86_FEAT_SEP (VG_X86_FEAT*32 + 11) -#define VG_X86_FEAT_MTRR (VG_X86_FEAT*32 + 12) -#define VG_X86_FEAT_PGE (VG_X86_FEAT*32 + 13) -#define VG_X86_FEAT_MCA (VG_X86_FEAT*32 + 14) -#define VG_X86_FEAT_CMOV (VG_X86_FEAT*32 + 15) -#define VG_X86_FEAT_PAT (VG_X86_FEAT*32 + 16) -#define VG_X86_FEAT_PSE36 (VG_X86_FEAT*32 + 17) -#define VG_X86_FEAT_CLFSH (VG_X86_FEAT*32 + 19) -#define VG_X86_FEAT_DS (VG_X86_FEAT*32 + 21) -#define VG_X86_FEAT_ACPI (VG_X86_FEAT*32 + 22) -#define VG_X86_FEAT_MMX (VG_X86_FEAT*32 + 23) -#define VG_X86_FEAT_FXSR (VG_X86_FEAT*32 + 24) -#define VG_X86_FEAT_SSE (VG_X86_FEAT*32 + 25) -#define VG_X86_FEAT_SSE2 (VG_X86_FEAT*32 + 26) -#define VG_X86_FEAT_SS (VG_X86_FEAT*32 + 27) -#define VG_X86_FEAT_HT (VG_X86_FEAT*32 + 28) -#define VG_X86_FEAT_TM (VG_X86_FEAT*32 + 29) -#define VG_X86_FEAT_IA64 (VG_X86_FEAT*32 + 30) -#define VG_X86_FEAT_PBE (VG_X86_FEAT*32 + 31) - -/* Intel extended feature word */ -#define VG_X86_FEAT_SSE3 (VG_EXT_FEAT*32 + 0) -#define VG_X86_FEAT_MON (VG_EXT_FEAT*32 + 3) -#define VG_X86_FEAT_DSCPL (VG_EXT_FEAT*32 + 4) -#define VG_X86_FEAT_EST (VG_EXT_FEAT*32 + 7) -#define VG_X86_FEAT_TM2 (VG_EXT_FEAT*32 + 8) -#define VG_X86_FEAT_CNXTID (VG_EXT_FEAT*32 + 10) - -/* Used internally to mark whether CPUID is even implemented */ -#define VG_X86_FEAT_CPUID (VG_INT_FEAT*32 + 0) - -/* AMD special features */ -#define VG_AMD_FEAT_SYSCALL (VG_AMD_FEAT*32 + 11) -#define VG_AMD_FEAT_NXP (VG_AMD_FEAT*32 + 20) -#define VG_AMD_FEAT_MMXEXT (VG_AMD_FEAT*32 + 22) -#define VG_AMD_FEAT_FFXSR (VG_AMD_FEAT*32 + 25) -#define VG_AMD_FEAT_LONGMODE (VG_AMD_FEAT*32 + 29) -#define VG_AMD_FEAT_3DNOWEXT (VG_AMD_FEAT*32 + 30) -#define VG_AMD_FEAT_3DNOW (VG_AMD_FEAT*32 + 31) - -#endif /* ndef __CORE_ASM_H */ - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/demangle/.cvsignore b/VEX/head20041019/coregrind/demangle/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/coregrind/demangle/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/coregrind/demangle/CVS/Entries b/VEX/head20041019/coregrind/demangle/CVS/Entries deleted file mode 100644 index bd1a91c97..000000000 --- a/VEX/head20041019/coregrind/demangle/CVS/Entries +++ /dev/null @@ -1,11 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:28 2002// -/Makefile.am/1.13/Wed Sep 1 23:20:47 2004// -/ansidecl.h/1.1.1.1/Fri Mar 22 01:29:43 2002// -/cp-demangle.c/1.7/Wed Sep 1 23:58:16 2004// -/cplus-dem.c/1.7/Wed Sep 1 23:58:16 2004// -/demangle.h/1.1.1.1/Fri Mar 22 01:29:43 2002// -/dyn-string.c/1.6/Wed Sep 1 23:58:16 2004// -/dyn-string.h/1.1.1.1/Fri Mar 22 01:29:43 2002// -/safe-ctype.c/1.2/Mon Feb 24 10:49:08 2003// -/safe-ctype.h/1.1.1.1/Fri Mar 22 01:29:43 2002// -D diff --git a/VEX/head20041019/coregrind/demangle/CVS/Repository b/VEX/head20041019/coregrind/demangle/CVS/Repository deleted file mode 100644 index 1e1632d28..000000000 --- a/VEX/head20041019/coregrind/demangle/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/coregrind/demangle diff --git a/VEX/head20041019/coregrind/demangle/CVS/Root b/VEX/head20041019/coregrind/demangle/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/coregrind/demangle/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/coregrind/demangle/CVS/Template b/VEX/head20041019/coregrind/demangle/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/coregrind/demangle/Makefile.am b/VEX/head20041019/coregrind/demangle/Makefile.am deleted file mode 100644 index 48cb75220..000000000 --- a/VEX/head20041019/coregrind/demangle/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -include $(top_srcdir)/Makefile.all.am -include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am - -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -g - -noinst_HEADERS = \ - ansidecl.h \ - dyn-string.h \ - demangle.h \ - safe-ctype.h - -noinst_LIBRARIES = libdemangle.a - -libdemangle_a_SOURCES = \ - cp-demangle.c cplus-dem.c dyn-string.c safe-ctype.c - -## Ignore harmless warnings for these ones -cp-demangle.o: CFLAGS += -Wno-unused -Wno-shadow -cplus-dem.o: CFLAGS += -Wno-unused - diff --git a/VEX/head20041019/coregrind/demangle/ansidecl.h b/VEX/head20041019/coregrind/demangle/ansidecl.h deleted file mode 100644 index 9a7c5777f..000000000 --- a/VEX/head20041019/coregrind/demangle/ansidecl.h +++ /dev/null @@ -1,295 +0,0 @@ -/* ANSI and traditional C compatability macros - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - -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. */ - -/* ANSI and traditional C compatibility macros - - ANSI C is assumed if __STDC__ is #defined. - - Macro ANSI C definition Traditional C definition - ----- ---- - ---------- ----------- - ---------- - ANSI_PROTOTYPES 1 not defined - PTR `void *' `char *' - PTRCONST `void *const' `char *' - LONG_DOUBLE `long double' `double' - const not defined `' - volatile not defined `' - signed not defined `' - VA_START(ap, var) va_start(ap, var) va_start(ap) - - Note that it is safe to write "void foo();" indicating a function - with no return value, in all K+R compilers we have been able to test. - - For declaring functions with prototypes, we also provide these: - - PARAMS ((prototype)) - -- for functions which take a fixed number of arguments. Use this - when declaring the function. When defining the function, write a - K+R style argument list. For example: - - char *strcpy PARAMS ((char *dest, char *source)); - ... - char * - strcpy (dest, source) - char *dest; - char *source; - { ... } - - - VPARAMS ((prototype, ...)) - -- for functions which take a variable number of arguments. Use - PARAMS to declare the function, VPARAMS to define it. For example: - - int printf PARAMS ((const char *format, ...)); - ... - int - printf VPARAMS ((const char *format, ...)) - { - ... - } - - For writing functions which take variable numbers of arguments, we - also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These - hide the differences between K+R and C89 more - thoroughly than the simple VA_START() macro mentioned above. - - VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. - Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls - corresponding to the list of fixed arguments. Then use va_arg - normally to get the variable arguments, or pass your va_list object - around. You do not declare the va_list yourself; VA_OPEN does it - for you. - - Here is a complete example: - - int - printf VPARAMS ((const char *format, ...)) - { - int result; - - VA_OPEN (ap, format); - VA_FIXEDARG (ap, const char *, format); - - result = vfprintf (stdout, format, ap); - VA_CLOSE (ap); - - return result; - } - - - You can declare variables either before or after the VA_OPEN, - VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning - and end of a block. They must appear at the same nesting level, - and any variables declared after VA_OPEN go out of scope at - VA_CLOSE. Unfortunately, with a K+R compiler, that includes the - argument list. You can have multiple instances of VA_OPEN/VA_CLOSE - pairs in a single function in case you need to traverse the - argument list more than once. - - For ease of writing code which uses GCC extensions but needs to be - portable to other compilers, we provide the GCC_VERSION macro that - simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various - wrappers around __attribute__. Also, __extension__ will be #defined - to nothing if it doesn't work. See below. - - This header also defines a lot of obsolete macros: - CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, - AND, DOTS, NOARGS. Don't use them. */ - -#ifndef _ANSIDECL_H -#define _ANSIDECL_H 1 - -/* Every source file includes this file, - so they will all get the switch for lint. */ -/* LINTLIBRARY */ - -/* Using MACRO(x,y) in cpp #if conditionals does not work with some - older preprocessors. Thus we can't define something like this: - -#define HAVE_GCC_VERSION(MAJOR, MINOR) \ - (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) - -and then test "#if HAVE_GCC_VERSION(2,7)". - -So instead we use the macro below and test it against specific values. */ - -/* This macro simplifies testing whether we are using gcc, and if it - is of a particular minimum version. (Both major & minor numbers are - significant.) This macro will evaluate to 0 if we are not using - gcc at all. */ -#ifndef GCC_VERSION -#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) -#endif /* GCC_VERSION */ - -#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) -/* All known AIX compilers implement these things (but don't always - define __STDC__). The RISC/OS MIPS compiler defines these things - in SVR4 mode, but does not define __STDC__. */ - -#define ANSI_PROTOTYPES 1 -#define PTR void * -#define PTRCONST void *const -#define LONG_DOUBLE long double - -#define PARAMS(ARGS) ARGS -#define VPARAMS(ARGS) ARGS -#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) - -/* variadic function helper macros */ -/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's - use without inhibiting further decls and without declaring an - actual variable. */ -#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy -#define VA_CLOSE(AP) } va_end(AP); } -#define VA_FIXEDARG(AP, T, N) struct Qdmy - -#undef const -#undef volatile -#undef signed - -/* inline requires special treatment; it's in C99, and GCC >=2.7 supports - it too, but it's not in C89. */ -#undef inline -#if __STDC_VERSION__ > 199901L -/* it's a keyword */ -#else -# if GCC_VERSION >= 2007 -# define inline __inline__ /* __inline__ prevents -pedantic warnings */ -# else -# define inline /* nothing */ -# endif -#endif - -/* These are obsolete. Do not use. */ -#ifndef IN_GCC -#define CONST const -#define VOLATILE volatile -#define SIGNED signed - -#define PROTO(type, name, arglist) type name arglist -#define EXFUN(name, proto) name proto -#define DEFUN(name, arglist, args) name(args) -#define DEFUN_VOID(name) name(void) -#define AND , -#define DOTS , ... -#define NOARGS void -#endif /* ! IN_GCC */ - -#else /* Not ANSI C. */ - -#undef ANSI_PROTOTYPES -#define PTR char * -#define PTRCONST PTR -#define LONG_DOUBLE double - -#define PARAMS(args) () -#define VPARAMS(args) (va_alist) va_dcl -#define VA_START(va_list, var) va_start(va_list) - -#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy -#define VA_CLOSE(AP) } va_end(AP); } -#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) - -/* some systems define these in header files for non-ansi mode */ -#undef const -#undef volatile -#undef signed -#undef inline -#define const -#define volatile -#define signed -#define inline - -#ifndef IN_GCC -#define CONST -#define VOLATILE -#define SIGNED - -#define PROTO(type, name, arglist) type name () -#define EXFUN(name, proto) name() -#define DEFUN(name, arglist, args) name arglist args; -#define DEFUN_VOID(name) name() -#define AND ; -#define DOTS -#define NOARGS -#endif /* ! IN_GCC */ - -#endif /* ANSI C. */ - -/* Define macros for some gcc attributes. This permits us to use the - macros freely, and know that they will come into play for the - version of gcc in which they are supported. */ - -#if (GCC_VERSION < 2007) -# define __attribute__(x) -#endif - -/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ -#ifndef ATTRIBUTE_MALLOC -# if (GCC_VERSION >= 2096) -# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -# else -# define ATTRIBUTE_MALLOC -# endif /* GNUC >= 2.96 */ -#endif /* ATTRIBUTE_MALLOC */ - -/* Attributes on labels were valid as of gcc 2.93. */ -#ifndef ATTRIBUTE_UNUSED_LABEL -# if (GCC_VERSION >= 2093) -# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED -# else -# define ATTRIBUTE_UNUSED_LABEL -# endif /* GNUC >= 2.93 */ -#endif /* ATTRIBUTE_UNUSED_LABEL */ - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif /* ATTRIBUTE_UNUSED */ - -#ifndef ATTRIBUTE_NORETURN -#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -#endif /* ATTRIBUTE_NORETURN */ - -#ifndef ATTRIBUTE_PRINTF -#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) -#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) -#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) -#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) -#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) -#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) -#endif /* ATTRIBUTE_PRINTF */ - -/* We use __extension__ in some places to suppress -pedantic warnings - about GCC extensions. This feature didn't work properly before - gcc 2.8. */ -#if GCC_VERSION < 2008 -#define __extension__ -#endif - -/* Bootstrap support: Adjust certain macros defined by Autoconf, - which are only valid for the stage1 compiler. If we detect - a modern version of GCC, we are probably in stage2 or beyond, - so unconditionally reset the values. Note that const, inline, - etc. have been dealt with above. */ -#if (GCC_VERSION >= 2007) -# ifndef HAVE_LONG_DOUBLE -# define HAVE_LONG_DOUBLE 1 -# endif -#endif /* GCC >= 2.7 */ - -#endif /* ansidecl.h */ diff --git a/VEX/head20041019/coregrind/demangle/cp-demangle.c b/VEX/head20041019/coregrind/demangle/cp-demangle.c deleted file mode 100644 index 4bd37481f..000000000 --- a/VEX/head20041019/coregrind/demangle/cp-demangle.c +++ /dev/null @@ -1,4176 +0,0 @@ -/* Demangler for IA64 / g++ V3 ABI. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Alex Samuel . - - This file is part of GNU CC. - - 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. -*/ - -/* This file implements demangling of C++ names mangled according to - the IA64 / g++ V3 ABI. Use the cp_demangle function to - demangle a mangled name, or compile with the preprocessor macro - STANDALONE_DEMANGLER defined to create a demangling filter - executable (functionally similar to c++filt, but includes this - demangler only). */ - -/*#include */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/*#ifdef HAVE_STDLIB_H -#include -#endif*/ - -/*#ifdef HAVE_STRING_H -#include -#endif*/ - -#include "core.h" -#include "ansidecl.h" -#include "dyn-string.h" -#include "demangle.h" - -#ifndef STANDALONE -#define size_t Int - -#define malloc(s) VG_(arena_malloc) (VG_AR_DEMANGLE, s) -#define free(p) VG_(arena_free) (VG_AR_DEMANGLE, p) -#define realloc(p,s) VG_(arena_realloc)(VG_AR_DEMANGLE, p, VG_MIN_MALLOC_SZB, s) -#endif - -/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation, - and other debugging output, will be generated. */ -#ifdef CP_DEMANGLE_DEBUG -#define DEMANGLE_TRACE(PRODUCTION, DM) \ - fprintf (stderr, " -> %-24s at position %3d\n", \ - (PRODUCTION), current_position (DM)); -#else -#define DEMANGLE_TRACE(PRODUCTION, DM) -#endif - -/* Don't include , to prevent additional unresolved symbols - from being dragged into the C++ runtime library. */ -#define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9') -#define IS_ALPHA(CHAR) \ - (((CHAR) >= 'a' && (CHAR) <= 'z') \ - || ((CHAR) >= 'A' && (CHAR) <= 'Z')) - -/* The prefix prepended by GCC to an identifier represnting the - anonymous namespace. */ -#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_" - -/* Character(s) to use for namespace separation in demangled output */ -#define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::") - -/* If flag_verbose is zero, some simplifications will be made to the - output to make it easier to read and suppress details that are - generally not of interest to the average C++ programmer. - Otherwise, the demangled representation will attempt to convey as - much information as the mangled form. */ -static int flag_verbose; - -/* If flag_strict is non-zero, demangle strictly according to the - specification -- don't demangle special g++ manglings. */ -static int flag_strict; - -/* String_list_t is an extended form of dyn_string_t which provides a - link field and a caret position for additions to the string. A - string_list_t may safely be cast to and used as a dyn_string_t. */ - -struct string_list_def -{ - /* The dyn_string; must be first. */ - struct dyn_string string; - - /* The position at which additional text is added to this string - (using the result_add* macros). This value is an offset from the - end of the string, not the beginning (and should be - non-positive). */ - int caret_position; - - /* The next string in the list. */ - struct string_list_def *next; -}; - -typedef struct string_list_def *string_list_t; - -/* Data structure representing a potential substitution. */ - -struct substitution_def -{ - /* The demangled text of the substitution. */ - dyn_string_t text; - - /* Whether this substitution represents a template item. */ - int template_p : 1; -}; - -/* Data structure representing a template argument list. */ - -struct template_arg_list_def -{ - /* The next (lower) template argument list in the stack of currently - active template arguments. */ - struct template_arg_list_def *next; - - /* The first element in the list of template arguments in - left-to-right order. */ - string_list_t first_argument; - - /* The last element in the arguments lists. */ - string_list_t last_argument; -}; - -typedef struct template_arg_list_def *template_arg_list_t; - -/* Data structure to maintain the state of the current demangling. */ - -struct demangling_def -{ - /* The full mangled name being mangled. */ - const char *name; - - /* Pointer into name at the current position. */ - const char *next; - - /* Stack for strings containing demangled result generated so far. - Text is emitted to the topmost (first) string. */ - string_list_t result; - - /* The number of presently available substitutions. */ - int num_substitutions; - - /* The allocated size of the substitutions array. */ - int substitutions_allocated; - - /* An array of available substitutions. The number of elements in - the array is given by num_substitions, and the allocated array - size in substitutions_size. - - The most recent substition is at the end, so - - - `S_' corresponds to substititutions[num_substitutions - 1] - - `S0_' corresponds to substititutions[num_substitutions - 2] - - etc. */ - struct substitution_def *substitutions; - - /* The stack of template argument lists. */ - template_arg_list_t template_arg_lists; - - /* The most recently demangled source-name. */ - dyn_string_t last_source_name; - - /* Language style to use for demangled output. */ - int style; - - /* Set to non-zero iff this name is a constructor. The actual value - indicates what sort of constructor this is; see demangle.h. */ - enum gnu_v3_ctor_kinds is_constructor; - - /* Set to non-zero iff this name is a destructor. The actual value - indicates what sort of destructor this is; see demangle.h. */ - enum gnu_v3_dtor_kinds is_destructor; - -}; - -typedef struct demangling_def *demangling_t; - -/* This type is the standard return code from most functions. Values - other than STATUS_OK contain descriptive messages. */ -typedef const char *status_t; - -/* Special values that can be used as a status_t. */ -#define STATUS_OK NULL -#define STATUS_ERROR "Error." -#define STATUS_UNIMPLEMENTED "Unimplemented." -#define STATUS_INTERNAL_ERROR "Internal error." - -/* This status code indicates a failure in malloc or realloc. */ -static const char *const status_allocation_failed = "Allocation failed."; -#define STATUS_ALLOCATION_FAILED status_allocation_failed - -/* Non-zero if STATUS indicates that no error has occurred. */ -#define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK) - -/* Evaluate EXPR, which must produce a status_t. If the status code - indicates an error, return from the current function with that - status code. */ -#define RETURN_IF_ERROR(EXPR) \ - do \ - { \ - status_t s = EXPR; \ - if (!STATUS_NO_ERROR (s)) \ - return s; \ - } \ - while (0) - -static status_t int_to_dyn_string - PARAMS ((int, dyn_string_t)); -static string_list_t string_list_new - PARAMS ((int)); -static void string_list_delete - PARAMS ((string_list_t)); -static status_t result_add_separated_char - PARAMS ((demangling_t, int)); -static status_t result_push - PARAMS ((demangling_t)); -static string_list_t result_pop - PARAMS ((demangling_t)); -static int substitution_start - PARAMS ((demangling_t)); -static status_t substitution_add - PARAMS ((demangling_t, int, int)); -static dyn_string_t substitution_get - PARAMS ((demangling_t, int, int *)); -#ifdef CP_DEMANGLE_DEBUG -static void substitutions_print - PARAMS ((demangling_t, FILE *)); -#endif -static template_arg_list_t template_arg_list_new - PARAMS ((void)); -static void template_arg_list_delete - PARAMS ((template_arg_list_t)); -static void template_arg_list_add_arg - PARAMS ((template_arg_list_t, string_list_t)); -static string_list_t template_arg_list_get_arg - PARAMS ((template_arg_list_t, int)); -static void push_template_arg_list - PARAMS ((demangling_t, template_arg_list_t)); -static void pop_to_template_arg_list - PARAMS ((demangling_t, template_arg_list_t)); -#ifdef CP_DEMANGLE_DEBUG -static void template_arg_list_print - PARAMS ((template_arg_list_t, FILE *)); -#endif -static template_arg_list_t current_template_arg_list - PARAMS ((demangling_t)); -static demangling_t demangling_new - PARAMS ((const char *, int)); -static void demangling_delete - PARAMS ((demangling_t)); - -/* The last character of DS. Warning: DS is evaluated twice. */ -#define dyn_string_last_char(DS) \ - (dyn_string_buf (DS)[dyn_string_length (DS) - 1]) - -/* Append a space character (` ') to DS if it does not already end - with one. Evaluates to 1 on success, or 0 on allocation failure. */ -#define dyn_string_append_space(DS) \ - ((dyn_string_length (DS) > 0 \ - && dyn_string_last_char (DS) != ' ') \ - ? dyn_string_append_char ((DS), ' ') \ - : 1) - -/* Returns the index of the current position in the mangled name. */ -#define current_position(DM) ((DM)->next - (DM)->name) - -/* Returns the character at the current position of the mangled name. */ -#define peek_char(DM) (*((DM)->next)) - -/* Returns the character one past the current position of the mangled - name. */ -#define peek_char_next(DM) \ - (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1))) - -/* Returns the character at the current position, and advances the - current position to the next character. */ -#define next_char(DM) (*((DM)->next)++) - -/* Returns non-zero if the current position is the end of the mangled - name, i.e. one past the last character. */ -#define end_of_name_p(DM) (peek_char (DM) == '\0') - -/* Advances the current position by one character. */ -#define advance_char(DM) (++(DM)->next) - -/* Returns the string containing the current demangled result. */ -#define result_string(DM) (&(DM)->result->string) - -/* Returns the position at which new text is inserted into the - demangled result. */ -#define result_caret_pos(DM) \ - (result_length (DM) + \ - ((string_list_t) result_string (DM))->caret_position) - -/* Adds a dyn_string_t to the demangled result. */ -#define result_add_string(DM, STRING) \ - (dyn_string_insert (&(DM)->result->string, \ - result_caret_pos (DM), (STRING)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* Adds NUL-terminated string CSTR to the demangled result. */ -#define result_add(DM, CSTR) \ - (dyn_string_insert_cstr (&(DM)->result->string, \ - result_caret_pos (DM), (CSTR)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* Adds character CHAR to the demangled result. */ -#define result_add_char(DM, CHAR) \ - (dyn_string_insert_char (&(DM)->result->string, \ - result_caret_pos (DM), (CHAR)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* Inserts a dyn_string_t to the demangled result at position POS. */ -#define result_insert_string(DM, POS, STRING) \ - (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* Inserts NUL-terminated string CSTR to the demangled result at - position POS. */ -#define result_insert(DM, POS, CSTR) \ - (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* Inserts character CHAR to the demangled result at position POS. */ -#define result_insert_char(DM, POS, CHAR) \ - (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \ - ? STATUS_OK : STATUS_ALLOCATION_FAILED) - -/* The length of the current demangled result. */ -#define result_length(DM) \ - dyn_string_length (&(DM)->result->string) - -/* Appends a (less-than, greater-than) character to the result in DM - to (open, close) a template argument or parameter list. Appends a - space first if necessary to prevent spurious elision of angle - brackets with the previous character. */ -#define result_open_template_list(DM) result_add_separated_char(DM, '<') -#define result_close_template_list(DM) result_add_separated_char(DM, '>') - -/* Appends a base 10 representation of VALUE to DS. STATUS_OK on - success. On failure, deletes DS and returns an error code. */ - -static status_t -int_to_dyn_string (value, ds) - int value; - dyn_string_t ds; -{ - int i; - int mask = 1; - - /* Handle zero up front. */ - if (value == 0) - { - if (!dyn_string_append_char (ds, '0')) - return STATUS_ALLOCATION_FAILED; - return STATUS_OK; - } - - /* For negative numbers, emit a minus sign. */ - if (value < 0) - { - if (!dyn_string_append_char (ds, '-')) - return STATUS_ALLOCATION_FAILED; - value = -value; - } - - /* Find the power of 10 of the first digit. */ - i = value; - while (i > 9) - { - mask *= 10; - i /= 10; - } - - /* Write the digits. */ - while (mask > 0) - { - int digit = value / mask; - - if (!dyn_string_append_char (ds, '0' + digit)) - return STATUS_ALLOCATION_FAILED; - - value -= digit * mask; - mask /= 10; - } - - return STATUS_OK; -} - -/* Creates a new string list node. The contents of the string are - empty, but the initial buffer allocation is LENGTH. The string - list node should be deleted with string_list_delete. Returns NULL - if allocation fails. */ - -static string_list_t -string_list_new (length) - int length; -{ - string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def)); - s->caret_position = 0; - if (s == NULL) - return NULL; - if (!dyn_string_init ((dyn_string_t) s, length)) - return NULL; - return s; -} - -/* Deletes the entire string list starting at NODE. */ - -static void -string_list_delete (node) - string_list_t node; -{ - while (node != NULL) - { - string_list_t next = node->next; - dyn_string_delete ((dyn_string_t) node); - node = next; - } -} - -/* Appends CHARACTER to the demangled result. If the current trailing - character of the result is CHARACTER, a space is inserted first. */ - -static status_t -result_add_separated_char (dm, character) - demangling_t dm; - int character; -{ - char *result = dyn_string_buf (result_string (dm)); - int caret_pos = result_caret_pos (dm); - - /* Add a space if the last character is already the character we - want to add. */ - if (caret_pos > 0 && result[caret_pos - 1] == character) - RETURN_IF_ERROR (result_add_char (dm, ' ')); - /* Add the character. */ - RETURN_IF_ERROR (result_add_char (dm, character)); - - return STATUS_OK; -} - -/* Allocates and pushes a new string onto the demangled results stack - for DM. Subsequent demangling with DM will emit to the new string. - Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on - allocation failure. */ - -static status_t -result_push (dm) - demangling_t dm; -{ - string_list_t new_string = string_list_new (0); - if (new_string == NULL) - /* Allocation failed. */ - return STATUS_ALLOCATION_FAILED; - - /* Link the new string to the front of the list of result strings. */ - new_string->next = (string_list_t) dm->result; - dm->result = new_string; - return STATUS_OK; -} - -/* Removes and returns the topmost element on the demangled results - stack for DM. The caller assumes ownership for the returned - string. */ - -static string_list_t -result_pop (dm) - demangling_t dm; -{ - string_list_t top = dm->result; - dm->result = top->next; - return top; -} - -/* Returns the current value of the caret for the result string. The - value is an offet from the end of the result string. */ - -static int -result_get_caret (dm) - demangling_t dm; -{ - return ((string_list_t) result_string (dm))->caret_position; -} - -/* Sets the value of the caret for the result string, counted as an - offet from the end of the result string. */ - -static void -result_set_caret (dm, position) - demangling_t dm; - int position; -{ - ((string_list_t) result_string (dm))->caret_position = position; -} - -/* Shifts the position of the next addition to the result by - POSITION_OFFSET. A negative value shifts the caret to the left. */ - -static void -result_shift_caret (dm, position_offset) - demangling_t dm; - int position_offset; -{ - ((string_list_t) result_string (dm))->caret_position += position_offset; -} - -/* Returns non-zero if the character that comes right before the place - where text will be added to the result is a space. In this case, - the caller should suppress adding another space. */ - -static int -result_previous_char_is_space (dm) - demangling_t dm; -{ - char *result = dyn_string_buf (result_string (dm)); - int pos = result_caret_pos (dm); - return pos > 0 && result[pos - 1] == ' '; -} - -/* Returns the start position of a fragment of the demangled result - that will be a substitution candidate. Should be called at the - start of productions that can add substitutions. */ - -static int -substitution_start (dm) - demangling_t dm; -{ - return result_caret_pos (dm); -} - -/* Adds the suffix of the current demangled result of DM starting at - START_POSITION as a potential substitution. If TEMPLATE_P is - non-zero, this potential substitution is a template-id. */ - -static status_t -substitution_add (dm, start_position, template_p) - demangling_t dm; - int start_position; - int template_p; -{ - dyn_string_t result = result_string (dm); - dyn_string_t substitution = dyn_string_new (0); - int i; - - if (substitution == NULL) - return STATUS_ALLOCATION_FAILED; - - /* Extract the substring of the current demangling result that - represents the subsitution candidate. */ - if (!dyn_string_substring (substitution, - result, start_position, result_caret_pos (dm))) - { - dyn_string_delete (substitution); - return STATUS_ALLOCATION_FAILED; - } - - /* If there's no room for the new entry, grow the array. */ - if (dm->substitutions_allocated == dm->num_substitutions) - { - size_t new_array_size; - if (dm->substitutions_allocated > 0) - dm->substitutions_allocated *= 2; - else - dm->substitutions_allocated = 2; - new_array_size = - sizeof (struct substitution_def) * dm->substitutions_allocated; - - dm->substitutions = (struct substitution_def *) - realloc (dm->substitutions, new_array_size); - if (dm->substitutions == NULL) - /* Realloc failed. */ - { - dyn_string_delete (substitution); - return STATUS_ALLOCATION_FAILED; - } - } - - /* Add the substitution to the array. */ - i = dm->num_substitutions++; - dm->substitutions[i].text = substitution; - dm->substitutions[i].template_p = template_p; - -#ifdef CP_DEMANGLE_DEBUG - substitutions_print (dm, stderr); -#endif - - return STATUS_OK; -} - -/* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to - non-zero if the substitution is a template-id, zero otherwise. - N is numbered from zero. DM retains ownership of the returned - string. If N is negative, or equal to or greater than the current - number of substitution candidates, returns NULL. */ - -static dyn_string_t -substitution_get (dm, n, template_p) - demangling_t dm; - int n; - int *template_p; -{ - struct substitution_def *sub; - - /* Make sure N is in the valid range. */ - if (n < 0 || n >= dm->num_substitutions) - return NULL; - - sub = &(dm->substitutions[n]); - *template_p = sub->template_p; - return sub->text; -} - -#ifdef CP_DEMANGLE_DEBUG -/* Debugging routine to print the current substitutions to FP. */ - -static void -substitutions_print (dm, fp) - demangling_t dm; - FILE *fp; -{ - int seq_id; - int num = dm->num_substitutions; - - fprintf (fp, "SUBSTITUTIONS:\n"); - for (seq_id = -1; seq_id < num - 1; ++seq_id) - { - int template_p; - dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p); - - if (seq_id == -1) - fprintf (fp, " S_ "); - else - fprintf (fp, " S%d_", seq_id); - fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text)); - } -} - -#endif /* CP_DEMANGLE_DEBUG */ - -/* Creates a new template argument list. Returns NULL if allocation - fails. */ - -static template_arg_list_t -template_arg_list_new () -{ - template_arg_list_t new_list = - (template_arg_list_t) malloc (sizeof (struct template_arg_list_def)); - if (new_list == NULL) - return NULL; - /* Initialize the new list to have no arguments. */ - new_list->first_argument = NULL; - new_list->last_argument = NULL; - /* Return the new list. */ - return new_list; -} - -/* Deletes a template argument list and the template arguments it - contains. */ - -static void -template_arg_list_delete (list) - template_arg_list_t list; -{ - /* If there are any arguments on LIST, delete them. */ - if (list->first_argument != NULL) - string_list_delete (list->first_argument); - /* Delete LIST. */ - free (list); -} - -/* Adds ARG to the template argument list ARG_LIST. */ - -static void -template_arg_list_add_arg (arg_list, arg) - template_arg_list_t arg_list; - string_list_t arg; -{ - if (arg_list->first_argument == NULL) - /* If there were no arguments before, ARG is the first one. */ - arg_list->first_argument = arg; - else - /* Make ARG the last argument on the list. */ - arg_list->last_argument->next = arg; - /* Make ARG the last on the list. */ - arg_list->last_argument = arg; - arg->next = NULL; -} - -/* Returns the template arugment at position INDEX in template - argument list ARG_LIST. */ - -static string_list_t -template_arg_list_get_arg (arg_list, index) - template_arg_list_t arg_list; - int index; -{ - string_list_t arg = arg_list->first_argument; - /* Scan down the list of arguments to find the one at position - INDEX. */ - while (index--) - { - arg = arg->next; - if (arg == NULL) - /* Ran out of arguments before INDEX hit zero. That's an - error. */ - return NULL; - } - /* Return the argument at position INDEX. */ - return arg; -} - -/* Pushes ARG_LIST onto the top of the template argument list stack. */ - -static void -push_template_arg_list (dm, arg_list) - demangling_t dm; - template_arg_list_t arg_list; -{ - arg_list->next = dm->template_arg_lists; - dm->template_arg_lists = arg_list; -#ifdef CP_DEMANGLE_DEBUG - fprintf (stderr, " ** pushing template arg list\n"); - template_arg_list_print (arg_list, stderr); -#endif -} - -/* Pops and deletes elements on the template argument list stack until - arg_list is the topmost element. If arg_list is NULL, all elements - are popped and deleted. */ - -static void -pop_to_template_arg_list (dm, arg_list) - demangling_t dm; - template_arg_list_t arg_list; -{ - while (dm->template_arg_lists != arg_list) - { - template_arg_list_t top = dm->template_arg_lists; - /* Disconnect the topmost element from the list. */ - dm->template_arg_lists = top->next; - /* Delete the popped element. */ - template_arg_list_delete (top); -#ifdef CP_DEMANGLE_DEBUG - fprintf (stderr, " ** removing template arg list\n"); -#endif - } -} - -#ifdef CP_DEMANGLE_DEBUG - -/* Prints the contents of ARG_LIST to FP. */ - -static void -template_arg_list_print (arg_list, fp) - template_arg_list_t arg_list; - FILE *fp; -{ - string_list_t arg; - int index = -1; - - fprintf (fp, "TEMPLATE ARGUMENT LIST:\n"); - for (arg = arg_list->first_argument; arg != NULL; arg = arg->next) - { - if (index == -1) - fprintf (fp, " T_ : "); - else - fprintf (fp, " T%d_ : ", index); - ++index; - fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg)); - } -} - -#endif /* CP_DEMANGLE_DEBUG */ - -/* Returns the topmost element on the stack of template argument - lists. If there is no list of template arguments, returns NULL. */ - -static template_arg_list_t -current_template_arg_list (dm) - demangling_t dm; -{ - return dm->template_arg_lists; -} - -/* Allocates a demangling_t object for demangling mangled NAME. A new - result must be pushed before the returned object can be used. - Returns NULL if allocation fails. */ - -static demangling_t -demangling_new (name, style) - const char *name; - int style; -{ - demangling_t dm; - dm = (demangling_t) malloc (sizeof (struct demangling_def)); - if (dm == NULL) - return NULL; - - dm->name = name; - dm->next = name; - dm->result = NULL; - dm->num_substitutions = 0; - dm->substitutions_allocated = 10; - dm->template_arg_lists = NULL; - dm->last_source_name = dyn_string_new (0); - if (dm->last_source_name == NULL) - return NULL; - dm->substitutions = (struct substitution_def *) - malloc (dm->substitutions_allocated * sizeof (struct substitution_def)); - if (dm->substitutions == NULL) - { - dyn_string_delete (dm->last_source_name); - return NULL; - } - dm->style = style; - dm->is_constructor = 0; - dm->is_destructor = 0; - - return dm; -} - -/* Deallocates a demangling_t object and all memory associated with - it. */ - -static void -demangling_delete (dm) - demangling_t dm; -{ - int i; - template_arg_list_t arg_list = dm->template_arg_lists; - - /* Delete the stack of template argument lists. */ - while (arg_list != NULL) - { - template_arg_list_t next = arg_list->next; - template_arg_list_delete (arg_list); - arg_list = next; - } - /* Delete the list of substitutions. */ - for (i = dm->num_substitutions; --i >= 0; ) - dyn_string_delete (dm->substitutions[i].text); - free (dm->substitutions); - /* Delete the demangled result. */ - string_list_delete (dm->result); - /* Delete the stored identifier name. */ - dyn_string_delete (dm->last_source_name); - /* Delete the context object itself. */ - free (dm); -} - -/* These functions demangle an alternative of the corresponding - production in the mangling spec. The first argument of each is a - demangling context structure for the current demangling - operation. Most emit demangled text directly to the topmost result - string on the result string stack in the demangling context - structure. */ - -static status_t demangle_char - PARAMS ((demangling_t, int)); -static status_t demangle_mangled_name - PARAMS ((demangling_t)); -static status_t demangle_encoding - PARAMS ((demangling_t)); -static status_t demangle_name - PARAMS ((demangling_t, int *)); -static status_t demangle_nested_name - PARAMS ((demangling_t, int *)); -static status_t demangle_prefix_v3 - PARAMS ((demangling_t, int *)); -static status_t demangle_unqualified_name - PARAMS ((demangling_t, int *)); -static status_t demangle_source_name - PARAMS ((demangling_t)); -static status_t demangle_number - PARAMS ((demangling_t, int *, int, int)); -static status_t demangle_number_literally - PARAMS ((demangling_t, dyn_string_t, int, int)); -static status_t demangle_identifier - PARAMS ((demangling_t, int, dyn_string_t)); -static status_t demangle_operator_name - PARAMS ((demangling_t, int, int *)); -static status_t demangle_nv_offset - PARAMS ((demangling_t)); -static status_t demangle_v_offset - PARAMS ((demangling_t)); -static status_t demangle_call_offset - PARAMS ((demangling_t)); -static status_t demangle_special_name - PARAMS ((demangling_t)); -static status_t demangle_ctor_dtor_name - PARAMS ((demangling_t)); -static status_t demangle_type_ptr - PARAMS ((demangling_t, int *, int)); -static status_t demangle_type - PARAMS ((demangling_t)); -static status_t demangle_CV_qualifiers - PARAMS ((demangling_t, dyn_string_t)); -static status_t demangle_builtin_type - PARAMS ((demangling_t)); -static status_t demangle_function_type - PARAMS ((demangling_t, int *)); -static status_t demangle_bare_function_type - PARAMS ((demangling_t, int *)); -static status_t demangle_class_enum_type - PARAMS ((demangling_t, int *)); -static status_t demangle_array_type - PARAMS ((demangling_t, int *)); -static status_t demangle_template_param - PARAMS ((demangling_t)); -static status_t demangle_template_args_1 - PARAMS ((demangling_t, template_arg_list_t)); -static status_t demangle_template_args - PARAMS ((demangling_t)); -static status_t demangle_literal - PARAMS ((demangling_t)); -static status_t demangle_template_arg - PARAMS ((demangling_t)); -static status_t demangle_expression_v3 - PARAMS ((demangling_t)); -static status_t demangle_scope_expression - PARAMS ((demangling_t)); -static status_t demangle_expr_primary - PARAMS ((demangling_t)); -static status_t demangle_substitution - PARAMS ((demangling_t, int *)); -static status_t demangle_local_name - PARAMS ((demangling_t)); -static status_t demangle_discriminator - PARAMS ((demangling_t, int)); -static status_t cp_demangle - PARAMS ((const char *, dyn_string_t, int)); -#ifdef IN_LIBGCC2 -static status_t cp_demangle_type - PARAMS ((const char*, dyn_string_t)); -#endif - -/* When passed to demangle_bare_function_type, indicates that the - function's return type is not encoded before its parameter types. */ -#define BFT_NO_RETURN_TYPE NULL - -/* Check that the next character is C. If so, consume it. If not, - return an error. */ - -static status_t -demangle_char (dm, c) - demangling_t dm; - int c; -{ - static char *error_message = NULL; - - if (peek_char (dm) == c) - { - advance_char (dm); - return STATUS_OK; - } - else - { - vg_assert (0); - /* - if (error_message == NULL) - error_message = strdup ("Expected ?"); - error_message[9] = c; - return error_message; - */ - } -} - -/* Demangles and emits a . - - ::= _Z */ - -static status_t -demangle_mangled_name (dm) - demangling_t dm; -{ - DEMANGLE_TRACE ("mangled-name", dm); - RETURN_IF_ERROR (demangle_char (dm, '_')); - RETURN_IF_ERROR (demangle_char (dm, 'Z')); - RETURN_IF_ERROR (demangle_encoding (dm)); - return STATUS_OK; -} - -/* Demangles and emits an . - - ::= - ::= - ::= */ - -static status_t -demangle_encoding (dm) - demangling_t dm; -{ - int encode_return_type; - int start_position; - template_arg_list_t old_arg_list = current_template_arg_list (dm); - char peek = peek_char (dm); - - DEMANGLE_TRACE ("encoding", dm); - - /* Remember where the name starts. If it turns out to be a template - function, we'll have to insert the return type here. */ - start_position = result_caret_pos (dm); - - if (peek == 'G' || peek == 'T') - RETURN_IF_ERROR (demangle_special_name (dm)); - else - { - /* Now demangle the name. */ - RETURN_IF_ERROR (demangle_name (dm, &encode_return_type)); - - /* If there's anything left, the name was a function name, with - maybe its return type, and its parameter types, following. */ - if (!end_of_name_p (dm) - && peek_char (dm) != 'E') - { - if (encode_return_type) - /* Template functions have their return type encoded. The - return type should be inserted at start_position. */ - RETURN_IF_ERROR - (demangle_bare_function_type (dm, &start_position)); - else - /* Non-template functions don't have their return type - encoded. */ - RETURN_IF_ERROR - (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE)); - } - } - - /* Pop off template argument lists that were built during the - mangling of this name, to restore the old template context. */ - pop_to_template_arg_list (dm, old_arg_list); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= - ::= - ::= - ::= - - ::= - ::= St # ::std:: - - - ::= - ::= */ - -static status_t -demangle_name (dm, encode_return_type) - demangling_t dm; - int *encode_return_type; -{ - int start = substitution_start (dm); - char peek = peek_char (dm); - int is_std_substitution = 0; - - /* Generally, the return type is encoded if the function is a - template-id, and suppressed otherwise. There are a few cases, - though, in which the return type is not encoded even for a - templated function. In these cases, this flag is set. */ - int suppress_return_type = 0; - - DEMANGLE_TRACE ("name", dm); - - switch (peek) - { - case 'N': - /* This is a . */ - RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type)); - break; - - case 'Z': - RETURN_IF_ERROR (demangle_local_name (dm)); - *encode_return_type = 0; - break; - - case 'S': - /* The `St' substitution allows a name nested in std:: to appear - without being enclosed in a nested name. */ - if (peek_char_next (dm) == 't') - { - (void) next_char (dm); - (void) next_char (dm); - RETURN_IF_ERROR (result_add (dm, "std::")); - RETURN_IF_ERROR - (demangle_unqualified_name (dm, &suppress_return_type)); - is_std_substitution = 1; - } - else - RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type)); - /* Check if a template argument list immediately follows. - If so, then we just demangled an . */ - if (peek_char (dm) == 'I') - { - /* A template name of the form std:: is a - substitution candidate. */ - if (is_std_substitution) - RETURN_IF_ERROR (substitution_add (dm, start, 0)); - /* Demangle the here. */ - RETURN_IF_ERROR (demangle_template_args (dm)); - *encode_return_type = !suppress_return_type; - } - else - *encode_return_type = 0; - - break; - - default: - /* This is an or . */ - RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type)); - - /* If the is followed by template args, this - is an . */ - if (peek_char (dm) == 'I') - { - /* Add a substitution for the unqualified template name. */ - RETURN_IF_ERROR (substitution_add (dm, start, 0)); - - RETURN_IF_ERROR (demangle_template_args (dm)); - *encode_return_type = !suppress_return_type; - } - else - *encode_return_type = 0; - - break; - } - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= N [] E */ - -static status_t -demangle_nested_name (dm, encode_return_type) - demangling_t dm; - int *encode_return_type; -{ - char peek; - - DEMANGLE_TRACE ("nested-name", dm); - - RETURN_IF_ERROR (demangle_char (dm, 'N')); - - peek = peek_char (dm); - if (peek == 'r' || peek == 'V' || peek == 'K') - { - dyn_string_t cv_qualifiers; - status_t status; - - /* Snarf up CV qualifiers. */ - cv_qualifiers = dyn_string_new (24); - if (cv_qualifiers == NULL) - return STATUS_ALLOCATION_FAILED; - demangle_CV_qualifiers (dm, cv_qualifiers); - - /* Emit them, preceded by a space. */ - status = result_add_char (dm, ' '); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, cv_qualifiers); - /* The CV qualifiers that occur in a will be - qualifiers for member functions. These are placed at the end - of the function. Therefore, shift the caret to the left by - the length of the qualifiers, so other text is inserted - before them and they stay at the end. */ - result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1); - /* Clean up. */ - dyn_string_delete (cv_qualifiers); - RETURN_IF_ERROR (status); - } - - RETURN_IF_ERROR (demangle_prefix_v3 (dm, encode_return_type)); - /* No need to demangle the final ; demangle_prefix - will handle it. */ - RETURN_IF_ERROR (demangle_char (dm, 'E')); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= - ::= - ::= # empty - ::= - - ::= - ::= */ - -static status_t -demangle_prefix_v3 (dm, encode_return_type) - demangling_t dm; - int *encode_return_type; -{ - int start = substitution_start (dm); - int nested = 0; - - /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain. - After , it is set to non-zero; after everything - else it is set to zero. */ - - /* Generally, the return type is encoded if the function is a - template-id, and suppressed otherwise. There are a few cases, - though, in which the return type is not encoded even for a - templated function. In these cases, this flag is set. */ - int suppress_return_type = 0; - - DEMANGLE_TRACE ("prefix", dm); - - while (1) - { - char peek; - - if (end_of_name_p (dm)) - return "Unexpected end of name in ."; - - peek = peek_char (dm); - - /* We'll initialize suppress_return_type to false, and set it to true - if we end up demangling a constructor name. However, make - sure we're not actually about to demangle template arguments - -- if so, this is the following a - , so we'll want the previous flag value - around. */ - if (peek != 'I') - suppress_return_type = 0; - - if (IS_DIGIT ((unsigned char) peek) - || (peek >= 'a' && peek <= 'z') - || peek == 'C' || peek == 'D' - || peek == 'S') - { - /* We have another level of scope qualification. */ - if (nested) - RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR)); - else - nested = 1; - - if (peek == 'S') - /* The substitution determines whether this is a - template-id. */ - RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type)); - else - { - /* It's just a name. */ - RETURN_IF_ERROR - (demangle_unqualified_name (dm, &suppress_return_type)); - *encode_return_type = 0; - } - } - else if (peek == 'Z') - RETURN_IF_ERROR (demangle_local_name (dm)); - else if (peek == 'I') - { - RETURN_IF_ERROR (demangle_template_args (dm)); - - /* Now we want to indicate to the caller that we've - demangled template arguments, thus the prefix was a - . That's so that the caller knows to - demangle the function's return type, if this turns out to - be a function name. But, if it's a member template - constructor or a templated conversion operator, report it - as untemplated. Those never get encoded return types. */ - *encode_return_type = !suppress_return_type; - } - else if (peek == 'E') - /* All done. */ - return STATUS_OK; - else - return "Unexpected character in ."; - - if (peek != 'S' - && peek_char (dm) != 'E') - /* Add a new substitution for the prefix thus far. */ - RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type)); - } -} - -/* Demangles and emits an . If this - is for a special function type that should never - have its return type encoded (particularly, a constructor or - conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise, - it is set to zero. - - ::= - ::= - ::= */ - -static status_t -demangle_unqualified_name (dm, suppress_return_type) - demangling_t dm; - int *suppress_return_type; -{ - char peek = peek_char (dm); - - DEMANGLE_TRACE ("unqualified-name", dm); - - /* By default, don't force suppression of the return type (though - non-template functions still don't get a return type encoded). */ - *suppress_return_type = 0; - - if (IS_DIGIT ((unsigned char) peek)) - RETURN_IF_ERROR (demangle_source_name (dm)); - else if (peek >= 'a' && peek <= 'z') - { - int num_args; - - /* Conversion operators never have a return type encoded. */ - if (peek == 'c' && peek_char_next (dm) == 'v') - *suppress_return_type = 1; - - RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args)); - } - else if (peek == 'C' || peek == 'D') - { - /* Constructors never have a return type encoded. */ - if (peek == 'C') - *suppress_return_type = 1; - - RETURN_IF_ERROR (demangle_ctor_dtor_name (dm)); - } - else - return "Unexpected character in ."; - - return STATUS_OK; -} - -/* Demangles and emits . - - ::= */ - -static status_t -demangle_source_name (dm) - demangling_t dm; -{ - int length; - - DEMANGLE_TRACE ("source-name", dm); - - /* Decode the length of the identifier. */ - RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0)); - if (length == 0) - return "Zero length in ."; - - /* Now the identifier itself. It's placed into last_source_name, - where it can be used to build a constructor or destructor name. */ - RETURN_IF_ERROR (demangle_identifier (dm, length, - dm->last_source_name)); - - /* Emit it. */ - RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name)); - - return STATUS_OK; -} - -/* Demangles a number, either a or a at the - current position, consuming all consecutive digit characters. Sets - *VALUE to the resulting numberand returns STATUS_OK. The number is - interpreted as BASE, which must be either 10 or 36. If IS_SIGNED - is non-zero, negative numbers -- prefixed with `n' -- are accepted. - - ::= [n] - - ::= */ - -static status_t -demangle_number (dm, value, base, is_signed) - demangling_t dm; - int *value; - int base; - int is_signed; -{ - dyn_string_t number = dyn_string_new (10); - - DEMANGLE_TRACE ("number", dm); - - if (number == NULL) - return STATUS_ALLOCATION_FAILED; - - demangle_number_literally (dm, number, base, is_signed); - /* - *value = strtol (dyn_string_buf (number), NULL, base); - */ - /* vg_assert( base == 10 ); */ - if ( base != 10 && base != 36 ) { - dyn_string_delete(number); - return STATUS_UNIMPLEMENTED; - } - - if (base == 36) { - *value = VG_(atoll36) (36, dyn_string_buf (number)); - } else { - *value = VG_(atoll) (dyn_string_buf (number)); - } - dyn_string_delete (number); - - return STATUS_OK; -} - -/* Demangles a number at the current position. The digits (and minus - sign, if present) that make up the number are appended to STR. - Only base-BASE digits are accepted; BASE must be either 10 or 36. - If IS_SIGNED, negative numbers -- prefixed with `n' -- are - accepted. Does not consume a trailing underscore or other - terminating character. */ - -static status_t -demangle_number_literally (dm, str, base, is_signed) - demangling_t dm; - dyn_string_t str; - int base; - int is_signed; -{ - DEMANGLE_TRACE ("number*", dm); - - if (base != 10 && base != 36) - return STATUS_INTERNAL_ERROR; - - /* An `n' denotes a negative number. */ - if (is_signed && peek_char (dm) == 'n') - { - /* Skip past the n. */ - advance_char (dm); - /* The normal way to write a negative number is with a minus - sign. */ - if (!dyn_string_append_char (str, '-')) - return STATUS_ALLOCATION_FAILED; - } - - /* Loop until we hit a non-digit. */ - while (1) - { - char peek = peek_char (dm); - if (IS_DIGIT ((unsigned char) peek) - || (base == 36 && peek >= 'A' && peek <= 'Z')) - { - /* Accumulate digits. */ - if (!dyn_string_append_char (str, next_char (dm))) - return STATUS_ALLOCATION_FAILED; - } - else - /* Not a digit? All done. */ - break; - } - - return STATUS_OK; -} - -/* Demangles an identifier at the current position of LENGTH - characters and places it in IDENTIFIER. */ - -static status_t -demangle_identifier (dm, length, identifier) - demangling_t dm; - int length; - dyn_string_t identifier; -{ - DEMANGLE_TRACE ("identifier", dm); - - dyn_string_clear (identifier); - if (!dyn_string_resize (identifier, length)) - return STATUS_ALLOCATION_FAILED; - - while (length-- > 0) - { - if (end_of_name_p (dm)) - return "Unexpected end of name in ."; - if (!dyn_string_append_char (identifier, next_char (dm))) - return STATUS_ALLOCATION_FAILED; - } - - /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.' - followed by the source file name and some random characters. - Unless we're in strict mode, decipher these names appropriately. */ - if (!flag_strict) - { - char *name = dyn_string_buf (identifier); - int prefix_length = VG_(strlen) (ANONYMOUS_NAMESPACE_PREFIX); - - /* Compare the first, fixed part. */ - if (VG_(strncmp) (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0) - { - name += prefix_length; - /* The next character might be a period, an underscore, or - dollar sign, depending on the target architecture's - assembler's capabilities. After that comes an `N'. */ - if ((*name == '.' || *name == '_' || *name == '$') - && *(name + 1) == 'N') - /* This looks like the anonymous namespace identifier. - Replace it with something comprehensible. */ - dyn_string_copy_cstr (identifier, "(anonymous namespace)"); - } - } - - return STATUS_OK; -} - -/* Demangles and emits an . If SHORT_NAME is non-zero, - the short form is emitted; otherwise the full source form - (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of - operands that the operator takes. - - - ::= nw # new - ::= na # new[] - ::= dl # delete - ::= da # delete[] - ::= ps # + (unary) - ::= ng # - (unary) - ::= ad # & (unary) - ::= de # * (unary) - ::= co # ~ - ::= pl # + - ::= mi # - - ::= ml # * - ::= dv # / - ::= rm # % - ::= an # & - ::= or # | - ::= eo # ^ - ::= aS # = - ::= pL # += - ::= mI # -= - ::= mL # *= - ::= dV # /= - ::= rM # %= - ::= aN # &= - ::= oR # |= - ::= eO # ^= - ::= ls # << - ::= rs # >> - ::= lS # <<= - ::= rS # >>= - ::= eq # == - ::= ne # != - ::= lt # < - ::= gt # > - ::= le # <= - ::= ge # >= - ::= nt # ! - ::= aa # && - ::= oo # || - ::= pp # ++ - ::= mm # -- - ::= cm # , - ::= pm # ->* - ::= pt # -> - ::= cl # () - ::= ix # [] - ::= qu # ? - ::= sz # sizeof - ::= cv # cast - ::= v [0-9] # vendor extended operator */ - -static status_t -demangle_operator_name (dm, short_name, num_args) - demangling_t dm; - int short_name; - int *num_args; -{ - struct operator_code - { - /* The mangled code for this operator. */ - const char *const code; - /* The source name of this operator. */ - const char *const name; - /* The number of arguments this operator takes. */ - const int num_args; - }; - - static const struct operator_code operators[] = - { - { "aN", "&=" , 2 }, - { "aS", "=" , 2 }, - { "aa", "&&" , 2 }, - { "ad", "&" , 1 }, - { "an", "&" , 2 }, - { "cl", "()" , 0 }, - { "cm", "," , 2 }, - { "co", "~" , 1 }, - { "dV", "/=" , 2 }, - { "da", " delete[]", 1 }, - { "de", "*" , 1 }, - { "dl", " delete" , 1 }, - { "dv", "/" , 2 }, - { "eO", "^=" , 2 }, - { "eo", "^" , 2 }, - { "eq", "==" , 2 }, - { "ge", ">=" , 2 }, - { "gt", ">" , 2 }, - { "ix", "[]" , 2 }, - { "lS", "<<=" , 2 }, - { "le", "<=" , 2 }, - { "ls", "<<" , 2 }, - { "lt", "<" , 2 }, - { "mI", "-=" , 2 }, - { "mL", "*=" , 2 }, - { "mi", "-" , 2 }, - { "ml", "*" , 2 }, - { "mm", "--" , 1 }, - { "na", " new[]" , 1 }, - { "ne", "!=" , 2 }, - { "ng", "-" , 1 }, - { "nt", "!" , 1 }, - { "nw", " new" , 1 }, - { "oR", "|=" , 2 }, - { "oo", "||" , 2 }, - { "or", "|" , 2 }, - { "pL", "+=" , 2 }, - { "pl", "+" , 2 }, - { "pm", "->*" , 2 }, - { "pp", "++" , 1 }, - { "ps", "+" , 1 }, - { "pt", "->" , 2 }, - { "qu", "?" , 3 }, - { "rM", "%=" , 2 }, - { "rS", ">>=" , 2 }, - { "rm", "%" , 2 }, - { "rs", ">>" , 2 }, - { "sz", " sizeof" , 1 } - }; - - const int num_operators = - sizeof (operators) / sizeof (struct operator_code); - - int c0 = next_char (dm); - int c1 = next_char (dm); - const struct operator_code* p1 = operators; - const struct operator_code* p2 = operators + num_operators; - - DEMANGLE_TRACE ("operator-name", dm); - - /* Is this a vendor-extended operator? */ - if (c0 == 'v' && IS_DIGIT (c1)) - { - RETURN_IF_ERROR (result_add (dm, "operator ")); - RETURN_IF_ERROR (demangle_source_name (dm)); - *num_args = 0; - return STATUS_OK; - } - - /* Is this a conversion operator? */ - if (c0 == 'c' && c1 == 'v') - { - RETURN_IF_ERROR (result_add (dm, "operator ")); - /* Demangle the converted-to type. */ - RETURN_IF_ERROR (demangle_type (dm)); - *num_args = 0; - return STATUS_OK; - } - - /* Perform a binary search for the operator code. */ - while (1) - { - const struct operator_code* p = p1 + (p2 - p1) / 2; - char match0 = p->code[0]; - char match1 = p->code[1]; - - if (c0 == match0 && c1 == match1) - /* Found it. */ - { - if (!short_name) - RETURN_IF_ERROR (result_add (dm, "operator")); - RETURN_IF_ERROR (result_add (dm, p->name)); - *num_args = p->num_args; - - return STATUS_OK; - } - - if (p == p1) - /* Couldn't find it. */ - return "Unknown code in ."; - - /* Try again. */ - if (c0 < match0 || (c0 == match0 && c1 < match1)) - p2 = p; - else - p1 = p; - } -} - -/* Demangles and omits an . - - ::= # non-virtual base override */ - -static status_t -demangle_nv_offset (dm) - demangling_t dm; -{ - dyn_string_t number; - status_t status = STATUS_OK; - - DEMANGLE_TRACE ("h-offset", dm); - - /* Demangle the offset. */ - number = dyn_string_new (4); - if (number == NULL) - return STATUS_ALLOCATION_FAILED; - demangle_number_literally (dm, number, 10, 1); - - /* Don't display the offset unless in verbose mode. */ - if (flag_verbose) - { - status = result_add (dm, " [nv:"); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, number); - if (STATUS_NO_ERROR (status)) - status = result_add_char (dm, ']'); - } - - /* Clean up. */ - dyn_string_delete (number); - RETURN_IF_ERROR (status); - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= _ - # virtual base override, with vcall offset */ - -static status_t -demangle_v_offset (dm) - demangling_t dm; -{ - dyn_string_t number; - status_t status = STATUS_OK; - - DEMANGLE_TRACE ("v-offset", dm); - - /* Demangle the offset. */ - number = dyn_string_new (4); - if (number == NULL) - return STATUS_ALLOCATION_FAILED; - demangle_number_literally (dm, number, 10, 1); - - /* Don't display the offset unless in verbose mode. */ - if (flag_verbose) - { - status = result_add (dm, " [v:"); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, number); - if (STATUS_NO_ERROR (status)) - result_add_char (dm, ','); - } - dyn_string_delete (number); - RETURN_IF_ERROR (status); - - /* Demangle the separator. */ - RETURN_IF_ERROR (demangle_char (dm, '_')); - - /* Demangle the vcall offset. */ - number = dyn_string_new (4); - if (number == NULL) - return STATUS_ALLOCATION_FAILED; - demangle_number_literally (dm, number, 10, 1); - - /* Don't display the vcall offset unless in verbose mode. */ - if (flag_verbose) - { - status = result_add_string (dm, number); - if (STATUS_NO_ERROR (status)) - status = result_add_char (dm, ']'); - } - dyn_string_delete (number); - RETURN_IF_ERROR (status); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= h _ - ::= v _ */ - -static status_t -demangle_call_offset (dm) - demangling_t dm; -{ - DEMANGLE_TRACE ("call-offset", dm); - - switch (peek_char (dm)) - { - case 'h': - advance_char (dm); - /* Demangle the offset. */ - RETURN_IF_ERROR (demangle_nv_offset (dm)); - /* Demangle the separator. */ - RETURN_IF_ERROR (demangle_char (dm, '_')); - break; - - case 'v': - advance_char (dm); - /* Demangle the offset. */ - RETURN_IF_ERROR (demangle_v_offset (dm)); - /* Demangle the separator. */ - RETURN_IF_ERROR (demangle_char (dm, '_')); - break; - - default: - return "Unrecognized ."; - } - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= GV # Guard variable - ::= TV # virtual table - ::= TT # VTT - ::= TI # typeinfo structure - ::= TS # typeinfo name - - Other relevant productions include thunks: - - ::= T - # base is the nominal target function of thunk - - ::= Tc - # base is the nominal target function of thunk - # first call-offset is 'this' adjustment - # second call-offset is result adjustment - - where - - ::= h _ - ::= v _ - - Also demangles the special g++ manglings, - - ::= TC _ - # construction vtable - ::= TF # typeinfo function (old ABI only) - ::= TJ # java Class structure */ - -static status_t -demangle_special_name (dm) - demangling_t dm; -{ - dyn_string_t number; - int unused; - char peek = peek_char (dm); - - DEMANGLE_TRACE ("special-name", dm); - - if (peek == 'G') - { - /* Consume the G. */ - advance_char (dm); - switch (peek_char (dm)) - { - case 'V': - /* A guard variable name. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "guard variable for ")); - RETURN_IF_ERROR (demangle_name (dm, &unused)); - break; - - case 'R': - /* A reference temporary. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "reference temporary for ")); - RETURN_IF_ERROR (demangle_name (dm, &unused)); - break; - - default: - return "Unrecognized ."; - } - } - else if (peek == 'T') - { - status_t status = STATUS_OK; - - /* Other C++ implementation miscellania. Consume the T. */ - advance_char (dm); - - switch (peek_char (dm)) - { - case 'V': - /* Virtual table. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "vtable for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'T': - /* VTT structure. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "VTT for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'I': - /* Typeinfo structure. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "typeinfo for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'F': - /* Typeinfo function. Used only in old ABI with new mangling. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "typeinfo fn for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'S': - /* Character string containing type name, used in typeinfo. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "typeinfo name for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'J': - /* The java Class variable corresponding to a C++ class. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "java Class for ")); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'h': - /* Non-virtual thunk. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "non-virtual thunk")); - RETURN_IF_ERROR (demangle_nv_offset (dm)); - /* Demangle the separator. */ - RETURN_IF_ERROR (demangle_char (dm, '_')); - /* Demangle and emit the target name and function type. */ - RETURN_IF_ERROR (result_add (dm, " to ")); - RETURN_IF_ERROR (demangle_encoding (dm)); - break; - - case 'v': - /* Virtual thunk. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "virtual thunk")); - RETURN_IF_ERROR (demangle_v_offset (dm)); - /* Demangle the separator. */ - RETURN_IF_ERROR (demangle_char (dm, '_')); - /* Demangle and emit the target function. */ - RETURN_IF_ERROR (result_add (dm, " to ")); - RETURN_IF_ERROR (demangle_encoding (dm)); - break; - - case 'c': - /* Covariant return thunk. */ - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "covariant return thunk")); - RETURN_IF_ERROR (demangle_call_offset (dm)); - RETURN_IF_ERROR (demangle_call_offset (dm)); - /* Demangle and emit the target function. */ - RETURN_IF_ERROR (result_add (dm, " to ")); - RETURN_IF_ERROR (demangle_encoding (dm)); - break; - - case 'C': - /* TC is a special g++ mangling for a construction vtable. */ - if (!flag_strict) - { - dyn_string_t derived_type; - - advance_char (dm); - RETURN_IF_ERROR (result_add (dm, "construction vtable for ")); - - /* Demangle the derived type off to the side. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_type (dm)); - derived_type = (dyn_string_t) result_pop (dm); - - /* Demangle the offset. */ - number = dyn_string_new (4); - if (number == NULL) - { - dyn_string_delete (derived_type); - return STATUS_ALLOCATION_FAILED; - } - demangle_number_literally (dm, number, 10, 1); - /* Demangle the underscore separator. */ - status = demangle_char (dm, '_'); - - /* Demangle the base type. */ - if (STATUS_NO_ERROR (status)) - status = demangle_type (dm); - - /* Emit the derived type. */ - if (STATUS_NO_ERROR (status)) - status = result_add (dm, "-in-"); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, derived_type); - dyn_string_delete (derived_type); - - /* Don't display the offset unless in verbose mode. */ - if (flag_verbose) - { - status = result_add_char (dm, ' '); - if (STATUS_NO_ERROR (status)) - result_add_string (dm, number); - } - dyn_string_delete (number); - RETURN_IF_ERROR (status); - break; - } - /* If flag_strict, fall through. */ - - default: - return "Unrecognized ."; - } - } - else - return STATUS_ERROR; - - return STATUS_OK; -} - -/* Demangles and emits a . - - - ::= C1 # complete object (in-charge) ctor - ::= C2 # base object (not-in-charge) ctor - ::= C3 # complete object (in-charge) allocating ctor - ::= D0 # deleting (in-charge) dtor - ::= D1 # complete object (in-charge) dtor - ::= D2 # base object (not-in-charge) dtor */ - -static status_t -demangle_ctor_dtor_name (dm) - demangling_t dm; -{ - static const char *const ctor_flavors[] = - { - "in-charge", - "not-in-charge", - "allocating" - }; - static const char *const dtor_flavors[] = - { - "in-charge deleting", - "in-charge", - "not-in-charge" - }; - - int flavor; - char peek = peek_char (dm); - - DEMANGLE_TRACE ("ctor-dtor-name", dm); - - if (peek == 'C') - { - /* A constructor name. Consume the C. */ - advance_char (dm); - flavor = next_char (dm); - if (flavor < '1' || flavor > '3') - return "Unrecognized constructor."; - RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name)); - switch (flavor) - { - case '1': dm->is_constructor = gnu_v3_complete_object_ctor; - break; - case '2': dm->is_constructor = gnu_v3_base_object_ctor; - break; - case '3': dm->is_constructor = gnu_v3_complete_object_allocating_ctor; - break; - } - /* Print the flavor of the constructor if in verbose mode. */ - if (flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, "[")); - RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor - '1'])); - RETURN_IF_ERROR (result_add_char (dm, ']')); - } - } - else if (peek == 'D') - { - /* A destructor name. Consume the D. */ - advance_char (dm); - flavor = next_char (dm); - if (flavor < '0' || flavor > '2') - return "Unrecognized destructor."; - RETURN_IF_ERROR (result_add_char (dm, '~')); - RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name)); - switch (flavor) - { - case '0': dm->is_destructor = gnu_v3_deleting_dtor; - break; - case '1': dm->is_destructor = gnu_v3_complete_object_dtor; - break; - case '2': dm->is_destructor = gnu_v3_base_object_dtor; - break; - } - /* Print the flavor of the destructor if in verbose mode. */ - if (flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, " [")); - RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor - '0'])); - RETURN_IF_ERROR (result_add_char (dm, ']')); - } - } - else - return STATUS_ERROR; - - return STATUS_OK; -} - -/* Handle pointer, reference, and pointer-to-member cases for - demangle_type. All consecutive `P's, `R's, and 'M's are joined to - build a pointer/reference type. We snarf all these, plus the - following , all at once since we need to know whether we have - a pointer to data or pointer to function to construct the right - output syntax. C++'s pointer syntax is hairy. - - This function adds substitution candidates for every nested - pointer/reference type it processes, including the outermost, final - type, assuming the substitution starts at SUBSTITUTION_START in the - demangling result. For example, if this function demangles - `PP3Foo', it will add a substitution for `Foo', `Foo*', and - `Foo**', in that order. - - *INSERT_POS is a quantity used internally, when this function calls - itself recursively, to figure out where to insert pointer - punctuation on the way up. On entry to this function, INSERT_POS - should point to a temporary value, but that value need not be - initialized. - - ::= P - ::= R - ::= - - ::= M */ - -static status_t -demangle_type_ptr (dm, insert_pos, substitution_start) - demangling_t dm; - int *insert_pos; - int substitution_start; -{ - status_t status; - int is_substitution_candidate = 1; - - DEMANGLE_TRACE ("type*", dm); - - /* Scan forward, collecting pointers and references into symbols, - until we hit something else. Then emit the type. */ - switch (peek_char (dm)) - { - case 'P': - /* A pointer. Snarf the `P'. */ - advance_char (dm); - /* Demangle the underlying type. */ - RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, - substitution_start)); - /* Insert an asterisk where we're told to; it doesn't - necessarily go at the end. If we're doing Java style output, - there is no pointer symbol. */ - if (dm->style != DMGL_JAVA) - RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*')); - /* The next (outermost) pointer or reference character should go - after this one. */ - ++(*insert_pos); - break; - - case 'R': - /* A reference. Snarf the `R'. */ - advance_char (dm); - /* Demangle the underlying type. */ - RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, - substitution_start)); - /* Insert an ampersand where we're told to; it doesn't - necessarily go at the end. */ - RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&')); - /* The next (outermost) pointer or reference character should go - after this one. */ - ++(*insert_pos); - break; - - case 'M': - { - /* A pointer-to-member. */ - dyn_string_t class_type; - - /* Eat the 'M'. */ - advance_char (dm); - - /* Capture the type of which this is a pointer-to-member. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_type (dm)); - class_type = (dyn_string_t) result_pop (dm); - - if (peek_char (dm) == 'F') - /* A pointer-to-member function. We want output along the - lines of `void (C::*) (int, int)'. Demangle the function - type, which would in this case give `void () (int, int)' - and set *insert_pos to the spot between the first - parentheses. */ - status = demangle_type_ptr (dm, insert_pos, substitution_start); - else if (peek_char (dm) == 'A') - /* A pointer-to-member array variable. We want output that - looks like `int (Klass::*) [10]'. Demangle the array type - as `int () [10]', and set *insert_pos to the spot between - the parentheses. */ - status = demangle_array_type (dm, insert_pos); - else - { - /* A pointer-to-member variable. Demangle the type of the - pointed-to member. */ - status = demangle_type (dm); - /* Make it pretty. */ - if (STATUS_NO_ERROR (status) - && !result_previous_char_is_space (dm)) - status = result_add_char (dm, ' '); - /* The pointer-to-member notation (e.g. `C::*') follows the - member's type. */ - *insert_pos = result_caret_pos (dm); - } - - /* Build the pointer-to-member notation. */ - if (STATUS_NO_ERROR (status)) - status = result_insert (dm, *insert_pos, "::*"); - if (STATUS_NO_ERROR (status)) - status = result_insert_string (dm, *insert_pos, class_type); - /* There may be additional levels of (pointer or reference) - indirection in this type. If so, the `*' and `&' should be - added after the pointer-to-member notation (e.g. `C::*&' for - a reference to a pointer-to-member of class C). */ - *insert_pos += dyn_string_length (class_type) + 3; - - /* Clean up. */ - dyn_string_delete (class_type); - - RETURN_IF_ERROR (status); - } - break; - - case 'F': - /* Ooh, tricky, a pointer-to-function. When we demangle the - function type, the return type should go at the very - beginning. */ - *insert_pos = result_caret_pos (dm); - /* The parentheses indicate this is a function pointer or - reference type. */ - RETURN_IF_ERROR (result_add (dm, "()")); - /* Now demangle the function type. The return type will be - inserted before the `()', and the argument list will go after - it. */ - RETURN_IF_ERROR (demangle_function_type (dm, insert_pos)); - /* We should now have something along the lines of - `void () (int, int)'. The pointer or reference characters - have to inside the first set of parentheses. *insert_pos has - already been updated to point past the end of the return - type. Move it one character over so it points inside the - `()'. */ - ++(*insert_pos); - break; - - case 'A': - /* An array pointer or reference. demangle_array_type will figure - out where the asterisks and ampersands go. */ - RETURN_IF_ERROR (demangle_array_type (dm, insert_pos)); - break; - - default: - /* No more pointer or reference tokens; this is therefore a - pointer to data. Finish up by demangling the underlying - type. */ - RETURN_IF_ERROR (demangle_type (dm)); - /* The pointer or reference characters follow the underlying - type, as in `int*&'. */ - *insert_pos = result_caret_pos (dm); - /* Because of the production ::= , - demangle_type will already have added the underlying type as - a substitution candidate. Don't do it again. */ - is_substitution_candidate = 0; - break; - } - - if (is_substitution_candidate) - RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0)); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= - ::= - ::= - ::= - ::= - ::= - ::= - ::= - ::= P # pointer-to - ::= R # reference-to - ::= C # complex pair (C 2000) - ::= G # imaginary (C 2000) - ::= U # vendor extended type qualifier - ::= */ - -static status_t -demangle_type (dm) - demangling_t dm; -{ - int start = substitution_start (dm); - char peek = peek_char (dm); - char peek_next; - int encode_return_type = 0; - template_arg_list_t old_arg_list = current_template_arg_list (dm); - int insert_pos; - - /* A can be a ; therefore, this is a - substitution candidate unless a special condition holds (see - below). */ - int is_substitution_candidate = 1; - - DEMANGLE_TRACE ("type", dm); - - /* A can start with a digit (a ), an - N (a ), or a Z (a ). */ - if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z') - RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type)); - /* Lower-case letters begin s, except for `r', which - denotes restrict. */ - else if (peek >= 'a' && peek <= 'z' && peek != 'r') - { - RETURN_IF_ERROR (demangle_builtin_type (dm)); - /* Built-in types are not substitution candidates. */ - is_substitution_candidate = 0; - } - else - switch (peek) - { - case 'r': - case 'V': - case 'K': - /* CV-qualifiers (including restrict). We have to demangle - them off to the side, since C++ syntax puts them in a funny - place for qualified pointer and reference types. */ - { - status_t status; - dyn_string_t cv_qualifiers = dyn_string_new (24); - int old_caret_position = result_get_caret (dm); - - if (cv_qualifiers == NULL) - return STATUS_ALLOCATION_FAILED; - - /* Decode all adjacent CV qualifiers. */ - demangle_CV_qualifiers (dm, cv_qualifiers); - /* Emit them, and shift the caret left so that the - underlying type will be emitted before the qualifiers. */ - status = result_add_string (dm, cv_qualifiers); - result_shift_caret (dm, -dyn_string_length (cv_qualifiers)); - /* Clean up. */ - dyn_string_delete (cv_qualifiers); - RETURN_IF_ERROR (status); - /* Also prepend a blank, if needed. */ - RETURN_IF_ERROR (result_add_char (dm, ' ')); - result_shift_caret (dm, -1); - - /* Demangle the underlying type. It will be emitted before - the CV qualifiers, since we moved the caret. */ - RETURN_IF_ERROR (demangle_type (dm)); - - /* Put the caret back where it was previously. */ - result_set_caret (dm, old_caret_position); - } - break; - - case 'F': - return "Non-pointer or -reference function type."; - - case 'A': - RETURN_IF_ERROR (demangle_array_type (dm, NULL)); - break; - - case 'T': - /* It's either a or a - . In either case, demangle the - `T' token first. */ - RETURN_IF_ERROR (demangle_template_param (dm)); - - /* Check for a template argument list; if one is found, it's a - ::= - ::= */ - if (peek_char (dm) == 'I') - { - /* Add a substitution candidate. The template parameter - `T' token is a substitution candidate by itself, - without the template argument list. */ - RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type)); - - /* Now demangle the template argument list. */ - RETURN_IF_ERROR (demangle_template_args (dm)); - /* The entire type, including the template template - parameter and its argument list, will be added as a - substitution candidate below. */ - } - - break; - - case 'S': - /* First check if this is a special substitution. If it is, - this is a . Special substitutions have a - letter following the `S'; other substitutions have a digit - or underscore. */ - peek_next = peek_char_next (dm); - if (IS_DIGIT (peek_next) || peek_next == '_') - { - RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type)); - - /* The substituted name may have been a template name. - Check if template arguments follow, and if so, demangle - them. */ - if (peek_char (dm) == 'I') - RETURN_IF_ERROR (demangle_template_args (dm)); - else - /* A substitution token is not itself a substitution - candidate. (However, if the substituted template is - instantiated, the resulting type is.) */ - is_substitution_candidate = 0; - } - else - { - /* Now some trickiness. We have a special substitution - here. Often, the special substitution provides the - name of a template that's subsequently instantiated, - for instance `SaIcE' => std::allocator. In these - cases we need to add a substitution candidate for the - entire and thus don't want to clear - the is_substitution_candidate flag. - - However, it's possible that what we have here is a - substitution token representing an entire type, such as - `Ss' => std::string. In this case, we mustn't add a - new substitution candidate for this substitution token. - To detect this case, remember where the start of the - substitution token is. */ - const char *next = dm->next; - /* Now demangle the . */ - RETURN_IF_ERROR - (demangle_class_enum_type (dm, &encode_return_type)); - /* If all that was just demangled is the two-character - special substitution token, suppress the addition of a - new candidate for it. */ - if (dm->next == next + 2) - is_substitution_candidate = 0; - } - - break; - - case 'P': - case 'R': - case 'M': - RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start)); - /* demangle_type_ptr adds all applicable substitution - candidates. */ - is_substitution_candidate = 0; - break; - - case 'C': - /* A C99 complex type. */ - RETURN_IF_ERROR (result_add (dm, "complex ")); - advance_char (dm); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'G': - /* A C99 imaginary type. */ - RETURN_IF_ERROR (result_add (dm, "imaginary ")); - advance_char (dm); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - case 'U': - /* Vendor-extended type qualifier. */ - advance_char (dm); - RETURN_IF_ERROR (demangle_source_name (dm)); - RETURN_IF_ERROR (result_add_char (dm, ' ')); - RETURN_IF_ERROR (demangle_type (dm)); - break; - - default: - return "Unexpected character in ."; - } - - if (is_substitution_candidate) - /* Add a new substitution for the type. If this type was a - , pass its index since from the point of - substitutions; a token is a substitution - candidate distinct from the type that is substituted for it. */ - RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type)); - - /* Pop off template argument lists added during mangling of this - type. */ - pop_to_template_arg_list (dm, old_arg_list); - - return STATUS_OK; -} - -/* C++ source names of builtin types, indexed by the mangled code - letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */ -static const char *const builtin_type_names[26] = -{ - "signed char", /* a */ - "bool", /* b */ - "char", /* c */ - "double", /* d */ - "long double", /* e */ - "float", /* f */ - "__float128", /* g */ - "unsigned char", /* h */ - "int", /* i */ - "unsigned", /* j */ - NULL, /* k */ - "long", /* l */ - "unsigned long", /* m */ - "__int128", /* n */ - "unsigned __int128", /* o */ - NULL, /* p */ - NULL, /* q */ - NULL, /* r */ - "short", /* s */ - "unsigned short", /* t */ - NULL, /* u */ - "void", /* v */ - "wchar_t", /* w */ - "long long", /* x */ - "unsigned long long", /* y */ - "..." /* z */ -}; - -/* Java source names of builtin types. Types that arn't valid in Java - are also included here - we don't fail if someone attempts to demangle a - C++ symbol in Java style. */ -static const char *const java_builtin_type_names[26] = -{ - "signed char", /* a */ - "boolean", /* C++ "bool" */ /* b */ - "byte", /* C++ "char" */ /* c */ - "double", /* d */ - "long double", /* e */ - "float", /* f */ - "__float128", /* g */ - "unsigned char", /* h */ - "int", /* i */ - "unsigned", /* j */ - NULL, /* k */ - "long", /* l */ - "unsigned long", /* m */ - "__int128", /* n */ - "unsigned __int128", /* o */ - NULL, /* p */ - NULL, /* q */ - NULL, /* r */ - "short", /* s */ - "unsigned short", /* t */ - NULL, /* u */ - "void", /* v */ - "char", /* C++ "wchar_t" */ /* w */ - "long", /* C++ "long long" */ /* x */ - "unsigned long long", /* y */ - "..." /* z */ -}; - -/* Demangles and emits a . - - ::= v # void - ::= w # wchar_t - ::= b # bool - ::= c # char - ::= a # signed char - ::= h # unsigned char - ::= s # short - ::= t # unsigned short - ::= i # int - ::= j # unsigned int - ::= l # long - ::= m # unsigned long - ::= x # long long, __int64 - ::= y # unsigned long long, __int64 - ::= n # __int128 - ::= o # unsigned __int128 - ::= f # float - ::= d # double - ::= e # long double, __float80 - ::= g # __float128 - ::= z # ellipsis - ::= u # vendor extended type */ - -static status_t -demangle_builtin_type (dm) - demangling_t dm; -{ - - char code = peek_char (dm); - - DEMANGLE_TRACE ("builtin-type", dm); - - if (code == 'u') - { - advance_char (dm); - RETURN_IF_ERROR (demangle_source_name (dm)); - return STATUS_OK; - } - else if (code >= 'a' && code <= 'z') - { - const char *type_name; - /* Java uses different names for some built-in types. */ - if (dm->style == DMGL_JAVA) - type_name = java_builtin_type_names[code - 'a']; - else - type_name = builtin_type_names[code - 'a']; - if (type_name == NULL) - return "Unrecognized code."; - - RETURN_IF_ERROR (result_add (dm, type_name)); - advance_char (dm); - return STATUS_OK; - } - else - return "Non-alphabetic code."; -} - -/* Demangles all consecutive CV-qualifiers (const, volatile, and - restrict) at the current position. The qualifiers are appended to - QUALIFIERS. Returns STATUS_OK. */ - -static status_t -demangle_CV_qualifiers (dm, qualifiers) - demangling_t dm; - dyn_string_t qualifiers; -{ - DEMANGLE_TRACE ("CV-qualifiers", dm); - - while (1) - { - switch (peek_char (dm)) - { - case 'r': - if (!dyn_string_append_space (qualifiers)) - return STATUS_ALLOCATION_FAILED; - if (!dyn_string_append_cstr (qualifiers, "restrict")) - return STATUS_ALLOCATION_FAILED; - break; - - case 'V': - if (!dyn_string_append_space (qualifiers)) - return STATUS_ALLOCATION_FAILED; - if (!dyn_string_append_cstr (qualifiers, "volatile")) - return STATUS_ALLOCATION_FAILED; - break; - - case 'K': - if (!dyn_string_append_space (qualifiers)) - return STATUS_ALLOCATION_FAILED; - if (!dyn_string_append_cstr (qualifiers, "const")) - return STATUS_ALLOCATION_FAILED; - break; - - default: - return STATUS_OK; - } - - advance_char (dm); - } -} - -/* Demangles and emits a . *FUNCTION_NAME_POS is the - position in the result string of the start of the function - identifier, at which the function's return type will be inserted; - *FUNCTION_NAME_POS is updated to position past the end of the - function's return type. - - ::= F [Y] E */ - -static status_t -demangle_function_type (dm, function_name_pos) - demangling_t dm; - int *function_name_pos; -{ - DEMANGLE_TRACE ("function-type", dm); - RETURN_IF_ERROR (demangle_char (dm, 'F')); - if (peek_char (dm) == 'Y') - { - /* Indicate this function has C linkage if in verbose mode. */ - if (flag_verbose) - RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] ")); - advance_char (dm); - } - RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos)); - RETURN_IF_ERROR (demangle_char (dm, 'E')); - return STATUS_OK; -} - -/* Demangles and emits a . RETURN_TYPE_POS is the - position in the result string at which the function return type - should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the - function's return type is assumed not to be encoded. - - ::= + */ - -static status_t -demangle_bare_function_type (dm, return_type_pos) - demangling_t dm; - int *return_type_pos; -{ - /* Sequence is the index of the current function parameter, counting - from zero. The value -1 denotes the return type. */ - int sequence = - (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1); - - DEMANGLE_TRACE ("bare-function-type", dm); - - RETURN_IF_ERROR (result_add_char (dm, '(')); - while (!end_of_name_p (dm) && peek_char (dm) != 'E') - { - if (sequence == -1) - /* We're decoding the function's return type. */ - { - dyn_string_t return_type; - status_t status = STATUS_OK; - - /* Decode the return type off to the side. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_type (dm)); - return_type = (dyn_string_t) result_pop (dm); - - /* Add a space to the end of the type. Insert the return - type where we've been asked to. */ - if (!dyn_string_append_space (return_type)) - status = STATUS_ALLOCATION_FAILED; - if (STATUS_NO_ERROR (status)) - { - if (!dyn_string_insert (result_string (dm), *return_type_pos, - return_type)) - status = STATUS_ALLOCATION_FAILED; - else - *return_type_pos += dyn_string_length (return_type); - } - - dyn_string_delete (return_type); - RETURN_IF_ERROR (status); - } - else - { - /* Skip `void' parameter types. One should only occur as - the only type in a parameter list; in that case, we want - to print `foo ()' instead of `foo (void)'. */ - if (peek_char (dm) == 'v') - /* Consume the v. */ - advance_char (dm); - else - { - /* Separate parameter types by commas. */ - if (sequence > 0) - RETURN_IF_ERROR (result_add (dm, ", ")); - /* Demangle the type. */ - RETURN_IF_ERROR (demangle_type (dm)); - } - } - - ++sequence; - } - RETURN_IF_ERROR (result_add_char (dm, ')')); - - /* We should have demangled at least one parameter type (which would - be void, for a function that takes no parameters), plus the - return type, if we were supposed to demangle that. */ - if (sequence == -1) - return "Missing function return type."; - else if (sequence == 0) - return "Missing function parameter."; - - return STATUS_OK; -} - -/* Demangles and emits a . *ENCODE_RETURN_TYPE is set to - non-zero if the type is a template-id, zero otherwise. - - ::= */ - -static status_t -demangle_class_enum_type (dm, encode_return_type) - demangling_t dm; - int *encode_return_type; -{ - DEMANGLE_TRACE ("class-enum-type", dm); - - RETURN_IF_ERROR (demangle_name (dm, encode_return_type)); - return STATUS_OK; -} - -/* Demangles and emits an . - - If PTR_INSERT_POS is not NULL, the array type is formatted as a - pointer or reference to an array, except that asterisk and - ampersand punctuation is omitted (since it's not know at this - point). *PTR_INSERT_POS is set to the position in the demangled - name at which this punctuation should be inserted. For example, - `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points - between the parentheses. - - If PTR_INSERT_POS is NULL, the array type is assumed not to be - pointer- or reference-qualified. Then, for example, `A10_i' is - demangled simply as `int[10]'. - - ::= A [] _ - ::= A _ */ - -static status_t -demangle_array_type (dm, ptr_insert_pos) - demangling_t dm; - int *ptr_insert_pos; -{ - status_t status = STATUS_OK; - dyn_string_t array_size = NULL; - char peek; - - DEMANGLE_TRACE ("array-type", dm); - - RETURN_IF_ERROR (demangle_char (dm, 'A')); - - /* Demangle the array size into array_size. */ - peek = peek_char (dm); - if (peek == '_') - /* Array bound is omitted. This is a C99-style VLA. */ - ; - else if (IS_DIGIT (peek_char (dm))) - { - /* It looks like a constant array bound. */ - array_size = dyn_string_new (10); - if (array_size == NULL) - return STATUS_ALLOCATION_FAILED; - status = demangle_number_literally (dm, array_size, 10, 0); - } - else - { - /* Anything is must be an expression for a nont-constant array - bound. This happens if the array type occurs in a template - and the array bound references a template parameter. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_expression_v3 (dm)); - array_size = (dyn_string_t) result_pop (dm); - } - /* array_size may have been allocated by now, so we can't use - RETURN_IF_ERROR until it's been deallocated. */ - - /* Demangle the base type of the array. */ - if (STATUS_NO_ERROR (status)) - status = demangle_char (dm, '_'); - if (STATUS_NO_ERROR (status)) - status = demangle_type (dm); - - if (ptr_insert_pos != NULL) - { - /* This array is actually part of an pointer- or - reference-to-array type. Format appropriately, except we - don't know which and how much punctuation to use. */ - if (STATUS_NO_ERROR (status)) - status = result_add (dm, " () "); - /* Let the caller know where to insert the punctuation. */ - *ptr_insert_pos = result_caret_pos (dm) - 2; - } - - /* Emit the array dimension syntax. */ - if (STATUS_NO_ERROR (status)) - status = result_add_char (dm, '['); - if (STATUS_NO_ERROR (status) && array_size != NULL) - status = result_add_string (dm, array_size); - if (STATUS_NO_ERROR (status)) - status = result_add_char (dm, ']'); - if (array_size != NULL) - dyn_string_delete (array_size); - - RETURN_IF_ERROR (status); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= T_ # first template parameter - ::= T _ */ - -static status_t -demangle_template_param (dm) - demangling_t dm; -{ - int parm_number; - template_arg_list_t current_arg_list = current_template_arg_list (dm); - string_list_t arg; - - DEMANGLE_TRACE ("template-param", dm); - - /* Make sure there is a template argmust list in which to look up - this parameter reference. */ - if (current_arg_list == NULL) - return "Template parameter outside of template."; - - RETURN_IF_ERROR (demangle_char (dm, 'T')); - if (peek_char (dm) == '_') - parm_number = 0; - else - { - RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0)); - ++parm_number; - } - RETURN_IF_ERROR (demangle_char (dm, '_')); - - arg = template_arg_list_get_arg (current_arg_list, parm_number); - if (arg == NULL) - /* parm_number exceeded the number of arguments in the current - template argument list. */ - return "Template parameter number out of bounds."; - RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg)); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= I + E */ - -static status_t -demangle_template_args_1 (dm, arg_list) - demangling_t dm; - template_arg_list_t arg_list; -{ - int first = 1; - - DEMANGLE_TRACE ("template-args", dm); - - RETURN_IF_ERROR (demangle_char (dm, 'I')); - RETURN_IF_ERROR (result_open_template_list (dm)); - do - { - string_list_t arg; - - if (first) - first = 0; - else - RETURN_IF_ERROR (result_add (dm, ", ")); - - /* Capture the template arg. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_template_arg (dm)); - arg = result_pop (dm); - - /* Emit it in the demangled name. */ - RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg)); - - /* Save it for use in expanding s. */ - template_arg_list_add_arg (arg_list, arg); - } - while (peek_char (dm) != 'E'); - /* Append the '>'. */ - RETURN_IF_ERROR (result_close_template_list (dm)); - - /* Consume the 'E'. */ - advance_char (dm); - - return STATUS_OK; -} - -static status_t -demangle_template_args (dm) - demangling_t dm; -{ - int first = 1; - dyn_string_t old_last_source_name; - dyn_string_t new_name; - template_arg_list_t arg_list = template_arg_list_new (); - status_t status; - - if (arg_list == NULL) - return STATUS_ALLOCATION_FAILED; - - /* Preserve the most recently demangled source name. */ - old_last_source_name = dm->last_source_name; - new_name = dyn_string_new (0); - - if (new_name == NULL) - { - template_arg_list_delete (arg_list); - return STATUS_ALLOCATION_FAILED; - } - - dm->last_source_name = new_name; - - status = demangle_template_args_1 (dm, arg_list); - /* Restore the most recent demangled source name. */ - dyn_string_delete (dm->last_source_name); - dm->last_source_name = old_last_source_name; - - if (!STATUS_NO_ERROR (status)) - { - template_arg_list_delete (arg_list); - return status; - } - - /* Push the list onto the top of the stack of template argument - lists, so that arguments from it are used from now on when - expanding s. */ - push_template_arg_list (dm, arg_list); - - return STATUS_OK; -} - -/* This function, which does not correspond to a production in the - mangling spec, handles the `literal' production for both - and . It does not expect or consume - the initial `L' or final `E'. The demangling is given by: - - ::= - - and the emitted output is `(type)number'. */ - -static status_t -demangle_literal (dm) - demangling_t dm; -{ - char peek = peek_char (dm); - dyn_string_t value_string; - status_t status; - - DEMANGLE_TRACE ("literal", dm); - - if (!flag_verbose && peek >= 'a' && peek <= 'z') - { - /* If not in verbose mode and this is a builtin type, see if we - can produce simpler numerical output. In particular, for - integer types shorter than `long', just write the number - without type information; for bools, write `true' or `false'. - Other refinements could be made here too. */ - - /* This constant string is used to map from codes - (26 letters of the alphabet) to codes that determine how the - value will be displayed. The codes are: - b: display as bool - i: display as int - l: display as long - A space means the value will be represented using cast - notation. */ - static const char *const code_map = "ibi iii ll ii i "; - - char code = code_map[peek - 'a']; - /* FIXME: Implement demangling of floats and doubles. */ - if (code == 'u') - return STATUS_UNIMPLEMENTED; - if (code == 'b') - { - /* It's a boolean. */ - char value; - - /* Consume the b. */ - advance_char (dm); - /* Look at the next character. It should be 0 or 1, - corresponding to false or true, respectively. */ - value = peek_char (dm); - if (value == '0') - RETURN_IF_ERROR (result_add (dm, "false")); - else if (value == '1') - RETURN_IF_ERROR (result_add (dm, "true")); - else - return "Unrecognized bool constant."; - /* Consume the 0 or 1. */ - advance_char (dm); - return STATUS_OK; - } - else if (code == 'i' || code == 'l') - { - /* It's an integer or long. */ - - /* Consume the type character. */ - advance_char (dm); - - /* Demangle the number and write it out. */ - value_string = dyn_string_new (0); - status = demangle_number_literally (dm, value_string, 10, 1); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, value_string); - /* For long integers, append an l. */ - if (code == 'l' && STATUS_NO_ERROR (status)) - status = result_add_char (dm, code); - dyn_string_delete (value_string); - - RETURN_IF_ERROR (status); - return STATUS_OK; - } - /* ...else code == ' ', so fall through to represent this - literal's type explicitly using cast syntax. */ - } - - RETURN_IF_ERROR (result_add_char (dm, '(')); - RETURN_IF_ERROR (demangle_type (dm)); - RETURN_IF_ERROR (result_add_char (dm, ')')); - - value_string = dyn_string_new (0); - if (value_string == NULL) - return STATUS_ALLOCATION_FAILED; - - status = demangle_number_literally (dm, value_string, 10, 1); - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, value_string); - dyn_string_delete (value_string); - RETURN_IF_ERROR (status); - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= # type - ::= L E # literal - ::= LZ E # external name - ::= X E # expression */ - -static status_t -demangle_template_arg (dm) - demangling_t dm; -{ - DEMANGLE_TRACE ("template-arg", dm); - - switch (peek_char (dm)) - { - case 'L': - advance_char (dm); - - if (peek_char (dm) == 'Z') - { - /* External name. */ - advance_char (dm); - /* FIXME: Standard is contradictory here. */ - RETURN_IF_ERROR (demangle_encoding (dm)); - } - else - RETURN_IF_ERROR (demangle_literal (dm)); - RETURN_IF_ERROR (demangle_char (dm, 'E')); - break; - - case 'X': - /* Expression. */ - advance_char (dm); - RETURN_IF_ERROR (demangle_expression_v3 (dm)); - RETURN_IF_ERROR (demangle_char (dm, 'E')); - break; - - default: - RETURN_IF_ERROR (demangle_type (dm)); - break; - } - - return STATUS_OK; -} - -/* Demangles and emits an . - - ::= - ::= - ::= - ::= */ - -static status_t -demangle_expression_v3 (dm) - demangling_t dm; -{ - char peek = peek_char (dm); - - DEMANGLE_TRACE ("expression", dm); - - if (peek == 'L' || peek == 'T') - RETURN_IF_ERROR (demangle_expr_primary (dm)); - else if (peek == 's' && peek_char_next (dm) == 'r') - RETURN_IF_ERROR (demangle_scope_expression (dm)); - else - /* An operator expression. */ - { - int num_args; - status_t status = STATUS_OK; - dyn_string_t operator_name; - - /* We have an operator name. Since we want to output binary - operations in infix notation, capture the operator name - first. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args)); - operator_name = (dyn_string_t) result_pop (dm); - - /* If it's binary, do an operand first. */ - if (num_args > 1) - { - status = result_add_char (dm, '('); - if (STATUS_NO_ERROR (status)) - status = demangle_expression_v3 (dm); - if (STATUS_NO_ERROR (status)) - status = result_add_char (dm, ')'); - } - - /* Emit the operator. */ - if (STATUS_NO_ERROR (status)) - status = result_add_string (dm, operator_name); - dyn_string_delete (operator_name); - RETURN_IF_ERROR (status); - - /* Emit its second (if binary) or only (if unary) operand. */ - RETURN_IF_ERROR (result_add_char (dm, '(')); - RETURN_IF_ERROR (demangle_expression_v3 (dm)); - RETURN_IF_ERROR (result_add_char (dm, ')')); - - /* The ternary operator takes a third operand. */ - if (num_args == 3) - { - RETURN_IF_ERROR (result_add (dm, ":(")); - RETURN_IF_ERROR (demangle_expression_v3 (dm)); - RETURN_IF_ERROR (result_add_char (dm, ')')); - } - } - - return STATUS_OK; -} - -/* Demangles and emits a . - - ::= sr - ::= sr */ - -static status_t -demangle_scope_expression (dm) - demangling_t dm; -{ - RETURN_IF_ERROR (demangle_char (dm, 's')); - RETURN_IF_ERROR (demangle_char (dm, 'r')); - RETURN_IF_ERROR (demangle_type (dm)); - RETURN_IF_ERROR (result_add (dm, "::")); - RETURN_IF_ERROR (demangle_encoding (dm)); - return STATUS_OK; -} - -/* Demangles and emits an . - - ::= - ::= L E # literal - ::= L E # external name */ - -static status_t -demangle_expr_primary (dm) - demangling_t dm; -{ - char peek = peek_char (dm); - - DEMANGLE_TRACE ("expr-primary", dm); - - if (peek == 'T') - RETURN_IF_ERROR (demangle_template_param (dm)); - else if (peek == 'L') - { - /* Consume the `L'. */ - advance_char (dm); - peek = peek_char (dm); - - if (peek == '_') - RETURN_IF_ERROR (demangle_mangled_name (dm)); - else - RETURN_IF_ERROR (demangle_literal (dm)); - - RETURN_IF_ERROR (demangle_char (dm, 'E')); - } - else - return STATUS_ERROR; - - return STATUS_OK; -} - -/* Demangles and emits a . Sets *TEMPLATE_P to non-zero - if the substitution is the name of a template, zero otherwise. - - ::= S _ - ::= S_ - - ::= St # ::std:: - ::= Sa # ::std::allocator - ::= Sb # ::std::basic_string - ::= Ss # ::std::basic_string, - ::std::allocator > - ::= Si # ::std::basic_istream > - ::= So # ::std::basic_ostream > - ::= Sd # ::std::basic_iostream > -*/ - -static status_t -demangle_substitution (dm, template_p) - demangling_t dm; - int *template_p; -{ - int seq_id; - int peek; - dyn_string_t text; - - DEMANGLE_TRACE ("substitution", dm); - - RETURN_IF_ERROR (demangle_char (dm, 'S')); - - /* Scan the substitution sequence index. A missing number denotes - the first index. */ - peek = peek_char (dm); - if (peek == '_') - seq_id = -1; - /* If the following character is 0-9 or a capital letter, interpret - the sequence up to the next underscore as a base-36 substitution - index. */ - else if (IS_DIGIT ((unsigned char) peek) - || (peek >= 'A' && peek <= 'Z')) - RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0)); - else - { - const char *new_last_source_name = NULL; - - switch (peek) - { - case 't': - RETURN_IF_ERROR (result_add (dm, "std")); - break; - - case 'a': - RETURN_IF_ERROR (result_add (dm, "std::allocator")); - new_last_source_name = "allocator"; - *template_p = 1; - break; - - case 'b': - RETURN_IF_ERROR (result_add (dm, "std::basic_string")); - new_last_source_name = "basic_string"; - *template_p = 1; - break; - - case 's': - if (!flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, "std::string")); - new_last_source_name = "string"; - } - else - { - RETURN_IF_ERROR (result_add (dm, "std::basic_string, std::allocator >")); - new_last_source_name = "basic_string"; - } - *template_p = 0; - break; - - case 'i': - if (!flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, "std::istream")); - new_last_source_name = "istream"; - } - else - { - RETURN_IF_ERROR (result_add (dm, "std::basic_istream >")); - new_last_source_name = "basic_istream"; - } - *template_p = 0; - break; - - case 'o': - if (!flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, "std::ostream")); - new_last_source_name = "ostream"; - } - else - { - RETURN_IF_ERROR (result_add (dm, "std::basic_ostream >")); - new_last_source_name = "basic_ostream"; - } - *template_p = 0; - break; - - case 'd': - if (!flag_verbose) - { - RETURN_IF_ERROR (result_add (dm, "std::iostream")); - new_last_source_name = "iostream"; - } - else - { - RETURN_IF_ERROR (result_add (dm, "std::basic_iostream >")); - new_last_source_name = "basic_iostream"; - } - *template_p = 0; - break; - - default: - return "Unrecognized ."; - } - - /* Consume the character we just processed. */ - advance_char (dm); - - if (new_last_source_name != NULL) - { - if (!dyn_string_copy_cstr (dm->last_source_name, - new_last_source_name)) - return STATUS_ALLOCATION_FAILED; - } - - return STATUS_OK; - } - - /* Look up the substitution text. Since `S_' is the most recent - substitution, `S0_' is the second-most-recent, etc., shift the - numbering by one. */ - text = substitution_get (dm, seq_id + 1, template_p); - if (text == NULL) - return "Substitution number out of range."; - - /* Emit the substitution text. */ - RETURN_IF_ERROR (result_add_string (dm, text)); - - RETURN_IF_ERROR (demangle_char (dm, '_')); - return STATUS_OK; -} - -/* Demangles and emits a . - - := Z E [] - := Z E s [] */ - -static status_t -demangle_local_name (dm) - demangling_t dm; -{ - DEMANGLE_TRACE ("local-name", dm); - - RETURN_IF_ERROR (demangle_char (dm, 'Z')); - RETURN_IF_ERROR (demangle_encoding (dm)); - RETURN_IF_ERROR (demangle_char (dm, 'E')); - RETURN_IF_ERROR (result_add (dm, "::")); - - if (peek_char (dm) == 's') - { - /* Local character string literal. */ - RETURN_IF_ERROR (result_add (dm, "string literal")); - /* Consume the s. */ - advance_char (dm); - RETURN_IF_ERROR (demangle_discriminator (dm, 0)); - } - else - { - int unused; - /* Local name for some other entity. Demangle its name. */ - RETURN_IF_ERROR (demangle_name (dm, &unused)); - RETURN_IF_ERROR (demangle_discriminator (dm, 1)); - } - - return STATUS_OK; - } - - /* Optimonally demangles and emits a . If there is no - at the current position in the mangled string, the - descriminator is assumed to be zero. Emit the discriminator number - in parentheses, unless SUPPRESS_FIRST is non-zero and the - discriminator is zero. - - ::= _ */ - -static status_t -demangle_discriminator (dm, suppress_first) - demangling_t dm; - int suppress_first; -{ - /* Output for s to the demangled name is completely - suppressed if not in verbose mode. */ - - if (peek_char (dm) == '_') - { - /* Consume the underscore. */ - advance_char (dm); - if (flag_verbose) - RETURN_IF_ERROR (result_add (dm, " [#")); - /* Check if there's a number following the underscore. */ - if (IS_DIGIT ((unsigned char) peek_char (dm))) - { - int discriminator; - /* Demangle the number. */ - RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0)); - if (flag_verbose) - /* Write the discriminator. The mangled number is two - less than the discriminator ordinal, counting from - zero. */ - RETURN_IF_ERROR (int_to_dyn_string (discriminator + 1, - (dyn_string_t) dm->result)); - } - else - return STATUS_ERROR; - if (flag_verbose) - RETURN_IF_ERROR (result_add_char (dm, ']')); - } - else if (!suppress_first) - { - if (flag_verbose) - RETURN_IF_ERROR (result_add (dm, " [#0]")); - } - - return STATUS_OK; -} - -/* Demangle NAME into RESULT, which must be an initialized - dyn_string_t. On success, returns STATUS_OK. On failure, returns - an error message, and the contents of RESULT are unchanged. */ - -static status_t -cp_demangle (name, result, style) - const char *name; - dyn_string_t result; - int style; -{ - status_t status; - int length = VG_(strlen) (name); - - if (length > 2 && name[0] == '_' && name[1] == 'Z') - { - demangling_t dm = demangling_new (name, style); - if (dm == NULL) - return STATUS_ALLOCATION_FAILED; - - status = result_push (dm); - if (status != STATUS_OK) - { - demangling_delete (dm); - return status; - } - - status = demangle_mangled_name (dm); - if (STATUS_NO_ERROR (status)) - { - dyn_string_t demangled = (dyn_string_t) result_pop (dm); - if (!dyn_string_copy (result, demangled)) - { - demangling_delete (dm); - return STATUS_ALLOCATION_FAILED; - } - dyn_string_delete (demangled); - } - - demangling_delete (dm); - } - else - { - /* It's evidently not a mangled C++ name. It could be the name - of something with C linkage, though, so just copy NAME into - RESULT. */ - if (!dyn_string_copy_cstr (result, name)) - return STATUS_ALLOCATION_FAILED; - status = STATUS_OK; - } - - return status; -} - -/* Demangle TYPE_NAME into RESULT, which must be an initialized - dyn_string_t. On success, returns STATUS_OK. On failiure, returns - an error message, and the contents of RESULT are unchanged. */ - -#ifdef IN_LIBGCC2 -static status_t -cp_demangle_type (type_name, result) - const char* type_name; - dyn_string_t result; -{ - status_t status; - demangling_t dm = demangling_new (type_name); - - if (dm == NULL) - return STATUS_ALLOCATION_FAILED; - - /* Demangle the type name. The demangled name is stored in dm. */ - status = result_push (dm); - if (status != STATUS_OK) - { - demangling_delete (dm); - return status; - } - - status = demangle_type (dm); - - if (STATUS_NO_ERROR (status)) - { - /* The demangling succeeded. Pop the result out of dm and copy - it into RESULT. */ - dyn_string_t demangled = (dyn_string_t) result_pop (dm); - if (!dyn_string_copy (result, demangled)) - return STATUS_ALLOCATION_FAILED; - dyn_string_delete (demangled); - } - - /* Clean up. */ - demangling_delete (dm); - - return status; -} - -extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *)); - -/* ia64 ABI-mandated entry point in the C++ runtime library for performing - demangling. MANGLED_NAME is a NUL-terminated character string - containing the name to be demangled. - - OUTPUT_BUFFER is a region of memory, allocated with malloc, of - *LENGTH bytes, into which the demangled name is stored. If - OUTPUT_BUFFER is not long enough, it is expanded using realloc. - OUTPUT_BUFFER may instead be NULL; in that case, the demangled name - is placed in a region of memory allocated with malloc. - - If LENGTH is non-NULL, the length of the buffer conaining the - demangled name, is placed in *LENGTH. - - The return value is a pointer to the start of the NUL-terminated - demangled name, or NULL if the demangling fails. The caller is - responsible for deallocating this memory using free. - - *STATUS is set to one of the following values: - 0: The demangling operation succeeded. - -1: A memory allocation failiure occurred. - -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules. - -3: One of the arguments is invalid. - - The demagling is performed using the C++ ABI mangling rules, with - GNU extensions. */ - -char * -__cxa_demangle (mangled_name, output_buffer, length, status) - const char *mangled_name; - char *output_buffer; - size_t *length; - int *status; -{ - struct dyn_string demangled_name; - status_t result; - - if (status == NULL) - return NULL; - - if (mangled_name == NULL) { - *status = -3; - return NULL; - } - - /* Did the caller provide a buffer for the demangled name? */ - if (output_buffer == NULL) { - /* No; dyn_string will malloc a buffer for us. */ - if (!dyn_string_init (&demangled_name, 0)) - { - *status = -1; - return NULL; - } - } - else { - /* Yes. Check that the length was provided. */ - if (length == NULL) { - *status = -3; - return NULL; - } - /* Install the buffer into a dyn_string. */ - demangled_name.allocated = *length; - demangled_name.length = 0; - demangled_name.s = output_buffer; - } - - if (mangled_name[0] == '_' && mangled_name[1] == 'Z') - /* MANGLED_NAME apprears to be a function or variable name. - Demangle it accordingly. */ - result = cp_demangle (mangled_name, &demangled_name, 0); - else - /* Try to demangled MANGLED_NAME as the name of a type. */ - result = cp_demangle_type (mangled_name, &demangled_name); - - if (result == STATUS_OK) - /* The demangling succeeded. */ - { - /* If LENGTH isn't NULL, store the allocated buffer length - there; the buffer may have been realloced by dyn_string - functions. */ - if (length != NULL) - *length = demangled_name.allocated; - /* The operation was a success. */ - *status = 0; - return dyn_string_buf (&demangled_name); - } - else if (result == STATUS_ALLOCATION_FAILED) - /* A call to malloc or realloc failed during the demangling - operation. */ - { - *status = -1; - return NULL; - } - else - /* The demangling failed for another reason, most probably because - MANGLED_NAME isn't a valid mangled name. */ - { - /* If the buffer containing the demangled name wasn't provided - by the caller, free it. */ - if (output_buffer == NULL) - free (dyn_string_buf (&demangled_name)); - *status = -2; - return NULL; - } -} - -#else /* !IN_LIBGCC2 */ - -/* Variant entry point for integration with the existing cplus-dem - demangler. Attempts to demangle MANGLED. If the demangling - succeeds, returns a buffer, allocated with malloc, containing the - demangled name. The caller must deallocate the buffer using free. - If the demangling failes, returns NULL. */ - -char * -VG_(cplus_demangle_v3) (mangled) - const char* mangled; -{ - dyn_string_t demangled; - status_t status; - - /* If this isn't a mangled name, don't pretend to demangle it. */ - if (VG_(strncmp) (mangled, "_Z", 2) != 0) - return NULL; - - /* Create a dyn_string to hold the demangled name. */ - demangled = dyn_string_new (0); - /* Attempt the demangling. */ - status = cp_demangle ((char *) mangled, demangled, 0); - - if (STATUS_NO_ERROR (status)) - /* Demangling succeeded. */ - { - /* Grab the demangled result from the dyn_string. It was - allocated with malloc, so we can return it directly. */ - char *return_value = dyn_string_release (demangled); - /* Hand back the demangled name. */ - return return_value; - } - else if (status == STATUS_ALLOCATION_FAILED) - { - vg_assert (0); - /* - fprintf (stderr, "Memory allocation failed.\n"); - abort (); - */ - } - else - /* Demangling failed. */ - { - dyn_string_delete (demangled); - return NULL; - } -} - -/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling - conventions, but the output formatting is a little different. - This instructs the C++ demangler not to emit pointer characters ("*"), and - to use Java's namespace separator symbol ("." instead of "::"). It then - does an additional pass over the demangled output to replace instances - of JArray with TYPE[]. */ - -char * -VG_(java_demangle_v3) (mangled) - const char* mangled; -{ - dyn_string_t demangled; - char *next; - char *end; - int len; - status_t status; - int nesting = 0; - char *cplus_demangled; - char *return_value; - - /* Create a dyn_string to hold the demangled name. */ - demangled = dyn_string_new (0); - - /* Attempt the demangling. */ - status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA); - - if (STATUS_NO_ERROR (status)) - /* Demangling succeeded. */ - { - /* Grab the demangled result from the dyn_string. */ - cplus_demangled = dyn_string_release (demangled); - } - else if (status == STATUS_ALLOCATION_FAILED) - { - vg_assert (0); - /* - fprintf (stderr, "Memory allocation failed.\n"); - abort (); - */ - } - else - /* Demangling failed. */ - { - dyn_string_delete (demangled); - return NULL; - } - - len = VG_(strlen) (cplus_demangled); - next = cplus_demangled; - end = next + len; - demangled = NULL; - - /* Replace occurrences of JArray with TYPE[]. */ - while (next < end) - { - char *open_str = VG_(strstr) (next, "JArray<"); - char *close_str = NULL; - if (nesting > 0) - close_str = VG_(strchr) (next, '>'); - - if (open_str != NULL && (close_str == NULL || close_str > open_str)) - { - ++nesting; - - if (!demangled) - demangled = dyn_string_new(len); - - /* Copy prepending symbols, if any. */ - if (open_str > next) - { - open_str[0] = 0; - dyn_string_append_cstr (demangled, next); - } - next = open_str + 7; - } - else if (close_str != NULL) - { - --nesting; - - /* Copy prepending type symbol, if any. Squash any spurious - whitespace. */ - if (close_str > next && next[0] != ' ') - { - close_str[0] = 0; - dyn_string_append_cstr (demangled, next); - } - dyn_string_append_cstr (demangled, "[]"); - next = close_str + 1; - } - else - { - /* There are no more arrays. Copy the rest of the symbol, or - simply return the original symbol if no changes were made. */ - if (next == cplus_demangled) - return cplus_demangled; - - dyn_string_append_cstr (demangled, next); - next = end; - } - } - - free (cplus_demangled); - - return_value = dyn_string_release (demangled); - return return_value; -} - -#endif /* IN_LIBGCC2 */ - - -/* Demangle NAME in the G++ V3 ABI demangling style, and return either - zero, indicating that some error occurred, or a demangling_t - holding the results. */ -static demangling_t -demangle_v3_with_details (name) - const char *name; -{ - demangling_t dm; - status_t status; - - if (VG_(strncmp) (name, "_Z", 2)) - return 0; - - dm = demangling_new (name, DMGL_GNU_V3); - if (dm == NULL) - { - vg_assert (0); - /* - fprintf (stderr, "Memory allocation failed.\n"); - abort (); - */ - } - - status = result_push (dm); - if (! STATUS_NO_ERROR (status)) - { - demangling_delete (dm); - vg_assert (0); - /* - fprintf (stderr, "%s\n", status); - abort (); - */ - } - - status = demangle_mangled_name (dm); - if (STATUS_NO_ERROR (status)) - return dm; - - demangling_delete (dm); - return 0; -} - - -/* Return non-zero iff NAME is the mangled form of a constructor name - in the G++ V3 ABI demangling style. Specifically, return: - - '1' if NAME is a complete object constructor, - - '2' if NAME is a base object constructor, or - - '3' if NAME is a complete object allocating constructor. */ -/* -enum gnu_v3_ctor_kinds -is_gnu_v3_mangled_ctor (name) - const char *name; -{ - demangling_t dm = demangle_v3_with_details (name); - - if (dm) - { - enum gnu_v3_ctor_kinds result = dm->is_constructor; - demangling_delete (dm); - return result; - } - else - return 0; -} -*/ - - -/* Return non-zero iff NAME is the mangled form of a destructor name - in the G++ V3 ABI demangling style. Specifically, return: - - '0' if NAME is a deleting destructor, - - '1' if NAME is a complete object destructor, or - - '2' if NAME is a base object destructor. */ -/* -enum gnu_v3_dtor_kinds -is_gnu_v3_mangled_dtor (name) - const char *name; -{ - demangling_t dm = demangle_v3_with_details (name); - - if (dm) - { - enum gnu_v3_dtor_kinds result = dm->is_destructor; - demangling_delete (dm); - return result; - } - else - return 0; -} -*/ - -#ifdef STANDALONE_DEMANGLER - -#include "getopt.h" - -static void print_usage - PARAMS ((FILE* fp, int exit_value)); - -/* Non-zero if CHAR is a character than can occur in a mangled name. */ -#define is_mangled_char(CHAR) \ - (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \ - || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$') - -/* The name of this program, as invoked. */ -const char* program_name; - -/* Prints usage summary to FP and then exits with EXIT_VALUE. */ - -static void -print_usage (fp, exit_value) - FILE* fp; - int exit_value; -{ - fprintf (fp, "Usage: %s [options] [names ...]\n", program_name); - fprintf (fp, "Options:\n"); - fprintf (fp, " -h,--help Display this message.\n"); - fprintf (fp, " -s,--strict Demangle standard names only.\n"); - fprintf (fp, " -v,--verbose Produce verbose demanglings.\n"); - fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n"); - - exit (exit_value); -} - -/* Option specification for getopt_long. */ -static const struct option long_options[] = -{ - { "help", no_argument, NULL, 'h' }, - { "strict", no_argument, NULL, 's' }, - { "verbose", no_argument, NULL, 'v' }, - { NULL, no_argument, NULL, 0 }, -}; - -/* Main entry for a demangling filter executable. It will demangle - its command line arguments, if any. If none are provided, it will - filter stdin to stdout, replacing any recognized mangled C++ names - with their demangled equivalents. */ - -int -main (argc, argv) - int argc; - char *argv[]; -{ - status_t status; - int i; - int opt_char; - - /* Use the program name of this program, as invoked. */ - program_name = argv[0]; - - /* Parse options. */ - do - { - opt_char = getopt_long (argc, argv, "hsv", long_options, NULL); - switch (opt_char) - { - case '?': /* Unrecognized option. */ - print_usage (stderr, 1); - break; - - case 'h': - print_usage (stdout, 0); - break; - - case 's': - flag_strict = 1; - break; - - case 'v': - flag_verbose = 1; - break; - } - } - while (opt_char != -1); - - if (optind == argc) - /* No command line arguments were provided. Filter stdin. */ - { - dyn_string_t mangled = dyn_string_new (3); - dyn_string_t demangled = dyn_string_new (0); - status_t status; - - /* Read all of input. */ - while (!feof (stdin)) - { - char c = getchar (); - - /* The first character of a mangled name is an underscore. */ - if (feof (stdin)) - break; - if (c != '_') - { - /* It's not a mangled name. Print the character and go - on. */ - putchar (c); - continue; - } - c = getchar (); - - /* The second character of a mangled name is a capital `Z'. */ - if (feof (stdin)) - break; - if (c != 'Z') - { - /* It's not a mangled name. Print the previous - underscore, the `Z', and go on. */ - putchar ('_'); - putchar (c); - continue; - } - - /* Start keeping track of the candidate mangled name. */ - dyn_string_append_char (mangled, '_'); - dyn_string_append_char (mangled, 'Z'); - - /* Pile characters into mangled until we hit one that can't - occur in a mangled name. */ - c = getchar (); - while (!feof (stdin) && is_mangled_char (c)) - { - dyn_string_append_char (mangled, c); - if (feof (stdin)) - break; - c = getchar (); - } - - /* Attempt to demangle the name. */ - status = cp_demangle (dyn_string_buf (mangled), demangled, 0); - - /* If the demangling succeeded, great! Print out the - demangled version. */ - if (STATUS_NO_ERROR (status)) - fputs (dyn_string_buf (demangled), stdout); - /* Abort on allocation failures. */ - else if (status == STATUS_ALLOCATION_FAILED) - { - fprintf (stderr, "Memory allocation failed.\n"); - abort (); - } - /* Otherwise, it might not have been a mangled name. Just - print out the original text. */ - else - fputs (dyn_string_buf (mangled), stdout); - - /* If we haven't hit EOF yet, we've read one character that - can't occur in a mangled name, so print it out. */ - if (!feof (stdin)) - putchar (c); - - /* Clear the candidate mangled name, to start afresh next - time we hit a `_Z'. */ - dyn_string_clear (mangled); - } - - dyn_string_delete (mangled); - dyn_string_delete (demangled); - } - else - /* Demangle command line arguments. */ - { - dyn_string_t result = dyn_string_new (0); - - /* Loop over command line arguments. */ - for (i = optind; i < argc; ++i) - { - /* Attempt to demangle. */ - status = cp_demangle (argv[i], result, 0); - - /* If it worked, print the demangled name. */ - if (STATUS_NO_ERROR (status)) - printf ("%s\n", dyn_string_buf (result)); - /* Abort on allocaiton failures. */ - else if (status == STATUS_ALLOCATION_FAILED) - { - fprintf (stderr, "Memory allocation failed.\n"); - abort (); - } - /* If not, print the error message to stderr instead. */ - else - fprintf (stderr, "%s\n", status); - } - dyn_string_delete (result); - } - - return 0; -} - -#endif /* STANDALONE_DEMANGLER */ diff --git a/VEX/head20041019/coregrind/demangle/cplus-dem.c b/VEX/head20041019/coregrind/demangle/cplus-dem.c deleted file mode 100644 index 311b84fb9..000000000 --- a/VEX/head20041019/coregrind/demangle/cplus-dem.c +++ /dev/null @@ -1,5275 +0,0 @@ -/* Demangler for GNU C++ - Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 Free Software Foundation, Inc. - Written by James Clark (jjc@jclark.uucp) - Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling - Modified by Satish Pai (pai@apollo.hp.com) for HP demangling - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file exports two functions; cplus_mangle_opname and cplus_demangle. - - This file imports xmalloc and xrealloc, which are like malloc and - realloc except that they generate a fatal error if there is no - available memory. */ - -/* This file lives in both GCC and libiberty. When making changes, please - try not to break either. */ - -#define __NO_STRING_INLINES - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "safe-ctype.h" -#include "core.h" - -/*#include -#include -#include */ - -/*#ifdef HAVE_STDLIB_H -#include -#else -char * malloc (); -char * realloc (); -#endif*/ - -#include -#include "dyn-string.h" -#undef CURRENT_DEMANGLING_STYLE -#define CURRENT_DEMANGLING_STYLE work->options - -/*#include "libiberty.h"*/ - -static char *ada_demangle PARAMS ((const char *, int)); - -#define min(X,Y) (((X) < (Y)) ? (X) : (Y)) - -/* A value at least one greater than the maximum number of characters - that will be output when using the `%d' format with `printf'. */ -#define INTBUF_SIZE 32 - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) -#endif - -#ifndef STANDALONE -#define size_t Int - -#define xstrdup(ptr) VG_(arena_strdup) (VG_AR_DEMANGLE, ptr) -#define free(ptr) VG_(arena_free) (VG_AR_DEMANGLE, ptr) -#define xmalloc(size) VG_(arena_malloc) (VG_AR_DEMANGLE, size) -#define xrealloc(ptr, size) VG_(arena_realloc)(VG_AR_DEMANGLE, ptr, \ - VG_MIN_MALLOC_SZB, size) - -#define abort() vg_assert(0) -#undef strstr -#define strstr VG_(strstr) -#define sprintf VG_(sprintf) -#define strcpy VG_(strcpy) -#define strncpy VG_(strncpy) -#define strncat VG_(strncat) -#define strchr VG_(strchr) -#define strpbrk VG_(strpbrk) -#define strlen VG_(strlen) -#define strcmp VG_(strcmp) -#define strncmp VG_(strncmp) -#define memcpy VG_(memcpy) -#define memset VG_(memset) -#define memcmp VG_(memcmp) -#endif - -extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN; - -/* In order to allow a single demangler executable to demangle strings - using various common values of CPLUS_MARKER, as well as any specific - one set at compile time, we maintain a string containing all the - commonly used ones, and check to see if the marker we are looking for - is in that string. CPLUS_MARKER is usually '$' on systems where the - assembler can deal with that. Where the assembler can't, it's usually - '.' (but on many systems '.' is used for other things). We put the - current defined CPLUS_MARKER first (which defaults to '$'), followed - by the next most common value, followed by an explicit '$' in case - the value of CPLUS_MARKER is not '$'. - - We could avoid this if we could just get g++ to tell us what the actual - cplus marker character is as part of the debug information, perhaps by - ensuring that it is the character that terminates the gcc_compiled - marker symbol (FIXME). */ - -#if !defined (CPLUS_MARKER) -#define CPLUS_MARKER '$' -#endif - -enum demangling_styles current_demangling_style = auto_demangling; - -static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; - -static char char_str[2] = { '\000', '\000' }; - -/* -void -set_cplus_marker_for_demangling (ch) - int ch; -{ - cplus_markers[0] = ch; -} -*/ - -typedef struct string /* Beware: these aren't required to be */ -{ /* '\0' terminated. */ - char *b; /* pointer to start of string */ - char *p; /* pointer after last character */ - char *e; /* pointer after end of allocated space */ -} string; - -/* Stuff that is shared between sub-routines. - Using a shared structure allows cplus_demangle to be reentrant. */ - -struct work_stuff -{ - int options; - char **typevec; - char **ktypevec; - char **btypevec; - int numk; - int numb; - int ksize; - int bsize; - int ntypes; - int typevec_size; - int constructor; - int destructor; - int static_type; /* A static member function */ - int temp_start; /* index in demangled to start of template args */ - int type_quals; /* The type qualifiers. */ - int dllimported; /* Symbol imported from a PE DLL */ - char **tmpl_argvec; /* Template function arguments. */ - int ntmpl_args; /* The number of template function arguments. */ - int forgetting_types; /* Nonzero if we are not remembering the types - we see. */ - string* previous_argument; /* The last function argument demangled. */ - int nrepeats; /* The number of times to repeat the previous - argument. */ -}; - -#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) -#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) - -static const struct optable -{ - const char *const in; - const char *const out; - const int flags; -} optable[] = { - {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ - {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ - {"new", " new", 0}, /* old (1.91, and 1.x) */ - {"delete", " delete", 0}, /* old (1.91, and 1.x) */ - {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ - {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ - {"as", "=", DMGL_ANSI}, /* ansi */ - {"ne", "!=", DMGL_ANSI}, /* old, ansi */ - {"eq", "==", DMGL_ANSI}, /* old, ansi */ - {"ge", ">=", DMGL_ANSI}, /* old, ansi */ - {"gt", ">", DMGL_ANSI}, /* old, ansi */ - {"le", "<=", DMGL_ANSI}, /* old, ansi */ - {"lt", "<", DMGL_ANSI}, /* old, ansi */ - {"plus", "+", 0}, /* old */ - {"pl", "+", DMGL_ANSI}, /* ansi */ - {"apl", "+=", DMGL_ANSI}, /* ansi */ - {"minus", "-", 0}, /* old */ - {"mi", "-", DMGL_ANSI}, /* ansi */ - {"ami", "-=", DMGL_ANSI}, /* ansi */ - {"mult", "*", 0}, /* old */ - {"ml", "*", DMGL_ANSI}, /* ansi */ - {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ - {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ - {"convert", "+", 0}, /* old (unary +) */ - {"negate", "-", 0}, /* old (unary -) */ - {"trunc_mod", "%", 0}, /* old */ - {"md", "%", DMGL_ANSI}, /* ansi */ - {"amd", "%=", DMGL_ANSI}, /* ansi */ - {"trunc_div", "/", 0}, /* old */ - {"dv", "/", DMGL_ANSI}, /* ansi */ - {"adv", "/=", DMGL_ANSI}, /* ansi */ - {"truth_andif", "&&", 0}, /* old */ - {"aa", "&&", DMGL_ANSI}, /* ansi */ - {"truth_orif", "||", 0}, /* old */ - {"oo", "||", DMGL_ANSI}, /* ansi */ - {"truth_not", "!", 0}, /* old */ - {"nt", "!", DMGL_ANSI}, /* ansi */ - {"postincrement","++", 0}, /* old */ - {"pp", "++", DMGL_ANSI}, /* ansi */ - {"postdecrement","--", 0}, /* old */ - {"mm", "--", DMGL_ANSI}, /* ansi */ - {"bit_ior", "|", 0}, /* old */ - {"or", "|", DMGL_ANSI}, /* ansi */ - {"aor", "|=", DMGL_ANSI}, /* ansi */ - {"bit_xor", "^", 0}, /* old */ - {"er", "^", DMGL_ANSI}, /* ansi */ - {"aer", "^=", DMGL_ANSI}, /* ansi */ - {"bit_and", "&", 0}, /* old */ - {"ad", "&", DMGL_ANSI}, /* ansi */ - {"aad", "&=", DMGL_ANSI}, /* ansi */ - {"bit_not", "~", 0}, /* old */ - {"co", "~", DMGL_ANSI}, /* ansi */ - {"call", "()", 0}, /* old */ - {"cl", "()", DMGL_ANSI}, /* ansi */ - {"alshift", "<<", 0}, /* old */ - {"ls", "<<", DMGL_ANSI}, /* ansi */ - {"als", "<<=", DMGL_ANSI}, /* ansi */ - {"arshift", ">>", 0}, /* old */ - {"rs", ">>", DMGL_ANSI}, /* ansi */ - {"ars", ">>=", DMGL_ANSI}, /* ansi */ - {"component", "->", 0}, /* old */ - {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ - {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ - {"indirect", "*", 0}, /* old */ - {"method_call", "->()", 0}, /* old */ - {"addr", "&", 0}, /* old (unary &) */ - {"array", "[]", 0}, /* old */ - {"vc", "[]", DMGL_ANSI}, /* ansi */ - {"compound", ", ", 0}, /* old */ - {"cm", ", ", DMGL_ANSI}, /* ansi */ - {"cond", "?:", 0}, /* old */ - {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ - {"max", ">?", 0}, /* old */ - {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ - {"min", "*", DMGL_ANSI}, /* ansi */ - {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */ -}; - -/* These values are used to indicate the various type varieties. - They are all non-zero so that they can be used as `success' - values. */ -typedef enum type_kind_t -{ - tk_none, - tk_pointer, - tk_reference, - tk_integral, - tk_bool, - tk_char, - tk_real -} type_kind_t; - -const struct demangler_engine libiberty_demanglers[] = -{ - { - NO_DEMANGLING_STYLE_STRING, - no_demangling, - "Demangling disabled" - } - , - { - AUTO_DEMANGLING_STYLE_STRING, - auto_demangling, - "Automatic selection based on executable" - } - , - { - GNU_DEMANGLING_STYLE_STRING, - gnu_demangling, - "GNU (g++) style demangling" - } - , - { - LUCID_DEMANGLING_STYLE_STRING, - lucid_demangling, - "Lucid (lcc) style demangling" - } - , - { - ARM_DEMANGLING_STYLE_STRING, - arm_demangling, - "ARM style demangling" - } - , - { - HP_DEMANGLING_STYLE_STRING, - hp_demangling, - "HP (aCC) style demangling" - } - , - { - EDG_DEMANGLING_STYLE_STRING, - edg_demangling, - "EDG style demangling" - } - , - { - GNU_V3_DEMANGLING_STYLE_STRING, - gnu_v3_demangling, - "GNU (g++) V3 ABI-style demangling" - } - , - { - JAVA_DEMANGLING_STYLE_STRING, - java_demangling, - "Java style demangling" - } - , - { - GNAT_DEMANGLING_STYLE_STRING, - gnat_demangling, - "GNAT style demangling" - } - , - { - NULL, unknown_demangling, NULL - } -}; - -#define STRING_EMPTY(str) ((str) -> b == (str) -> p) -#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_prepend(str, " ");} -#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_append(str, " ");} -#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) - -/* The scope separator appropriate for the language being demangled. */ - -#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::") - -#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ -#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ - -/* Prototypes for local functions */ - -static void -delete_work_stuff PARAMS ((struct work_stuff *)); - -static void -delete_non_B_K_work_stuff PARAMS ((struct work_stuff *)); - -static char * -mop_up PARAMS ((struct work_stuff *, string *, int)); - -static void -squangle_mop_up PARAMS ((struct work_stuff *)); - -static void -work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *)); - -#if 0 -static int -demangle_method_args PARAMS ((struct work_stuff *, const char **, string *)); -#endif - -static char * -internal_cplus_demangle PARAMS ((struct work_stuff *, const char *)); - -static int -demangle_template_template_parm PARAMS ((struct work_stuff *work, - const char **, string *)); - -static int -demangle_template PARAMS ((struct work_stuff *work, const char **, string *, - string *, int, int)); - -static int -arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **, - const char **)); - -static int -demangle_class_name PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_qualified PARAMS ((struct work_stuff *, const char **, string *, - int, int)); - -static int -demangle_class PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_signature PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_prefix PARAMS ((struct work_stuff *, const char **, string *)); - -static int -gnu_special PARAMS ((struct work_stuff *, const char **, string *)); - -static int -arm_special PARAMS ((const char **, string *)); - -static void -string_need PARAMS ((string *, int)); - -static void -string_delete PARAMS ((string *)); - -static void -string_init PARAMS ((string *)); - -static void -string_clear PARAMS ((string *)); - -#if 0 -static int -string_empty PARAMS ((string *)); -#endif - -static void -string_append PARAMS ((string *, const char *)); - -static void -string_appends PARAMS ((string *, string *)); - -static void -string_appendn PARAMS ((string *, const char *, int)); - -static void -string_prepend PARAMS ((string *, const char *)); - -static void -string_prependn PARAMS ((string *, const char *, int)); - -static void -string_append_template_idx PARAMS ((string *, int)); - -static int -get_count PARAMS ((const char **, int *)); - -static int -consume_count PARAMS ((const char **)); - -static int -consume_count_with_underscores PARAMS ((const char**)); - -static int -demangle_args PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*)); - -static int -do_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_arg PARAMS ((struct work_stuff *, const char **, string *)); - -static void -demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, - const char *)); - -static int -iterate_demangle_function PARAMS ((struct work_stuff *, - const char **, string *, const char *)); - -static void -remember_type PARAMS ((struct work_stuff *, const char *, int)); - -static void -remember_Btype PARAMS ((struct work_stuff *, const char *, int, int)); - -static int -register_Btype PARAMS ((struct work_stuff *)); - -static void -remember_Ktype PARAMS ((struct work_stuff *, const char *, int)); - -static void -forget_types PARAMS ((struct work_stuff *)); - -static void -forget_B_and_K_types PARAMS ((struct work_stuff *)); - -static void -string_prepends PARAMS ((string *, string *)); - -static int -demangle_template_value_parm PARAMS ((struct work_stuff*, const char**, - string*, type_kind_t)); - -static int -do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *)); - -static int -snarf_numeric_literal PARAMS ((const char **, string *)); - -/* There is a TYPE_QUAL value for each type qualifier. They can be - combined by bitwise-or to form the complete set of qualifiers for a - type. */ - -#define TYPE_UNQUALIFIED 0x0 -#define TYPE_QUAL_CONST 0x1 -#define TYPE_QUAL_VOLATILE 0x2 -#define TYPE_QUAL_RESTRICT 0x4 - -static int -code_for_qualifier PARAMS ((int)); - -static const char* -qualifier_string PARAMS ((int)); - -static const char* -demangle_qualifier PARAMS ((int)); - -static int -demangle_expression PARAMS ((struct work_stuff *, const char **, string *, - type_kind_t)); - -static int -demangle_integral_value PARAMS ((struct work_stuff *, const char **, - string *)); - -static int -demangle_real_value PARAMS ((struct work_stuff *, const char **, string *)); - -static void -demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int, - string *)); - -static void -recursively_demangle PARAMS ((struct work_stuff *, const char **, string *, - int)); - -static void -grow_vect PARAMS ((void **, size_t *, size_t, int)); - -/* Translate count to integer, consuming tokens in the process. - Conversion terminates on the first non-digit character. - - Trying to consume something that isn't a count results in no - consumption of input and a return of -1. - - Overflow consumes the rest of the digits, and returns -1. */ - -static int -consume_count (type) - const char **type; -{ - int count = 0; - - if (! ISDIGIT ((unsigned char)**type)) - return -1; - - while (ISDIGIT ((unsigned char)**type)) - { - count *= 10; - - /* Check for overflow. - We assume that count is represented using two's-complement; - no power of two is divisible by ten, so if an overflow occurs - when multiplying by ten, the result will not be a multiple of - ten. */ - if ((count % 10) != 0) - { - while (ISDIGIT ((unsigned char) **type)) - (*type)++; - return -1; - } - - count += **type - '0'; - (*type)++; - } - - if (count < 0) - count = -1; - - return (count); -} - - -/* Like consume_count, but for counts that are preceded and followed - by '_' if they are greater than 10. Also, -1 is returned for - failure, since 0 can be a valid value. */ - -static int -consume_count_with_underscores (mangled) - const char **mangled; -{ - int idx; - - if (**mangled == '_') - { - (*mangled)++; - if (!ISDIGIT ((unsigned char)**mangled)) - return -1; - - idx = consume_count (mangled); - if (**mangled != '_') - /* The trailing underscore was missing. */ - return -1; - - (*mangled)++; - } - else - { - if (**mangled < '0' || **mangled > '9') - return -1; - - idx = **mangled - '0'; - (*mangled)++; - } - - return idx; -} - -/* C is the code for a type-qualifier. Return the TYPE_QUAL - corresponding to this qualifier. */ - -static int -code_for_qualifier (c) - int c; -{ - switch (c) - { - case 'C': - return TYPE_QUAL_CONST; - - case 'V': - return TYPE_QUAL_VOLATILE; - - case 'u': - return TYPE_QUAL_RESTRICT; - - default: - break; - } - - /* C was an invalid qualifier. */ - abort (); -} - -/* Return the string corresponding to the qualifiers given by - TYPE_QUALS. */ - -static const char* -qualifier_string (type_quals) - int type_quals; -{ - switch (type_quals) - { - case TYPE_UNQUALIFIED: - return ""; - - case TYPE_QUAL_CONST: - return "const"; - - case TYPE_QUAL_VOLATILE: - return "volatile"; - - case TYPE_QUAL_RESTRICT: - return "__restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: - return "const volatile"; - - case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: - return "const __restrict"; - - case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "volatile __restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "const volatile __restrict"; - - default: - break; - } - - /* TYPE_QUALS was an invalid qualifier set. */ - abort (); -} - -/* C is the code for a type-qualifier. Return the string - corresponding to this qualifier. This function should only be - called with a valid qualifier code. */ - -static const char* -demangle_qualifier (c) - int c; -{ - return qualifier_string (code_for_qualifier (c)); -} - -#if 0 -int -cplus_demangle_opname (opname, result, options) - const char *opname; - char *result; - int options; -{ - int len, len1, ret; - string type; - struct work_stuff work[1]; - const char *tem; - - len = strlen(opname); - result[0] = '\0'; - ret = 0; - memset ((char *) work, 0, sizeof (work)); - work->options = options; - - if (opname[0] == '_' && opname[1] == '_' - && opname[2] == 'o' && opname[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = opname + 4; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - else if (opname[0] == '_' && opname[1] == '_' - && ISLOWER((unsigned char)opname[2]) - && ISLOWER((unsigned char)opname[3])) - { - if (opname[4] == '\0') - { - /* Operator. */ - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, opname + 2, 2) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - else - { - if (opname[2] == 'a' && opname[5] == '\0') - { - /* Assignment. */ - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, opname + 2, 3) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - } - else if (len >= 3 - && opname[0] == 'o' - && opname[1] == 'p' - && strchr (cplus_markers, opname[2]) != NULL) - { - /* see if it's an assignment expression */ - if (len >= 10 /* op$assign_ */ - && memcmp (opname + 3, "assign_", 7) == 0) - { - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - len1 = len - 10; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 10, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - strcat (result, "="); - ret = 1; - break; - } - } - } - else - { - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - len1 = len - 3; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 3, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - else if (len >= 5 && memcmp (opname, "type", 4) == 0 - && strchr (cplus_markers, opname[4]) != NULL) - { - /* type conversion operator */ - tem = opname + 5; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - squangle_mop_up (work); - return ret; - -} -#endif /* 0 */ - -/* Takes operator name as e.g. "++" and returns mangled - operator name (e.g. "postincrement_expr"), or NULL if not found. - - If OPTIONS & DMGL_ANSI == 1, return the ANSI name; - if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ - -/* -const char * -cplus_mangle_opname (opname, options) - const char *opname; - int options; -{ - size_t i; - int len; - - len = strlen (opname); - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if ((int) strlen (optable[i].out) == len - && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) - && memcmp (optable[i].out, opname, len) == 0) - return optable[i].in; - } - return (0); -} -*/ - -/* Add a routine to set the demangling style to be sure it is valid and - allow for any demangler initialization that maybe necessary. */ - -/* -enum demangling_styles -cplus_demangle_set_style (style) - enum demangling_styles style; -{ - const struct demangler_engine *demangler = libiberty_demanglers; - - for (; demangler->demangling_style != unknown_demangling; ++demangler) - if (style == demangler->demangling_style) - { - current_demangling_style = style; - return current_demangling_style; - } - - return unknown_demangling; -} -*/ - -/* Do string name to style translation */ - -/* -enum demangling_styles -cplus_demangle_name_to_style (name) - const char *name; -{ - const struct demangler_engine *demangler = libiberty_demanglers; - - for (; demangler->demangling_style != unknown_demangling; ++demangler) - if (strcmp (name, demangler->demangling_style_name) == 0) - return demangler->demangling_style; - - return unknown_demangling; -} -*/ - -/* char *cplus_demangle (const char *mangled, int options) - - If MANGLED is a mangled function name produced by GNU C++, then - a pointer to a @code{malloc}ed string giving a C++ representation - of the name will be returned; otherwise NULL will be returned. - It is the caller's responsibility to free the string which - is returned. - - The OPTIONS arg may contain one or more of the following bits: - - DMGL_ANSI ANSI qualifiers such as `const' and `void' are - included. - DMGL_PARAMS Function parameters are included. - - For example, - - cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" - cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" - cplus_demangle ("foo__1Ai", 0) => "A::foo" - - cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" - cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" - cplus_demangle ("foo__1Afe", 0) => "A::foo" - - Note that any leading underscores, or other such characters prepended by - the compilation system, are presumed to have already been stripped from - MANGLED. */ - -char * -VG_(cplus_demangle) (mangled, options) - const char *mangled; - int options; -{ - char *ret; - struct work_stuff work[1]; - - if (current_demangling_style == no_demangling) - return xstrdup (mangled); - - memset ((char *) work, 0, sizeof (work)); - work->options = options; - if ((work->options & DMGL_STYLE_MASK) == 0) - work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; - - /* The V3 ABI demangling is implemented elsewhere. */ - if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) - { - ret = VG_(cplus_demangle_v3) (mangled/*, work->options*/); - if (ret || GNU_V3_DEMANGLING) - return ret; - } - - if (JAVA_DEMANGLING) - { - ret = VG_(java_demangle_v3) (mangled); - if (ret) - return ret; - } - - if (GNAT_DEMANGLING) - return ada_demangle(mangled,options); - - ret = internal_cplus_demangle (work, mangled); - squangle_mop_up (work); - return (ret); -} - - -/* Assuming *OLD_VECT points to an array of *SIZE objects of size - ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, - updating *OLD_VECT and *SIZE as necessary. */ - -static void -grow_vect (old_vect, size, min_size, element_size) - void **old_vect; - size_t *size; - size_t min_size; - int element_size; -{ - if (*size < min_size) - { - *size *= 2; - if (*size < min_size) - *size = min_size; - *old_vect = xrealloc (*old_vect, *size * element_size); - } -} - -/* Demangle ada names: - 1. Discard final __{DIGIT}+ or ${DIGIT}+ - 2. Convert other instances of embedded "__" to `.'. - 3. Discard leading _ada_. - 4. Remove everything after first ___ if it is followed by 'X'. - 5. Put symbols that should be suppressed in <...> brackets. - The resulting string is valid until the next call of ada_demangle. */ - -static char * -ada_demangle (mangled, option) - const char *mangled; - int option ATTRIBUTE_UNUSED; -{ - int i, j; - int len0; - const char* p; - char *demangled = NULL; - int at_start_name; - int changed; - char *demangling_buffer = NULL; - size_t demangling_buffer_size = 0; - - changed = 0; - - if (strncmp (mangled, "_ada_", 5) == 0) - { - mangled += 5; - changed = 1; - } - - if (mangled[0] == '_' || mangled[0] == '<') - goto Suppress; - - p = strstr (mangled, "___"); - if (p == NULL) - len0 = strlen (mangled); - else - { - if (p[3] == 'X') - { - len0 = p - mangled; - changed = 1; - } - else - goto Suppress; - } - - /* Make demangled big enough for possible expansion by operator name. */ - grow_vect ((void **) &(demangling_buffer), - &demangling_buffer_size, 2 * len0 + 1, - sizeof (char)); - demangled = demangling_buffer; - - if (ISDIGIT ((unsigned char) mangled[len0 - 1])) { - for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1) - ; - if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') - { - len0 = i - 1; - changed = 1; - } - else if (mangled[i] == '$') - { - len0 = i; - changed = 1; - } - } - - for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]); - i += 1, j += 1) - demangled[j] = mangled[i]; - - at_start_name = 1; - while (i < len0) - { - at_start_name = 0; - - if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') - { - demangled[j] = '.'; - changed = at_start_name = 1; - i += 2; j += 1; - } - else - { - demangled[j] = mangled[i]; - i += 1; j += 1; - } - } - demangled[j] = '\000'; - - for (i = 0; demangled[i] != '\0'; i += 1) - if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') - goto Suppress; - - if (! changed) - return NULL; - else - return demangled; - - Suppress: - grow_vect ((void **) &(demangling_buffer), - &demangling_buffer_size, strlen (mangled) + 3, - sizeof (char)); - demangled = demangling_buffer; - if (mangled[0] == '<') - strcpy (demangled, mangled); - else - sprintf (demangled, "<%s>", mangled); - - return demangled; -} - -/* This function performs most of what cplus_demangle use to do, but - to be able to demangle a name with a B, K or n code, we need to - have a longer term memory of what types have been seen. The original - now initializes and cleans up the squangle code info, while internal - calls go directly to this routine to avoid resetting that info. */ - -static char * -internal_cplus_demangle (work, mangled) - struct work_stuff *work; - const char *mangled; -{ - - string decl; - int success = 0; - char *demangled = NULL; - int s1, s2, s3, s4; - s1 = work->constructor; - s2 = work->destructor; - s3 = work->static_type; - s4 = work->type_quals; - work->constructor = work->destructor = 0; - work->type_quals = TYPE_UNQUALIFIED; - work->dllimported = 0; - - if ((mangled != NULL) && (*mangled != '\0')) - { - string_init (&decl); - - /* First check to see if gnu style demangling is active and if the - string to be demangled contains a CPLUS_MARKER. If so, attempt to - recognize one of the gnu special forms rather than looking for a - standard prefix. In particular, don't worry about whether there - is a "__" string in the mangled string. Consider "_$_5__foo" for - example. */ - - if ((AUTO_DEMANGLING || GNU_DEMANGLING)) - { - success = gnu_special (work, &mangled, &decl); - } - if (!success) - { - success = demangle_prefix (work, &mangled, &decl); - } - if (success && (*mangled != '\0')) - { - success = demangle_signature (work, &mangled, &decl); - } - if (work->constructor == 2) - { - string_prepend (&decl, "global constructors keyed to "); - work->constructor = 0; - } - else if (work->destructor == 2) - { - string_prepend (&decl, "global destructors keyed to "); - work->destructor = 0; - } - else if (work->dllimported == 1) - { - string_prepend (&decl, "import stub for "); - work->dllimported = 0; - } - demangled = mop_up (work, &decl, success); - } - work->constructor = s1; - work->destructor = s2; - work->static_type = s3; - work->type_quals = s4; - return demangled; -} - - -/* Clear out and squangling related storage */ -static void -squangle_mop_up (work) - struct work_stuff *work; -{ - /* clean up the B and K type mangling types. */ - forget_B_and_K_types (work); - if (work -> btypevec != NULL) - { - free ((char *) work -> btypevec); - } - if (work -> ktypevec != NULL) - { - free ((char *) work -> ktypevec); - } -} - - -/* Copy the work state and storage. */ - -static void -work_stuff_copy_to_from (to, from) - struct work_stuff *to; - struct work_stuff *from; -{ - int i; - - delete_work_stuff (to); - - /* Shallow-copy scalars. */ - memcpy (to, from, sizeof (*to)); - - /* Deep-copy dynamic storage. */ - if (from->typevec_size) - to->typevec - = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0])); - - for (i = 0; i < from->ntypes; i++) - { - int len = strlen (from->typevec[i]) + 1; - - to->typevec[i] = xmalloc (len); - memcpy (to->typevec[i], from->typevec[i], len); - } - - if (from->ksize) - to->ktypevec - = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0])); - - for (i = 0; i < from->numk; i++) - { - int len = strlen (from->ktypevec[i]) + 1; - - to->ktypevec[i] = xmalloc (len); - memcpy (to->ktypevec[i], from->ktypevec[i], len); - } - - if (from->bsize) - to->btypevec - = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0])); - - for (i = 0; i < from->numb; i++) - { - int len = strlen (from->btypevec[i]) + 1; - - to->btypevec[i] = xmalloc (len); - memcpy (to->btypevec[i], from->btypevec[i], len); - } - - if (from->ntmpl_args) - to->tmpl_argvec - = xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0])); - - for (i = 0; i < from->ntmpl_args; i++) - { - int len = strlen (from->tmpl_argvec[i]) + 1; - - to->tmpl_argvec[i] = xmalloc (len); - memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); - } - - if (from->previous_argument) - { - to->previous_argument = (string*) xmalloc (sizeof (string)); - string_init (to->previous_argument); - string_appends (to->previous_argument, from->previous_argument); - } -} - - -/* Delete dynamic stuff in work_stuff that is not to be re-used. */ - -static void -delete_non_B_K_work_stuff (work) - struct work_stuff *work; -{ - /* Discard the remembered types, if any. */ - - forget_types (work); - if (work -> typevec != NULL) - { - free ((char *) work -> typevec); - work -> typevec = NULL; - work -> typevec_size = 0; - } - if (work->tmpl_argvec) - { - int i; - - for (i = 0; i < work->ntmpl_args; i++) - if (work->tmpl_argvec[i]) - free ((char*) work->tmpl_argvec[i]); - - free ((char*) work->tmpl_argvec); - work->tmpl_argvec = NULL; - } - if (work->previous_argument) - { - string_delete (work->previous_argument); - free ((char*) work->previous_argument); - work->previous_argument = NULL; - } -} - - -/* Delete all dynamic storage in work_stuff. */ -static void -delete_work_stuff (work) - struct work_stuff *work; -{ - delete_non_B_K_work_stuff (work); - squangle_mop_up (work); -} - - -/* Clear out any mangled storage */ - -static char * -mop_up (work, declp, success) - struct work_stuff *work; - string *declp; - int success; -{ - char *demangled = NULL; - - delete_non_B_K_work_stuff (work); - - /* If demangling was successful, ensure that the demangled string is null - terminated and return it. Otherwise, free the demangling decl. */ - - if (!success) - { - string_delete (declp); - } - else - { - string_appendn (declp, "", 1); - demangled = declp->b; - } - return (demangled); -} - -/* - -LOCAL FUNCTION - - demangle_signature -- demangle the signature part of a mangled name - -SYNOPSIS - - static int - demangle_signature (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the signature portion of the mangled name. - - DECLP is the string where demangled output is being built. At - entry it contains the demangled root name from the mangled name - prefix. I.E. either a demangled operator name or the root function - name. In some special cases, it may contain nothing. - - *MANGLED points to the current unconsumed location in the mangled - name. As tokens are consumed and demangling is performed, the - pointer is updated to continuously point at the next token to - be consumed. - - Demangling GNU style mangled names is nasty because there is no - explicit token that marks the start of the outermost function - argument list. */ - -static int -demangle_signature (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - int func_done = 0; - int expect_func = 0; - int expect_return_type = 0; - const char *oldmangled = NULL; - string trawname; - string tname; - - while (success && (**mangled != '\0')) - { - switch (**mangled) - { - case 'Q': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (success) - remember_type (work, oldmangled, *mangled - oldmangled); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - expect_func = 1; - oldmangled = NULL; - break; - - case 'K': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'S': - /* Static member function */ - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - (*mangled)++; - work -> static_type = 1; - break; - - case 'C': - case 'V': - case 'u': - work->type_quals |= code_for_qualifier (**mangled); - - /* a qualified member function */ - if (oldmangled == NULL) - oldmangled = *mangled; - (*mangled)++; - break; - - case 'L': - /* Local class name follows after "Lnnn_" */ - if (HP_DEMANGLING) - { - while (**mangled && (**mangled != '_')) - (*mangled)++; - if (!**mangled) - success = 0; - else - (*mangled)++; - } - else - success = 0; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - work->temp_start = -1; /* uppermost call to demangle_class */ - success = demangle_class (work, mangled, declp); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) - { - /* EDG and others will have the "F", so we let the loop cycle - if we are looking at one. */ - if (**mangled != 'F') - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'B': - { - string s; - success = do_type (work, mangled, &s); - if (success) - { - string_append (&s, SCOPE_STRING (work)); - string_prepends (declp, &s); - } - oldmangled = NULL; - expect_func = 1; - } - break; - - case 'F': - /* Function */ - /* ARM/HP style demangling includes a specific 'F' character after - the class name. For GNU style, it is just implied. So we can - safely just consume any 'F' at this point and be compatible - with either style. */ - - oldmangled = NULL; - func_done = 1; - (*mangled)++; - - /* For lucid/ARM/HP style we have to forget any types we might - have remembered up to this point, since they were not argument - types. GNU style considers all types seen as available for - back references. See comment in demangle_args() */ - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* After picking off the function args, we expect to either - find the function return type (preceded by an '_') or the - end of the string. */ - if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') - { - ++(*mangled); - /* At this level, we do not care about the return type. */ - success = do_type (work, mangled, &tname); - string_delete (&tname); - } - - break; - - case 't': - /* G++ Template */ - string_init(&trawname); - string_init(&tname); - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - success = demangle_template (work, mangled, &tname, - &trawname, 1, 1); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - string_append (&tname, SCOPE_STRING (work)); - - string_prepends(declp, &tname); - if (work -> destructor & 1) - { - string_prepend (&trawname, "~"); - string_appends (declp, &trawname); - work->destructor -= 1; - } - if ((work->constructor & 1) || (work->destructor & 1)) - { - string_appends (declp, &trawname); - work->constructor -= 1; - } - string_delete(&trawname); - string_delete(&tname); - oldmangled = NULL; - expect_func = 1; - break; - - case '_': - if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type) - { - /* Read the return type. */ - string return_type; - string_init (&return_type); - - (*mangled)++; - success = do_type (work, mangled, &return_type); - APPEND_BLANK (&return_type); - - string_prepends (declp, &return_type); - string_delete (&return_type); - break; - } - else - /* At the outermost level, we cannot have a return type specified, - so if we run into another '_' at this point we are dealing with - a mangled name that is either bogus, or has been mangled by - some algorithm we don't know how to deal with. So just - reject the entire demangling. */ - /* However, "_nnn" is an expected suffix for alternate entry point - numbered nnn for a function, with HP aCC, so skip over that - without reporting failure. pai/1997-09-04 */ - if (HP_DEMANGLING) - { - (*mangled)++; - while (**mangled && ISDIGIT ((unsigned char)**mangled)) - (*mangled)++; - } - else - success = 0; - break; - - case 'H': - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* A G++ template function. Read the template arguments. */ - success = demangle_template (work, mangled, declp, 0, 0, - 0); - if (!(work->constructor & 1)) - expect_return_type = 1; - (*mangled)++; - break; - } - else - /* fall through */ - {;} - - default: - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = 1; - success = demangle_args (work, mangled, declp); - } - else - { - /* Non-GNU demanglers use a specific token to mark the start - of the outermost function argument tokens. Typically 'F', - for ARM/HP-demangling, for example. So if we find something - we are not prepared for, it must be an error. */ - success = 0; - } - break; - } - /* - if (AUTO_DEMANGLING || GNU_DEMANGLING) - */ - { - if (success && expect_func) - { - func_done = 1; - if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* Since template include the mangling of their return types, - we must set expect_func to 0 so that we don't try do - demangle more arguments the next time we get here. */ - expect_func = 0; - } - } - } - if (success && !func_done) - { - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added to - the current declp. Note that with ARM/HP, the first case - represents the name of a static data member 'foo::bar', - which is in the current declp, so we leave it alone. */ - success = demangle_args (work, mangled, declp); - } - } - if (success && PRINT_ARG_TYPES) - { - if (work->static_type) - string_append (declp, " static"); - if (work->type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (declp); - string_append (declp, qualifier_string (work->type_quals)); - } - } - - return (success); -} - -#if 0 - -static int -demangle_method_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - return (success); -} - -#endif - -static int -demangle_template_template_parm (work, mangled, tname) - struct work_stuff *work; - const char **mangled; - string *tname; -{ - int i; - int r; - int need_comma = 0; - int success = 1; - string temp; - - string_append (tname, "template <"); - /* get size of template parameter list */ - if (get_count (mangled, &r)) - { - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - string_append (tname, "class"); - } - /* z for template parameters */ - else if (**mangled == 'z') - { - (*mangled)++; - success = - demangle_template_template_parm (work, mangled, tname); - if (!success) - { - break; - } - } - else - { - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - } - string_delete(&temp); - if (!success) - { - break; - } - } - need_comma = 1; - } - - } - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, "> class"); - return (success); -} - -static int -demangle_expression (work, mangled, s, tk) - struct work_stuff *work; - const char** mangled; - string* s; - type_kind_t tk; -{ - int need_operator = 0; - int success; - - success = 1; - string_appendn (s, "(", 1); - (*mangled)++; - while (success && **mangled != 'W' && **mangled != '\0') - { - if (need_operator) - { - size_t i; - size_t len; - - success = 0; - - len = strlen (*mangled); - - for (i = 0; i < (size_t)ARRAY_SIZE (optable); ++i) - { - size_t l = strlen (optable[i].in); - - if (l <= len - && memcmp (optable[i].in, *mangled, l) == 0) - { - string_appendn (s, " ", 1); - string_append (s, optable[i].out); - string_appendn (s, " ", 1); - success = 1; - (*mangled) += l; - break; - } - } - - if (!success) - break; - } - else - need_operator = 1; - - success = demangle_template_value_parm (work, mangled, s, tk); - } - - if (**mangled != 'W') - success = 0; - else - { - string_appendn (s, ")", 1); - (*mangled)++; - } - - return success; -} - -static int -demangle_integral_value (work, mangled, s) - struct work_stuff *work; - const char** mangled; - string* s; -{ - int success; - - if (**mangled == 'E') - success = demangle_expression (work, mangled, s, tk_integral); - else if (**mangled == 'Q' || **mangled == 'K') - success = demangle_qualified (work, mangled, s, 0, 1); - else - { - int value; - - /* By default, we let the number decide whether we shall consume an - underscore. */ - int consume_following_underscore = 0; - int leave_following_underscore = 0; - - success = 0; - - /* Negative numbers are indicated with a leading `m'. */ - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - else if (mangled[0][0] == '_' && mangled[0][1] == 'm') - { - /* Since consume_count_with_underscores does not handle the - `m'-prefix we must do it here, using consume_count and - adjusting underscores: we have to consume the underscore - matching the prepended one. */ - consume_following_underscore = 1; - string_appendn (s, "-", 1); - (*mangled) += 2; - } - else if (**mangled == '_') - { - /* Do not consume a following underscore; - consume_following_underscore will consume what should be - consumed. */ - leave_following_underscore = 1; - } - - /* We must call consume_count if we expect to remove a trailing - underscore, since consume_count_with_underscores expects - the leading underscore (that we consumed) if it is to handle - multi-digit numbers. */ - if (consume_following_underscore) - value = consume_count (mangled); - else - value = consume_count_with_underscores (mangled); - - if (value != -1) - { - char buf[INTBUF_SIZE]; - sprintf (buf, "%d", value); - string_append (s, buf); - - /* Numbers not otherwise delimited, might have an underscore - appended as a delimeter, which we should skip. - - ??? This used to always remove a following underscore, which - is wrong. If other (arbitrary) cases are followed by an - underscore, we need to do something more radical. */ - - if ((value > 9 || consume_following_underscore) - && ! leave_following_underscore - && **mangled == '_') - (*mangled)++; - - /* All is well. */ - success = 1; - } - } - - return success; -} - -/* Demangle the real value in MANGLED. */ - -static int -demangle_real_value (work, mangled, s) - struct work_stuff *work; - const char **mangled; - string* s; -{ - if (**mangled == 'E') - return demangle_expression (work, mangled, s, tk_real); - - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - if (**mangled == '.') /* fraction */ - { - string_appendn (s, ".", 1); - (*mangled)++; - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - if (**mangled == 'e') /* exponent */ - { - string_appendn (s, "e", 1); - (*mangled)++; - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - - return 1; -} - -static int -demangle_template_value_parm (work, mangled, s, tk) - struct work_stuff *work; - const char **mangled; - string* s; - type_kind_t tk; -{ - int success = 1; - - if (**mangled == 'Y') - { - /* The next argument is a template parameter. */ - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return -1; - if (work->tmpl_argvec) - string_append (s, work->tmpl_argvec[idx]); - else - string_append_template_idx (s, idx); - } - else if (tk == tk_integral) - success = demangle_integral_value (work, mangled, s); - else if (tk == tk_char) - { - char tmp[2]; - int val; - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - string_appendn (s, "'", 1); - val = consume_count(mangled); - if (val <= 0) - success = 0; - else - { - tmp[0] = (char)val; - tmp[1] = '\0'; - string_appendn (s, &tmp[0], 1); - string_appendn (s, "'", 1); - } - } - else if (tk == tk_bool) - { - int val = consume_count (mangled); - if (val == 0) - string_appendn (s, "false", 5); - else if (val == 1) - string_appendn (s, "true", 4); - else - success = 0; - } - else if (tk == tk_real) - success = demangle_real_value (work, mangled, s); - else if (tk == tk_pointer || tk == tk_reference) - { - if (**mangled == 'Q') - success = demangle_qualified (work, mangled, s, - /*isfuncname=*/0, - /*append=*/1); - else - { - int symbol_len = consume_count (mangled); - if (symbol_len == -1) - return -1; - if (symbol_len == 0) - string_appendn (s, "0", 1); - else - { - char *p = xmalloc (symbol_len + 1), *q; - strncpy (p, *mangled, symbol_len); - p [symbol_len] = '\0'; - /* We use cplus_demangle here, rather than - internal_cplus_demangle, because the name of the entity - mangled here does not make use of any of the squangling - or type-code information we have built up thus far; it is - mangled independently. */ - q = VG_(cplus_demangle) (p, work->options); - if (tk == tk_pointer) - string_appendn (s, "&", 1); - /* FIXME: Pointer-to-member constants should get a - qualifying class name here. */ - if (q) - { - string_append (s, q); - free (q); - } - else - string_append (s, p); - free (p); - } - *mangled += symbol_len; - } - } - - return success; -} - -/* Demangle the template name in MANGLED. The full name of the - template (e.g., S) is placed in TNAME. The name without the - template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is - non-NULL. If IS_TYPE is nonzero, this template is a type template, - not a function template. If both IS_TYPE and REMEMBER are nonzero, - the template is remembered in the list of back-referenceable - types. */ - -static int -demangle_template (work, mangled, tname, trawname, is_type, remember) - struct work_stuff *work; - const char **mangled; - string *tname; - string *trawname; - int is_type; - int remember; -{ - int i; - int r; - int need_comma = 0; - int success = 0; - const char *start; - int is_java_array = 0; - string temp; - int bindex = 0; - - (*mangled)++; - if (is_type) - { - if (remember) - bindex = register_Btype (work); - start = *mangled; - /* get template name */ - if (**mangled == 'z') - { - int idx; - (*mangled)++; - (*mangled)++; - - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return (0); - - if (work->tmpl_argvec) - { - string_append (tname, work->tmpl_argvec[idx]); - if (trawname) - string_append (trawname, work->tmpl_argvec[idx]); - } - else - { - string_append_template_idx (tname, idx); - if (trawname) - string_append_template_idx (trawname, idx); - } - } - else - { - if ((r = consume_count (mangled)) <= 0 - || (int) strlen (*mangled) < r) - { - return (0); - } - is_java_array = (work -> options & DMGL_JAVA) - && strncmp (*mangled, "JArray1Z", 8) == 0; - if (! is_java_array) - { - string_appendn (tname, *mangled, r); - } - if (trawname) - string_appendn (trawname, *mangled, r); - *mangled += r; - } - } - if (!is_java_array) - string_append (tname, "<"); - /* get size of template parameter list */ - if (!get_count (mangled, &r)) - { - return (0); - } - if (!is_type) - { - /* Create an array for saving the template argument values. */ - work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); - work->ntmpl_args = r; - for (i = 0; i < r; i++) - work->tmpl_argvec[i] = 0; - } - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - - if (!is_type) - { - /* Save the template argument. */ - int len = temp.p - temp.b; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], temp.b, len); - work->tmpl_argvec[i][len] = '\0'; - } - } - string_delete(&temp); - if (!success) - { - break; - } - } - /* z for template parameters */ - else if (**mangled == 'z') - { - int r2; - (*mangled)++; - success = demangle_template_template_parm (work, mangled, tname); - - if (success - && (r2 = consume_count (mangled)) > 0 - && (int) strlen (*mangled) >= r2) - { - string_append (tname, " "); - string_appendn (tname, *mangled, r2); - if (!is_type) - { - /* Save the template argument. */ - int len = r2; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], *mangled, len); - work->tmpl_argvec[i][len] = '\0'; - } - *mangled += r2; - } - if (!success) - { - break; - } - } - else - { - string param; - string* s; - - /* otherwise, value parameter */ - - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - string_delete(&temp); - if (!success) - break; - - if (!is_type) - { - s = ¶m; - string_init (s); - } - else - s = tname; - - success = demangle_template_value_parm (work, mangled, s, - (type_kind_t) success); - - if (!success) - { - if (!is_type) - string_delete (s); - success = 0; - break; - } - - if (!is_type) - { - int len = s->p - s->b; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], s->b, len); - work->tmpl_argvec[i][len] = '\0'; - - string_appends (tname, s); - string_delete (s); - } - } - need_comma = 1; - } - if (is_java_array) - { - string_append (tname, "[]"); - } - else - { - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, ">"); - } - - if (is_type && remember) - remember_Btype (work, tname->b, LEN_STRING (tname), bindex); - - /* - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - } - */ - return (success); -} - -static int -arm_pt (work, mangled, n, anchor, args) - struct work_stuff *work; - const char *mangled; - int n; - const char **anchor, **args; -{ - /* Check if ARM template with "__pt__" in it ("parameterized type") */ - /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ - if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - if (AUTO_DEMANGLING || EDG_DEMANGLING) - { - if ((*anchor = strstr (mangled, "__tm__")) - || (*anchor = strstr (mangled, "__ps__")) - || (*anchor = strstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - else if ((*anchor = strstr (mangled, "__S"))) - { - int len; - *args = *anchor + 3; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - } - - return 0; -} - -static void -demangle_arm_hp_template (work, mangled, n, declp) - struct work_stuff *work; - const char **mangled; - int n; - string *declp; -{ - const char *p; - const char *args; - const char *e = *mangled + n; - string arg; - - /* Check for HP aCC template spec: classXt1t2 where t1, t2 are - template args */ - if (HP_DEMANGLING && ((*mangled)[n] == 'X')) - { - char *start_spec_args = NULL; - - /* First check for and omit template specialization pseudo-arguments, - such as in "Spec<#1,#1.*>" */ - start_spec_args = strchr (*mangled, '<'); - if (start_spec_args && (start_spec_args - *mangled < n)) - string_appendn (declp, *mangled, start_spec_args - *mangled); - else - string_appendn (declp, *mangled, n); - (*mangled) += n + 1; - string_init (&arg); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - string_append (declp, "<"); - while (1) - { - string_clear (&arg); - switch (**mangled) - { - case 'T': - /* 'T' signals a type parameter */ - (*mangled)++; - if (!do_type (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'U': - case 'S': - /* 'U' or 'S' signals an integral value */ - if (!do_hpacc_template_const_value (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'A': - /* 'A' signals a named constant expression (literal) */ - if (!do_hpacc_template_literal (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - default: - /* Today, 1997-09-03, we have only the above types - of template parameters */ - /* FIXME: maybe this should fail and return null */ - goto hpacc_template_args_done; - } - string_appends (declp, &arg); - /* Check if we're at the end of template args. - 0 if at end of static member of template class, - _ if done with template args for a function */ - if ((**mangled == '\000') || (**mangled == '_')) - break; - else - string_append (declp, ","); - } - hpacc_template_args_done: - string_append (declp, ">"); - string_delete (&arg); - if (**mangled == '_') - (*mangled)++; - return; - } - /* ARM template? (Also handles HP cfront extensions) */ - else if (arm_pt (work, *mangled, n, &p, &args)) - { - string type_str; - - string_init (&arg); - string_appendn (declp, *mangled, p - *mangled); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - string_append (declp, "<"); - /* should do error checking here */ - while (args < e) { - string_clear (&arg); - - /* Check for type or literal here */ - switch (*args) - { - /* HP cfront extensions to ARM for template args */ - /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ - /* FIXME: We handle only numeric literals for HP cfront */ - case 'X': - /* A typed constant value follows */ - args++; - if (!do_type (work, &args, &type_str)) - goto cfront_template_args_done; - string_append (&arg, "("); - string_appends (&arg, &type_str); - string_append (&arg, ")"); - if (*args != 'L') - goto cfront_template_args_done; - args++; - /* Now snarf a literal value following 'L' */ - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - - case 'L': - /* Snarf a literal following 'L' */ - args++; - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - default: - /* Not handling other HP cfront stuff */ - if (!do_type (work, &args, &arg)) - goto cfront_template_args_done; - } - string_appends (declp, &arg); - string_append (declp, ","); - } - cfront_template_args_done: - string_delete (&arg); - if (args >= e) - --declp->p; /* remove extra comma */ - string_append (declp, ">"); - } - else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 - && (*mangled)[9] == 'N' - && (*mangled)[8] == (*mangled)[10] - && strchr (cplus_markers, (*mangled)[8])) - { - /* A member of the anonymous namespace. */ - string_append (declp, "{anonymous}"); - } - else - { - if (work->temp_start == -1) /* non-recursive call only */ - work->temp_start = 0; /* disable in recursive calls */ - string_appendn (declp, *mangled, n); - } - *mangled += n; -} - -/* Extract a class name, possibly a template with arguments, from the - mangled string; qualifiers, local class indicators, etc. have - already been dealt with */ - -static int -demangle_class_name (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 0; - - n = consume_count (mangled); - if (n == -1) - return 0; - if ((int) strlen (*mangled) >= n) - { - demangle_arm_hp_template (work, mangled, n, declp); - success = 1; - } - - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_class -- demangle a mangled class sequence - -SYNOPSIS - - static int - demangle_class (struct work_stuff *work, const char **mangled, - strint *declp) - -DESCRIPTION - - DECLP points to the buffer into which demangling is being done. - - *MANGLED points to the current token to be demangled. On input, - it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) - On exit, it points to the next token after the mangled class on - success, or the first unconsumed token on failure. - - If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then - we are demangling a constructor or destructor. In this case - we prepend "class::class" or "class::~class" to DECLP. - - Otherwise, we prepend "class::" to the current DECLP. - - Reset the constructor/destructor flags once they have been - "consumed". This allows demangle_class to be called later during - the same demangling, to do normal class demangling. - - Returns 1 if demangling is successful, 0 otherwise. - -*/ - -static int -demangle_class (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - int btype; - string class_name; - char *save_class_name_end = 0; - - string_init (&class_name); - btype = register_Btype (work); - if (demangle_class_name (work, mangled, &class_name)) - { - save_class_name_end = class_name.p; - if ((work->constructor & 1) || (work->destructor & 1)) - { - /* adjust so we don't include template args */ - if (work->temp_start && (work->temp_start != -1)) - { - class_name.p = class_name.b + work->temp_start; - } - string_prepends (declp, &class_name); - if (work -> destructor & 1) - { - string_prepend (declp, "~"); - work -> destructor -= 1; - } - else - { - work -> constructor -= 1; - } - } - class_name.p = save_class_name_end; - remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); - remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); - string_prepend (declp, SCOPE_STRING (work)); - string_prepends (declp, &class_name); - success = 1; - } - string_delete (&class_name); - return (success); -} - - -/* Called when there's a "__" in the mangled name, with `scan' pointing to - the rightmost guess. - - Find the correct "__"-sequence where the function name ends and the - signature starts, which is ambiguous with GNU mangling. - Call demangle_signature here, so we can make sure we found the right - one; *mangled will be consumed so caller will not make further calls to - demangle_signature. */ - -static int -iterate_demangle_function (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; -{ - const char *mangle_init = *mangled; - int success = 0; - string decl_init; - struct work_stuff work_init; - - if (*(scan + 2) == '\0') - return 0; - - /* Do not iterate for some demangling modes, or if there's only one - "__"-sequence. This is the normal case. */ - if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING - || strstr (scan + 2, "__") == NULL) - { - demangle_function_name (work, mangled, declp, scan); - return 1; - } - - /* Save state so we can restart if the guess at the correct "__" was - wrong. */ - string_init (&decl_init); - string_appends (&decl_init, declp); - memset (&work_init, 0, sizeof work_init); - work_stuff_copy_to_from (&work_init, work); - - /* Iterate over occurrences of __, allowing names and types to have a - "__" sequence in them. We must start with the first (not the last) - occurrence, since "__" most often occur between independent mangled - parts, hence starting at the last occurrence inside a signature - might get us a "successful" demangling of the signature. */ - - while (scan[2]) - { - demangle_function_name (work, mangled, declp, scan); - success = demangle_signature (work, mangled, declp); - if (success) - break; - - /* Reset demangle state for the next round. */ - *mangled = mangle_init; - string_clear (declp); - string_appends (declp, &decl_init); - work_stuff_copy_to_from (work, &work_init); - - /* Leave this underscore-sequence. */ - scan += 2; - - /* Scan for the next "__" sequence. */ - while (*scan && (scan[0] != '_' || scan[1] != '_')) - scan++; - - /* Move to last "__" in this sequence. */ - while (*scan && *scan == '_') - scan++; - scan -= 2; - } - - /* Delete saved state. */ - delete_work_stuff (&work_init); - string_delete (&decl_init); - - return success; -} - -/* - -LOCAL FUNCTION - - demangle_prefix -- consume the mangled name prefix and find signature - -SYNOPSIS - - static int - demangle_prefix (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the prefix of the mangled name. - While processing the function name root, arrange to call - demangle_signature if the root is ambiguous. - - DECLP points to the string buffer into which demangled output is - placed. On entry, the buffer is empty. On exit it contains - the root function name, the demangled operator name, or in some - special cases either nothing or the completely demangled result. - - MANGLED points to the current pointer into the mangled name. As each - token of the mangled name is consumed, it is updated. Upon entry - the current mangled name pointer points to the first character of - the mangled name. Upon exit, it should point to the first character - of the signature if demangling was successful, or to the first - unconsumed character if demangling of the prefix was unsuccessful. - - Returns 1 on success, 0 otherwise. - */ - -static int -demangle_prefix (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - const char *scan; - int i; - - if (strlen(*mangled) > 6 - && (strncmp(*mangled, "_imp__", 6) == 0 - || strncmp(*mangled, "__imp_", 6) == 0)) - { - /* it's a symbol imported from a PE dynamic library. Check for both - new style prefix _imp__ and legacy __imp_ used by older versions - of dlltool. */ - (*mangled) += 6; - work->dllimported = 1; - } - else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) - { - char *marker = strchr (cplus_markers, (*mangled)[8]); - if (marker != NULL && *marker == (*mangled)[10]) - { - if ((*mangled)[9] == 'D') - { - /* it's a GNU global destructor to be executed at program exit */ - (*mangled) += 11; - work->destructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - else if ((*mangled)[9] == 'I') - { - /* it's a GNU global constructor to be executed at program init */ - (*mangled) += 11; - work->constructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - } - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0) - { - /* it's a ARM global destructor to be executed at program exit */ - (*mangled) += 7; - work->destructor = 2; - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0) - { - /* it's a ARM global constructor to be executed at program initial */ - (*mangled) += 7; - work->constructor = 2; - } - - /* This block of code is a reduction in strength time optimization - of: - scan = strstr (*mangled, "__"); */ - - { - scan = *mangled; - - do { - scan = strchr (scan, '_'); - } while (scan != NULL && *++scan != '_'); - - if (scan != NULL) --scan; - } - - if (scan != NULL) - { - /* We found a sequence of two or more '_', ensure that we start at - the last pair in the sequence. */ - /* i = strspn (scan, "_"); */ - i = 0; - while (scan[i] == '_') i++; - if (i > 2) - { - scan += (i - 2); - } - } - - if (scan == NULL) - { - success = 0; - } - else if (work -> static_type) - { - if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't')) - { - success = 0; - } - } - else if ((scan == *mangled) - && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q') - || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) - { - /* The ARM says nothing about the mangling of local variables. - But cfront mangles local variables by prepending __ - to them. As an extension to ARM demangling we handle this case. */ - if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) - && ISDIGIT ((unsigned char)scan[2])) - { - *mangled = scan + 2; - consume_count (mangled); - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - else - { - /* A GNU style constructor starts with __[0-9Qt]. But cfront uses - names like __Q2_3foo3bar for nested type names. So don't accept - this style of constructor for cfront demangling. A GNU - style member-template constructor starts with 'H'. */ - if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)) - work -> constructor += 1; - *mangled = scan + 2; - } - } - else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') - { - /* Cfront-style parameterized type. Handled later as a signature. */ - success = 1; - - /* ARM template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm') - || (scan[2] == 'p' && scan[3] == 's') - || (scan[2] == 'p' && scan[3] == 't'))) - { - /* EDG-style parameterized type. Handled later as a signature. */ - success = 1; - - /* EDG template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2]) - && (scan[2] != 't')) - { - /* Mangled name starts with "__". Skip over any leading '_' characters, - then find the next "__" that separates the prefix from the signature. - */ - if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - || (arm_special (mangled, declp) == 0)) - { - while (*scan == '_') - { - scan++; - } - if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) - { - /* No separator (I.E. "__not_mangled"), or empty signature - (I.E. "__not_mangled_either__") */ - success = 0; - } - else - return iterate_demangle_function (work, mangled, declp, scan); - } - } - else if (*(scan + 2) != '\0') - { - /* Mangled name does not start with "__" but does have one somewhere - in there with non empty stuff after it. Looks like a global - function name. Iterate over all "__":s until the right - one is found. */ - return iterate_demangle_function (work, mangled, declp, scan); - } - else - { - /* Doesn't look like a mangled name */ - success = 0; - } - - if (!success && (work->constructor == 2 || work->destructor == 2)) - { - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - return (success); -} - -/* - -LOCAL FUNCTION - - gnu_special -- special handling of gnu mangled strings - -SYNOPSIS - - static int - gnu_special (struct work_stuff *work, const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special GNU style mangling forms that don't fit - the normal pattern. For example: - - _$_3foo (destructor for class foo) - _vt$foo (foo virtual table) - _vt$foo$bar (foo::bar virtual table) - __vt_foo (foo virtual table, new style with thunks) - _3foo$varname (static data member) - _Q22rs2tu$vw (static data member) - __t6vector1Zii (constructor with template) - __thunk_4__$_7ostream (virtual function thunk) - */ - -static int -gnu_special (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *p; - - if ((*mangled)[0] == '_' - && strchr (cplus_markers, (*mangled)[1]) != NULL - && (*mangled)[2] == '_') - { - /* Found a GNU style destructor, get past "__" */ - (*mangled) += 3; - work -> destructor += 1; - } - else if ((*mangled)[0] == '_' - && (((*mangled)[1] == '_' - && (*mangled)[2] == 'v' - && (*mangled)[3] == 't' - && (*mangled)[4] == '_') - || ((*mangled)[1] == 'v' - && (*mangled)[2] == 't' - && strchr (cplus_markers, (*mangled)[3]) != NULL))) - { - /* Found a GNU style virtual table, get past "_vt" - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - if ((*mangled)[2] == 'v') - (*mangled) += 5; /* New style, with thunks: "__vt_" */ - else - (*mangled) += 4; /* Old style, no thunks: "_vt" */ - while (**mangled != '\0') - { - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, - 1); - break; - default: - if (ISDIGIT((unsigned char)*mangled[0])) - { - n = consume_count(mangled); - /* We may be seeing a too-large size, or else a - "." indicating a static local symbol. In - any case, declare victory and move on; *don't* try - to use n to allocate. */ - if (n > (int) strlen (*mangled)) - { - success = 1; - break; - } - } - else - { - /*n = strcspn (*mangled, cplus_markers);*/ - const char *check = *mangled; - n = 0; - while (*check) - if (strchr (cplus_markers, *check++) == NULL) - n++; - else - break; - } - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - - p = strpbrk (*mangled, cplus_markers); - if (success && ((p == NULL) || (p == *mangled))) - { - if (p != NULL) - { - string_append (declp, SCOPE_STRING (work)); - (*mangled)++; - } - } - else - { - success = 0; - break; - } - } - if (success) - string_append (declp, " virtual table"); - } - else if ((*mangled)[0] == '_' - && (strchr("0123456789Qt", (*mangled)[1]) != NULL) - && (p = strpbrk (*mangled, cplus_markers)) != NULL) - { - /* static data member, "_3foo$varname" for example */ - (*mangled)++; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - n = consume_count (mangled); - if (n < 0 || n > (long) strlen (*mangled)) - { - success = 0; - break; - } - - if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 - && (*mangled)[9] == 'N' - && (*mangled)[8] == (*mangled)[10] - && strchr (cplus_markers, (*mangled)[8])) - { - /* A member of the anonymous namespace. There's information - about what identifier or filename it was keyed to, but - it's just there to make the mangled name unique; we just - step over it. */ - string_append (declp, "{anonymous}"); - (*mangled) += n; - - /* Now p points to the marker before the N, so we need to - update it to the first marker after what we consumed. */ - p = strpbrk (*mangled, cplus_markers); - break; - } - - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - if (success && (p == *mangled)) - { - /* Consumed everything up to the cplus_marker, append the - variable name. */ - (*mangled)++; - string_append (declp, SCOPE_STRING (work)); - n = strlen (*mangled); - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - else - { - success = 0; - } - } - else if (strncmp (*mangled, "__thunk_", 8) == 0) - { - int delta; - - (*mangled) += 8; - delta = consume_count (mangled); - if (delta == -1) - success = 0; - else - { - char *method = internal_cplus_demangle (work, ++*mangled); - - if (method) - { - char buf[50]; - sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); - string_append (declp, buf); - string_append (declp, method); - free (method); - n = strlen (*mangled); - (*mangled) += n; - } - else - { - success = 0; - } - } - } - else if (strncmp (*mangled, "__t", 3) == 0 - && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) - { - p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; - (*mangled) += 4; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - success = do_type (work, mangled, declp); - break; - } - if (success && **mangled != '\0') - success = 0; - if (success) - string_append (declp, p); - } - else - { - success = 0; - } - return (success); -} - -static void -recursively_demangle(work, mangled, result, namelength) - struct work_stuff *work; - const char **mangled; - string *result; - int namelength; -{ - char * recurse = (char *)NULL; - char * recurse_dem = (char *)NULL; - - recurse = (char *) xmalloc (namelength + 1); - memcpy (recurse, *mangled, namelength); - recurse[namelength] = '\000'; - - recurse_dem = VG_(cplus_demangle) (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, namelength); - } - free (recurse); - *mangled += namelength; -} - -/* - -LOCAL FUNCTION - - arm_special -- special handling of ARM/lucid mangled strings - -SYNOPSIS - - static int - arm_special (const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special ARM style mangling forms that don't fit - the normal pattern. For example: - - __vtbl__3foo (foo virtual table) - __vtbl__3foo__3bar (bar::foo virtual table) - - */ - -static int -arm_special (mangled, declp) - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *scan; - - if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) - { - /* Found a ARM style virtual table, get past ARM_VTABLE_STRING - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - scan = *mangled + ARM_VTABLE_STRLEN; - while (*scan != '\0') /* first check it can be demangled */ - { - n = consume_count (&scan); - if (n == -1) - { - return (0); /* no good */ - } - scan += n; - if (scan[0] == '_' && scan[1] == '_') - { - scan += 2; - } - } - (*mangled) += ARM_VTABLE_STRLEN; - while (**mangled != '\0') - { - n = consume_count (mangled); - if (n == -1 - || n > (long) strlen (*mangled)) - return 0; - string_prependn (declp, *mangled, n); - (*mangled) += n; - if ((*mangled)[0] == '_' && (*mangled)[1] == '_') - { - string_prepend (declp, "::"); - (*mangled) += 2; - } - } - string_append (declp, " virtual table"); - } - else - { - success = 0; - } - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_qualified -- demangle 'Q' qualified name strings - -SYNOPSIS - - static int - demangle_qualified (struct work_stuff *, const char *mangled, - string *result, int isfuncname, int append); - -DESCRIPTION - - Demangle a qualified name, such as "Q25Outer5Inner" which is - the mangled form of "Outer::Inner". The demangled output is - prepended or appended to the result string according to the - state of the append flag. - - If isfuncname is nonzero, then the qualified name we are building - is going to be used as a member function name, so if it is a - constructor or destructor function, append an appropriate - constructor or destructor name. I.E. for the above example, - the result for use as a constructor is "Outer::Inner::Inner" - and the result for use as a destructor is "Outer::Inner::~Inner". - -BUGS - - Numeric conversion is ASCII dependent (FIXME). - - */ - -static int -demangle_qualified (work, mangled, result, isfuncname, append) - struct work_stuff *work; - const char **mangled; - string *result; - int isfuncname; - int append; -{ - int qualifiers = 0; - int success = 1; - string temp; - string last_name; - int bindex = register_Btype (work); - - /* We only make use of ISFUNCNAME if the entity is a constructor or - destructor. */ - isfuncname = (isfuncname - && ((work->constructor & 1) || (work->destructor & 1))); - - string_init (&temp); - string_init (&last_name); - - if ((*mangled)[0] == 'K') - { - /* Squangling qualified name reuse */ - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work -> numk) - success = 0; - else - string_append (&temp, work -> ktypevec[idx]); - } - else - switch ((*mangled)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is preceded - by an underscore (to distinguish it from the <= 9 case) and followed - by an underscore. */ - (*mangled)++; - qualifiers = consume_count_with_underscores (mangled); - if (qualifiers == -1) - success = 0; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* The count is in a single digit. */ - qualifiers = (*mangled)[1] - '0'; - - /* If there is an underscore after the digit, skip it. This is - said to be for ARM-qualified names, but the ARM makes no - mention of such an underscore. Perhaps cfront uses one. */ - if ((*mangled)[2] == '_') - { - (*mangled)++; - } - (*mangled) += 2; - break; - - case '0': - default: - success = 0; - } - - if (!success) - { - string_delete (&last_name); - string_delete (&temp); - return success; - } - - /* Pick off the names and collect them in the temp buffer in the order - in which they are found, separated by '::'. */ - - while (qualifiers-- > 0) - { - int remember_K = 1; - string_clear (&last_name); - - if (*mangled[0] == '_') - (*mangled)++; - - if (*mangled[0] == 't') - { - /* Here we always append to TEMP since we will want to use - the template name without the template parameters as a - constructor or destructor name. The appropriate - (parameter-less) value is returned by demangle_template - in LAST_NAME. We do not remember the template type here, - in order to match the G++ mangling algorithm. */ - success = demangle_template(work, mangled, &temp, - &last_name, 1, 0); - if (!success) - break; - } - else if (*mangled[0] == 'K') - { - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work->numk) - success = 0; - else - string_append (&temp, work->ktypevec[idx]); - remember_K = 0; - - if (!success) break; - } - else - { - if (EDG_DEMANGLING) - { - int namelength; - /* Now recursively demangle the qualifier - * This is necessary to deal with templates in - * mangling styles like EDG */ - namelength = consume_count (mangled); - if (namelength == -1) - { - success = 0; - break; - } - recursively_demangle(work, mangled, &temp, namelength); - } - else - { - string temp_last_name; - string_init (&temp_last_name); - success = do_type (work, mangled, &temp_last_name); - if (!success) - { - string_delete (&temp_last_name); - break; - } - string_appends (&temp, &temp_last_name); - string_appends (&last_name, &temp_last_name); - string_delete (&temp_last_name); - } - } - - if (remember_K) - remember_Ktype (work, temp.b, LEN_STRING (&temp)); - - if (qualifiers > 0) - string_append (&temp, SCOPE_STRING (work)); - } - - remember_Btype (work, temp.b, LEN_STRING (&temp), bindex); - - /* If we are using the result as a function name, we need to append - the appropriate '::' separated constructor or destructor name. - We do this here because this is the most convenient place, where - we already have a pointer to the name and the length of the name. */ - - if (isfuncname) - { - string_append (&temp, SCOPE_STRING (work)); - if (work -> destructor & 1) - string_append (&temp, "~"); - string_appends (&temp, &last_name); - } - - /* Now either prepend the temp buffer to the result, or append it, - depending upon the state of the append flag. */ - - if (append) - string_appends (result, &temp); - else - { - if (!STRING_EMPTY (result)) - string_append (&temp, SCOPE_STRING (work)); - string_prepends (result, &temp); - } - - string_delete (&last_name); - string_delete (&temp); - return (success); -} - -/* - -LOCAL FUNCTION - - get_count -- convert an ascii count to integer, consuming tokens - -SYNOPSIS - - static int - get_count (const char **type, int *count) - -DESCRIPTION - - Assume that *type points at a count in a mangled name; set - *count to its value, and set *type to the next character after - the count. There are some weird rules in effect here. - - If *type does not point at a string of digits, return zero. - - If *type points at a string of digits followed by an - underscore, set *count to their value as an integer, advance - *type to point *after the underscore, and return 1. - - If *type points at a string of digits not followed by an - underscore, consume only the first digit. Set *count to its - value as an integer, leave *type pointing after that digit, - and return 1. - - The excuse for this odd behavior: in the ARM and HP demangling - styles, a type can be followed by a repeat count of the form - `Nxy', where: - - `x' is a single digit specifying how many additional copies - of the type to append to the argument list, and - - `y' is one or more digits, specifying the zero-based index of - the first repeated argument in the list. Yes, as you're - unmangling the name you can figure this out yourself, but - it's there anyway. - - So, for example, in `bar__3fooFPiN51', the first argument is a - pointer to an integer (`Pi'), and then the next five arguments - are the same (`N5'), and the first repeat is the function's - second argument (`1'). -*/ - -static int -get_count (type, count) - const char **type; - int *count; -{ - const char *p; - int n; - - if (!ISDIGIT ((unsigned char)**type)) - return (0); - else - { - *count = **type - '0'; - (*type)++; - if (ISDIGIT ((unsigned char)**type)) - { - p = *type; - n = *count; - do - { - n *= 10; - n += *p - '0'; - p++; - } - while (ISDIGIT ((unsigned char)*p)); - if (*p == '_') - { - *type = p + 1; - *count = n; - } - } - } - return (1); -} - -/* RESULT will be initialised here; it will be freed on failure. The - value returned is really a type_kind_t. */ - -static int -do_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int n; - int done; - int success; - string decl; - const char *remembered_type; - int type_quals; - string btype; - type_kind_t tk = tk_none; - - string_init (&btype); - string_init (&decl); - string_init (result); - - done = 0; - success = 1; - while (success && !done) - { - int member; - switch (**mangled) - { - - /* A pointer type */ - case 'P': - case 'p': - (*mangled)++; - if (! (work -> options & DMGL_JAVA)) - string_prepend (&decl, "*"); - if (tk == tk_none) - tk = tk_pointer; - break; - - /* A reference type */ - case 'R': - (*mangled)++; - string_prepend (&decl, "&"); - if (tk == tk_none) - tk = tk_reference; - break; - - /* An array */ - case 'A': - { - ++(*mangled); - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - string_append (&decl, "["); - if (**mangled != '_') - success = demangle_template_value_parm (work, mangled, &decl, - tk_integral); - if (**mangled == '_') - ++(*mangled); - string_append (&decl, "]"); - break; - } - - /* A back reference to a previously seen type */ - case 'T': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> ntypes) - { - success = 0; - } - else - { - remembered_type = work -> typevec[n]; - mangled = &remembered_type; - } - break; - - /* A function */ - case 'F': - (*mangled)++; - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - /* After picking off the function args, we expect to either find the - function return type (preceded by an '_') or the end of the - string. */ - if (!demangle_nested_args (work, mangled, &decl) - || (**mangled != '_' && **mangled != '\0')) - { - success = 0; - break; - } - if (success && (**mangled == '_')) - (*mangled)++; - break; - - case 'M': - case 'O': - { - type_quals = TYPE_UNQUALIFIED; - - member = **mangled == 'M'; - (*mangled)++; - - string_append (&decl, ")"); - - /* We don't need to prepend `::' for a qualified name; - demangle_qualified will do that for us. */ - if (**mangled != 'Q') - string_prepend (&decl, SCOPE_STRING (work)); - - if (ISDIGIT ((unsigned char)**mangled)) - { - n = consume_count (mangled); - if (n == -1 - || (int) strlen (*mangled) < n) - { - success = 0; - break; - } - string_prependn (&decl, *mangled, n); - *mangled += n; - } - else if (**mangled == 'X' || **mangled == 'Y') - { - string temp; - do_type (work, mangled, &temp); - string_prepends (&decl, &temp); - } - else if (**mangled == 't') - { - string temp; - string_init (&temp); - success = demangle_template (work, mangled, &temp, - NULL, 1, 1); - if (success) - { - string_prependn (&decl, temp.b, temp.p - temp.b); - string_clear (&temp); - } - else - break; - } - else if (**mangled == 'Q') - { - success = demangle_qualified (work, mangled, &decl, - /*isfuncnam=*/0, - /*append=*/0); - if (!success) - break; - } - else - { - success = 0; - break; - } - - string_prepend (&decl, "("); - if (member) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - type_quals |= code_for_qualifier (**mangled); - (*mangled)++; - break; - - default: - break; - } - - if (*(*mangled)++ != 'F') - { - success = 0; - break; - } - } - if ((member && !demangle_nested_args (work, mangled, &decl)) - || **mangled != '_') - { - success = 0; - break; - } - (*mangled)++; - if (! PRINT_ANSI_QUALIFIERS) - { - break; - } - if (type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (&decl); - string_append (&decl, qualifier_string (type_quals)); - } - break; - } - case 'G': - (*mangled)++; - break; - - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (&decl)) - string_prepend (&decl, " "); - - string_prepend (&decl, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - /* - } - */ - - /* fall through */ - default: - done = 1; - break; - } - } - - if (success) switch (**mangled) - { - /* A qualified name, such as "Outer::Inner". */ - case 'Q': - case 'K': - { - success = demangle_qualified (work, mangled, result, 0, 1); - break; - } - - /* A back reference to a previously seen squangled type */ - case 'B': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> numb) - success = 0; - else - string_append (result, work->btypevec[n]); - break; - - case 'X': - case 'Y': - /* A template parm. We substitute the corresponding argument. */ - { - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - { - success = 0; - break; - } - - if (work->tmpl_argvec) - string_append (result, work->tmpl_argvec[idx]); - else - string_append_template_idx (result, idx); - - success = 1; - } - break; - - default: - success = demangle_fund_type (work, mangled, result); - if (tk == tk_none) - tk = (type_kind_t) success; - break; - } - - if (success) - { - if (!STRING_EMPTY (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - } - else - string_delete (result); - string_delete (&decl); - - if (success) - /* Assume an integral type, if we're not sure. */ - return (int) ((tk == tk_none) ? tk_integral : tk); - else - return 0; -} - -/* Given a pointer to a type string that represents a fundamental type - argument (int, long, unsigned int, etc) in TYPE, a pointer to the - string in which the demangled output is being built in RESULT, and - the WORK structure, decode the types and add them to the result. - - For example: - - "Ci" => "const int" - "Sl" => "signed long" - "CUs" => "const unsigned short" - - The value returned is really a type_kind_t. */ - -static int -demangle_fund_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int done = 0; - int success = 1; - char buf[10]; - unsigned int dec = 0; - string btype; - type_kind_t tk = tk_integral; - - string_init (&btype); - - /* First pick off any type qualifiers. There can be more than one. */ - - while (!done) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (result)) - string_prepend (result, " "); - string_prepend (result, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - case 'U': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "unsigned"); - break; - case 'S': /* signed char only */ - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "signed"); - break; - case 'J': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "__complex"); - break; - default: - done = 1; - break; - } - } - - /* Now pick off the fundamental type. There can be only one. */ - - switch (**mangled) - { - case '\0': - case '_': - break; - case 'v': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "void"); - break; - case 'x': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long long"); - break; - case 'l': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long"); - break; - case 'i': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "int"); - break; - case 's': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "short"); - break; - case 'b': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "bool"); - tk = tk_bool; - break; - case 'c': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "char"); - tk = tk_char; - break; - case 'w': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "wchar_t"); - tk = tk_char; - break; - case 'r': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long double"); - tk = tk_real; - break; - case 'd': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "double"); - tk = tk_real; - break; - case 'f': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "float"); - tk = tk_real; - break; - case 'G': - (*mangled)++; - if (!ISDIGIT ((unsigned char)**mangled)) - { - success = 0; - break; - } - case 'I': - (*mangled)++; - if (**mangled == '_') - { - int i; - (*mangled)++; - for (i = 0; - i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_'; - (*mangled)++, i++) - buf[i] = **mangled; - if (**mangled != '_') - { - success = 0; - break; - } - buf[i] = '\0'; - (*mangled)++; - } - else - { - strncpy (buf, *mangled, 2); - buf[2] = '\0'; - *mangled += min (strlen (*mangled), 2); - } - /*sscanf (buf, "%x", &dec); - sprintf (buf, "int%u_t", dec);*/ - sprintf (buf, "i_xx_t"); - APPEND_BLANK (result); - string_append (result, buf); - break; - - /* fall through */ - /* An explicit type, such as "6mytype" or "7integer" */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - int bindex = register_Btype (work); - string loc_btype; - string_init (&loc_btype); - if (demangle_class_name (work, mangled, &loc_btype)) { - remember_Btype (work, loc_btype.b, LEN_STRING (&loc_btype), bindex); - APPEND_BLANK (result); - string_appends (result, &loc_btype); - } - else - success = 0; - string_delete (&loc_btype); - break; - } - case 't': - { - success = demangle_template (work, mangled, &btype, 0, 1, 1); - string_appends (result, &btype); - break; - } - default: - success = 0; - break; - } - - string_delete (&btype); - - return success ? ((int) tk) : 0; -} - - -/* Handle a template's value parameter for HP aCC (extension from ARM) - **mangled points to 'S' or 'U' */ - -static int -do_hpacc_template_const_value (work, mangled, result) - struct work_stuff *work ATTRIBUTE_UNUSED; - const char **mangled; - string *result; -{ - int unsigned_const; - - if (**mangled != 'U' && **mangled != 'S') - return 0; - - unsigned_const = (**mangled == 'U'); - - (*mangled)++; - - switch (**mangled) - { - case 'N': - string_append (result, "-"); - /* fall through */ - case 'P': - (*mangled)++; - break; - case 'M': - /* special case for -2^31 */ - string_append (result, "-2147483648"); - (*mangled)++; - return 1; - default: - return 0; - } - - /* We have to be looking at an integer now */ - if (!(ISDIGIT ((unsigned char)**mangled))) - return 0; - - /* We only deal with integral values for template - parameters -- so it's OK to look only for digits */ - while (ISDIGIT ((unsigned char)**mangled)) - { - char_str[0] = **mangled; - string_append (result, char_str); - (*mangled)++; - } - - if (unsigned_const) - string_append (result, "U"); - - /* FIXME? Some day we may have 64-bit (or larger :-) ) constants - with L or LL suffixes. pai/1997-09-03 */ - - return 1; /* success */ -} - -/* Handle a template's literal parameter for HP aCC (extension from ARM) - **mangled is pointing to the 'A' */ - -static int -do_hpacc_template_literal (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int literal_len = 0; - char * recurse; - char * recurse_dem; - - if (**mangled != 'A') - return 0; - - (*mangled)++; - - literal_len = consume_count (mangled); - - if (literal_len <= 0) - return 0; - - /* Literal parameters are names of arrays, functions, etc. and the - canonical representation uses the address operator */ - string_append (result, "&"); - - /* Now recursively demangle the literal name */ - recurse = (char *) xmalloc (literal_len + 1); - memcpy (recurse, *mangled, literal_len); - recurse[literal_len] = '\000'; - - recurse_dem = VG_(cplus_demangle) (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, literal_len); - } - (*mangled) += literal_len; - free (recurse); - - return 1; -} - -static int -snarf_numeric_literal (args, arg) - const char ** args; - string * arg; -{ - if (**args == '-') - { - char_str[0] = '-'; - string_append (arg, char_str); - (*args)++; - } - else if (**args == '+') - (*args)++; - - if (!ISDIGIT ((unsigned char)**args)) - return 0; - - while (ISDIGIT ((unsigned char)**args)) - { - char_str[0] = **args; - string_append (arg, char_str); - (*args)++; - } - - return 1; -} - -/* Demangle the next argument, given by MANGLED into RESULT, which - *should be an uninitialized* string. It will be initialized here, - and free'd should anything go wrong. */ - -static int -do_arg (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - /* Remember where we started so that we can record the type, for - non-squangling type remembering. */ - const char *start = *mangled; - string temp_result; - - string_init (result); - string_init (&temp_result); - - if (work->nrepeats > 0) - { - --work->nrepeats; - - if (work->previous_argument == 0) - return 0; - - /* We want to reissue the previous type in this argument list. */ - string_appends (result, work->previous_argument); - return 1; - } - - if (**mangled == 'n') - { - /* A squangling-style repeat. */ - (*mangled)++; - work->nrepeats = consume_count(mangled); - - if (work->nrepeats <= 0) - /* This was not a repeat count after all. */ - return 0; - - if (work->nrepeats > 9) - { - if (**mangled != '_') - /* The repeat count should be followed by an '_' in this - case. */ - return 0; - else - (*mangled)++; - } - - /* Now, the repeat is all set up. */ - return do_arg (work, mangled, result); - } - - /* Save the result in WORK->previous_argument so that we can find it - if it's repeated. Note that saving START is not good enough: we - do not want to add additional types to the back-referenceable - type vector when processing a repeated type. */ - if (work->previous_argument) - string_clear (work->previous_argument); - else - { - work->previous_argument = (string*) xmalloc (sizeof (string)); - string_init (work->previous_argument); - } - - if (!do_type (work, mangled, &temp_result)) - { - string_delete (&temp_result); - return 0; - } - string_appends (work->previous_argument, &temp_result); - string_delete (&temp_result); - - string_appends (result, work->previous_argument); - - remember_type (work, start, *mangled - start); - return 1; -} - -static void -remember_type (work, start, len) - struct work_stuff *work; - const char *start; - int len; -{ - char *tem; - - if (work->forgetting_types) - return; - - if (work -> ntypes >= work -> typevec_size) - { - if (work -> typevec_size == 0) - { - work -> typevec_size = 3; - work -> typevec - = (char **) xmalloc (sizeof (char *) * work -> typevec_size); - } - else - { - work -> typevec_size *= 2; - work -> typevec - = (char **) xrealloc ((char *)work -> typevec, - sizeof (char *) * work -> typevec_size); - } - } - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> typevec[work -> ntypes++] = tem; -} - - -/* Remember a K type class qualifier. */ -static void -remember_Ktype (work, start, len) - struct work_stuff *work; - const char *start; - int len; -{ - char *tem; - - if (work -> numk >= work -> ksize) - { - if (work -> ksize == 0) - { - work -> ksize = 5; - work -> ktypevec - = (char **) xmalloc (sizeof (char *) * work -> ksize); - } - else - { - work -> ksize *= 2; - work -> ktypevec - = (char **) xrealloc ((char *)work -> ktypevec, - sizeof (char *) * work -> ksize); - } - } - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> ktypevec[work -> numk++] = tem; -} - -/* Register a B code, and get an index for it. B codes are registered - as they are seen, rather than as they are completed, so map > - registers map > as B0, and temp as B1 */ - -static int -register_Btype (work) - struct work_stuff *work; -{ - int ret; - - if (work -> numb >= work -> bsize) - { - if (work -> bsize == 0) - { - work -> bsize = 5; - work -> btypevec - = (char **) xmalloc (sizeof (char *) * work -> bsize); - } - else - { - work -> bsize *= 2; - work -> btypevec - = (char **) xrealloc ((char *)work -> btypevec, - sizeof (char *) * work -> bsize); - } - } - ret = work -> numb++; - work -> btypevec[ret] = NULL; - return(ret); -} - -/* Store a value into a previously registered B code type. */ - -static void -remember_Btype (work, start, len, ind) - struct work_stuff *work; - const char *start; - int len, ind; -{ - char *tem; - - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> btypevec[ind] = tem; -} - -/* Lose all the info related to B and K type codes. */ -static void -forget_B_and_K_types (work) - struct work_stuff *work; -{ - int i; - - while (work -> numk > 0) - { - i = --(work -> numk); - if (work -> ktypevec[i] != NULL) - { - free (work -> ktypevec[i]); - work -> ktypevec[i] = NULL; - } - } - - while (work -> numb > 0) - { - i = --(work -> numb); - if (work -> btypevec[i] != NULL) - { - free (work -> btypevec[i]); - work -> btypevec[i] = NULL; - } - } -} -/* Forget the remembered types, but not the type vector itself. */ - -static void -forget_types (work) - struct work_stuff *work; -{ - int i; - - while (work -> ntypes > 0) - { - i = --(work -> ntypes); - if (work -> typevec[i] != NULL) - { - free (work -> typevec[i]); - work -> typevec[i] = NULL; - } - } -} - -/* Process the argument list part of the signature, after any class spec - has been consumed, as well as the first 'F' character (if any). For - example: - - "__als__3fooRT0" => process "RT0" - "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" - - DECLP must be already initialised, usually non-empty. It won't be freed - on failure. - - Note that g++ differs significantly from ARM and lucid style mangling - with regards to references to previously seen types. For example, given - the source fragment: - - class foo { - public: - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); - }; - - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - - g++ produces the names: - - __3fooiRT0iT2iT2 - foo__FiR3fooiT1iT1 - - while lcc (and presumably other ARM style compilers as well) produces: - - foo__FiR3fooT1T2T1T2 - __ct__3fooFiR3fooT1T2T1T2 - - Note that g++ bases its type numbers starting at zero and counts all - previously seen types, while lucid/ARM bases its type numbers starting - at one and only considers types after it has seen the 'F' character - indicating the start of the function args. For lucid/ARM style, we - account for this difference by discarding any previously seen types when - we see the 'F' character, and subtracting one from the type number - reference. - - */ - -static int -demangle_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - string arg; - int need_comma = 0; - int r; - int t; - const char *tem; - char temptype; - - if (PRINT_ARG_TYPES) - { - string_append (declp, "("); - if (**mangled == '\0') - { - string_append (declp, "void"); - } - } - - while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e') - || work->nrepeats > 0) - { - if ((**mangled == 'N') || (**mangled == 'T')) - { - temptype = *(*mangled)++; - - if (temptype == 'N') - { - if (!get_count (mangled, &r)) - { - return (0); - } - } - else - { - r = 1; - } - if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10) - { - /* If we have 10 or more types we might have more than a 1 digit - index so we'll have to consume the whole count here. This - will lose if the next thing is a type name preceded by a - count but it's impossible to demangle that case properly - anyway. Eg if we already have 12 types is T12Pc "(..., type1, - Pc, ...)" or "(..., type12, char *, ...)" */ - if ((t = consume_count(mangled)) <= 0) - { - return (0); - } - } - else - { - if (!get_count (mangled, &t)) - { - return (0); - } - } - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - t--; - } - /* Validate the type index. Protect against illegal indices from - malformed type strings. */ - if ((t < 0) || (t >= work -> ntypes)) - { - return (0); - } - while (work->nrepeats > 0 || --r >= 0) - { - tem = work -> typevec[t]; - if (need_comma && PRINT_ARG_TYPES) - { - string_append (declp, ", "); - } - if (!do_arg (work, &tem, &arg)) - { - return (0); - } - if (PRINT_ARG_TYPES) - { - string_appends (declp, &arg); - } - string_delete (&arg); - need_comma = 1; - } - } - else - { - if (need_comma && PRINT_ARG_TYPES) - string_append (declp, ", "); - if (!do_arg (work, mangled, &arg)) - { - string_delete (&arg); - return (0); - } - if (PRINT_ARG_TYPES) - string_appends (declp, &arg); - string_delete (&arg); - need_comma = 1; - } - } - - if (**mangled == 'e') - { - (*mangled)++; - if (PRINT_ARG_TYPES) - { - if (need_comma) - { - string_append (declp, ","); - } - string_append (declp, "..."); - } - } - - if (PRINT_ARG_TYPES) - { - string_append (declp, ")"); - } - return (1); -} - -/* Like demangle_args, but for demangling the argument lists of function - and method pointers or references, not top-level declarations. */ - -static int -demangle_nested_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - string* saved_previous_argument; - int result; - int saved_nrepeats; - - /* The G++ name-mangling algorithm does not remember types on nested - argument lists, unless -fsquangling is used, and in that case the - type vector updated by remember_type is not used. So, we turn - off remembering of types here. */ - ++work->forgetting_types; - - /* For the repeat codes used with -fsquangling, we must keep track of - the last argument. */ - saved_previous_argument = work->previous_argument; - saved_nrepeats = work->nrepeats; - work->previous_argument = 0; - work->nrepeats = 0; - - /* Actually demangle the arguments. */ - result = demangle_args (work, mangled, declp); - - /* Restore the previous_argument field. */ - if (work->previous_argument) - { - string_delete (work->previous_argument); - free ((char*) work->previous_argument); - } - work->previous_argument = saved_previous_argument; - --work->forgetting_types; - work->nrepeats = saved_nrepeats; - - return result; -} - -static void -demangle_function_name (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; -{ - size_t i; - string type; - const char *tem; - - string_appendn (declp, (*mangled), scan - (*mangled)); - string_need (declp, 1); - *(declp -> p) = '\0'; - - /* Consume the function name, including the "__" separating the name - from the signature. We are guaranteed that SCAN points to the - separator. */ - - (*mangled) = scan + 2; - /* We may be looking at an instantiation of a template function: - foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a - following _F marks the start of the function arguments. Handle - the template arguments first. */ - - if (HP_DEMANGLING && (**mangled == 'X')) - { - demangle_arm_hp_template (work, mangled, 0, declp); - /* This leaves MANGLED pointing to the 'F' marking func args */ - } - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - - /* See if we have an ARM style constructor or destructor operator. - If so, then just record it, clear the decl, and return. - We can't build the actual constructor/destructor decl until later, - when we recover the class name from the signature. */ - - if (strcmp (declp -> b, "__ct") == 0) - { - work -> constructor += 1; - string_clear (declp); - return; - } - else if (strcmp (declp -> b, "__dt") == 0) - { - work -> destructor += 1; - string_clear (declp); - return; - } - } - - if (declp->p - declp->b >= 3 - && declp->b[0] == 'o' - && declp->b[1] == 'p' - && strchr (cplus_markers, declp->b[2]) != NULL) - { - /* see if it's an assignment expression */ - if (declp->p - declp->b >= 10 /* op$assign_ */ - && memcmp (declp->b + 3, "assign_", 7) == 0) - { - for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++) - { - int len = declp->p - declp->b - 10; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 10, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - string_append (declp, "="); - break; - } - } - } - else - { - for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++) - { - int len = declp->p - declp->b - 3; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 3, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 - && strchr (cplus_markers, declp->b[4]) != NULL) - { - /* type conversion operator */ - tem = declp->b + 5; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] == 'o' && declp->b[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = declp->b + 4; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && ISLOWER((unsigned char)declp->b[2]) - && ISLOWER((unsigned char)declp->b[3])) - { - if (declp->b[4] == '\0') - { - /* Operator. */ - for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, declp->b + 2, 2) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - else - { - if (declp->b[2] == 'a' && declp->b[5] == '\0') - { - /* Assignment. */ - for (i = 0; i < (size_t)ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, declp->b + 2, 3) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - } -} - -/* a mini string-handling package */ - -static void -string_need (s, n) - string *s; - int n; -{ - int tem; - - if (s->b == NULL) - { - if (n < 32) - { - n = 32; - } - s->p = s->b = xmalloc (n); - s->e = s->b + n; - } - else if (s->e - s->p < n) - { - tem = s->p - s->b; - n += tem; - n *= 2; - s->b = xrealloc (s->b, n); - s->p = s->b + tem; - s->e = s->b + n; - } -} - -static void -string_delete (s) - string *s; -{ - if (s->b != NULL) - { - free (s->b); - s->b = s->e = s->p = NULL; - } -} - -static void -string_init (s) - string *s; -{ - s->b = s->p = s->e = NULL; -} - -static void -string_clear (s) - string *s; -{ - s->p = s->b; -} - -#if 0 - -static int -string_empty (s) - string *s; -{ - return (s->b == s->p); -} - -#endif - -static void -string_append (p, s) - string *p; - const char *s; -{ - int n; - if (s == NULL || *s == '\0') - return; - n = strlen (s); - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; -} - -static void -string_appends (p, s) - string *p, *s; -{ - int n; - - if (s->b != s->p) - { - n = s->p - s->b; - string_need (p, n); - memcpy (p->p, s->b, n); - p->p += n; - } -} - -static void -string_appendn (p, s, n) - string *p; - const char *s; - int n; -{ - if (n != 0) - { - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; - } -} - -static void -string_prepend (p, s) - string *p; - const char *s; -{ - if (s != NULL && *s != '\0') - { - string_prependn (p, s, strlen (s)); - } -} - -static void -string_prepends (p, s) - string *p, *s; -{ - if (s->b != s->p) - { - string_prependn (p, s->b, s->p - s->b); - } -} - -static void -string_prependn (p, s, n) - string *p; - const char *s; - int n; -{ - char *q; - - if (n != 0) - { - string_need (p, n); - for (q = p->p - 1; q >= p->b; q--) - { - q[n] = q[0]; - } - memcpy (p->b, s, n); - p->p += n; - } -} - -static void -string_append_template_idx (s, idx) - string *s; - int idx; -{ - char buf[INTBUF_SIZE + 1 /* 'T' */]; - sprintf(buf, "T%d", idx); - string_append (s, buf); -} - -/* To generate a standalone demangler program for testing purposes, - just compile and link this file with -DMAIN and libiberty.a. When - run, it demangles each command line arg, or each stdin string, and - prints the result on stdout. */ - -#ifdef MAIN - -#include "getopt.h" - -static const char *program_name; -static const char *program_version = VERSION; -static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE; - -static void demangle_it PARAMS ((char *)); -static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN; -static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN; -static void print_demangler_list PARAMS ((FILE *)); - -static void -demangle_it (mangled_name) - char *mangled_name; -{ - char *result; - - /* For command line args, also try to demangle type encodings. */ - result = cplus_demangle (mangled_name, flags | DMGL_TYPES); - if (result == NULL) - { - printf ("%s\n", mangled_name); - } - else - { - printf ("%s\n", result); - free (result); - } -} - -static void -print_demangler_list (stream) - FILE *stream; -{ - const struct demangler_engine *demangler; - - fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name); - - for (demangler = libiberty_demanglers + 1; - demangler->demangling_style != unknown_demangling; - ++demangler) - fprintf (stream, ",%s", demangler->demangling_style_name); - - fprintf (stream, "}"); -} - -static void -usage (stream, status) - FILE *stream; - int status; -{ - fprintf (stream, "\ -Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n", - program_name); - - fprintf (stream, "\ - [-s "); - print_demangler_list (stream); - fprintf (stream, "]\n"); - - fprintf (stream, "\ - [--format "); - print_demangler_list (stream); - fprintf (stream, "]\n"); - - fprintf (stream, "\ - [--help] [--version] [arg...]\n"); - exit (status); -} - -#define MBUF_SIZE 32767 -char mbuffer[MBUF_SIZE]; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -int strip_underscore = 0; - -static const struct option long_options[] = { - {"strip-underscores", no_argument, 0, '_'}, - {"format", required_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"no-strip-underscores", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'v'}, - {0, no_argument, 0, 0} -}; - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - - -static const char * -standard_symbol_characters PARAMS ((void)); - -static const char * -hp_symbol_characters PARAMS ((void)); - -static const char * -gnu_v3_symbol_characters PARAMS ((void)); - -/* Return the string of non-alnum characters that may occur - as a valid symbol component, in the standard assembler symbol - syntax. */ - -static const char * -standard_symbol_characters () -{ - return "_$."; -} - - -/* Return the string of non-alnum characters that may occur - as a valid symbol name component in an HP object file. - - Note that, since HP's compiler generates object code straight from - C++ source, without going through an assembler, its mangled - identifiers can use all sorts of characters that no assembler would - tolerate, so the alphabet this function creates is a little odd. - Here are some sample mangled identifiers offered by HP: - - typeid*__XT24AddressIndExpClassMember_ - [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv - __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv - - This still seems really weird to me, since nowhere else in this - file is there anything to recognize curly brackets, parens, etc. - I've talked with Srikanth , and he assures me - this is right, but I still strongly suspect that there's a - misunderstanding here. - - If we decide it's better for c++filt to use HP's assembler syntax - to scrape identifiers out of its input, here's the definition of - the symbol name syntax from the HP assembler manual: - - Symbols are composed of uppercase and lowercase letters, decimal - digits, dollar symbol, period (.), ampersand (&), pound sign(#) and - underscore (_). A symbol can begin with a letter, digit underscore or - dollar sign. If a symbol begins with a digit, it must contain a - non-digit character. - - So have fun. */ -static const char * -hp_symbol_characters () -{ - return "_$.<>#,*&[]:(){}"; -} - - -/* Return the string of non-alnum characters that may occur - as a valid symbol component in the GNU C++ V3 ABI mangling - scheme. */ - -static const char * -gnu_v3_symbol_characters () -{ - return "_$."; -} - - -extern int main PARAMS ((int, char **)); - -int -main (argc, argv) - int argc; - char **argv; -{ - char *result; - int c; - const char *valid_symbols; - enum demangling_styles style = auto_demangling; - - program_name = argv[0]; - - strip_underscore = prepends_underscore; - - while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF) - { - switch (c) - { - case '?': - usage (stderr, 1); - break; - case 'h': - usage (stdout, 0); - case 'n': - strip_underscore = 0; - break; - case 'v': - printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version); - return (0); - case '_': - strip_underscore = 1; - break; - case 's': - { - style = cplus_demangle_name_to_style (optarg); - if (style == unknown_demangling) - { - fprintf (stderr, "%s: unknown demangling style `%s'\n", - program_name, optarg); - return (1); - } - else - cplus_demangle_set_style (style); - } - break; - } - } - - if (optind < argc) - { - for ( ; optind < argc; optind++) - { - demangle_it (argv[optind]); - } - } - else - { - switch (current_demangling_style) - { - case gnu_demangling: - case lucid_demangling: - case arm_demangling: - case java_demangling: - case edg_demangling: - case gnat_demangling: - case auto_demangling: - valid_symbols = standard_symbol_characters (); - break; - case hp_demangling: - valid_symbols = hp_symbol_characters (); - break; - case gnu_v3_demangling: - valid_symbols = gnu_v3_symbol_characters (); - break; - default: - /* Folks should explicitly indicate the appropriate alphabet for - each demangling. Providing a default would allow the - question to go unconsidered. */ - abort (); - } - - for (;;) - { - int i = 0; - c = getchar (); - /* Try to read a label. */ - while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c))) - { - if (i >= MBUF_SIZE-1) - break; - mbuffer[i++] = c; - c = getchar (); - } - if (i > 0) - { - int skip_first = 0; - - if (mbuffer[0] == '.' || mbuffer[0] == '$') - ++skip_first; - if (strip_underscore && mbuffer[skip_first] == '_') - ++skip_first; - - if (skip_first > i) - skip_first = i; - - mbuffer[i] = 0; - flags |= (int) style; - result = cplus_demangle (mbuffer + skip_first, flags); - if (result) - { - if (mbuffer[0] == '.') - putc ('.', stdout); - fputs (result, stdout); - free (result); - } - else - fputs (mbuffer, stdout); - - fflush (stdout); - } - if (c == EOF) - break; - putchar (c); - fflush (stdout); - } - } - - return (0); -} - -static void -fatal (str) - const char *str; -{ - fprintf (stderr, "%s: %s\n", program_name, str); - exit (1); -} - -PTR -xmalloc (size) - size_t size; -{ - register PTR value = (PTR) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -PTR -xrealloc (ptr, size) - PTR ptr; - size_t size; -{ - register PTR value = (PTR) realloc (ptr, size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} -#endif /* main */ diff --git a/VEX/head20041019/coregrind/demangle/demangle.h b/VEX/head20041019/coregrind/demangle/demangle.h deleted file mode 100644 index 238ae3398..000000000 --- a/VEX/head20041019/coregrind/demangle/demangle.h +++ /dev/null @@ -1,177 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, 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. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#include - -#define current_demangling_style VG_(current_demangling_style) - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -#define DMGL_HP (1 << 12) /* For the HP aCC compiler; - same as ARM except for - template arguments, etc. */ -#define DMGL_EDG (1 << 13) -#define DMGL_GNU_V3 (1 << 14) -#define DMGL_GNAT (1 << 15) - -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - no_demangling = -1, - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM, - hp_demangling = DMGL_HP, - edg_demangling = DMGL_EDG, - gnu_v3_demangling = DMGL_GNU_V3, - java_demangling = DMGL_JAVA, - gnat_demangling = DMGL_GNAT -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define NO_DEMANGLING_STYLE_STRING "none" -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" -#define HP_DEMANGLING_STYLE_STRING "hp" -#define EDG_DEMANGLING_STYLE_STRING "edg" -#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3" -#define JAVA_DEMANGLING_STYLE_STRING "java" -#define GNAT_DEMANGLING_STYLE_STRING "gnat" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM) -#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP) -#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG) -#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3) -#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA) -#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) - -/* Provide information about the available demangle styles. This code is - pulled from gdb into libiberty because it is useful to binutils also. */ - -extern const struct demangler_engine -{ - const char *const demangling_style_name; - const enum demangling_styles demangling_style; - const char *const demangling_style_doc; -} libiberty_demanglers[]; - -extern char * -VG_(cplus_demangle) PARAMS ((const char *mangled, int options)); - -/* -extern int -cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); -*/ - -/* -extern const char * -cplus_mangle_opname PARAMS ((const char *opname, int options)); -*/ - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -/* -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); -*/ - -/* -extern enum demangling_styles -cplus_demangle_set_style PARAMS ((enum demangling_styles style)); -*/ - -/* -extern enum demangling_styles -cplus_demangle_name_to_style PARAMS ((const char *name)); -*/ - -/* V3 ABI demangling entry points, defined in cp-demangle.c. */ -extern char* -VG_(cplus_demangle_v3) PARAMS ((const char* mangled)); - -extern char* -VG_(java_demangle_v3) PARAMS ((const char* mangled)); - - -enum gnu_v3_ctor_kinds { - gnu_v3_complete_object_ctor = 1, - gnu_v3_base_object_ctor, - gnu_v3_complete_object_allocating_ctor -}; - -/* Return non-zero iff NAME is the mangled form of a constructor name - in the G++ V3 ABI demangling style. Specifically, return an `enum - gnu_v3_ctor_kinds' value indicating what kind of constructor - it is. */ -/* -extern enum gnu_v3_ctor_kinds - is_gnu_v3_mangled_ctor PARAMS ((const char *name)); -*/ - - -enum gnu_v3_dtor_kinds { - gnu_v3_deleting_dtor = 1, - gnu_v3_complete_object_dtor, - gnu_v3_base_object_dtor -}; - -/* Return non-zero iff NAME is the mangled form of a destructor name - in the G++ V3 ABI demangling style. Specifically, return an `enum - gnu_v3_dtor_kinds' value, indicating what kind of destructor - it is. */ -/* -extern enum gnu_v3_dtor_kinds - is_gnu_v3_mangled_dtor PARAMS ((const char *name)); -*/ - -#endif /* DEMANGLE_H */ diff --git a/VEX/head20041019/coregrind/demangle/dyn-string.c b/VEX/head20041019/coregrind/demangle/dyn-string.c deleted file mode 100644 index 96a2f7dba..000000000 --- a/VEX/head20041019/coregrind/demangle/dyn-string.c +++ /dev/null @@ -1,439 +0,0 @@ -/* An abstract string datatype. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - Contributed by Mark Mitchell (mark@markmitchell.com). - -This file is part of GNU CC. - -GNU CC 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, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/*#ifdef HAVE_STRING_H -#include -#endif*/ - -/*#ifdef HAVE_STDLIB_H -#include -#endif*/ - -#include "core.h" -#include "ansidecl.h" -#include "dyn-string.h" - -#ifndef STANDALONE -#define malloc(s) VG_(arena_malloc) (VG_AR_DEMANGLE, s) -#define free(p) VG_(arena_free) (VG_AR_DEMANGLE, p) -#define realloc(p,s) VG_(arena_realloc)(VG_AR_DEMANGLE, p, VG_MIN_MALLOC_SZB, s) -#endif - -/* If this file is being compiled for inclusion in the C++ runtime - library, as part of the demangler implementation, we don't want to - abort if an allocation fails. Instead, percolate an error code up - through the call chain. */ - -#ifdef IN_LIBGCC2 -#define RETURN_ON_ALLOCATION_FAILURE -#endif - -/* Performs in-place initialization of a dyn_string struct. This - function can be used with a dyn_string struct on the stack or - embedded in another object. The contents of of the string itself - are still dynamically allocated. The string initially is capable - of holding at least SPACE characeters, including the terminating - NUL. If SPACE is 0, it will silently be increated to 1. - - If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation - fails, returns 0. Otherwise returns 1. */ - -int -dyn_string_init (ds_struct_ptr, space) - struct dyn_string *ds_struct_ptr; - int space; -{ - /* We need at least one byte in which to store the terminating NUL. */ - if (space == 0) - space = 1; - -#ifdef RETURN_ON_ALLOCATION_FAILURE - ds_struct_ptr->s = (char *) malloc (space); - if (ds_struct_ptr->s == NULL) - return 0; -#else - ds_struct_ptr->s = (char *) malloc (space); -#endif - ds_struct_ptr->allocated = space; - ds_struct_ptr->length = 0; - ds_struct_ptr->s[0] = '\0'; - - return 1; -} - -/* Create a new dynamic string capable of holding at least SPACE - characters, including the terminating NUL. If SPACE is 0, it will - be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is - defined and memory allocation fails, returns NULL. Otherwise - returns the newly allocated string. */ - -dyn_string_t -dyn_string_new (space) - int space; -{ - dyn_string_t result; -#ifdef RETURN_ON_ALLOCATION_FAILURE - result = (dyn_string_t) malloc (sizeof (struct dyn_string)); - if (result == NULL) - return NULL; - if (!dyn_string_init (result, space)) - { - free (result); - return NULL; - } -#else - result = (dyn_string_t) malloc (sizeof (struct dyn_string)); - dyn_string_init (result, space); -#endif - return result; -} - -/* Free the memory used by DS. */ - -void -dyn_string_delete (ds) - dyn_string_t ds; -{ - free (ds->s); - free (ds); -} - -/* Returns the contents of DS in a buffer allocated with malloc. It - is the caller's responsibility to deallocate the buffer using free. - DS is then set to the empty string. Deletes DS itself. */ - -char* -dyn_string_release (ds) - dyn_string_t ds; -{ - /* Store the old buffer. */ - char* result = ds->s; - /* The buffer is no longer owned by DS. */ - ds->s = NULL; - /* Delete DS. */ - free (ds); - /* Return the old buffer. */ - return result; -} - -/* Increase the capacity of DS so it can hold at least SPACE - characters, plus the terminating NUL. This function will not (at - present) reduce the capacity of DS. Returns DS on success. - - If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation - operation fails, deletes DS and returns NULL. */ - -dyn_string_t -dyn_string_resize (ds, space) - dyn_string_t ds; - int space; -{ - int new_allocated = ds->allocated; - - /* Increase SPACE to hold the NUL termination. */ - ++space; - - /* Increase allocation by factors of two. */ - while (space > new_allocated) - new_allocated *= 2; - - if (new_allocated != ds->allocated) - { - ds->allocated = new_allocated; - /* We actually need more space. */ -#ifdef RETURN_ON_ALLOCATION_FAILURE - ds->s = (char *) realloc (ds->s, ds->allocated); - if (ds->s == NULL) - { - free (ds); - return NULL; - } -#else - ds->s = (char *) realloc (ds->s, ds->allocated); -#endif - } - - return ds; -} - -/* Sets the contents of DS to the empty string. */ - -void -dyn_string_clear (ds) - dyn_string_t ds; -{ - /* A dyn_string always has room for at least the NUL terminator. */ - ds->s[0] = '\0'; - ds->length = 0; -} - -/* Makes the contents of DEST the same as the contents of SRC. DEST - and SRC must be distinct. Returns 1 on success. On failure, if - RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ - -int -dyn_string_copy (dest, src) - dyn_string_t dest; - dyn_string_t src; -{ - if (dest == src) - VG_(core_panic) ("dyn_string_copy: src==dest"); - - /* Make room in DEST. */ - if (dyn_string_resize (dest, src->length) == NULL) - return 0; - /* Copy DEST into SRC. */ - VG_(strcpy) (dest->s, src->s); - /* Update the size of DEST. */ - dest->length = src->length; - return 1; -} - -/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on - success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST - and returns 0. */ - -int -dyn_string_copy_cstr (dest, src) - dyn_string_t dest; - const char *src; -{ - int length = VG_(strlen) (src); - /* Make room in DEST. */ - if (dyn_string_resize (dest, length) == NULL) - return 0; - /* Copy DEST into SRC. */ - VG_(strcpy) (dest->s, src); - /* Update the size of DEST. */ - dest->length = length; - return 1; -} - -/* Inserts SRC at the beginning of DEST. DEST is expanded as - necessary. SRC and DEST must be distinct. Returns 1 on success. - On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and - returns 0. */ - -int -dyn_string_prepend (dest, src) - dyn_string_t dest; - dyn_string_t src; -{ - return dyn_string_insert (dest, 0, src); -} - -/* Inserts SRC, a NUL-terminated string, at the beginning of DEST. - DEST is expanded as necessary. Returns 1 on success. On failure, - if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ - -int -dyn_string_prepend_cstr (dest, src) - dyn_string_t dest; - const char *src; -{ - return dyn_string_insert_cstr (dest, 0, src); -} - -/* Inserts SRC into DEST starting at position POS. DEST is expanded - as necessary. SRC and DEST must be distinct. Returns 1 on - success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST - and returns 0. */ - -int -dyn_string_insert (dest, pos, src) - dyn_string_t dest; - int pos; - dyn_string_t src; -{ - int i; - - if (src == dest) - VG_(core_panic)( "dyn_string_insert: src==dest" ); - - if (dyn_string_resize (dest, dest->length + src->length) == NULL) - return 0; - /* Make room for the insertion. Be sure to copy the NUL. */ - for (i = dest->length; i >= pos; --i) - dest->s[i + src->length] = dest->s[i]; - /* Splice in the new stuff. */ - VG_(strncpy) (dest->s + pos, src->s, src->length); - /* Compute the new length. */ - dest->length += src->length; - return 1; -} - -/* Inserts SRC, a NUL-terminated string, into DEST starting at - position POS. DEST is expanded as necessary. Returns 1 on - success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST - and returns 0. */ - -int -dyn_string_insert_cstr (dest, pos, src) - dyn_string_t dest; - int pos; - const char *src; -{ - int i; - int length = VG_(strlen) (src); - - if (dyn_string_resize (dest, dest->length + length) == NULL) - return 0; - /* Make room for the insertion. Be sure to copy the NUL. */ - for (i = dest->length; i >= pos; --i) - dest->s[i + length] = dest->s[i]; - /* Splice in the new stuff. */ - VG_(strncpy) (dest->s + pos, src, length); - /* Compute the new length. */ - dest->length += length; - return 1; -} - -/* Inserts character C into DEST starting at position POS. DEST is - expanded as necessary. Returns 1 on success. On failure, - RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ - -int -dyn_string_insert_char (dest, pos, c) - dyn_string_t dest; - int pos; - int c; -{ - int i; - - if (dyn_string_resize (dest, dest->length + 1) == NULL) - return 0; - /* Make room for the insertion. Be sure to copy the NUL. */ - for (i = dest->length; i >= pos; --i) - dest->s[i + 1] = dest->s[i]; - /* Add the new character. */ - dest->s[pos] = c; - /* Compute the new length. */ - ++dest->length; - return 1; -} - -/* Append S to DS, resizing DS if necessary. Returns 1 on success. - On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and - returns 0. */ - -int -dyn_string_append (dest, s) - dyn_string_t dest; - dyn_string_t s; -{ - if (dyn_string_resize (dest, dest->length + s->length) == 0) - return 0; - VG_(strcpy) (dest->s + dest->length, s->s); - dest->length += s->length; - return 1; -} - -/* Append the NUL-terminated string S to DS, resizing DS if necessary. - Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, - deletes DEST and returns 0. */ - -int -dyn_string_append_cstr (dest, s) - dyn_string_t dest; - const char *s; -{ - int len = VG_(strlen) (s); - - /* The new length is the old length plus the size of our string, plus - one for the null at the end. */ - if (dyn_string_resize (dest, dest->length + len) == NULL) - return 0; - VG_(strcpy) (dest->s + dest->length, s); - dest->length += len; - return 1; -} - -/* Appends C to the end of DEST. Returns 1 on success. On failiure, - if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ - -int -dyn_string_append_char (dest, c) - dyn_string_t dest; - int c; -{ - /* Make room for the extra character. */ - if (dyn_string_resize (dest, dest->length + 1) == NULL) - return 0; - /* Append the character; it will overwrite the old NUL. */ - dest->s[dest->length] = c; - /* Add a new NUL at the end. */ - dest->s[dest->length + 1] = '\0'; - /* Update the length. */ - ++(dest->length); - return 1; -} - -/* Sets the contents of DEST to the substring of SRC starting at START - and ending before END. START must be less than or equal to END, - and both must be between zero and the length of SRC, inclusive. - Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, - deletes DEST and returns 0. */ - -int -dyn_string_substring (dest, src, start, end) - dyn_string_t dest; - dyn_string_t src; - int start; - int end; -{ - int i; - int length = end - start; - - /* - vg_assert (start > end || start > src->length || end > src->length); - */ - - /* Make room for the substring. */ - if (dyn_string_resize (dest, length) == NULL) - return 0; - /* Copy the characters in the substring, */ - for (i = length; --i >= 0; ) - dest->s[i] = src->s[start + i]; - /* NUL-terimate the result. */ - dest->s[length] = '\0'; - /* Record the length of the substring. */ - dest->length = length; - - return 1; -} - -/* Returns non-zero if DS1 and DS2 have the same contents. */ - -int -dyn_string_eq (ds1, ds2) - dyn_string_t ds1; - dyn_string_t ds2; -{ - /* If DS1 and DS2 have different lengths, they must not be the same. */ - if (ds1->length != ds2->length) - return 0; - else - return !VG_(strcmp) (ds1->s, ds2->s); -} diff --git a/VEX/head20041019/coregrind/demangle/dyn-string.h b/VEX/head20041019/coregrind/demangle/dyn-string.h deleted file mode 100644 index 9615cd64e..000000000 --- a/VEX/head20041019/coregrind/demangle/dyn-string.h +++ /dev/null @@ -1,96 +0,0 @@ -/* An abstract string datatype. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - Contributed by Mark Mitchell (mark@markmitchell.com). - -This file is part of GCC. - -GCC 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, or (at your option) -any later version. - -GCC 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 GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ -#ifndef __DYN_STRING_H -#define __DYN_STRING_H - - -typedef struct dyn_string -{ - int allocated; /* The amount of space allocated for the string. */ - int length; /* The actual length of the string. */ - char *s; /* The string itself, NUL-terminated. */ -}* dyn_string_t; - -/* The length STR, in bytes, not including the terminating NUL. */ -#define dyn_string_length(STR) \ - ((STR)->length) - -/* The NTBS in which the contents of STR are stored. */ -#define dyn_string_buf(STR) \ - ((STR)->s) - -/* Compare DS1 to DS2 with strcmp. */ -#define dyn_string_compare(DS1, DS2) \ - (VG_(strcmp) ((DS1)->s, (DS2)->s)) - - -/* dyn_string functions are used in the demangling implementation - included in the G++ runtime library. To prevent collisions with - names in user programs, the functions that are used in the - demangler are given implementation-reserved names. */ - -#if 1 /* def IN_LIBGCC2 */ - -#define dyn_string_init VG_(__cxa_dyn_string_init) -#define dyn_string_new VG_(__cxa_dyn_string_new) -#define dyn_string_delete VG_(__cxa_dyn_string_delete) -#define dyn_string_release VG_(__cxa_dyn_string_release) -#define dyn_string_resize VG_(__cxa_dyn_string_resize) -#define dyn_string_clear VG_(__cxa_dyn_string_clear) -#define dyn_string_copy VG_(__cxa_dyn_string_copy) -#define dyn_string_copy_cstr VG_(__cxa_dyn_string_copy_cstr) -#define dyn_string_prepend VG_(__cxa_dyn_string_prepend) -#define dyn_string_prepend_cstr VG_(__cxa_dyn_string_prepend_cstr) -#define dyn_string_insert VG_(__cxa_dyn_string_insert) -#define dyn_string_insert_cstr VG_(__cxa_dyn_string_insert_cstr) -#define dyn_string_insert_char VG_(__cxa_dyn_string_insert_char) -#define dyn_string_append VG_(__cxa_dyn_string_append) -#define dyn_string_append_cstr VG_(__cxa_dyn_string_append_cstr) -#define dyn_string_append_char VG_(__cxa_dyn_string_append_char) -#define dyn_string_substring VG_(__cxa_dyn_string_substring) -#define dyn_string_eq VG_(__cxa_dyn_string_eq) - -#endif /* IN_LIBGCC2 */ - - -extern int dyn_string_init PARAMS ((struct dyn_string *, int)); -extern dyn_string_t dyn_string_new PARAMS ((int)); -extern void dyn_string_delete PARAMS ((dyn_string_t)); -extern char *dyn_string_release PARAMS ((dyn_string_t)); -extern dyn_string_t dyn_string_resize PARAMS ((dyn_string_t, int)); -extern void dyn_string_clear PARAMS ((dyn_string_t)); -extern int dyn_string_copy PARAMS ((dyn_string_t, dyn_string_t)); -extern int dyn_string_copy_cstr PARAMS ((dyn_string_t, const char *)); -extern int dyn_string_prepend PARAMS ((dyn_string_t, dyn_string_t)); -extern int dyn_string_prepend_cstr PARAMS ((dyn_string_t, const char *)); -extern int dyn_string_insert PARAMS ((dyn_string_t, int, - dyn_string_t)); -extern int dyn_string_insert_cstr PARAMS ((dyn_string_t, int, - const char *)); -extern int dyn_string_insert_char PARAMS ((dyn_string_t, int, int)); -extern int dyn_string_append PARAMS ((dyn_string_t, dyn_string_t)); -extern int dyn_string_append_cstr PARAMS ((dyn_string_t, const char *)); -extern int dyn_string_append_char PARAMS ((dyn_string_t, int)); -extern int dyn_string_substring PARAMS ((dyn_string_t, - dyn_string_t, int, int)); -extern int dyn_string_eq PARAMS ((dyn_string_t, dyn_string_t)); - -#endif diff --git a/VEX/head20041019/coregrind/demangle/safe-ctype.c b/VEX/head20041019/coregrind/demangle/safe-ctype.c deleted file mode 100644 index 340abba2b..000000000 --- a/VEX/head20041019/coregrind/demangle/safe-ctype.c +++ /dev/null @@ -1,163 +0,0 @@ -/* replacement macros. - - Copyright (C) 2000 Free Software Foundation, Inc. - Contributed by Zack Weinberg . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is a compatible replacement of the standard C library's - with the following properties: - - - Implements all isxxx() macros required by C99. - - Also implements some character classes useful when - parsing C-like languages. - - Does not change behavior depending on the current locale. - - Behaves properly for all values in the range of a signed or - unsigned char. */ - -#include "ansidecl.h" -#include -/*#include */ /* for EOF */ - -/* Shorthand */ -#define bl _sch_isblank -#define cn _sch_iscntrl -#define di _sch_isdigit -#define is _sch_isidst -#define lo _sch_islower -#define nv _sch_isnvsp -#define pn _sch_ispunct -#define pr _sch_isprint -#define sp _sch_isspace -#define up _sch_isupper -#define vs _sch_isvsp -#define xd _sch_isxdigit - -/* Masks. */ -#define L lo|is |pr /* lower case letter */ -#define XL lo|is|xd|pr /* lowercase hex digit */ -#define U up|is |pr /* upper case letter */ -#define XU up|is|xd|pr /* uppercase hex digit */ -#define D di |xd|pr /* decimal digit */ -#define P pn |pr /* punctuation */ -#define _ pn|is |pr /* underscore */ - -#define C cn /* control character */ -#define Z nv |cn /* NUL */ -#define M nv|sp |cn /* cursor movement: \f \v */ -#define V vs|sp |cn /* vertical space: \r \n */ -#define T nv|sp|bl|cn /* tab */ -#define S nv|sp|bl|pr /* space */ - -/* Are we ASCII? */ -#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ - && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \ -/* && EOF == -1*/ - -const unsigned short _sch_istable[256] = -{ - Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */ - C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */ - C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ - C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */ - S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */ - P, P, P, P, P, P, P, P, /* ( ) * + , - . / */ - D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */ - D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */ - P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */ - U, U, U, U, U, U, U, U, /* H I J K L M N O */ - U, U, U, U, U, U, U, U, /* P Q R S T U V W */ - U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */ - P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */ - L, L, L, L, L, L, L, L, /* h i j k l m n o */ - L, L, L, L, L, L, L, L, /* p q r s t u v w */ - L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */ - - /* high half of unsigned char is locale-specific, so all tests are - false in "C" locale */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const unsigned char _sch_tolower[256] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, - - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - - 91, 92, 93, 94, 95, 96, - - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - - 123,124,125,126,127, - - 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, - 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, - 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, - 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, - - 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, - 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, - 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, - 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, -}; - -const unsigned char _sch_toupper[256] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, - - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - - 91, 92, 93, 94, 95, 96, - - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - - 123,124,125,126,127, - - 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, - 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, - 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, - 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, - - 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, - 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, - 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, - 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, -}; - -#else - #error "Unsupported host character set" -#endif /* not ASCII */ diff --git a/VEX/head20041019/coregrind/demangle/safe-ctype.h b/VEX/head20041019/coregrind/demangle/safe-ctype.h deleted file mode 100644 index b2ad8490b..000000000 --- a/VEX/head20041019/coregrind/demangle/safe-ctype.h +++ /dev/null @@ -1,103 +0,0 @@ -/* replacement macros. - - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Contributed by Zack Weinberg . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is a compatible replacement of the standard C library's - with the following properties: - - - Implements all isxxx() macros required by C99. - - Also implements some character classes useful when - parsing C-like languages. - - Does not change behavior depending on the current locale. - - Behaves properly for all values in the range of a signed or - unsigned char. - - To avoid conflicts, this header defines the isxxx functions in upper - case, e.g. ISALPHA not isalpha. */ - -#ifndef SAFE_CTYPE_H -#define SAFE_CTYPE_H - -#ifdef isalpha - #error "safe-ctype.h and ctype.h may not be used simultaneously" -#else - -/* Categories. */ - -enum { - /* In C99 */ - _sch_isblank = 0x0001, /* space \t */ - _sch_iscntrl = 0x0002, /* nonprinting characters */ - _sch_isdigit = 0x0004, /* 0-9 */ - _sch_islower = 0x0008, /* a-z */ - _sch_isprint = 0x0010, /* any printing character including ' ' */ - _sch_ispunct = 0x0020, /* all punctuation */ - _sch_isspace = 0x0040, /* space \t \n \r \f \v */ - _sch_isupper = 0x0080, /* A-Z */ - _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */ - - /* Extra categories useful to cpplib. */ - _sch_isidst = 0x0200, /* A-Za-z_ */ - _sch_isvsp = 0x0400, /* \n \r */ - _sch_isnvsp = 0x0800, /* space \t \f \v \0 */ - - /* Combinations of the above. */ - _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */ - _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */ - _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */ - _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */ - _sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */ - _sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C - (plus ` and @) */ -}; - -/* Character classification. */ -extern const unsigned short _sch_istable[256]; - -#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit)) - -#define ISALPHA(c) _sch_test(c, _sch_isalpha) -#define ISALNUM(c) _sch_test(c, _sch_isalnum) -#define ISBLANK(c) _sch_test(c, _sch_isblank) -#define ISCNTRL(c) _sch_test(c, _sch_iscntrl) -#define ISDIGIT(c) _sch_test(c, _sch_isdigit) -#define ISGRAPH(c) _sch_test(c, _sch_isgraph) -#define ISLOWER(c) _sch_test(c, _sch_islower) -#define ISPRINT(c) _sch_test(c, _sch_isprint) -#define ISPUNCT(c) _sch_test(c, _sch_ispunct) -#define ISSPACE(c) _sch_test(c, _sch_isspace) -#define ISUPPER(c) _sch_test(c, _sch_isupper) -#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit) - -#define ISIDNUM(c) _sch_test(c, _sch_isidnum) -#define ISIDST(c) _sch_test(c, _sch_isidst) -#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic) -#define IS_VSPACE(c) _sch_test(c, _sch_isvsp) -#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp) -#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp) - -/* Character transformation. */ -extern const unsigned char _sch_toupper[256]; -extern const unsigned char _sch_tolower[256]; -#define TOUPPER(c) _sch_toupper[(c) & 0xff] -#define TOLOWER(c) _sch_tolower[(c) & 0xff] - -#endif /* no ctype.h */ -#endif /* SAFE_CTYPE_H */ diff --git a/VEX/head20041019/coregrind/docs/.cvsignore b/VEX/head20041019/coregrind/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/coregrind/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/coregrind/docs/CVS/Entries b/VEX/head20041019/coregrind/docs/CVS/Entries deleted file mode 100644 index 5e7eb926d..000000000 --- a/VEX/head20041019/coregrind/docs/CVS/Entries +++ /dev/null @@ -1,6 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:29 2002// -/Makefile.am/1.5/Wed Aug 25 11:40:05 2004// -/coregrind_core.html/1.35/Thu Sep 2 08:10:13 2004// -/coregrind_intro.html/1.8/Wed Jan 21 13:59:23 2004// -/coregrind_tools.html/1.3/Thu Sep 2 08:51:41 2004// -D diff --git a/VEX/head20041019/coregrind/docs/CVS/Repository b/VEX/head20041019/coregrind/docs/CVS/Repository deleted file mode 100644 index 898d609ab..000000000 --- a/VEX/head20041019/coregrind/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/coregrind/docs diff --git a/VEX/head20041019/coregrind/docs/CVS/Root b/VEX/head20041019/coregrind/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/coregrind/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/coregrind/docs/CVS/Template b/VEX/head20041019/coregrind/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/coregrind/docs/Makefile.am b/VEX/head20041019/coregrind/docs/Makefile.am deleted file mode 100644 index 27a9e9bf5..000000000 --- a/VEX/head20041019/coregrind/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = coregrind_core.html coregrind_intro.html coregrind_tools.html diff --git a/VEX/head20041019/coregrind/docs/coregrind_core.html b/VEX/head20041019/coregrind/docs/coregrind_core.html deleted file mode 100644 index feaf757fc..000000000 --- a/VEX/head20041019/coregrind/docs/coregrind_core.html +++ /dev/null @@ -1,1552 +0,0 @@ - - - -

2  Using and understanding the Valgrind core

- -This section describes the Valgrind core services, flags and behaviours. That -means it is relevant regardless of what particular tool you are using. -A point of terminology: most references to "valgrind" in the rest of -this section (Section 2) refer to the valgrind core services. - - - -

2.1  What it does with your program

- -Valgrind is designed to be as non-intrusive as possible. It works -directly with existing executables. You don't need to recompile, -relink, or otherwise modify, the program to be checked. - -Simply put valgrind --tool=tool_name at the start of -the command line normally used to run the program. For example, -if want to run the command ls -l -using the heavyweight memory-checking tool Memcheck, issue the command: - -
- valgrind --tool=memcheck ls -l. -
- -

Regardless of which tool is in use, Valgrind takes control of your -program before it starts. Debugging information is read from the -executable and associated libraries, so that error messages and other -outputs can be phrased in terms of source code locations (if that is -appropriate) - -

-Your program is then run on a synthetic x86 CPU provided by the -Valgrind core. As new code is executed for the first time, the core -hands the code to the selected tool. The tool adds its own -instrumentation code to this and hands the result back to the core, -which coordinates the continued execution of this instrumented code. - -

-The amount of instrumentation code added varies widely between tools. -At one end of the scale, Memcheck adds code to check every -memory access and every value computed, increasing the size of the -code at least 12 times, and making it run 25-50 times slower than -natively. At the other end of the spectrum, the ultra-trivial "none" -tool (a.k.a. Nulgrind) adds no instrumentation at all and causes in total -"only" about a 4 times slowdown. - -

-Valgrind simulates every single instruction your program executes. -Because of this, the active tool checks, or profiles, not only the -code in your application but also in all supporting dynamically-linked -(.so-format) libraries, including the GNU C library, the -X client libraries, Qt, if you work with KDE, and so on. - -

-If you're using one of the error-detection tools, Valgrind will often -detect errors in libraries, for example the GNU C or X11 libraries, -which you have to use. You might not be interested in these errors, -since you probably have noo control over that code. Therefore, Valgrind -allows you to selectively suppress errors, by recording them in a -suppressions file which is read when Valgrind starts up. The build -mechanism attempts to select suppressions which give reasonable -behaviour for the libc and XFree86 versions detected on your machine. -To make it easier to write suppressions, you can use the ---gen-suppressions=yes option which tells Valgrind to print -out a suppression for each error that appears, which you can then copy -into a suppressions file. - -

-Different error-checking tools report different kinds of errors. The -suppression mechanism therefore allows you to say which tool or tool(s) -each suppression applies to. - - - -

2.2  Getting started

- -First off, consider whether it might be beneficial to recompile your -application and supporting libraries with debugging info enabled (the --g flag). Without debugging info, the best Valgrind tools -will be able to do is guess which function a particular piece of code -belongs to, which makes both error messages and profiling output -nearly useless. With -g, you'll hopefully get messages -which point directly to the relevant source code lines. - -

-Another flag you might like to consider, if you are working with -C++, is -fno-inline. That makes it easier to see the -function-call chain, which can help reduce confusion when navigating -around large C++ apps. For whatever it's worth, debugging -OpenOffice.org with Memcheck is a bit easier when using this flag. - -

-You don't have to do this, but doing so helps Valgrind produce more -accurate and less confusing error reports. Chances are you're set up -like this already, if you intended to debug your program with GNU gdb, -or some other debugger. - -

-This paragraph applies only if you plan to use Memcheck: -On rare occasions, optimisation levels -at -O2 and above have been observed to generate code which -fools Memcheck into wrongly reporting uninitialised value -errors. We have looked in detail into fixing this, and unfortunately -the result is that doing so would give a further significant slowdown -in what is already a slow tool. So the best solution is to turn off -optimisation altogether. Since this often makes things unmanagably -slow, a plausible compromise is to use -O. This gets -you the majority of the benefits of higher optimisation levels whilst -keeping relatively small the chances of false complaints from Memcheck. -All other tools (as far as we know) are unaffected by optimisation -level. - -

-Valgrind understands both the older "stabs" debugging format, used by -gcc versions prior to 3.1, and the newer DWARF2 format used by gcc 3.1 -and later. We continue to refine and debug our debug-info readers, -although the majority of effort will naturally enough go into the -newer DWARF2 reader. - -

-When you're ready to roll, just run your application as you would -normally, but place valgrind --tool=tool_name in -front of your usual command-line invocation. Note that you should run -the real (machine-code) executable here. If your application is -started by, for example, a shell or perl script, you'll need to modify -it to invoke Valgrind on the real executables. Running such scripts -directly under Valgrind will result in you getting error reports -pertaining to /bin/sh, /usr/bin/perl, or -whatever interpreter you're using. This may not be what you want and -can be confusing. You can force the issue by giving the flag ---trace-children=yes, but confusion is still likely. - - - -

2.3  The commentary

- -Valgrind tools write a commentary, a stream of text, detailing error -reports and other significant events. All lines in the commentary -have following form:
-
-  ==12345== some-message-from-Valgrind
-
- -

The 12345 is the process ID. This scheme makes it easy -to distinguish program output from Valgrind commentary, and also easy -to differentiate commentaries from different processes which have -become merged together, for whatever reason. - -

By default, Valgrind tools write only essential messages to the commentary, -so as to avoid flooding you with information of secondary importance. -If you want more information about what is happening, re-run, passing -the -v flag to Valgrind. - -

-You can direct the commentary to three different places: - -

    -
  • The default: send it to a file descriptor, which is by default 2 - (stderr). So, if you give the core no options, it will write - commentary to the standard error stream. If you want to send - it to some other file descriptor, for example number 9, - you can specify --log-fd=9. -

    -

  • A less intrusive option is to write the commentary to a file, - which you specify by --log-file=filename. Note - carefully that the commentary is not written to the file - you specify, but instead to one called - filename.pid12345, if for example the pid of the - traced process is 12345. This is helpful when valgrinding a whole - tree of processes at once, since it means that each process writes - to its own logfile, rather than the result being jumbled up in one - big logfile. -

    -

  • The least intrusive option is to send the commentary to a network - socket. The socket is specified as an IP address and port number - pair, like this: --log-socket=192.168.0.1:12345 if you - want to send the output to host IP 192.168.0.1 port 12345 (I have - no idea if 12345 is a port of pre-existing significance). You can - also omit the port number: --log-socket=192.168.0.1, - in which case a default port of 1500 is used. This default is - defined by the constant VG_CLO_DEFAULT_LOGPORT - in the sources. -

    - Note, unfortunately, that you have to use an IP address here, rather - than a hostname. -

    - Writing to a network socket is pretty useless if you don't have - something listening at the other end. We provide a simple - listener program, valgrind-listener, which accepts - connections on the specified port and copies whatever it is sent - to stdout. Probably someone will tell us this is a horrible - security risk. It seems likely that people will write more - sophisticated listeners in the fullness of time. -

    - valgrind-listener can accept simultaneous connections from up to 50 - valgrinded processes. In front of each line of output it prints - the current number of active connections in round brackets. -

    - valgrind-listener accepts two command-line flags: -

      -
    • -e or --exit-at-zero: when the - number of connected processes falls back to zero, exit. - Without this, it will run forever, that is, until you send it - Control-C. -

      -

    • portnumber: changes the port it listens on from - the default (1500). The specified port must be in the range - 1024 to 65535. The same restriction applies to port numbers - specified by a --log-socket= to Valgrind itself. -
    -

    - If a valgrinded process fails to connect to a listener, for - whatever reason (the listener isn't running, invalid or - unreachable host or port, etc), Valgrind switches back to writing - the commentary to stderr. The same goes for any process which - loses an established connection to a listener. In other words, - killing the listener doesn't kill the processes sending data to - it. -

-

-Here is an important point about the relationship between the -commentary and profiling output from tools. The commentary contains a -mix of messages from the Valgrind core and the selected tool. If the -tool reports errors, it will report them to the commentary. However, -if the tool does profiling, the profile data will be written to a file -of some kind, depending on the tool, and independent of what ---log-* options are in force. The commentary is intended -to be a low-bandwidth, human-readable channel. Profiling data, on the -other hand, is usually voluminous and not meaningful without further -processing, which is why we have chosen this arrangement. - - - -

2.4  Reporting of errors

- -When one of the error-checking tools (Memcheck, Addrcheck, Helgrind) -detects something bad happening in the program, an error message is -written to the commentary. For example:
-
-  ==25832== Invalid read of size 4
-  ==25832==    at 0x8048724: BandMatrix::ReSize(int, int, int) (bogon.cpp:45)
-  ==25832==    by 0x80487AF: main (bogon.cpp:66)
-  ==25832==    by 0x40371E5E: __libc_start_main (libc-start.c:129)
-  ==25832==    by 0x80485D1: (within /home/sewardj/newmat10/bogon)
-  ==25832==    Address 0xBFFFF74C is not stack'd, malloc'd or free'd
-
- -

-This message says that the program did an illegal 4-byte read of -address 0xBFFFF74C, which, as far as Memcheck can tell, is not a valid -stack address, nor corresponds to any currently malloc'd or free'd -blocks. The read is happening at line 45 of bogon.cpp, -called from line 66 of the same file, etc. For errors associated with -an identified malloc'd/free'd block, for example reading free'd -memory, Valgrind reports not only the location where the error -happened, but also where the associated block was malloc'd/free'd. - -

-Valgrind remembers all error reports. When an error is detected, -it is compared against old reports, to see if it is a duplicate. If -so, the error is noted, but no further commentary is emitted. This -avoids you being swamped with bazillions of duplicate error reports. - -

-If you want to know how many times each error occurred, run with the --v option. When execution finishes, all the reports are -printed out, along with, and sorted by, their occurrence counts. This -makes it easy to see which errors have occurred most frequently. - -

-Errors are reported before the associated operation actually happens. -If you're using a tool (Memcheck, Addrcheck) which does address -checking, and your program attempts to read from address zero, the -tool will emit a message to this effect, and the program will then -duly die with a segmentation fault. - -

-In general, you should try and fix errors in the order that they are -reported. Not doing so can be confusing. For example, a program -which copies uninitialised values to several memory locations, and -later uses them, will generate several error messages, when run on -Memcheck. The first such error message may well give the most direct -clue to the root cause of the problem. - -

-The process of detecting duplicate errors is quite an expensive one -and can become a significant performance overhead if your program -generates huge quantities of errors. To avoid serious problems here, -Valgrind will simply stop collecting errors after 300 different errors -have been seen, or 30000 errors in total have been seen. In this -situation you might as well stop your program and fix it, because -Valgrind won't tell you anything else useful after this. Note that -the 300/30000 limits apply after suppressed errors are removed. These -limits are defined in core.h and can be increased -if necessary. - -

-To avoid this cutoff you can use the --error-limit=no -flag. Then Valgrind will always show errors, regardless of how many -there are. Use this flag carefully, since it may have a dire effect -on performance. - - - -

2.5  Suppressing errors

- -The error-checking tools detect numerous problems in the base -libraries, such as the GNU C library, and the XFree86 client -libraries, which come pre-installed on your GNU/Linux system. You -can't easily fix these, but you don't want to see these errors (and -yes, there are many!) So Valgrind reads a list of errors to suppress -at startup. A default suppression file is cooked up by the -./configure script when the system is built. - -

-You can modify and add to the suppressions file at your leisure, -or, better, write your own. Multiple suppression files are allowed. -This is useful if part of your project contains errors you can't or -don't want to fix, yet you don't want to continuously be reminded of -them. - -

-Note: By far the easiest way to add suppressions is to use the ---gen-suppressions=yes flag described in this -section. - -

-Each error to be suppressed is described very specifically, to -minimise the possibility that a suppression-directive inadvertantly -suppresses a bunch of similar errors which you did want to see. The -suppression mechanism is designed to allow precise yet flexible -specification of errors to suppress. - -

-If you use the -v flag, at the end of execution, Valgrind -prints out one line for each used suppression, giving its name and the -number of times it got used. Here's the suppressions used by a run of -valgrind --tool=memcheck ls -l: -

-  --27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getgrgid_r
-  --27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getpwuid_r
-  --27579-- supp: 6 strrchr/_dl_map_object_from_fd/_dl_map_object
-
- -

-Multiple suppressions files are allowed. By default, Valgrind uses -$PREFIX/lib/valgrind/default.supp. You can ask to add -suppressions from another file, by specifying ---suppressions=/path/to/file.supp. - -

-If you want to understand more about suppressions, look at an existing -suppressions file whilst reading the following documentation. The file -glibc-2.2.supp, in the source distribution, provides some good -examples. - -

Each suppression has the following components:
-

    -
  • First line: its name. This merely gives a handy name to the suppression, - by which it is referred to in the summary of used suppressions printed - out when a program finishes. It's not important what the name is; any - identifying string will do. -
  • -

    - -

  • Second line: name of the tool(s) that the suppression is for (if more - than one, comma-separated), and the name of the suppression itself, - separated by a colon, eg: -
    -      tool_name1,tool_name2:suppression_name
    -      
    - (Nb: no spaces are allowed). -

    - Recall that Valgrind-2.0.X is a modular system, in which - different instrumentation tools can observe your program whilst - it is running. Since different tools detect different kinds of - errors, it is necessary to say which tool(s) the suppression is - meaningful to. -

    - Tools will complain, at startup, if a tool does not understand - any suppression directed to it. Tools ignore suppressions which - are not directed to them. As a result, it is quite practical to - put suppressions for all tools into the same suppression file. -

    - Valgrind's core can detect certain PThreads API errors, for which this - line reads: -

    -      core:PThread
    -      
    - -
  • Next line: a small number of suppression types have extra information - after the second line (eg. the Param suppression for - Memcheck)

    - -

  • Remaining lines: This is the calling context for the error -- the chain - of function calls that led to it. There can be up to four of these lines. -

    - Locations may be either names of shared objects/executables or wildcards - matching function names. They begin obj: and - fun: respectively. Function and object names to match - against may use the wildcard characters * and - ?. -

    - Important note: C++ function names must be mangled. If - you are writing suppressions by hand, use the --demangle=no - option to get the mangled names in your error messages. -

    - -

  • Finally, the entire suppression must be between curly braces. Each - brace must be the first character on its own line. -
- -

- -A suppression only suppresses an error when the error matches all the -details in the suppression. Here's an example: -

-  {
-    __gconv_transform_ascii_internal/__mbrtowc/mbtowc
-    Memcheck:Value4
-    fun:__gconv_transform_ascii_internal
-    fun:__mbr*toc
-    fun:mbtowc
-  }
-
- -

What is means is: for Memcheck only, suppress a -use-of-uninitialised-value error, when the data size is 4, when it -occurs in the function __gconv_transform_ascii_internal, -when that is called from any function of name matching -__mbr*toc, when that is called from mbtowc. -It doesn't apply under any other circumstances. The string by which -this suppression is identified to the user is -__gconv_transform_ascii_internal/__mbrtowc/mbtowc. -

-(See this section for more details on -the specifics of Memcheck's suppression kinds.) - -

Another example, again for the Memcheck tool: -

-  {
-    libX11.so.6.2/libX11.so.6.2/libXaw.so.7.0
-    Memcheck:Value4
-    obj:/usr/X11R6/lib/libX11.so.6.2
-    obj:/usr/X11R6/lib/libX11.so.6.2
-    obj:/usr/X11R6/lib/libXaw.so.7.0
-  }
-
- -

Suppress any size 4 uninitialised-value error which occurs anywhere -in libX11.so.6.2, when called from anywhere in the same -library, when called from anywhere in libXaw.so.7.0. The -inexact specification of locations is regrettable, but is about all -you can hope for, given that the X11 libraries shipped with Red Hat -7.2 have had their symbol tables removed. - -

Note -- since the above two examples did not make it clear -- that -you can freely mix the obj: and fun: -styles of description within a single suppression record. -

- - -

2.6  Command-line flags for the Valgrind core

- - -As mentioned above, Valgrind's core accepts a common set of flags. -The tools also accept tool-specific flags, which are documented -seperately for each tool. - -You invoke Valgrind like this: -
-  valgrind --tool=tool_name [options-for-Valgrind] your-prog [options for your-prog]
-
- -

Valgrind's default settings succeed in giving reasonable behaviour -in most cases. We group the available options by rough categories. - -

Tool-selection option

-The single most important option. -
    -
  • --tool=name
    -

    Run the Valgrind tool called name, e.g. Memcheck, Addrcheck, - Cachegrind, etc. -


  • -

- -

Basic Options

-These options work with all tools. - -
    -
  • --help
    -

    Show help for all options, both for the core and for the - selected tool.


  • - -

  • --help-debug
    -

    Same as --help, but also lists debugging options which - usually are only of use to developers.


  • - -

  • --version

    Show the version number of the - Valgrind core. Tools can have their own version numbers. There - is a scheme in place to ensure that tools only execute when the - core version is one they are known to work with. This was done - to minimise the chances of strange problems arising from - tool-vs-core version incompatibilities.


  • - -

  • -v --verbose

    Be more verbose. Gives extra - information on various aspects of your program, such as: the - shared objects loaded, the suppressions used, the progress of - the instrumentation and execution engines, and warnings about - unusual behaviour. Repeating the flag increases the verbosity - level.


  • - -

  • -q --quiet
    -

    Run silently, and only print error messages. Useful if you - are running regression tests or have some other automated test - machinery. -


  • - -

  • --trace-children=no [default]
    - --trace-children=yes -

    When enabled, Valgrind will trace into child processes. This - is confusing and often not what you want, so is disabled by - default. - -

    Note that the name of this option is slightly misleading. - It actually controls whether programs started with - exec() are run under Valgrind's control. If your - program calls fork(), both the parent and the child - will run under Valgrind's control. -


  • - -

  • --log-fd=<number> [default: 2, stderr] -

    Specifies that Valgrind should send all of its - messages to the specified file descriptor. The default, 2, is - the standard error channel (stderr). Note that this may - interfere with the client's own use of stderr. -


  • - -

  • --log-file=<filename> -

    Specifies that Valgrind should send all of its - messages to the specified file. In fact, the file name used - is created by concatenating the text filename, - ".pid" and the process ID, so as to create a file per process. - The specified file name may not be the empty string. -


  • - -

  • --log-socket=<ip-address:port-number> -

    Specifies that Valgrind should send all of its messages to - the specified port at the specified IP address. The port may be - omitted, in which case port 1500 is used. If a connection - cannot be made to the specified socket, Valgrind falls back to - writing output to the standard error (stderr). This option is - intended to be used in conjunction with the - valgrind-listener program. For further details, - see section 2.3. -


  • - -

  • --time-stamp=no [default]
    - --time-stamp=yes -

    Specifies that valgrind should output a timestamp before - each message that it outputs. -


  • -

- -

Error-related options

-These options are used by all tools that can report errors, e.g. Memcheck, but -not Cachegrind. -
    -
  • --demangle=no
    - --demangle=yes [default] -

    Disable/enable automatic demangling (decoding) of C++ names. - Enabled by default. When enabled, Valgrind will attempt to - translate encoded C++ procedure names back to something - approaching the original. The demangler handles symbols mangled - by g++ versions 2.X and 3.X. - -

    An important fact about demangling is that function - names mentioned in suppressions files should be in their mangled - form. Valgrind does not demangle function names when searching - for applicable suppressions, because to do otherwise would make - suppressions file contents dependent on the state of Valgrind's - demangling machinery, and would also be slow and pointless. -


  • - -

  • --num-callers=<number> [default=4]
    -

    By default, Valgrind shows four levels of function call names - to help you identify program locations. You can change that - number with this option. This can help in determining the - program's location in deeply-nested call chains. Note that errors - are commoned up using only the top three function locations (the - place in the current function, and that of its two immediate - callers). So this doesn't affect the total number of errors - reported. -

    - The maximum value for this is 50. Note that higher settings - will make Valgrind run a bit more slowly and take a bit more - memory, but can be useful when working with programs with - deeply-nested call chains. -


  • - -

  • --error-limit=yes [default]
    - --error-limit=no

    When enabled, Valgrind stops - reporting errors after 30000 in total, or 300 different ones, - have been seen. This is to stop the error tracking machinery - from becoming a huge performance overhead in programs with many - errors. -


  • - -

  • --show-below-main=yes
    - --show-below-main=no [default] -

    By default, stack traces for errors do not show any functions that - appear beneath main(); most of the time it's uninteresting - C library stuff. If this option is enabled, these entries below - main() will be shown. -


  • - -

  • --suppressions=<filename> - [default: $PREFIX/lib/valgrind/default.supp] -

    Specifies an extra - file from which to read descriptions of errors to suppress. You - may use as many extra suppressions files as you - like. -


  • - -

  • --gen-suppressions=no [default]
    - --gen-suppressions=yes -

    When enabled, Valgrind will pause after every error shown, - and print the line -
    - ---- Print suppression ? --- [Return/N/n/Y/y/C/c] ---- -

    - The prompt's behaviour is the same as for the --db-attach - option. -

    - If you choose to, Valgrind will print out a suppression for this error. - You can then cut and paste it into a suppression file if you don't want - to hear about the error in the future. -

    - This option is particularly useful with C++ programs, as it prints out - the suppressions with mangled names, as required. -

    - Note that the suppressions printed are as specific as possible. You - may want to common up similar ones, eg. by adding wildcards to function - names. Also, sometimes two different errors are suppressed by the same - suppression, in which case Valgrind will output the suppression more than - once, but you only need to have one copy in your suppression file (but - having more than one won't cause problems). Also, the suppression - name is given as <insert a suppression name here>; - the name doesn't really matter, it's only used with the - -v option which prints out all used suppression records. -


  • - -

  • --track-fds=no [default]
    - --track-fds=yes -

    When enabled, Valgrind will print out a list of open file - descriptors on exit. Along with each file descriptor, Valgrind - prints out a stack backtrace of where the file was opened and any - details relating to the file descriptor such as the file name or - socket details. -

    - -

  • --db-attach=no [default]
    - --db-attach=yes -

    When enabled, Valgrind will pause after every error shown, - and print the line -
    - ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- -

    - Pressing Ret, or N Ret - or n Ret, causes Valgrind not to - start a debugger for this error. -

    - Y Ret - or y Ret causes Valgrind to - start a debugger, for the program at this point. When you have - finished with the debugger, quit from it, and the program will continue. - Trying to continue from inside the debugger doesn't work. -

    - C Ret - or c Ret causes Valgrind not to - start a debugger, and not to ask again. -

    - --db-attach=yes conflicts with - --trace-children=yes. You can't use them together. - Valgrind refuses to start up in this situation. 1 May 2002: - this is a historical relic which could be easily fixed if it - gets in your way. Mail me and complain if this is a problem for - you. -

    - Nov 2002: if you're sending output to a logfile or to a network - socket, I guess this option doesn't make any sense. Caveat emptor. -


  • - -

  • --db-command=<command> [default: gdb -nw %f %p]
    -

    This specifies how Valgrind will invoke the debugger. By - default it will use whatever GDB is detected at build time, - which is usually /usr/bin/gdb. Using this command, - you can specify some alternative command to invoke the debugger - you want to use. -

    - The command string given can include one or instances of the - %p and %f expansions. Each instance of %p expands to the PID of - the process to be debugged and each instance of %f expands to - the path to the executable for the process to be debugged. -


  • - -

  • --input-fd=<number> [default=0, stdin]
    -

    When using --db-attach=yes and - --gen-suppressions=yes, Valgrind will stop - so as to read keyboard input from you, when each error occurs. - By default it reads from the standard input (stdin), which is - problematic for programs which close stdin. This option - allows you to specify an alternative file descriptor from - which to read input. -


  • -

- -

malloc()-related options

-For tools that use their own version of malloc() (e.g. Memcheck -and Addrcheck), the following options apply. -
    -
  • --alignment=<number> [default: 8]

    By - default Valgrind's malloc, realloc, - etc, return 4-byte aligned addresses. These are suitable for - any accesses on x86 processors. - Some programs might however assume that malloc et - al return 8- or more aligned memory. The supplied value must be - between 4 and 4096 inclusive, and must be a power of two.


  • - -

  • --sloppy-malloc=no [default]
    - --sloppy-malloc=yes -

    When enabled, all requests for malloc/calloc are rounded up - to a multiple of 4 bytes. For example, a request for 17 bytes of space - would result in a 20-byte area being made available. This works - around bugs in sloppy libraries which assume that they can - safely rely on malloc/calloc requests being rounded up in this - fashion. Without the workaround, these libraries tend to - generate large numbers of errors when they access the ends of - these areas. -

    - Valgrind snapshots dated 17 Feb 2002 and later are - cleverer about this problem, and you should no longer need to - use this flag. To put it bluntly, if you do need to use this - flag, your program violates the ANSI C semantics defined for - malloc and free, even if it appears to - work correctly, and you should fix it, at least if you hope for - maximum portability. -


  • -

- -

Rare options

-These options apply to all tools, as they affect certain obscure workings of -the Valgrind core. Most people won't need to use these. -
    -
  • --run-libc-freeres=yes [default]
    - --run-libc-freeres=no -

    The GNU C library (libc.so), which is used by - all programs, may allocate memory for its own uses. Usually it - doesn't bother to free that memory when the program ends - there - would be no point, since the Linux kernel reclaims all process - resources when a process exits anyway, so it would just slow - things down. -

    - The glibc authors realised that this behaviour causes leak - checkers, such as Valgrind, to falsely report leaks in glibc, - when a leak check is done at exit. In order to avoid this, they - provided a routine called __libc_freeres - specifically to make glibc release all memory it has allocated. - Memcheck and Addrcheck therefore try and run - __libc_freeres at exit. -

    - Unfortunately, in some versions of glibc, - __libc_freeres is sufficiently buggy to cause - segmentation faults. This is particularly noticeable on Red Hat - 7.1. So this flag is provided in order to inhibit the run of - __libc_freeres. If your program seems to run fine - on Valgrind, but segfaults at exit, you may find that - --run-libc-freeres=no fixes that, although at the - cost of possibly falsely reporting space leaks in - libc.so. -


  • - -

  • --weird-hacks=hack1,hack2,... - Pass miscellaneous hints to Valgrind which slightly modify the - simulated behaviour in nonstandard or dangerous ways, possibly - to help the simulation of strange features. By default no hacks - are enabled. Use with caution! Currently known hacks are: -

    -

      -
    • lax-ioctls Be very lax about ioctl handling; the only - assumption is that the size is correct. Doesn't require the full - buffer to be initialized when writing. Without this, using some - device drivers with a large number of strange ioctl commands becomes - very tiresome. -
    -

  • - -

  • --signal-polltime=<time> [default=50]
    -

    How often to poll for signals (in milliseconds). Only applies for - older kernels that need signal routing. -


  • - -

  • --lowlat-signals=no [default]
    - --lowlat-signals=yes
    -

    Improve wake-up latency when a thread receives a signal. -


  • - -

  • --lowlat-syscalls=no [default]
    - --lowlat-syscalls=yes
    -

    Improve wake-up latency when a thread's syscall completes. -


  • - -

- -There are also some options for debugging Valgrind itself. You -shouldn't need to use them in the normal run of things. Nevertheless: - -
    - -
  • --single-step=no [default]
    - --single-step=yes -

    When enabled, each x86 insn is translated separately into - instrumented code. When disabled, translation is done on a - per-basic-block basis, giving much better translations.


  • -

    - -

  • --optimise=no
    - --optimise=yes [default] -

    When enabled, various improvements are applied to the - intermediate code, mainly aimed at allowing the simulated CPU's - registers to be cached in the real CPU's registers over several - simulated instructions.


  • -

    - -

  • --profile=no
    - --profile=yes [default] -

    When enabled, does crude internal profiling of Valgrind - itself. This is not for profiling your programs. Rather it is - to allow the developers to assess where Valgrind is spending - its time. The tools must be built for profiling for this to - work. -


  • - -

  • --trace-syscalls=no [default]
    - --trace-syscalls=yes -

    Enable/disable tracing of system call intercepts.


  • -

    - -

  • --trace-signals=no [default]
    - --trace-signals=yes -

    Enable/disable tracing of signal handling.


  • -

    - -

  • --trace-sched=no [default]
    - --trace-sched=yes -

    Enable/disable tracing of thread scheduling events.


  • -

    - -

  • --trace-pthread=none [default]
    - --trace-pthread=some
    - --trace-pthread=all -

    Specifies amount of trace detail for pthread-related events.


  • -

    - -

  • --trace-symtab=no [default]
    - --trace-symtab=yes -

    Enable/disable tracing of symbol table reading.


  • -

    - -

  • --trace-malloc=no [default]
    - --trace-malloc=yes -

    Enable/disable tracing of malloc/free (et al) intercepts. -


  • -

    - -

  • --trace-codegen=XXXXX [default: 00000] -

    Enable/disable tracing of code generation. Code can be printed - at five different stages of translation; each X element - must be 0 or 1. -


  • -

    - -

  • --dump-error=<number> [default: inactive] -

    After the program has exited, show gory details of the - translation of the basic block containing the <number>'th - error context. When used with --single-step=yes, - can show the exact x86 instruction causing an error. This is - all fairly dodgy and doesn't work at all if threads are - involved.


  • -

    -

- -

Setting default options

- -

Note that Valgrind also reads options from three places: -

    -
  • The file ~/.valgrindrc -
  • The environment variable $VALGRIND_OPTS -
  • The file ./.valgrindrc -
-These are processed in the given order, before the command-line options. -Options processed later override those processed earlier; for example, -options in ./.valgrindrc will take precedence over those in -~/.valgrindrc. The first two are particularly useful for -setting the default tool to use. -

-Any tool-specific options put in $VALGRIND_OPTS or the -.valgrindrc files should be prefixed with the tool name and -a colon. For example, if you want Memcheck to always do leak checking, -you can put the following entry in ~/.valgrindrc: - -

-    --memcheck:leak-check=yes
-
- -This will be ignored if any tool other than Memcheck is run. -Without the memcheck: part, this will cause problems if you -select other tools that don't understand --leak-check=yes. - - - -

2.7  The Client Request mechanism

- -Valgrind has a trapdoor mechanism via which the client program can -pass all manner of requests and queries to Valgrind and the current tool. -Internally, this is used extensively to make malloc, free, signals, threads, -etc, work, although you don't see that. -

-For your convenience, a subset of these so-called client requests is -provided to allow you to tell Valgrind facts about the behaviour of -your program, and conversely to make queries. In particular, your -program can tell Valgrind about changes in memory range permissions -that Valgrind would not otherwise know about, and so allows clients to -get Valgrind to do arbitrary custom checks. -

-Clients need to include a header file to make this work. Which header file -depends on which client requests you use. Some client requests are handled by -the core, and are defined in the header file valgrind.h. -Tool-specific header files are named after the tool, e.g. -memcheck.h. All header files can be found in the -include directory of wherever Valgrind was installed. -

-The macros in these header files have the magical property that -they generate code in-line which Valgrind can spot. However, the code -does nothing when not run on Valgrind, so you are not forced to run -your program on Valgrind just because you use the macros in this file. -Also, you are not required to link your program with any extra -supporting libraries. -

-Here is a brief description of the macros available in -valgrind.h, which work with more than one tool (see the -tool-specific documentation for explanations of the tool-specific macros). -

    -
  • RUNNING_ON_VALGRIND: returns 1 if running on - Valgrind, 0 if running on the real CPU. -

    -

  • VALGRIND_DISCARD_TRANSLATIONS: discard translations - of code in the specified address range. Useful if you are - debugging a JITter or some other dynamic code generation system. - After this call, attempts to execute code in the invalidated - address range will cause Valgrind to make new translations of that - code, which is probably the semantics you want. Note that this is - implemented naively, and involves checking all 200191 entries in - the translation table to see if any of them overlap the specified - address range. So try not to call it often, or performance will - nosedive. Note that you can be clever about this: you only need - to call it when an area which previously contained code is - overwritten with new code. You can choose to write code into - fresh memory, and just call this occasionally to discard large - chunks of old code all at once. -

    - Warning: minimally tested, especially for tools other than Memcheck. -

    -

  • VALGRIND_COUNT_ERRORS: returns the number of errors - found so far by Valgrind. Can be useful in test harness code when - combined with the --log-fd=-1 option; this runs - Valgrind silently, but the client program can detect when errors - occur. Only useful for tools that report errors, e.g. it's useful for - Memcheck, but for Cachegrind it will always return zero because - Cachegrind doesn't report errors. -

    -

  • VALGRIND_MALLOCLIKE_BLOCK: If your program manages its own - memory instead of using the standard - malloc()/new/new[], tools that track - information about heap blocks will not do nearly as good a - job. For example, Memcheck won't detect nearly as many errors, and the - error messages won't be as informative. To improve this situation, use - this macro just after your custom allocator allocates some new memory. See - the comments in valgrind.h for information on how to use it. -

    -

  • VALGRIND_FREELIKE_BLOCK: This should be used in conjunction - with VALGRIND_MALLOCLIKE_BLOCK. Again, see - memcheck/memcheck.h for information on how to use it. -

    -

  • VALGRIND_CREATE_MEMPOOL: This is similar to - VALGRIND_MALLOCLIKE_BLOCK, but is tailored towards code - that uses memory pools. See the comments in valgrind.h - for information on how to use it. -

    -

  • VALGRIND_DESTROY_MEMPOOL: This should be used in - conjunction with VALGRIND_CREATE_MEMPOOL Again, see the - comments in valgrind.h for information on how to use it. -

    -

  • VALGRIND_MEMPOOL_ALLOC: This should be used in - conjunction with VALGRIND_CREATE_MEMPOOL Again, see the - comments in valgrind.h for information on how to use it. -

    -

  • VALGRIND_MEMPOOL_FREE: This should be used in - conjunction with VALGRIND_CREATE_MEMPOOL Again, see the - comments in valgrind.h for information on how to use it. -

    -

  • VALGRIND_NON_SIMD_CALL[0123]: executes a function of 0, 1, 2 - or 3 args in the client program on the real CPU, not the virtual - CPU that Valgrind normally runs code on. These are used in various ways - internally to Valgrind. They might be useful to client programs. - Warning: Only use these if you really know what you are - doing. -

    -

  • VALGRIND_PRINTF(format, ...): printf a message to the - log file when running under Valgrind. Nothing is output if not - running under Valgrind. Returns the number of characters output. -

    -

  • VALGRIND_PRINTF_BACKTRACE(format, ...): printf a message - to the log file along with a stack backtrace when running under - Valgrind. Nothing is output if not running under Valgrind. - Returns the number of characters output. -

    -

-Note that valgrind.h is included by all the tool-specific header -files (such as memcheck.h), so you don't need to include it in -your client if you include a tool-specific header. -

- - - -

2.8  Support for POSIX Pthreads

- -Valgrind supports programs which use POSIX pthreads. Getting this to work was -technically challenging but it all works well enough for significant threaded -applications to work. -

-It works as follows: threaded apps are (dynamically) linked against -libpthread.so. Usually this is the one installed with -your Linux distribution. Valgrind, however, supplies its own -libpthread.so and automatically connects your program to -it instead. -

-The fake libpthread.so and Valgrind cooperate to -implement a user-space pthreads package. This approach avoids the -horrible implementation problems of implementing a truly -multiprocessor version of Valgrind, but it does mean that threaded -apps run only on one CPU, even if you have a multiprocessor machine. -

-Valgrind schedules your threads in a round-robin fashion, with all -threads having equal priority. It switches threads every 50000 basic -blocks (typically around 300000 x86 instructions), which means you'll -get a much finer interleaving of thread executions than when run -natively. This in itself may cause your program to behave differently -if you have some kind of concurrency, critical race, locking, or -similar, bugs. -

-As of the Valgrind-1.0 release, the state of pthread support was as follows: -

    -
  • Mutexes, condition variables, thread-specific data, - pthread_once, reader-writer locks, semaphores, - cleanup stacks, cancellation and thread detaching currently work. - Various attribute-like calls are handled but ignored; you get a - warning message. -

    -

  • Currently the following syscalls are thread-safe (nonblocking): - write read nanosleep - sleep select poll - recvmsg and - accept. -

    -

  • Signals in pthreads are now handled properly(ish): - pthread_sigmask, pthread_kill, - sigwait and raise are now implemented. - Each thread has its own signal mask, as POSIX requires. - It's a bit kludgey -- there's a system-wide pending signal set, - rather than one for each thread. But hey. -
- -As of 18 May 02, the following threaded programs now work fine on my -RedHat 7.2 box: Opera 6.0Beta2, KNode in KDE 3.0, Mozilla-0.9.2.1 and -Galeon-0.11.3, both as supplied with RedHat 7.2. Also Mozilla 1.0RC2. -OpenOffice 1.0. MySQL 3.something (the current stable release). - - - - -

2.9  Handling of signals

- -Valgrind provides suitable handling of signals, so, provided you stick -to POSIX stuff, you should be ok. Basic sigaction() and sigprocmask() -are handled. Signal handlers may return in the normal way or do -longjmp(); both should work ok. As specified by POSIX, a signal is -blocked in its own handler. Default actions for signals should work -as before. Etc, etc. - -

Under the hood, dealing with signals is a real pain, and Valgrind's -simulation leaves much to be desired. If your program does -way-strange stuff with signals, bad things may happen. If so, let me -know. I don't promise to fix it, but I'd at least like to be aware of -it. - - - - -

2.10  Building and installing

- -We now use the standard Unix ./configure, -make, make install mechanism, and I have -attempted to ensure that it works on machines with kernel 2.4 or 2.6 -and glibc 2.2.X or 2.3.X. I don't think there is much else to say. -There are no options apart from the usual --prefix that -you should give to ./configure. - -

-The configure script tests the version of the X server -currently indicated by the current $DISPLAY. This is a -known bug. The intention was to detect the version of the current -XFree86 client libraries, so that correct suppressions could be -selected for them, but instead the test checks the server version. -This is just plain wrong. - -

-If you are building a binary package of Valgrind for distribution, -please read README_PACKAGERS. It contains some important -information. - -

-Apart from that there is no excitement here. Let me know if you have -build problems. - - - - -

2.11  If you have problems

-Contact us at valgrind.kde.org. - -

See this section for the known limitations of -Valgrind, and for a list of programs which are known not to work on -it. - -

The translator/instrumentor has a lot of assertions in it. They -are permanently enabled, and I have no plans to disable them. If one -of these breaks, please mail us! - -

If you get an assertion failure on the expression -chunkSane(ch) in vg_free() in -vg_malloc.c, this may have happened because your program -wrote off the end of a malloc'd block, or before its beginning. -Valgrind should have emitted a proper message to that effect before -dying in this way. This is a known problem which I should fix. - -

-Read the file FAQ.txt in the source distribution, for -more advice about common problems, crashes, etc. - - -

2.12  Limitations

- -The following list of limitations seems depressingly long. However, -most programs actually work fine. - -

Valgrind will run x86-GNU/Linux ELF dynamically linked binaries, on -a kernel 2.4.X or 2.6.X system, subject to the following constraints: - -

    -
  • No support for 3DNow instructions. If the translator encounters - these, Valgrind will generate a SIGILL when the instruction is - executed.
  • -

    - -

  • Pthreads support is improving, but there are still significant - limitations in that department. See the section above on - Pthreads. Note that your program must be dynamically linked - against libpthread.so, so that Valgrind can - substitute its own implementation at program startup time. If - you're statically linked against it, things will fail - badly.
  • -

    - -

  • Memcheck assumes that the floating point registers are - not used as intermediaries in memory-to-memory copies, so it - immediately checks definedness of values loaded from memory by - floating-point loads. If you want to write code which copies - around possibly-uninitialised values, you must ensure these - travel through the integer registers, not the FPU.
  • -

    - -

  • If your program does its own memory management, rather than - using malloc/new/free/delete, it should still work, but - Valgrind's error checking won't be so effective. - If you describe your program's memory management scheme - using "client requests" (Section 3.7 of this manual), - Memcheck can do better. Nevertheless, using malloc/new - and free/delete is still the best approach. -
  • -

    - -

  • Valgrind's signal simulation is not as robust as it could be. - Basic POSIX-compliant sigaction and sigprocmask functionality is - supplied, but it's conceivable that things could go badly awry - if you do weird things with signals. Workaround: don't. - Programs that do non-POSIX signal tricks are in any case - inherently unportable, so should be avoided if - possible.
  • -

    - -

  • Programs which switch stacks are not well handled. Valgrind - does have support for this, but I don't have great faith in it. - It's difficult -- there's no cast-iron way to decide whether a - large change in %esp is as a result of the program switching - stacks, or merely allocating a large object temporarily on the - current stack -- yet Valgrind needs to handle the two situations - differently.
  • -

    - -

  • x86 instructions, and system calls, have been implemented on - demand. So it's possible, although unlikely, that a program - will fall over with a message to that effect. If this happens, - please report ALL the details printed out, so we can try and - implement the missing feature.
  • -

    - -

  • x86 floating point works correctly, but floating-point code may - run even more slowly than integer code, due to my simplistic - approach to FPU emulation.
  • -

    - -

  • Memory consumption of your program is majorly increased whilst - running under Valgrind. This is due to the large amount of - administrative information maintained behind the scenes. Another - cause is that Valgrind dynamically translates the original - executable. Translated, instrumented code is 14-16 times larger - than the original (!) so you can easily end up with 30+ MB of - translations when running (eg) a web browser. -
  • -

    - -

  • Valgrind can handle dynamically-generated code just fine. - However, if you regenerate code over the top of old code - (ie. at the same memory addresses) Valgrind will not realise the - code has changed, and will run its old translations, which will - be out-of-date. You need to use the VALGRIND_DISCARD_TRANSLATIONS - client request in that case. For the same reason gcc's - - trampolines for nested functions are currently - unsupported, see - bug 69511. -
  • -

    - -

- -Programs which are known not to work are: - -
    -
  • emacs starts up but immediately concludes it is out of memory - and aborts. Emacs has it's own memory-management scheme, but I - don't understand why this should interact so badly with - Valgrind. Emacs works fine if you build it to use the standard - malloc/free routines.

  • -

    -

- -Known platform-specific limitations, as of release 1.0.0: - -
    -
  • On Red Hat 7.3, there have been reports of link errors (at - program start time) for threaded programs using - __pthread_clock_gettime and - __pthread_clock_settime. This appears to be due to - /lib/librt-2.2.5.so needing them. Unfortunately I - do not understand enough about this problem to fix it properly, - and I can't reproduce it on my test RedHat 7.3 system. Please - mail me if you have more information / understanding.

  • -

    -

- - - - -

2.13  How it works -- a rough overview

-Some gory details, for those with a passion for gory details. You -don't need to read this section if all you want to do is use Valgrind. -What follows is an outline of the machinery. A more detailed -(and somewhat out of date) description is to be found -here. - - -

2.13.1  Getting started

- -Valgrind is compiled into a shared object, valgrind.so. The shell -script valgrind sets the LD_PRELOAD environment variable to point to -valgrind.so. This causes the .so to be loaded as an extra library to -any subsequently executed dynamically-linked ELF binary, viz, the -program you want to debug. - -

The dynamic linker allows each .so in the process image to have an -initialisation function which is run before main(). It also allows -each .so to have a finalisation function run after main() exits. - -

When valgrind.so's initialisation function is called by the dynamic -linker, the synthetic CPU to starts up. The real CPU remains locked -in valgrind.so for the entire rest of the program, but the synthetic -CPU returns from the initialisation function. Startup of the program -now continues as usual -- the dynamic linker calls all the other .so's -initialisation routines, and eventually runs main(). This all runs on -the synthetic CPU, not the real one, but the client program cannot -tell the difference. - -

Eventually main() exits, so the synthetic CPU calls valgrind.so's -finalisation function. Valgrind detects this, and uses it as its cue -to exit. It prints summaries of all errors detected, possibly checks -for memory leaks, and then exits the finalisation routine, but now on -the real CPU. The synthetic CPU has now lost control -- permanently --- so the program exits back to the OS on the real CPU, just as it -would have done anyway. - -

On entry, Valgrind switches stacks, so it runs on its own stack. -On exit, it switches back. This means that the client program -continues to run on its own stack, so we can switch back and forth -between running it on the simulated and real CPUs without difficulty. -This was an important design decision, because it makes it easy (well, -significantly less difficult) to debug the synthetic CPU. - - - -

2.13.2  The translation/instrumentation engine

- -Valgrind does not directly run any of the original program's code. Only -instrumented translations are run. Valgrind maintains a translation -table, which allows it to find the translation quickly for any branch -target (code address). If no translation has yet been made, the -translator - a just-in-time translator - is summoned. This makes an -instrumented translation, which is added to the collection of -translations. Subsequent jumps to that address will use this -translation. - -

Valgrind no longer directly supports detection of self-modifying -code. Such checking is expensive, and in practice (fortunately) -almost no applications need it. However, to help people who are -debugging dynamic code generation systems, there is a Client Request -(basically a macro you can put in your program) which directs Valgrind -to discard translations in a given address range. So Valgrind can -still work in this situation provided the client tells it when -code has become out-of-date and needs to be retranslated. - -

The JITter translates basic blocks -- blocks of straight-line-code --- as single entities. To minimise the considerable difficulties of -dealing with the x86 instruction set, x86 instructions are first -translated to a RISC-like intermediate code, similar to sparc code, -but with an infinite number of virtual integer registers. Initially -each insn is translated seperately, and there is no attempt at -instrumentation. - -

The intermediate code is improved, mostly so as to try and cache -the simulated machine's registers in the real machine's registers over -several simulated instructions. This is often very effective. Also, -we try to remove redundant updates of the simulated machines's -condition-code register. - -

The intermediate code is then instrumented, giving more -intermediate code. There are a few extra intermediate-code operations -to support instrumentation; it is all refreshingly simple. After -instrumentation there is a cleanup pass to remove redundant value -checks. - -

This gives instrumented intermediate code which mentions arbitrary -numbers of virtual registers. A linear-scan register allocator is -used to assign real registers and possibly generate spill code. All -of this is still phrased in terms of the intermediate code. This -machinery is inspired by the work of Reuben Thomas (Mite). - -

Then, and only then, is the final x86 code emitted. The -intermediate code is carefully designed so that x86 code can be -generated from it without need for spare registers or other -inconveniences. - -

The translations are managed using a traditional LRU-based caching -scheme. The translation cache has a default size of about 14MB. - - - -

2.13.3  Tracking the status of memory

Each byte in the -process' address space has nine bits associated with it: one A bit and -eight V bits. The A and V bits for each byte are stored using a -sparse array, which flexibly and efficiently covers arbitrary parts of -the 32-bit address space without imposing significant space or -performance overheads for the parts of the address space never -visited. The scheme used, and speedup hacks, are described in detail -at the top of the source file vg_memory.c, so you should read that for -the gory details. - - - -

2.13.4 System calls

-All system calls are intercepted. The memory status map is consulted -before and updated after each call. It's all rather tiresome. See -coregrind/vg_syscalls.c for details. - - - -

2.13.5  Signals

-All system calls to sigaction() and sigprocmask() are intercepted. If -the client program is trying to set a signal handler, Valgrind makes a -note of the handler address and which signal it is for. Valgrind then -arranges for the same signal to be delivered to its own handler. - -

When such a signal arrives, Valgrind's own handler catches it, and -notes the fact. At a convenient safe point in execution, Valgrind -builds a signal delivery frame on the client's stack and runs its -handler. If the handler longjmp()s, there is nothing more to be said. -If the handler returns, Valgrind notices this, zaps the delivery -frame, and carries on where it left off before delivering the signal. - -

The purpose of this nonsense is that setting signal handlers -essentially amounts to giving callback addresses to the Linux kernel. -We can't allow this to happen, because if it did, signal handlers -would run on the real CPU, not the simulated one. This means the -checking machinery would not operate during the handler run, and, -worse, memory permissions maps would not be updated, which could cause -spurious error reports once the handler had returned. - -

An even worse thing would happen if the signal handler longjmp'd -rather than returned: Valgrind would completely lose control of the -client program. - -

Upshot: we can't allow the client to install signal handlers -directly. Instead, Valgrind must catch, on behalf of the client, any -signal the client asks to catch, and must delivery it to the client on -the simulated CPU, not the real one. This involves considerable -gruesome fakery; see vg_signals.c for details. -

- - - - -

2.14  An example run

-This is the log for a run of a small program using Memcheck -The program is in fact correct, and the reported error is as the -result of a potentially serious code generation bug in GNU g++ -(snapshot 20010527). -
-sewardj@phoenix:~/newmat10$
-~/Valgrind-6/valgrind -v ./bogon 
-==25832== Valgrind 0.10, a memory error detector for x86 RedHat 7.1.
-==25832== Copyright (C) 2000-2001, and GNU GPL'd, by Julian Seward.
-==25832== Startup, with flags:
-==25832== --suppressions=/home/sewardj/Valgrind/redhat71.supp
-==25832== reading syms from /lib/ld-linux.so.2
-==25832== reading syms from /lib/libc.so.6
-==25832== reading syms from /mnt/pima/jrs/Inst/lib/libgcc_s.so.0
-==25832== reading syms from /lib/libm.so.6
-==25832== reading syms from /mnt/pima/jrs/Inst/lib/libstdc++.so.3
-==25832== reading syms from /home/sewardj/Valgrind/valgrind.so
-==25832== reading syms from /proc/self/exe
-==25832== loaded 5950 symbols, 142333 line number locations
-==25832== 
-==25832== Invalid read of size 4
-==25832==    at 0x8048724: _ZN10BandMatrix6ReSizeEiii (bogon.cpp:45)
-==25832==    by 0x80487AF: main (bogon.cpp:66)
-==25832==    by 0x40371E5E: __libc_start_main (libc-start.c:129)
-==25832==    by 0x80485D1: (within /home/sewardj/newmat10/bogon)
-==25832==    Address 0xBFFFF74C is not stack'd, malloc'd or free'd
-==25832==
-==25832== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
-==25832== malloc/free: in use at exit: 0 bytes in 0 blocks.
-==25832== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
-==25832== For a detailed leak analysis, rerun with: --leak-check=yes
-==25832==
-==25832== exiting, did 1881 basic blocks, 0 misses.
-==25832== 223 translations, 3626 bytes in, 56801 bytes out.
-
-

The GCC folks fixed this about a week before gcc-3.0 shipped. -

- - -

2.15  Warning messages you might see

- -Most of these only appear if you run in verbose mode (enabled by --v): -
    -
  • More than 50 errors detected. Subsequent errors - will still be recorded, but in less detail than before. -
    - After 50 different errors have been shown, Valgrind becomes - more conservative about collecting them. It then requires only - the program counters in the top two stack frames to match when - deciding whether or not two errors are really the same one. - Prior to this point, the PCs in the top four frames are required - to match. This hack has the effect of slowing down the - appearance of new errors after the first 50. The 50 constant can - be changed by recompiling Valgrind. -

    -

  • More than 300 errors detected. I'm not reporting any more. - Final error counts may be inaccurate. Go fix your - program! -
    - After 300 different errors have been detected, Valgrind ignores - any more. It seems unlikely that collecting even more different - ones would be of practical help to anybody, and it avoids the - danger that Valgrind spends more and more of its time comparing - new errors against an ever-growing collection. As above, the 300 - number is a compile-time constant. -

    -

  • Warning: client switching stacks? -
    - Valgrind spotted such a large change in the stack pointer, %esp, - that it guesses the client is switching to a different stack. - At this point it makes a kludgey guess where the base of the new - stack is, and sets memory permissions accordingly. You may get - many bogus error messages following this, if Valgrind guesses - wrong. At the moment "large change" is defined as a change of - more that 2000000 in the value of the %esp (stack pointer) - register. -

    -

  • Warning: client attempted to close Valgrind's logfile fd <number> - -
    - Valgrind doesn't allow the client - to close the logfile, because you'd never see any diagnostic - information after that point. If you see this message, - you may want to use the --log-fd=<number> - option to specify a different logfile file-descriptor number. - Or -

    -

  • Warning: noted but unhandled ioctl <number> -
    - Valgrind observed a call to one of the vast family of - ioctl system calls, but did not modify its - memory status info (because I have not yet got round to it). - The call will still have gone through, but you may get spurious - errors after this as a result of the non-update of the memory info. -

    -

  • Warning: set address range perms: large range <number> -
    - Diagnostic message, mostly for benefit of the valgrind - developers, to do with memory permissions. -
- - - - - - diff --git a/VEX/head20041019/coregrind/docs/coregrind_intro.html b/VEX/head20041019/coregrind/docs/coregrind_intro.html deleted file mode 100644 index 662e205fc..000000000 --- a/VEX/head20041019/coregrind/docs/coregrind_intro.html +++ /dev/null @@ -1,162 +0,0 @@ - - - -

1  Introduction

- - -

1.1  An overview of Valgrind

- -Valgrind is a flexible system for debugging and profiling Linux-x86 -executables. The system consists of a core, which provides a synthetic -x86 CPU in software, and a series of tools, each of which performs some -kind of debugging, profiling, or similar task. The architecture is -modular, so that new tools can be created easily and without disturbing -the existing structure. - -

-A number of useful tools are supplied as standard. In summary, these -are: - -

    -
  • Memcheck detects memory-management problems in your programs. - All reads and writes of memory are checked, and calls to - malloc/new/free/delete are intercepted. As a result, Memcheck can - detect the following problems: -
      -
    • Use of uninitialised memory
    • -
    • Reading/writing memory after it has been free'd
    • -
    • Reading/writing off the end of malloc'd blocks
    • -
    • Reading/writing inappropriate areas on the stack
    • -
    • Memory leaks -- where pointers to malloc'd blocks are lost - forever
    • -
    • Mismatched use of malloc/new/new [] vs free/delete/delete []
    • -
    • Overlapping src and dst pointers in - memcpy() and related functions
    • -
    • Some misuses of the POSIX pthreads API
    • -
    -

    - Problems like these can be difficult to find by other means, often - lying undetected for long periods, then causing occasional, - difficult-to-diagnose crashes. -

    -

  • Addrcheck is a lightweight version of - Memcheck. It is identical to Memcheck except - for the single detail that it does not do any uninitialised-value - checks. All of the other checks -- primarily the fine-grained - address checking -- are still done. The downside of this is that - you don't catch the uninitialised-value errors that - Memcheck can find. -

    - But the upside is significant: programs run about twice as fast as - they do on Memcheck, and a lot less memory is used. It - still finds reads/writes of freed memory, memory off the end of - blocks and in other invalid places, bugs which you really want to - find before release! -

    - Because Addrcheck is lighter and faster than - Memcheck, you can run more programs for longer, and so you - may be able to cover more test scenarios. Addrcheck was - created because one of us (Julian) wanted to be able to - run a complete KDE desktop session with checking. As of early - November 2002, we have been able to run KDE-3.0.3 on a 1.7 GHz P4 - with 512 MB of memory, using Addrcheck. Although the - result is not stellar, it's quite usable, and it seems plausible - to run KDE for long periods at a time like this, collecting up - all the addressing errors that appear. -

    -

  • Cachegrind is a cache profiler. It performs detailed simulation of - the I1, D1 and L2 caches in your CPU and so can accurately - pinpoint the sources of cache misses in your code. If you desire, - it will show the number of cache misses, memory references and - instructions accruing to each line of source code, with - per-function, per-module and whole-program summaries. If you ask - really nicely it will even show counts for each individual x86 - instruction. -

    - Cachegrind auto-detects your machine's cache configuration - using the CPUID instruction, and so needs no further - configuration info, in most cases. -

    - Cachegrind is nicely complemented by Josef Weidendorfer's - amazing KCacheGrind visualisation tool ( - http://kcachegrind.sourceforge.net), a KDE application which - presents these profiling results in a graphical and - easier-to-understand form. -

    -

  • Helgrind finds data races in multithreaded programs. - Helgrind looks for - memory locations which are accessed by more than one (POSIX - p-)thread, but for which no consistently used (pthread_mutex_)lock - can be found. Such locations are indicative of missing - synchronisation between threads, and could cause hard-to-find - timing-dependent problems. -

    - Helgrind ("Hell's Gate", in Norse mythology) implements the - so-called "Eraser" data-race-detection algorithm, along with - various refinements (thread-segment lifetimes) which reduce the - number of false errors it reports. It is as yet somewhat of an - experimental tool, so your feedback is especially welcomed here. -

    - Helgrind has been hacked on extensively by Jeremy - Fitzhardinge, and we have him to thank for getting it to a - releasable state. -

- -A number of minor tools (corecheck, lackey and -Nulgrind) are also supplied. These aren't particularly useful -- -they exist to illustrate how to create simple tools and to help the -valgrind developers in various ways. - - -

-Valgrind is closely tied to details of the CPU, operating system and -to a less extent, compiler and basic C libraries. This makes it -difficult to make it portable, so we have chosen at the outset to -concentrate on what we believe to be a widely used platform: Linux on -x86s. Valgrind uses the standard Unix ./configure, -make, make install mechanism, and we have -attempted to ensure that it works on machines with kernel 2.2 or 2.4 -and glibc 2.1.X, 2.2.X or 2.3.1. This should cover the vast majority -of modern Linux installations. Note that glibc-2.3.2+, with the -NPTL (Native Posix Threads Library) package won't work. We hope to -be able to fix this, but it won't be easy. - - -

-Valgrind is licensed under the GNU General Public License, version -2. Read the file LICENSE in the source distribution for details. Some -of the PThreads test cases, pth_*.c, are taken from -"Pthreads Programming" by Bradford Nichols, Dick Buttlar & -Jacqueline Proulx Farrell, ISBN 1-56592-115-1, published by O'Reilly -& Associates, Inc. - - - - - -

1.2  How to navigate this manual

- -The Valgrind distribution consists of the Valgrind core, upon which are -built Valgrind tools, which do different kinds of debugging and -profiling. This manual is structured similarly. - -

-First, we describe the Valgrind core, how to use it, and the flags it -supports. Then, each tool has its own chapter in this manual. You only -need to read the documentation for the core and for the tool(s) you -actually use, although you may find it helpful to be at least a little -bit familar with what all tools do. If you're new to all this, you -probably want to run the Memcheck tool. If you want to write a new tool, -read this. - -

-Be aware that the core understands some command line flags, and the -tools have their own flags which they know about. This means -there is no central place describing all the flags that are accepted --- you have to read the flags documentation both for -Valgrind's core -and for the tool you want to use. - -

- diff --git a/VEX/head20041019/coregrind/docs/coregrind_tools.html b/VEX/head20041019/coregrind/docs/coregrind_tools.html deleted file mode 100644 index 20b42a360..000000000 --- a/VEX/head20041019/coregrind/docs/coregrind_tools.html +++ /dev/null @@ -1,761 +0,0 @@ - - - - Valgrind - - - - -  -

Valgrind Tools

-
- A guide to writing new tools for Valgrind
- This guide was last updated on 20030520 -
-

- -

-njn25@cam.ac.uk
-Nick Nethercote -

-Valgrind is licensed under the GNU General Public License, -version 2
-An open-source tool for supervising execution of Linux-x86 executables. -

- -

- -


- -

Contents of this manual

- -

Introduction

- 1.1  Supervised Execution
- 1.2  Tools
- 1.3  Execution Spaces
- -

Writing a Tool

- 2.1  Why write a tool?
- 2.2  Suggested tools
- 2.3  How tools work
- 2.4  Getting the code
- 2.5  Getting started
- 2.6  Writing the code
- 2.7  Initialisation
- 2.8  Instrumentation
- 2.9  Finalisation
- 2.10  Other important information
- 2.11  Words of advice
- -

Advanced Topics

- 3.1  Suppressions
- 3.2  Documentation
- 3.3  Regression tests
- 3.4  Profiling
- 3.5  Other makefile hackery
- 3.6  Core/tool interface versions
- -

Final Words

- -
- - -

1  Introduction

- - -

1.1  Supervised Execution

- -Valgrind provides a generic infrastructure for supervising the execution of -programs. This is done by providing a way to instrument programs in very -precise ways, making it relatively easy to support activities such as dynamic -error detection and profiling.

- -Although writing a tool is not easy, and requires learning quite a few things -about Valgrind, it is much easier than instrumenting a program from scratch -yourself. - - -

1.2  Tools

-The key idea behind Valgrind's architecture is the division between its -``core'' and ``tools''. -

-The core provides the common low-level infrastructure to support program -instrumentation, including the x86-to-x86 JIT compiler, low-level memory -manager, signal handling and a scheduler (for pthreads). It also provides -certain services that are useful to some but not all tools, such as support -for error recording and suppression. -

-But the core leaves certain operations undefined, which must be filled by tools. -Most notably, tools define how program code should be instrumented. They can -also define certain variables to indicate to the core that they would like to -use certain services, or be notified when certain interesting events occur. -But the core takes care of all the hard work. -

- - -

1.3  Execution Spaces

-An important concept to understand before writing a tool is that there are -three spaces in which program code executes: - -
    -
  1. User space: this covers most of the program's execution. The tool is - given the code and can instrument it any way it likes, providing (more or - less) total control over the code.

    - - Code executed in user space includes all the program code, almost all of - the C library (including things like the dynamic linker), and almost - all parts of all other libraries. -

  2. - -

  3. Core space: a small proportion of the program's execution takes place - entirely within Valgrind's core. This includes:

    - -

      -
    • Dynamic memory management (malloc() etc.)
    • - -
    • Pthread operations and scheduling
    • - -
    • Signal handling
    • -

    - - A tool has no control over these operations; it never ``sees'' the code - doing this work and thus cannot instrument it. However, the core - provides hooks so a tool can be notified when certain interesting events - happen, for example when when dynamic memory is allocated or freed, the - stack pointer is changed, or a pthread mutex is locked, etc.

    - - Note that these hooks only notify tools of events relevant to user - space. For example, when the core allocates some memory for its own use, - the tool is not notified of this, because it's not directly part of the - supervised program's execution. -

  4. - -

  5. Kernel space: execution in the kernel. Two kinds:

    - -

      -
    1. System calls: can't be directly observed by either the tool or the - core. But the core does have some idea of what happens to the - arguments, and it provides hooks for a tool to wrap system calls. -
    2. - -

    3. Other: all other kernel activity (e.g. process scheduling) is - totally opaque and irrelevant to the program. -
    4. -

    -
  6. - - It should be noted that a tool only has direct control over code executed in - user space. This is the vast majority of code executed, but it is not - absolutely all of it, so any profiling information recorded by a tool won't - be totally accurate. -

- - - -

2  Writing a Tool

- - -

2.1  Why write a tool?

- -Before you write a tool, you should have some idea of what it should do. What -is it you want to know about your programs of interest? Consider some existing -tools: - -
    -
  • memcheck: among other things, performs fine-grained validity and - addressibility checks of every memory reference performed by the program -
  • - -

  • addrcheck: performs lighterweight addressibility checks of every memory - reference performed by the program
  • - -

  • cachegrind: tracks every instruction and memory reference to simulate - instruction and data caches, tracking cache accesses and misses that - occur on every line in the program
  • - -

  • helgrind: tracks every memory access and mutex lock/unlock to determine - if a program contains any data races
  • - -

  • lackey: does simple counting of various things: the number of calls to a - particular function (_dl_runtime_resolve()); the number of - basic blocks, x86 instruction, UCode instructions executed; the number - of branches executed and the proportion of those which were taken.
  • -

- -These examples give a reasonable idea of what kinds of things Valgrind can be -used for. The instrumentation can range from very lightweight (e.g. counting -the number of times a particular function is called) to very intrusive (e.g. -memcheck's memory checking). - - - -

2.2  Suggested tools

- -Here is a list of ideas we have had for tools that should not be too hard to -implement. - -
    -
  • branch profiler: A machine's branch prediction hardware could be - simulated, and each branch annotated with the number of predicted and - mispredicted branches. Would be implemented quite similarly to - Cachegrind, and could reuse the cg_annotate script to - annotate source code.

    - - The biggest difficulty with this is the simulation; the chip-makers - are very cagey about how their chips do branch prediction. But - implementing one or more of the basic algorithms could still give good - information. -

  • - -

  • coverage tool: Cachegrind can already be used for doing test coverage, - but it's massive overkill to use it just for that.

    - - It would be easy to write a coverage tool that records how many times - each basic block was recorded. Again, the cg_annotate - script could be used for annotating source code with the gathered - information. Although, cg_annotate is only designed for - working with single program runs. It could be extended relatively easily - to deal with multiple runs of a program, so that the coverage of a whole - test suite could be determined.

    - - In addition to the standard coverage information, such a tool could - record extra information that would help a user generate test cases to - exercise unexercised paths. For example, for each conditional branch, - the tool could record all inputs to the conditional test, and print these - out when annotating.

    - -

  • run-time type checking: A nice example of a dynamic checker is given - in this paper: - -
    - Debugging via Run-Time Type Checking
    - Alexey Loginov, Suan Hsi Yong, Susan Horwitz and Thomas Reps
    - Proceedings of Fundamental Approaches to Software Engineering
    - April 2001. -
    - - Similar is the tool described in this paper: - -
    - Run-Time Type Checking for Binary Programs
    - Michael Burrows, Stephen N. Freund, Janet L. Wiener
    - Proceedings of the 12th International Conference on Compiler Construction - (CC 2003)
    - April 2003. -
    - - These approach can find quite a range of bugs, particularly in C and C++ - programs, and could be implemented quite nicely as a Valgrind tool.

    - - Ways to speed up this run-time type checking are described in this paper: - -

    - Reducing the Overhead of Dynamic Analysis
    - Suan Hsi Yong and Susan Horwitz
    - Proceedings of Runtime Verification '02
    - July 2002. -
    - - Valgrind's client requests could be used to pass information to a tool - about which elements need instrumentation and which don't. -
  • -

- -We would love to hear from anyone who implements these or other tools. - - -

2.3  How tools work

- -Tools must define various functions for instrumenting programs that are called -by Valgrind's core, yet they must be implemented in such a way that they can be -written and compiled without touching Valgrind's core. This is important, -because one of our aims is to allow people to write and distribute their own -tools that can be plugged into Valgrind's core easily.

- -This is achieved by packaging each tool into a separate shared object which is -then loaded ahead of the core shared object valgrind.so, using the -dynamic linker's LD_PRELOAD variable. Any functions defined in -the tool that share the name with a function defined in core (such as -the instrumentation function SK_(instrument)()) override the -core's definition. Thus the core can call the necessary tool functions.

- -This magic is all done for you; the shared object used is chosen with the ---tool option to the valgrind startup script. The -default tool used is memcheck, Valgrind's original memory checker. - - -

2.4  Getting the code

- -To write your own tool, you'll need to check out a copy of Valgrind from the -CVS repository, rather than using a packaged distribution. This is because it -contains several extra files needed for writing tools.

- -To check out the code from the CVS repository, first login: -

-cvs -d:pserver:anonymous@cvs.valgrind.sourceforge.net:/cvsroot/valgrind login -
- -Then checkout the code. To get a copy of the current development version -(recommended for the brave only): -
-cvs -z3 -d:pserver:anonymous@cvs.valgrind.sourceforge.net:/cvsroot/valgrind co valgrind -
- -To get a copy of the stable released branch: -
-cvs -z3 -d:pserver:anonymous@cvs.valgrind.sourceforge.net:/cvsroot/valgrind co -r TAG valgrind -
- -where TAG has the form VALGRIND_X_Y_Z for -version X.Y.Z. - - -

2.5  Getting started

- -Valgrind uses GNU automake and autoconf for the -creation of Makefiles and configuration. But don't worry, these instructions -should be enough to get you started even if you know nothing about those -tools.

- -In what follows, all filenames are relative to Valgrind's top-level directory -valgrind/. - -

    -
  1. Choose a name for the tool, and an abbreviation that can be used as a - short prefix. We'll use foobar and fb as an - example. -
  2. - -

  3. Make a new directory foobar/ which will hold the tool. -
  4. - -

  5. Copy none/Makefile.am into foobar/. - Edit it by replacing all occurrences of the string - ``none'' with ``foobar'' and the one - occurrence of the string ``nl_'' with ``fb_''. - It might be worth trying to understand this file, at least a little; you - might have to do more complicated things with it later on. In - particular, the name of the vgskin_foobar_so_SOURCES variable - determines the name of the tool's shared object, which determines what - name must be passed to the --tool option to use the tool. -
  6. - -

  7. Copy none/nl_main.c into - foobar/, renaming it as fb_main.c. - Edit it by changing the lines in SK_(pre_clo_init)() - to something appropriate for the tool. These fields are used in the - startup message, except for bug_reports_to which is used - if a tool assertion fails. -
  8. - -

  9. Edit Makefile.am, adding the new directory - foobar to the SUBDIRS variable. -
  10. - -

  11. Edit configure.in, adding foobar/Makefile to the - AC_OUTPUT list. -
  12. - -

  13. Run: -
    -    autogen.sh
    -    ./configure --prefix=`pwd`/inst
    -    make install
    - - It should automake, configure and compile without errors, putting copies - of the tool's shared object vgskin_foobar.so in - foobar/ and - inst/lib/valgrind/. -
  14. - -

  15. You can test it with a command like -
    -    inst/bin/valgrind --tool=foobar date
    - - (almost any program should work; date is just an example). - The output should be something like this: -
    -==738== foobar-0.0.1, a foobarring tool for x86-linux.
    -==738== Copyright (C) 1066AD, and GNU GPL'd, by J. Random Hacker.
    -==738== Built with valgrind-1.1.0, a program execution monitor.
    -==738== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
    -==738== Estimated CPU clock rate is 1400 MHz
    -==738== For more details, rerun with: -v
    -==738== 
    -Wed Sep 25 10:31:54 BST 2002
    -==738==
    - - The tool does nothing except run the program uninstrumented. -
  16. -

- -These steps don't have to be followed exactly - you can choose different names -for your source files, and use a different --prefix for -./configure.

- -Now that we've setup, built and tested the simplest possible tool, onto the -interesting stuff... - - - -

2.6  Writing the code

- -A tool must define at least these four functions: -
-    SK_(pre_clo_init)()
-    SK_(post_clo_init)()
-    SK_(instrument)()
-    SK_(fini)()
-
- -Also, it must use the macro VG_DETERMINE_INTERFACE_VERSION -exactly once in its source code. If it doesn't, you will get a link error -involving VG_(skin_interface_major_version). This macro is -used to ensure the core/tool interface used by the core and a plugged-in -tool are binary compatible. - -In addition, if a tool wants to use some of the optional services provided by -the core, it may have to define other functions. - - -

2.7  Initialisation

- -Most of the initialisation should be done in SK_(pre_clo_init)(). -Only use SK_(post_clo_init)() if a tool provides command line -options and must do some initialisation after option processing takes place -(``clo'' stands for ``command line options'').

- -First of all, various ``details'' need to be set for a tool, using the -functions VG_(details_*)(). Some are all compulsory, some aren't. -Some are used when constructing the startup message, -detail_bug_reports_to is used if VG_(skin_panic)() is -ever called, or a tool assertion fails. Others have other uses.

- -Second, various ``needs'' can be set for a tool, using the functions -VG_(needs_*)(). They are mostly booleans, and can be left -untouched (they default to False). They determine whether a tool -can do various things such as: record, report and suppress errors; process -command line options; wrap system calls; record extra information about -malloc'd blocks, etc.

- -For example, if a tool wants the core's help in recording and reporting errors, -it must set the skin_errors need to True, and then -provide definitions of six functions for comparing errors, printing out errors, -reading suppressions from a suppressions file, etc. While writing these -functions requires some work, it's much less than doing error handling from -scratch because the core is doing most of the work. See the type -VgNeeds in include/tool.h for full details of all -the needs.

- -Third, the tool can indicate which events in core it wants to be notified -about, using the functions VG_(track_*)(). These include things -such as blocks of memory being malloc'd, the stack pointer changing, a mutex -being locked, etc. If a tool wants to know about this, it should set the -relevant pointer in the structure to point to a function, which will be called -when that event happens.

- -For example, if the tool want to be notified when a new block of memory is -malloc'd, it should call VG_(track_new_mem_heap)() with an -appropriate function pointer, and the assigned function will be called each -time this happens.

- -More information about ``details'', ``needs'' and ``trackable events'' can be -found in include/tool.h.

- - -

2.8  Instrumentation

- -SK_(instrument)() is the interesting one. It allows you to -instrument UCode, which is Valgrind's RISC-like intermediate language. -UCode is described in the technical docs for -Memcheck. - -The easiest way to instrument UCode is to insert calls to C functions when -interesting things happen. See the tool ``Lackey'' -(lackey/lk_main.c) for a simple example of this, or -Cachegrind (cachegrind/cg_main.c) for a more complex -example.

- -A much more complicated way to instrument UCode, albeit one that might result -in faster instrumented programs, is to extend UCode with new UCode -instructions. This is recommended for advanced Valgrind hackers only! See -Memcheck for an example. - - -

2.9  Finalisation

- -This is where you can present the final results, such as a summary of the -information collected. Any log files should be written out at this point. - - -

2.10  Other important information

- -Please note that the core/tool split infrastructure is quite complex and -not brilliantly documented. Here are some important points, but there are -undoubtedly many others that I should note but haven't thought of.

- -The file include/tool.h contains all the types, -macros, functions, etc. that a tool should (hopefully) need, and is the only -.h file a tool should need to #include.

- -In particular, you probably shouldn't use anything from the C library (there -are deep reasons for this, trust us). Valgrind provides an implementation of a -reasonable subset of the C library, details of which are in -tool.h.

- -Similarly, when writing a tool, you shouldn't need to look at any of the code -in Valgrind's core. Although it might be useful sometimes to help understand -something.

- -tool.h has a reasonable amount of documentation in it that -should hopefully be enough to get you going. But ultimately, the tools -distributed (Memcheck, Addrcheck, Cachegrind, Lackey, etc.) are probably the -best documentation of all, for the moment.

- -Note that the VG_ and SK_ macros are used heavily. -These just prepend longer strings in front of names to avoid potential -namespace clashes. We strongly recommend using the SK_ macro for -any global functions and variables in your tool, or writing a similar macro.

- - -

2.11  Words of Advice

- -Writing and debugging tools is not trivial. Here are some suggestions for -solving common problems.

- -If you are getting segmentation faults in C functions used by your tool, the -usual GDB command: -

gdb prog core
-usually gives the location of the segmentation fault.

- -If you want to debug C functions used by your tool, you can attach GDB to -Valgrind with some effort: -

    -
  • Enable the following code in coregrind/vg_main.c by - changing if (0) into if (1): -
    -   /* Hook to delay things long enough so we can get the pid and
    -      attach GDB in another shell. */
    -   if (0) { 
    -      Int p, q;
    -      for (p = 0; p < 50000; p++)
    -         for (q = 0; q < 50000; q++) ;
    -   }
    -
    -
  • - and rebuild Valgrind. - -

  • Then run: -
    valgrind prog
    - - Valgrind starts the program, printing its process id, and then delays for - a few seconds (you may have to change the loop bounds to get a suitable - delay).
  • - -

  • In a second shell run: - -
    gdb prog pid
  • -

- -GDB may be able to give you useful information. Note that by default -most of the system is built with -fomit-frame-pointer, -and you'll need to get rid of this to extract useful tracebacks from -GDB.

- -If you just want to know whether a program point has been reached, using the -OINK macro (in include/tool.h) can be easier than -using GDB.

- -If you are having problems with your UCode instrumentation, it's likely that -GDB won't be able to help at all. In this case, Valgrind's ---trace-codegen option is invaluable for observing the results of -instrumentation.

- -The other debugging command line options can be useful too (run valgrind --h for the list).

- - -

3  Advanced Topics

- -Once a tool becomes more complicated, there are some extra things you may -want/need to do. - - -

3.1  Suppressions

- -If your tool reports errors and you want to suppress some common ones, you can -add suppressions to the suppression files. The relevant files are -valgrind/*.supp; the final suppression file is aggregated from -these files by combining the relevant .supp files depending on the -versions of linux, X and glibc on a system. -

-Suppression types have the form tool_name:suppression_name. The -tool_name here is the name you specify for the tool during -initialisation with VG_(details_name)(). - - -

3.2  Documentation

- -If you are feeling conscientious and want to write some HTML documentation for -your tool, follow these steps (using foobar as the example tool -name again): - -
    -
  1. Make a directory foobar/docs/. -
  2. - -

  3. Edit foobar/Makefile.am, adding docs to - the SUBDIRS variable. -
  4. - -

  5. Edit configure.in, adding - foobar/docs/Makefile to the AC_OUTPUT list. -
  6. - -

  7. Write foobar/docs/Makefile.am. Use - memcheck/docs/Makefile.am as an example. -
  8. - -

  9. Write the documentation, putting it in foobar/docs/. -
  10. -

- - -

3.3  Regression tests

- -Valgrind has some support for regression tests. If you want to write -regression tests for your tool: - -
    -
  1. Make a directory foobar/tests/. -
  2. - -

  3. Edit foobar/Makefile.am, adding tests to - the SUBDIRS variable. -
  4. - -

  5. Edit configure.in, adding - foobar/tests/Makefile to the AC_OUTPUT list. -
  6. - -

  7. Write foobar/tests/Makefile.am. Use - memcheck/tests/Makefile.am as an example. -
  8. - -

  9. Write the tests, .vgtest test description files, - .stdout.exp and .stderr.exp expected output - files. (Note that Valgrind's output goes to stderr.) Some details - on writing and running tests are given in the comments at the top of the - testing script tests/vg_regtest. -
  10. - -

  11. Write a filter for stderr results foobar/tests/filter_stderr. - It can call the existing filters in tests/. See - memcheck/tests/filter_stderr for an example; in particular - note the $dir trick that ensures the filter works correctly - from any directory. -
  12. -

- - -

3.4  Profiling

- -To do simple tick-based profiling of a tool, include the line -
-#include "vg_profile.c" -
-in the tool somewhere, and rebuild (you may have to make clean -first). Then run Valgrind with the --profile=yes option.

- -The profiler is stack-based; you can register a profiling event with -VGP_(register_profile_event)() and then use the -VGP_PUSHCC and VGP_POPCC macros to record time spent -doing certain things. New profiling event numbers must not overlap with the -core profiling event numbers. See include/tool.h for details -and Memcheck for an example. - - - -

3.5  Other makefile hackery

- -If you add any directories under valgrind/foobar/, you will -need to add an appropriate Makefile.am to it, and add a -corresponding entry to the AC_OUTPUT list in -valgrind/configure.in.

- -If you add any scripts to your tool (see Cachegrind for an example) you need to -add them to the bin_SCRIPTS variable in -valgrind/foobar/Makefile.am.

- - - -

3.5  Core/tool interface versions

- -In order to allow for the core/tool interface to evolve over time, Valgrind -uses a basic interface versioning system. All a tool has to do is use the -VG_DETERMINE_INTERFACE_VERSION macro exactly once in its code. -If not, a link error will occur when the tool is built. -

-The interface version number has the form X.Y. Changes in Y indicate binary -compatible changes. Changes in X indicate binary incompatible changes. If -the core and tool has the same major version number X they should work -together. If X doesn't match, Valgrind will abort execution with an -explanation of the problem. -

-This approach was chosen so that if the interface changes in the future, -old tools won't work and the reason will be clearly explained, instead of -possibly crashing mysteriously. We have attempted to minimise the potential -for binary incompatible changes by means such as minimising the use of naked -structs in the interface. - - -

4  Final Words

- -This whole core/tool business under active development, although it's slowly -maturing.

- -The first consequence of this is that the core/tool interface will continue -to change in the future; we have no intention of freezing it and then -regretting the inevitable stupidities. Hopefully most of the future changes -will be to add new features, hooks, functions, etc, rather than to change old -ones, which should cause a minimum of trouble for existing tools, and we've put -some effort into future-proofing the interface to avoid binary incompatibility. -But we can't guarantee anything. The versioning system should catch any -incompatibilities. Just something to be aware of.

- -The second consequence of this is that we'd love to hear your feedback about -it: - -

    -
  • If you love it or hate it
  • -

  • If you find bugs
  • -

  • If you write a tool
  • -

  • If you have suggestions for new features, needs, trackable events, - functions
  • -

  • If you have suggestions for making tools easier to write
  • -

  • If you have suggestions for improving this documentation
  • -

  • If you don't understand something
  • -

- -or anything else!

- -Happy programming. - diff --git a/VEX/head20041019/coregrind/dosyms b/VEX/head20041019/coregrind/dosyms deleted file mode 100755 index b7ba8503e..000000000 --- a/VEX/head20041019/coregrind/dosyms +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -# A simple script to help me ensure that my libpthread.so looks -# from the outside, to the linker, identical to the original. - -nm /lib/libpthread.so.0 | grep " T " | cut -c 10- > orig-T -nm /lib/libpthread.so.0 | grep " D " | cut -c 10- > orig-D -nm /lib/libpthread.so.0 | grep " W " | cut -c 10- > orig-W -nm /lib/libpthread.so.0 | grep " U " | cut -c 10- > orig-U - -nm ./libpthread.so | grep " T " | cut -c 10- > mine-T -nm ./libpthread.so | grep " D " | cut -c 10- > mine-D -nm ./libpthread.so | grep " W " | cut -c 10- > mine-W -nm ./libpthread.so | grep " U " | cut -c 10- > mine-U - -echo ========================== TEXT orig vs mine ========================= -sdiff -w 80 orig-T mine-T -echo - -echo ========================== WEAK orig vs mine ========================= -sdiff -w 80 orig-W mine-W -echo - -echo ========================== DATA orig vs mine ========================= -sdiff -w 80 orig-D mine-D -echo - -echo ========================== UNDF orig vs mine ========================= -sdiff -w 80 orig-U mine-U -echo - diff --git a/VEX/head20041019/coregrind/gen_intercepts.pl b/VEX/head20041019/coregrind/gen_intercepts.pl deleted file mode 100644 index ef23d4e59..000000000 --- a/VEX/head20041019/coregrind/gen_intercepts.pl +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/perl - -# This file is part of Valgrind, an extensible x86 protected-mode -# emulator for monitoring program execution on x86-Unixes. -# -# Copyright (C) 2000-2004 Julian Seward -# jseward@acm.org -# -# 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. -# -# The GNU General Public License is contained in the file COPYING. - -use strict; -use warnings; - -while(<>) { - if(/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) { - my $ver = $1 . ":" . $2; - $ver =~ s/\*/\$2A/g; - $ver =~ s/\+/\$2B/g; - $ver =~ s/\-/\$2D/g; - $ver =~ s/\./\$2E/g; - $ver =~ s/\:/\$3A/g; - s/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT($ver)/g; - } elsif(/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) { - my $ver = $1 . ":" . $2; - $ver =~ s/\*/\$2A/g; - $ver =~ s/\+/\$2B/g; - $ver =~ s/\-/\$2D/g; - $ver =~ s/\./\$2E/g; - $ver =~ s/\:/\$3A/g; - s/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT_ALIAS($ver)/g; - } - print $_; -} diff --git a/VEX/head20041019/coregrind/gen_toolint.pl b/VEX/head20041019/coregrind/gen_toolint.pl deleted file mode 100644 index edd716de9..000000000 --- a/VEX/head20041019/coregrind/gen_toolint.pl +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/perl - -# This file is part of Valgrind, an extensible x86 protected-mode -# emulator for monitoring program execution on x86-Unixes. -# -# Copyright (C) 2000-2004 Julian Seward -# jseward@acm.org -# -# 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. -# -# The GNU General Public License is contained in the file COPYING. - -use strict; -use warnings; - -my $output = shift @ARGV; -my $indent = ""; -my $headerguard; -my $include; -my $passcomment = 1; -my $pre; -my $post; -my $generate; - -my $struct = "VG_(tool_interface)"; - -my %pfxmap = ("track" => "SK_", - "tool" => "SK_", - "malloc"=> "SK_", - ); - -sub getargnames(@) { - my @args = @_; - my @ret; - - foreach my $a (@args) { - my @pieces = split /\s+/, $a; - my $name = pop @pieces; - push @ret, $name unless $name eq "void"; - } - return @ret; -} - -sub getargtypes(@) { - my @args = @_; - my @ret; - - foreach my $a (@args) { - my @pieces = split /\s+/, $a; - pop @pieces; - push @ret, (join " ", @pieces); - } - @ret = "void" if ($#ret == -1); - return @ret; -} - -# Different output modes -if ($output eq "callwrap") { - $include = "core.h"; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ", ", @args; - my $argnames = join ", ", getargnames(@args); - print "$ret $pfxmap{$pfx}($func)($args)\n{\n"; - print " return (*$struct.${pfx}_$func)($argnames);\n"; - print "}\n"; - } -} elsif ($output eq "proto") { - $include = "core.h"; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ', ', @args; - - print "$ret $pfxmap{$pfx}($func)($args);\n"; - print "Bool VG_(defined_$func)(void);\n"; - } -} elsif ($output eq "toolproto") { - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ', ', @args; - - print "$ret $pfxmap{$pfx}($func)($args);\n"; - } -} elsif ($output eq "missingfuncs") { - $include = "core.h"; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ", ", @args; - - print "static $ret missing_${pfx}_$func($args) {\n"; - print " VG_(missing_tool_func)(\"${pfx}_$func\");\n"; - print "}\n"; - print "Bool VG_(defined_$func)(void) {\n"; - print " return $struct.${pfx}_$func != missing_${pfx}_$func;\n"; - print "}\n\n"; - }; - $indent = " "; -} elsif ($output eq "struct") { - $include = "core.h"; - $pre = sub () { - print "typedef struct {\n"; - }; - $post = sub () { - print "} VgToolInterface;\n\n"; - print "extern VgToolInterface $struct;\n" - }; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ", ", @args; - - print "$indent$ret (*${pfx}_$func)($args);\n"; - }; - $indent = " "; - $headerguard=$output; -} elsif ($output eq "structdef") { - $include = "vg_toolint.h"; - $pre = sub () { - print "VgToolInterface $struct = {\n"; - }; - $post = sub () { - print "};\n"; - }; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - - print "$indent.${pfx}_$func = missing_${pfx}_$func,\n" - }; - $indent = " "; -} elsif ($output eq "initfunc") { - $include = "tool.h"; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ", ", @args; - my $argnames = join ", ", getargnames(@args); - - print < -void VG_(tool_init_dlsym)(void *dlhandle) -{ - void *ret; - -EOF - }; - $post = sub () { - print "}\n"; - }; - $generate = sub ($$$@) { - my ($pfx, $ret, $func, @args) = @_; - my $args = join ", ", getargtypes(@args); - - print <) { - # skip simple comments - next if (/^#[^#]/); - - if (/^:/) { - s/^://; - chomp; - $prefix=$_; - next; - } - - # look for inserted comments - if (/^##/) { - if ($state eq "idle") { - $state = "comment"; - $lines = 1; - $_ =~ s,^## ,/* ,; - $buf = $_; - next; - } elsif ($state eq "comment") { - $lines++; - $_ =~ s,^## , ,; - print $indent.$buf if $passcomment; - $buf = $_; - next; - } - next; - } - - # blank lines in a comment are part of the comment - if (/^\s*$/) { - if ($state eq "comment") { - $lines++; - print $indent.$buf if $passcomment; - $buf = "\n"; - } else { - print "\n" if $passcomment; - } - next; - } - - # coming out of a comment - if ($state eq "comment") { - chomp $buf; - - if ($passcomment) { - if ($lines == 1) { - print "$indent$buf */\n"; - } else { - print "$indent$buf\n$indent */\n"; - } - } - $buf = ""; - $state = "idle"; - } - - chomp; - my @func = split /,\s*/; - - my $rettype = shift @func; - my $funcname = shift @func; - - @func = "void" if scalar @func == 0; - - &$generate ($prefix, $rettype, $funcname, @func); -} - -&$post() if defined $post; # postamble - -print < -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core.h" -#include "ume.h" - -static int stack[SIGSTKSZ*4]; - -// Initial stack pointer, which points to argc. -static void* init_sp; - -/* Where we expect to find all our aux files (namely, stage2) */ -static const char *valgrind_lib = VG_LIBDIR; - -/* stage2's name */ -static const char stage2[] = "stage2"; - -/*------------------------------------------------------------*/ -/*--- Auxv modification ---*/ -/*------------------------------------------------------------*/ - -/* Modify the auxv the kernel gave us to make it look like we were - execed as the shared object. - - This also inserts a new entry into the auxv table so we can - communicate some extra information to stage2 (namely, the fd of the - padding file, so it can identiry and remove the padding later). -*/ -static void *fix_auxv(void *v_init_esp, const struct exeinfo *info, - int padfile) -{ - struct ume_auxv *auxv; - int *newesp; - int seen; - int delta; - int i; - static const int new_entries = 2; - - /* make sure we're running on the private stack */ - assert(&delta >= stack && &delta < &stack[sizeof(stack)/sizeof(*stack)]); - - /* find the beginning of the AUXV table */ - auxv = find_auxv(v_init_esp); - - /* Work out how we should move things to make space for the new - auxv entry. It seems that ld.so wants a 16-byte aligned stack on - entry, so make sure that's the case. */ - newesp = (int *)(((unsigned long)v_init_esp - new_entries * sizeof(*auxv)) & ~0xf); - delta = (char *)v_init_esp - (char *)newesp; - - memmove(newesp, v_init_esp, (char *)auxv - (char *)v_init_esp); - - v_init_esp = (void *)newesp; - auxv -= delta/sizeof(*auxv); - - /* stage2 needs this so it can clean up the padding we leave in - place when we start it */ - auxv[0].a_type = AT_UME_PADFD; - auxv[0].u.a_val = padfile; - - /* This will be needed by valgrind itself so that it can - subsequently execve() children. This needs to be done here - because /proc/self/exe will go away once we unmap stage1. */ - auxv[1].a_type = AT_UME_EXECFD; - auxv[1].u.a_val = open("/proc/self/exe", O_RDONLY); - - /* make sure the rest are sane */ - for(i = new_entries; i < delta/sizeof(*auxv); i++) { - auxv[i].a_type = AT_IGNORE; - auxv[i].u.a_val = 0; - } - - /* OK, go through and patch up the auxv entries to match the new - executable */ - seen = 0; - for(; auxv->a_type != AT_NULL; auxv++) { - if (0) - printf("doing auxv %p %4x: %d %p\n", auxv, auxv->a_type, auxv->u.a_val, auxv->u.a_ptr); - - switch(auxv->a_type) { - case AT_PHDR: - seen |= 1; - auxv->u.a_val = info->phdr; - break; - - case AT_PHNUM: - seen |= 2; - auxv->u.a_val = info->phnum; - break; - - case AT_BASE: - seen |= 4; - auxv->u.a_val = info->interp_base; - break; - - case AT_ENTRY: - seen |= 8; - auxv->u.a_val = info->entry; - break; - -#if (defined(AT_SYSINFO) || defined(AT_SYSINFO_EHDR)) -#ifdef AT_SYSINFO - case AT_SYSINFO: -#endif -#ifdef AT_SYSINFO_EHDR - case AT_SYSINFO_EHDR: -#endif - auxv->a_type = AT_IGNORE; - break; -#endif - } - } - - /* If we didn't see all the entries we need to fix up, then we - can't make the new executable viable. */ - if (seen != 0xf) { - fprintf(stderr, "valgrind: we didn't see enough auxv entries (seen=%x)\n", seen); - exit(1); - } - - return v_init_esp; -} - - -/*------------------------------------------------------------*/ -/*--- Address space padding ---*/ -/*------------------------------------------------------------*/ - -static void check_mmap(void* res, void* base, int len) -{ - if ((void*)-1 == res) { - fprintf(stderr, "valgrind: padding mmap(%p, %d) failed during startup.\n" - "valgrind: is there a hard virtual memory limit set?\n", - base, len); - exit(1); - } -} - -typedef struct { - char* fillgap_start; - char* fillgap_end; - int fillgap_padfile; -} fillgap_extra; - -static int fillgap(char *segstart, char *segend, const char *perm, off_t off, - int maj, int min, int ino, void* e) -{ - fillgap_extra* extra = e; - - if (segstart >= extra->fillgap_end) - return 0; - - if (segstart > extra->fillgap_start) { - void* res = mmap(extra->fillgap_start, segstart - extra->fillgap_start, - PROT_NONE, MAP_FIXED|MAP_PRIVATE, - extra->fillgap_padfile, 0); - check_mmap(res, extra->fillgap_start, segstart - extra->fillgap_start); - } - extra->fillgap_start = segend; - - return 1; -} - -// Choose a name for the padfile, open it. -int as_openpadfile(void) -{ - char buf[256]; - int padfile; - int seq = 1; - do { - snprintf(buf, 256, "/tmp/.pad.%d.%d", getpid(), seq++); - padfile = open(buf, O_RDWR|O_CREAT|O_EXCL, 0); - unlink(buf); - if (padfile == -1 && errno != EEXIST) { - fprintf(stderr, "valgrind: couldn't open padfile\n"); - exit(44); - } - } while(padfile == -1); - - return padfile; -} - -// Pad all the empty spaces in a range of address space to stop interlopers. -void as_pad(void *start, void *end, int padfile) -{ - fillgap_extra extra; - extra.fillgap_start = start; - extra.fillgap_end = end; - extra.fillgap_padfile = padfile; - - foreach_map(fillgap, &extra); - - if (extra.fillgap_start < extra.fillgap_end) { - void* res = mmap(extra.fillgap_start, - extra.fillgap_end - extra.fillgap_start, - PROT_NONE, MAP_FIXED|MAP_PRIVATE, padfile, 0); - check_mmap(res, extra.fillgap_start, - extra.fillgap_end - extra.fillgap_start); - } -} - - -/*------------------------------------------------------------*/ -/*--- main() and related pieces ---*/ -/*------------------------------------------------------------*/ - -static int prmap(char *start, char *end, const char *perm, off_t off, int maj, - int min, int ino, void* dummy) { - printf("mapping %10p-%10p %s %02x:%02x %d\n", - start, end, perm, maj, min, ino); - return 1; -} - -static void main2(void) -{ - int err, padfile; - struct exeinfo info; - extern char _end; - int *esp; - char buf[strlen(valgrind_lib) + sizeof(stage2) + 16]; - - info.exe_base = PGROUNDUP(&_end); - info.exe_end = PGROUNDDN(init_sp); - - /* XXX FIXME: how can stage1 know where stage2 wants things placed? - Options: - - we could look for a symbol - - it could have a special PHDR (v. ELF specific) - - something else? - */ - info.map_base = KICKSTART_BASE + 0x01000000; - info.argv = NULL; - - snprintf(buf, sizeof(buf), "%s/%s", valgrind_lib, stage2); - - err = do_exec(buf, &info); - - if (err != 0) { - fprintf(stderr, "valgrind: failed to load %s: %s\n", - buf, strerror(err)); - exit(1); - } - - /* Make sure stage2's dynamic linker can't tromp on the lower part - of the address space. */ - padfile = as_openpadfile(); - as_pad(0, (void *)info.map_base, padfile); - - esp = fix_auxv(init_sp, &info, padfile); - - if (0) { - printf("---------- launch stage 2 ----------\n"); - printf("eip=%p esp=%p\n", (void *)info.init_eip, esp); - foreach_map(prmap, /*dummy*/NULL); - } - - jmp_with_stack(info.init_eip, (addr_t)esp); -} - -int main(int argc, char** argv) -{ - struct rlimit rlim; - const char *cp = getenv(VALGRINDLIB); - - if (cp != NULL) - valgrind_lib = cp; - - // Initial stack pointer is to argc, which is immediately before argv[0] - // on the stack. Nb: Assumes argc is word-aligned. - init_sp = argv - 1; - - /* Set the address space limit as high as it will go, since we make - a lot of very large mappings. */ - getrlimit(RLIMIT_AS, &rlim); - rlim.rlim_cur = rlim.rlim_max; - setrlimit(RLIMIT_AS, &rlim); - - /* move onto another stack so we can play with the main one */ - jmp_with_stack((addr_t)main2, (addr_t)stack + sizeof(stack)); -} - -/*--------------------------------------------------------------------*/ -/*--- end stage1.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/toolfuncs.def b/VEX/head20041019/coregrind/toolfuncs.def deleted file mode 100644 index 62f6a2f8c..000000000 --- a/VEX/head20041019/coregrind/toolfuncs.def +++ /dev/null @@ -1,301 +0,0 @@ -# Tool interface functions -# The format for an interface function definition is: -# return_type, func_name, type arg, type arg -# If the function has no arguments, specify no arguments (rather than void) -# -# Comments starting with "##" are turned into C comments in the output -# -# Lines starting with : set the prefix - -## These are the parameterised functions in the core. The default definitions -## are overridden by LD_PRELOADed tool version. At the very least, a tool -## must define the fundamental template functions. Depending on what needs -## are set, extra template functions will be used too. Functions are -## grouped under the needs that govern their use. - -:tool -## ------------------------------------------------------------------ -## Fundamental template functions - -## Do initialisation that can only be done after command line processing. -void, post_clo_init - -## Instrument a basic block. Must be a true function, ie. the same input -## always results in the same output, because basic blocks can be -## retranslated. Unless you're doing something really strange... -## 'orig_addr' is the address of the first instruction in the block. -IRBB*, instrument, IRBB* bb, VexGuestLayout* layout, IRType hWordTy - -## Finish up, print out any results, etc. `exitcode' is program's exit -## code. The shadow (if the `shadow_regs' need is set) can be found with -## VG_(get_exit_status_shadow)(). -void, fini, Int exitcode - - -## ------------------------------------------------------------------ -## VG_(needs).core_errors - -## (none needed) - -## ------------------------------------------------------------------ -## VG_(needs).skin_errors - -## Identify if two errors are equal, or equal enough. `res' indicates how -## close is "close enough". `res' should be passed on as necessary, eg. if -## the Error's `extra' part contains an ExeContext, `res' should be -## passed to VG_(eq_ExeContext)() if the ExeContexts are considered. Other -## than that, probably don't worry about it unless you have lots of very -## similar errors occurring. -Bool, eq_SkinError, VgRes res, Error* e1, Error* e2 - -## Print error context. -void, pp_SkinError, Error* err - -## Should fill in any details that could be postponed until after the -## decision whether to ignore the error (ie. details not affecting the -## result of SK_(eq_SkinError)()). This saves time when errors are ignored. -## Yuk. - -## Return value: must be the size of the `extra' part in bytes -- used by -## the core to make a copy. -UInt, update_extra, Error* err - -## Return value indicates recognition. If recognised, must set skind using -## VG_(set_supp_kind)(). -Bool, recognised_suppression, Char* name, Supp* su - -## Read any extra info for this suppression kind. Most likely for filling -## in the `extra' and `string' parts (with VG_(set_supp_{extra, string})()) -## of a suppression if necessary. Should return False if a syntax error -## occurred, True otherwise. -Bool, read_extra_suppression_info, Int fd, Char* buf, Int nBuf, Supp* su - -## This should just check the kinds match and maybe some stuff in the -## `string' and `extra' field if appropriate (using VG_(get_supp_*)() to -## get the relevant suppression parts). -Bool, error_matches_suppression, Error* err, Supp* su - -## This should return the suppression name, for --gen-suppressions, or NULL -## if that error type cannot be suppressed. This is the inverse of -## SK_(recognised_suppression)(). -Char*, get_error_name, Error* err - -## This should print any extra info for the error, for --gen-suppressions, -## including the newline. This is the inverse of -## SK_(read_extra_suppression_info)(). -void, print_extra_suppression_info, Error* err - - -## ------------------------------------------------------------------ -## VG_(needs).basic_block_discards - -## Should discard any information that pertains to specific basic blocks -## or instructions within the address range given. -void, discard_basic_block_info, Addr a, UInt size - - -## ------------------------------------------------------------------ -## VG_(needs).shadow_regs - -## No functions must be defined, but the post_reg[s]_write_* events should -## be tracked. - -## ------------------------------------------------------------------ -## VG_(needs).command_line_options - -## Return True if option was recognised. Presumably sets some state to -## record the option as well. -Bool, process_cmd_line_option, Char* argv - -## Print out command line usage for options for normal tool operation. -void, print_usage - -## Print out command line usage for options for debugging the tool. -void, print_debug_usage - -## ------------------------------------------------------------------ -## VG_(needs).client_requests - -## If using client requests, the number of the first request should be equal -## to VG_USERREQ_SKIN_BASE('X', 'Y'), where 'X' and 'Y' form a suitable two -## character identification for the string. The second and subsequent -## requests should follow. - -## This function should use the VG_IS_SKIN_USERREQ macro (in -## include/valgrind.h) to first check if it's a request for this tool. Then -## should handle it if it's recognised (and return True), or return False if -## not recognised. arg_block[0] holds the request number, any further args -## from the request are in arg_block[1..]. 'ret' is for the return value... -## it should probably be filled, if only with 0. -Bool, handle_client_request, ThreadId tid, UInt* arg_block, UInt* ret - - -## ------------------------------------------------------------------ -## VG_(needs).extends_UCode - -## 'X' prefix indicates eXtended UCode. -Int, get_Xreg_usage, UInstr* u, Tag tag, Int* regs, Bool* isWrites -void, emit_XUInstr, UInstr* u, RRegSet regs_live_before -Bool, sane_XUInstr, Bool beforeRA, Bool beforeLiveness, UInstr* u -Char *, name_XUOpcode, Opcode opc -void, pp_XUInstr, UInstr* u - - -## ------------------------------------------------------------------ -## VG_(needs).syscall_wrapper - -## If either of the pre_ functions malloc() something to return, the -## corresponding post_ function had better free() it! - -void *, pre_syscall, ThreadId tid, UInt syscallno, Bool is_blocking -void, post_syscall, ThreadId tid, UInt syscallno, void* pre_result, Int res, Bool is_blocking - - -## --------------------------------------------------------------------- -## VG_(needs).sanity_checks - -## Can be useful for ensuring a tool's correctness. SK_(cheap_sanity_check) -## is called very frequently; SK_(expensive_sanity_check) is called less -## frequently and can be more involved. -Bool, cheap_sanity_check -Bool, expensive_sanity_check - - -## ================================================================================ -## Event tracking functions -:track - -## Events happening in core to track. To be notified, pass a callback -## function to the appropriate function. To ignore an event, don't do -## anything (default is for events to be ignored). - -## Note that most events aren't passed a ThreadId. To find out the ThreadId -## of the affected thread, use VG_(get_current_or_recent_tid)(). For the -## ones passed a ThreadId, use that instead, since -## VG_(get_current_or_recent_tid)() might not give the right ThreadId in -## that case. - -## Memory events (Nb: to track heap allocation/freeing, a tool must replace -## malloc() et al. See above how to do this.) - -## These ones occur at startup, upon some signals, and upon some syscalls -void, new_mem_startup, Addr a, UInt len, Bool rr, Bool ww, Bool xx -void, new_mem_stack_signal, Addr a, UInt len -void, new_mem_brk, Addr a, UInt len -void, new_mem_mmap, Addr a, UInt len, Bool rr, Bool ww, Bool xx - -void, copy_mem_remap, Addr from, Addr to, UInt len -void, change_mem_mprotect, Addr a, UInt len, Bool rr, Bool ww, Bool xx -void, die_mem_stack_signal, Addr a, UInt len -void, die_mem_brk, Addr a, UInt len -void, die_mem_munmap, Addr a, UInt len - -## These ones are called when %esp changes. A tool could track these itself -## (except for ban_mem_stack) but it's much easier to use the core's help. - -## The specialised ones are called in preference to the general one, if they -## are defined. These functions are called a lot if they are used, so -## specialising can optimise things significantly. If any of the -## specialised cases are defined, the general case must be defined too. - -## Nb: they must all use the REGPARM(n) attribute. -void, new_mem_stack_4, Addr new_ESP -void, new_mem_stack_8, Addr new_ESP -void, new_mem_stack_12, Addr new_ESP -void, new_mem_stack_16, Addr new_ESP -void, new_mem_stack_32, Addr new_ESP -void, new_mem_stack, Addr a, UInt len - -void, die_mem_stack_4, Addr die_ESP -void, die_mem_stack_8, Addr die_ESP -void, die_mem_stack_12, Addr die_ESP -void, die_mem_stack_16, Addr die_ESP -void, die_mem_stack_32, Addr die_ESP -void, die_mem_stack, Addr a, UInt len - -## Used for redzone at end of thread stacks -void, ban_mem_stack, Addr a, UInt len - -## These ones occur around syscalls, signal handling, etc -void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, UInt size -void, pre_mem_read_asciiz, CorePart part, ThreadId tid, Char* s, Addr a -void, pre_mem_write, CorePart part, ThreadId tid, Char* s, Addr a, UInt size -## Not implemented yet -- have to add in lots of places, which is a -## pain. Won't bother unless/until there's a need. -## void (*post_mem_read) ( ThreadState* tst, Char* s, Addr a, UInt size ); -void, post_mem_write, Addr a, UInt size - - -## Register events -- if `shadow_regs' need is set, all should probably be -## used. Use VG_(set_thread_shadow_archreg)() to set the shadow of the -## changed register. - -## Use VG_(set_shadow_archreg)() to set the eight general purpose regs, -## and use VG_(set_shadow_eflags)() to set eflags. -void, post_regs_write_init, void - -## Use VG_(set_thread_shadow_archreg)() to set the shadow regs for these -## events. -void, post_reg_write_syscall_return, ThreadId tid, UInt reg -void, post_reg_write_deliver_signal, ThreadId tid, UInt reg -void, post_reg_write_pthread_return, ThreadId tid, UInt reg -void, post_reg_write_clientreq_return, ThreadId tid, UInt reg -## This one is called for malloc() et al if they are replaced by a tool. -void, post_reg_write_clientcall_return, ThreadId tid, UInt reg, Addr f - - -## Scheduler events (not exhaustive) -void, thread_run, ThreadId tid - - -## Thread events (not exhaustive) - -## Called during thread create, before the new thread has run any -## instructions (or touched any memory). -void, post_thread_create, ThreadId tid, ThreadId child -void, post_thread_join, ThreadId joiner, ThreadId joinee - - -## Mutex events (not exhaustive) -## "void *mutex" is really a pthread_mutex * - -## Called before a thread can block while waiting for a mutex (called -## regardless of whether the thread will block or not). -void, pre_mutex_lock, ThreadId tid, void* mutex -## Called once the thread actually holds the mutex (always paired with -## pre_mutex_lock). -void, post_mutex_lock, ThreadId tid, void* mutex -## Called after a thread has released a mutex (no need for a corresponding -## pre_mutex_unlock, because unlocking can't block). -void, post_mutex_unlock, ThreadId tid, void* mutex - -## Signal events (not exhaustive) - -## ... pre_send_signal, post_send_signal ... - -## Called before a signal is delivered; `alt_stack' indicates if it is -## delivered on an alternative stack. -void, pre_deliver_signal, ThreadId tid, Int sigNo, Bool alt_stack -## Called after a signal is delivered. Nb: unfortunately, if the signal -## handler longjmps, this won't be called. -void, post_deliver_signal, ThreadId tid, Int sigNo - - -## Others... condition variable... -## ... - -## Shadow memory management -void, init_shadow_page, Addr p - -## ================================================================================ -## malloc and friends -:malloc -void*, malloc, Int n -void*, __builtin_new, Int n -void*, __builtin_vec_new, Int n -void*, memalign, Int align, Int n -void*, calloc, Int nmemb, Int n -void, free, void* p -void, __builtin_delete, void* p -void, __builtin_vec_delete, void* p -void*, realloc, void* p, Int size diff --git a/VEX/head20041019/coregrind/ume.c b/VEX/head20041019/coregrind/ume.c deleted file mode 100644 index 7fe3146d2..000000000 --- a/VEX/head20041019/coregrind/ume.c +++ /dev/null @@ -1,608 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- User-mode execve(), and other stuff shared between stage1 ---*/ -/*--- and stage2. ume.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - - -#define _GNU_SOURCE -#define _FILE_OFFSET_BITS 64 - -#include "core.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ume.h" - -struct elfinfo -{ - ESZ(Ehdr) e; - ESZ(Phdr) *p; - int fd; -}; - -static void check_mmap(void* res, void* base, int len) -{ - if ((void*)-1 == res) { - fprintf(stderr, "valgrind: mmap(%p, %d) failed in UME.\n", base, len); - exit(1); - } -} - -// 'extra' allows the caller to pass in extra args to 'fn', like free -// variables to a closure. -void foreach_map(int (*fn)(char *start, char *end, - const char *perm, off_t offset, - int maj, int min, int ino, void* extra), - void* extra) -{ - static char buf[10240]; - char *bufptr = buf; - int ret, fd; - - fd = open("/proc/self/maps", O_RDONLY); - - if (fd == -1) { - perror("open /proc/self/maps"); - return; - } - - ret = read(fd, buf, sizeof(buf)); - - if (ret == -1) { - perror("read /proc/self/maps"); - close(fd); - return; - } - close(fd); - - if (ret == sizeof(buf)) { - fprintf(stderr, "buf too small\n"); - return; - } - - while(bufptr && bufptr < buf+ret) { - char perm[5]; - off_t offset; - int maj, min; - int ino; - void *segstart, *segend; - - sscanf(bufptr, "%p-%p %s %Lx %x:%x %d", - &segstart, &segend, perm, &offset, &maj, &min, &ino); - bufptr = strchr(bufptr, '\n'); - if (bufptr != NULL) - bufptr++; /* skip \n */ - - if (!(*fn)(segstart, segend, perm, offset, maj, min, ino, extra)) - break; - } -} - -/*------------------------------------------------------------*/ -/*--- Finding auxv on the stack ---*/ -/*------------------------------------------------------------*/ - -struct ume_auxv *find_auxv(int *esp) -{ - esp++; /* skip argc */ - - while(*esp != 0) /* skip argv */ - esp++; - esp++; - - while(*esp != 0) /* skip env */ - esp++; - esp++; - - return (struct ume_auxv *)esp; -} - -/*------------------------------------------------------------*/ -/*--- Loading ELF files ---*/ -/*------------------------------------------------------------*/ - -struct elfinfo *readelf(int fd, const char *filename) -{ - struct elfinfo *e = malloc(sizeof(*e)); - int phsz; - - assert(e); - e->fd = fd; - - if (pread(fd, &e->e, sizeof(e->e), 0) != sizeof(e->e)) { - fprintf(stderr, "valgrind: %s: can't read elf header: %s\n", - filename, strerror(errno)); - return NULL; - } - - if (memcmp(&e->e.e_ident[0], ELFMAG, SELFMAG) != 0) { - fprintf(stderr, "valgrind: %s: bad ELF magic\n", filename); - return NULL; - } - if (e->e.e_ident[EI_CLASS] != VG_ELF_CLASS) { - fprintf(stderr, "valgrind: wrong executable class (eg. 32-bit instead\n" - "valgrind: of 64-bit)\n"); - return NULL; - } - if (e->e.e_ident[EI_DATA] != VG_ELF_ENDIANNESS) { - fprintf(stderr, "valgrind: wrong endian-ness\n"); - return NULL; - } - if (!(e->e.e_type == ET_EXEC || e->e.e_type == ET_DYN)) { - fprintf(stderr, "valgrind: need executable\n"); - return NULL; - } - - if (e->e.e_machine != VG_ELF_MACHINE) { - fprintf(stderr, "valgrind: wrong architecture\n"); - return NULL; - } - - if (e->e.e_phentsize != sizeof(ESZ(Phdr))) { - fprintf(stderr, "valgrind: sizeof Phdr wrong\n"); - return NULL; - } - - phsz = sizeof(ESZ(Phdr)) * e->e.e_phnum; - e->p = malloc(phsz); - assert(e->p); - - if (pread(fd, e->p, phsz, e->e.e_phoff) != phsz) { - fprintf(stderr, "valgrind: can't read phdr: %s\n", strerror(errno)); - return NULL; - } - - return e; -} - -/* Map an ELF file. Returns the brk address. */ -ESZ(Addr) mapelf(struct elfinfo *e, ESZ(Addr) base) -{ - int i; - void* res; - ESZ(Addr) elfbrk = 0; - - for(i = 0; i < e->e.e_phnum; i++) { - ESZ(Phdr) *ph = &e->p[i]; - ESZ(Addr) addr, brkaddr; - ESZ(Word) memsz; - - if (ph->p_type != PT_LOAD) - continue; - - addr = ph->p_vaddr+base; - memsz = ph->p_memsz; - brkaddr = addr+memsz; - - if (brkaddr > elfbrk) - elfbrk = brkaddr; - } - - for(i = 0; i < e->e.e_phnum; i++) { - ESZ(Phdr) *ph = &e->p[i]; - ESZ(Addr) addr, bss, brkaddr; - ESZ(Off) off; - ESZ(Word) filesz; - ESZ(Word) memsz; - ESZ(Word) align; - unsigned prot = 0; - - if (ph->p_type != PT_LOAD) - continue; - - if (ph->p_flags & PF_X) - prot |= PROT_EXEC; - if (ph->p_flags & PF_W) - prot |= PROT_WRITE; - if (ph->p_flags & PF_R) - prot |= PROT_READ; - - align = ph->p_align; - - addr = ph->p_vaddr+base; - off = ph->p_offset; - filesz = ph->p_filesz; - bss = addr+filesz; - memsz = ph->p_memsz; - brkaddr = addr+memsz; - - res = mmap((char *)ROUNDDN(addr, align), - ROUNDUP(bss, align)-ROUNDDN(addr, align), - prot, MAP_FIXED|MAP_PRIVATE, e->fd, ROUNDDN(off, align)); - check_mmap(res, (char*)ROUNDDN(addr,align), - ROUNDUP(bss, align)-ROUNDDN(addr, align)); - - /* if memsz > filesz, then we need to fill the remainder with zeroed pages */ - if (memsz > filesz) { - UInt bytes; - - bytes = ROUNDUP(brkaddr, align)-ROUNDUP(bss, align); - if (bytes > 0) { - res = mmap((char *)ROUNDUP(bss, align), bytes, - prot, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - check_mmap(res, (char*)ROUNDUP(bss,align), bytes); - } - - bytes = bss & (VKI_BYTES_PER_PAGE - 1); - if (bytes > 0) { - bytes = VKI_BYTES_PER_PAGE - bytes; - memset((char *)bss, 0, bytes); - } - } - } - - return elfbrk; -} - -// Forward declaration. -static int do_exec_inner(const char *exe, struct exeinfo *info); - -static int match_ELF(const char *hdr, int len) -{ - ESZ(Ehdr) *e = (ESZ(Ehdr) *)hdr; - return (len > sizeof(*e)) && memcmp(&e->e_ident[0], ELFMAG, SELFMAG) == 0; -} - -static int load_ELF(char *hdr, int len, int fd, const char *name, - struct exeinfo *info) -{ - struct elfinfo *e; - struct elfinfo *interp = NULL; - ESZ(Addr) exeoff = 0; /* offset between link address and load address */ - ESZ(Addr) minaddr = ~0; /* lowest mapped address */ - ESZ(Addr) maxaddr = 0; /* highest mapped address */ - ESZ(Addr) interp_addr = 0; /* interpreter (ld.so) address */ - ESZ(Word) interp_size = 0; /* interpreter size */ - int i; - void *entry; - - e = readelf(fd, name); - - if (e == NULL) - return ENOEXEC; - - info->phnum = e->e.e_phnum; - info->entry = e->e.e_entry; - - for(i = 0; i < e->e.e_phnum; i++) { - ESZ(Phdr) *ph = &e->p[i]; - - switch(ph->p_type) { - case PT_PHDR: - info->phdr = ph->p_vaddr; - break; - - case PT_LOAD: - if (ph->p_vaddr < minaddr) - minaddr = ph->p_vaddr; - if (ph->p_vaddr+ph->p_memsz > maxaddr) - maxaddr = ph->p_vaddr+ph->p_memsz; - break; - - case PT_INTERP: { - char *buf = malloc(ph->p_filesz+1); - int j; - int intfd; - int baseaddr_set; - - assert(buf); - pread(fd, buf, ph->p_filesz, ph->p_offset); - buf[ph->p_filesz] = '\0'; - - intfd = open(buf, O_RDONLY); - if (intfd == -1) { - perror("open interp"); - exit(1); - } - - interp = readelf(intfd, buf); - if (interp == NULL) { - fprintf(stderr, "Can't read interpreter\n"); - return 1; - } - free(buf); - - baseaddr_set = 0; - for(j = 0; j < interp->e.e_phnum; j++) { - ESZ(Phdr) *iph = &interp->p[j]; - ESZ(Addr) end; - - if (iph->p_type != PT_LOAD) - continue; - - if (!baseaddr_set) { - interp_addr = iph->p_vaddr; - baseaddr_set = 1; - } - - /* assumes that all segments in the interp are close */ - end = (iph->p_vaddr - interp_addr) + iph->p_memsz; - - if (end > interp_size) - interp_size = end; - } - break; - - default: - // do nothing - break; - } - } - } - - if (e->e.e_type == ET_DYN) { - /* PIE executable */ - exeoff = info->exe_base - minaddr; - } - - minaddr += exeoff; - maxaddr += exeoff; - info->phdr += exeoff; - info->entry += exeoff; - - if (info->exe_base != info->exe_end) { - if (minaddr >= maxaddr || - (minaddr < info->exe_base || - maxaddr > info->exe_end)) { - fprintf(stderr, "Executable range %p-%p is outside the\n" - "acceptable range %p-%p\n", - (void *)minaddr, (void *)maxaddr, - (void *)info->exe_base, (void *)info->exe_end); - return ENOMEM; - } - } - - info->brkbase = mapelf(e, exeoff); /* map the executable */ - - if (info->brkbase == 0) - return ENOMEM; - - if (interp != NULL) { - /* reserve a chunk of address space for interpreter */ - void* res; - char* base = (char *)info->exe_base; - char* baseoff; - int flags = MAP_PRIVATE|MAP_ANONYMOUS; - - if (info->map_base != 0) { - base = (char *)info->map_base; - flags |= MAP_FIXED; - } - - res = mmap(base, interp_size, PROT_NONE, flags, -1, 0); - check_mmap(res, base, interp_size); - base = res; - - baseoff = base - interp_addr; - - mapelf(interp, (ESZ(Addr))baseoff); - - close(interp->fd); - - entry = baseoff + interp->e.e_entry; - info->interp_base = (ESZ(Addr))base; - - free(interp); - } else - entry = (void *)e->e.e_entry + exeoff; - - info->exe_base = minaddr; - info->exe_end = maxaddr; - - info->init_eip = (addr_t)entry; - - free(e); - - return 0; -} - - -static int match_script(const char *hdr, Int len) -{ - return (len > 2) && memcmp(hdr, "#!", 2) == 0; -} - -static int load_script(char *hdr, int len, int fd, const char *name, - struct exeinfo *info) -{ - char *interp; - char *const end = hdr+len; - char *cp; - char *arg = NULL; - int eol; - - interp = hdr + 2; - while(interp < end && (*interp == ' ' || *interp == '\t')) - interp++; - - if (*interp != '/') - return ENOEXEC; /* absolute path only for interpreter */ - - /* skip over interpreter name */ - for(cp = interp; cp < end && *cp != ' ' && *cp != '\t' && *cp != '\n'; cp++) - ; - - eol = (*cp == '\n'); - - *cp++ = '\0'; - - if (!eol && cp < end) { - /* skip space before arg */ - while (cp < end && (*cp == '\t' || *cp == ' ')) - cp++; - - /* arg is from here to eol */ - arg = cp; - while (cp < end && *cp != '\n') - cp++; - *cp = '\0'; - } - - info->interp_name = strdup(interp); - assert(NULL != info->interp_name); - if (arg != NULL && *arg != '\0') { - info->interp_args = strdup(arg); - assert(NULL != info->interp_args); - } - - if (info->argv && info->argv[0] != NULL) - info->argv[0] = (char *)name; - - if (0) - printf("#! script: interp_name=\"%s\" interp_args=\"%s\"\n", - info->interp_name, info->interp_args); - - return do_exec_inner(interp, info); -} - -/* - Emulate the normal Unix permissions checking algorithm. - - If owner matches, then use the owner permissions, else - if group matches, then use the group permissions, else - use other permissions. - - Note that we can't deal with SUID/SGID, so we refuse to run them - (otherwise the executable may misbehave if it doesn't have the - permissions it thinks it does). -*/ -static int check_perms(int fd) -{ - struct stat st; - - if (fstat(fd, &st) == -1) - return errno; - - if (st.st_mode & (S_ISUID | S_ISGID)) { - //fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe); - return EACCES; - } - - if (geteuid() == st.st_uid) { - if (!(st.st_mode & S_IXUSR)) - return EACCES; - } else { - int grpmatch = 0; - - if (getegid() == st.st_gid) - grpmatch = 1; - else { - gid_t groups[32]; - int ngrp = getgroups(32, groups); - int i; - - for(i = 0; i < ngrp; i++) - if (groups[i] == st.st_gid) { - grpmatch = 1; - break; - } - } - - if (grpmatch) { - if (!(st.st_mode & S_IXGRP)) - return EACCES; - } else if (!(st.st_mode & S_IXOTH)) - return EACCES; - } - - return 0; -} - -static int do_exec_inner(const char *exe, struct exeinfo *info) -{ - int fd; - int err; - char buf[VKI_BYTES_PER_PAGE]; - int bufsz; - int i; - int ret; - static const struct { - int (*match)(const char *hdr, int len); - int (*load) ( char *hdr, int len, int fd2, const char *name, - struct exeinfo *); - } formats[] = { - { match_ELF, load_ELF }, - { match_script, load_script }, - }; - - fd = open(exe, O_RDONLY); - if (fd == -1) { - if (0) - fprintf(stderr, "Can't open executable %s: %s\n", - exe, strerror(errno)); - return errno; - } - - err = check_perms(fd); - if (err != 0) { - close(fd); - return err; - } - - bufsz = pread(fd, buf, sizeof(buf), 0); - if (bufsz < 0) { - fprintf(stderr, "Can't read executable header: %s\n", - strerror(errno)); - close(fd); - return errno; - } - - ret = ENOEXEC; - for(i = 0; i < sizeof(formats)/sizeof(*formats); i++) { - if ((formats[i].match)(buf, bufsz)) { - ret = (formats[i].load)(buf, bufsz, fd, exe, info); - break; - } - } - - close(fd); - - return ret; -} - -// See ume.h for an indication of which entries of 'info' are inputs, which -// are outputs, and which are both. -int do_exec(const char *exe, struct exeinfo *info) -{ - info->interp_name = NULL; - info->interp_args = NULL; - - return do_exec_inner(exe, info); -} - -/*--------------------------------------------------------------------*/ -/*--- end ume.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/ume.h b/VEX/head20041019/coregrind/ume.h deleted file mode 100644 index a015ff07d..000000000 --- a/VEX/head20041019/coregrind/ume.h +++ /dev/null @@ -1,117 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A header file used by both stage1 and stage2. ---*/ -/*--- ume.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef _COREGRIND_UME_H -#define _COREGRIND_UME_H - -#include -#include - -/*------------------------------------------------------------*/ -/*--- General stuff ---*/ -/*------------------------------------------------------------*/ - -void foreach_map(int (*fn)(char *start, char *end, - const char *perm, off_t offset, - int maj, int min, int ino, void* extra), - void* extra); - -#if ELFSZ == 64 -#define ESZ(x) Elf64_##x -#elif ELFSZ == 32 -#define ESZ(x) Elf32_##x -#else -#error ELFSZ needs to ==32 or ==64 -#endif - -/* Integer type the same size as a pointer */ -typedef ESZ(Addr) addr_t; - -// Jump to a new 'ip' with the stack 'sp'. -void jmp_with_stack(addr_t ip, addr_t sp) __attribute__((noreturn)); - -/*------------------------------------------------------------*/ -/*--- Loading ELF files ---*/ -/*------------------------------------------------------------*/ - -// Info needed to load and run a program. IN/INOUT/OUT refers to the -// inputs/outputs of do_exec(). -struct exeinfo -{ - addr_t map_base; // IN: if non-zero, base address of mappings - char** argv; // IN: the original argv - - addr_t exe_base; // INOUT: lowest (allowed) address of exe - addr_t exe_end; // INOUT: highest (allowed) address - - addr_t phdr; // OUT: address phdr was mapped at - int phnum; // OUT: number of phdrs - addr_t interp_base; // OUT: where interpreter (ld.so) was mapped - addr_t entry; // OUT: entrypoint in main executable - addr_t init_eip; // OUT: initial eip - addr_t brkbase; // OUT: base address of brk segment - - // These are the extra args added by #! scripts - char* interp_name; // OUT: the interpreter name - char* interp_args; // OUT: the args for the interpreter -}; - -// Does everything short of actually running 'exe': finds the file, -// checks execute permissions, sets up interpreter if program is a script, -// reads headers, maps file into memory, and returns important info about -// the program. -int do_exec(const char *exe, struct exeinfo *info); - -/*------------------------------------------------------------*/ -/*--- Finding and dealing with auxv ---*/ -/*------------------------------------------------------------*/ - -struct ume_auxv -{ - int a_type; - union { - void *a_ptr; - int a_val; - void (*a_fcn)(void); - } u; -}; - -struct ume_auxv *find_auxv(int *orig_esp); - -/* Our private auxv entries */ -#define AT_UME_PADFD 0xff01 /* padding file fd */ -#define AT_UME_EXECFD 0xff02 /* stage1 executable fd */ - -#endif /* _COREGRIND_UME_H */ - -/*--------------------------------------------------------------------*/ -/*--- end ume.h ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/valgrind.vs b/VEX/head20041019/coregrind/valgrind.vs deleted file mode 100644 index 6d54d63fb..000000000 --- a/VEX/head20041019/coregrind/valgrind.vs +++ /dev/null @@ -1,22 +0,0 @@ -VALGRIND_2.1 { - global: - vgPlain_*; - vgSkin_*; - vgProf_*; - vgOff_*; - vgArch_*; - *IROp*; - *IRExpr*; - *IRStmt*; - *IRBB*; - *IRDirty*; - *IRType*; - *IRTemp*; - *IRConst*; - *IRCallee*; - *IRArray*; - LibVEX_Alloc; - - local: - *; # default to hidden -}; diff --git a/VEX/head20041019/coregrind/vg_cpuid.S b/VEX/head20041019/coregrind/vg_cpuid.S deleted file mode 100644 index 439e6e125..000000000 --- a/VEX/head20041019/coregrind/vg_cpuid.S +++ /dev/null @@ -1,84 +0,0 @@ - -##--------------------------------------------------------------------## -##--- Support for determining CPU characteristics. ---## -##--- vg_cpuid.S ---## -##--------------------------------------------------------------------## - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core_asm.h" -#include "vki_unistd.h" - -/* - int VG_(cpuid)(UInt eax, - UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret) - */ -.globl VG_(cpuid) -VG_(cpuid): - pushl %ebp - movl %esp, %ebp - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - movl 8(%ebp), %eax - cpuid - movl 12(%ebp), %esi - testl %esi, %esi - jz 1f - movl %eax, (%esi) -1: - movl 16(%ebp), %esi - testl %esi, %esi - jz 2f - movl %ebx, (%esi) -2: - movl 20(%ebp), %esi - testl %esi, %esi - jz 3f - movl %ecx, (%esi) -3: - movl 24(%ebp), %esi - testl %esi, %esi - jz 4f - movl %edx, (%esi) -4: - popl %esi - popl %edx - popl %ecx - popl %ebx - popl %eax - movl %ebp, %esp - popl %ebp - ret - -/* Let the linker know we don't need an executable stack */ -.section .note.GNU-stack,"",@progbits - -##--------------------------------------------------------------------## -##--- end vg_cpuid.S ---## -##--------------------------------------------------------------------## diff --git a/VEX/head20041019/coregrind/vg_default.c b/VEX/head20041019/coregrind/vg_default.c deleted file mode 100644 index ed425e24b..000000000 --- a/VEX/head20041019/coregrind/vg_default.c +++ /dev/null @@ -1,102 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Default panicky definitions of template functions that tools ---*/ -/*--- should override. ---*/ -/*--- vg_defaults.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - - -#include "core.h" - -/* --------------------------------------------------------------------- - Error messages (for malformed tools) - ------------------------------------------------------------------ */ - -/* If the tool fails to define one or more of the required functions, - * make it very clear what went wrong! */ - -__attribute__ ((noreturn)) -void VG_(missing_tool_func) ( const Char* fn ) -{ - VG_(printf)( - "\nTool error:\n" - " The tool you have selected is missing the function `%s',\n" - " which is required.\n\n", - fn); - VG_(skin_panic)("Missing tool function"); -} - -static __attribute__ ((noreturn)) -void malloc_panic ( const Char* fn ) -{ - VG_(printf)( - "\nTool error:\n" - " The tool you have selected is missing the function `%s'\n" - " required because it is replacing malloc() et al.\n\n", - fn); - VG_(skin_panic)("Missing tool function"); -} - -/*------------------------------------------------------------*/ -/*--- Replacing malloc et al ---*/ -/*------------------------------------------------------------*/ - -/* Default redzone size for CLIENT arena of Valgrind's malloc() */ -__attribute__ ((weak)) -UInt VG_(vg_malloc_redzone_szB) = 8; - -Bool VG_(sk_malloc_called_by_scheduler) = False; - -/* If the tool hasn't replaced malloc(), this one can be called from the - scheduler, for the USERREQ__MALLOC user request used by vg_libpthread.c. - (Nb: it cannot call glibc's malloc().) The lock variable ensures that the - scheduler is the only place this can be called from; this ensures that a - malloc()-replacing tool cannot forget to implement SK_(malloc)() or - SK_(free)(). */ -__attribute__ ((weak)) -void* SK_(malloc)( Int size ) -{ - if (VG_(sk_malloc_called_by_scheduler)) - return VG_(cli_malloc)(VG_MIN_MALLOC_SZB, size); - else - malloc_panic(__PRETTY_FUNCTION__); -} - -__attribute__ ((weak)) -void SK_(free)( void* p ) -{ - /* see comment for SK_(malloc)() above */ - if (VG_(sk_malloc_called_by_scheduler)) - VG_(cli_free)(p); - else - malloc_panic(__PRETTY_FUNCTION__); -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_defaults.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_demangle.c b/VEX/head20041019/coregrind/vg_demangle.c deleted file mode 100644 index f5696aa1d..000000000 --- a/VEX/head20041019/coregrind/vg_demangle.c +++ /dev/null @@ -1,77 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Demangling of C++ mangled names. ---*/ -/*--- vg_demangle.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" -#include "demangle.h" - -#define ADD_TO_RESULT(zzstr,zzn) \ -{ \ - Char* zz = (zzstr); \ - Int nn = (zzn); \ - Int ii; \ - for (ii = 0; ii < nn; ii++) { \ - result[n_result] = zz[ii]; \ - if (n_result < result_size-1) n_result++; \ - result[n_result] = 0; \ - } \ -} - -void VG_(demangle) ( Char* orig, Char* result, Int result_size ) -{ - Int n_result = 0; - Char* demangled = NULL; - - VGP_PUSHCC(VgpDemangle); - - if (VG_(clo_demangle)) - demangled = VG_(cplus_demangle) ( orig, DMGL_ANSI | DMGL_PARAMS ); - - if (demangled) { - ADD_TO_RESULT(demangled, VG_(strlen)(demangled)); - VG_(arena_free) (VG_AR_DEMANGLE, demangled); - } else { - ADD_TO_RESULT(orig, VG_(strlen)(orig)); - } - - /* Check that the demangler isn't leaking. */ - /* 15 Feb 02: if this assertion fails, this is not a disaster. - Comment it out, and let me know. (jseward@acm.org). */ - vg_assert(VG_(is_empty_arena)(VG_AR_DEMANGLE)); - - /* VG_(show_all_arena_stats)(); */ - - VGP_POPCC(VgpDemangle); -} - - -/*--------------------------------------------------------------------*/ -/*--- end vg_demangle.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_dispatch.S b/VEX/head20041019/coregrind/vg_dispatch.S deleted file mode 100644 index 569724b36..000000000 --- a/VEX/head20041019/coregrind/vg_dispatch.S +++ /dev/null @@ -1,192 +0,0 @@ - -##--------------------------------------------------------------------## -##--- The core dispatch loop, for jumping to a code address. ---## -##--- vg_dispatch.S ---## -##--------------------------------------------------------------------## - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core_asm.h" - - -/*------------------------------------------------------------*/ -/*--- The normal-case dispatch machinery. ---*/ -/*------------------------------------------------------------*/ - -/* To transfer to an (original) code address, load it into %eax and - jump to vg_dispatch. This fragment of code tries to find the - address of the corresponding translation by searching the translation - table. If it fails, a new translation is made, added to the - translation table, and then jumped to. Almost all the hard - work is done by C routines; this code simply handles the - common case fast -- when the translation address is found in - the translation cache. - - At entry, %eax is the only live (real-machine) register; the - entire simulated state is tidily saved in vg_m_state. -*/ - - -#define TT_LOOKUP(reg, fail) \ - movl %eax, reg; \ - andl $VG_TT_FAST_MASK, reg; \ - movl VG_(tt_fast)(,reg,4), reg; \ - cmpl %eax, (reg); \ - jnz fail - -/* The C world needs a way to get started simulating. So we provide - a function void vg_run_innerloop ( void ), which starts running - from vg_m_eip, and exits when the counter reaches zero. This loop - can also exit if vg_oursignalhandler() catches a non-resumable - signal, for example SIGSEGV. It then longjmp()s back past here. -*/ - -.globl VG_(run_innerloop) -VG_(run_innerloop): - /* OYNK(1000) */ - - /* ----- entry point to VG_(run_innerloop) ----- */ - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - pushl %edi - pushl %ebp - - /* check to see if we're doing pointer checking */ - movb VG_(clo_pointercheck), %al - testb %al,%al - jz 1f - - pushl %fs /* save %fs */ - mov $(VG_POINTERCHECK_SEGIDX << 3) + 7, %eax /* load new %fs */ - movw %ax,%fs - -1: - /* Set up the baseBlock pointer */ - movl $VG_(baseBlock), %ebp - - /* fetch m_eip into %eax */ - movl VGOFF_(m_eip), %esi - movl (%ebp, %esi, 4), %eax - - /* fall into main loop */ - -dispatch_boring: - /* save the jump address at VG_(baseBlock)[VGOFF_(m_eip)] */ - movl VGOFF_(m_eip), %esi - movl %eax, (%ebp, %esi, 4) - - /* Are we out of timeslice? If yes, defer to scheduler. */ - subl $1, VG_(dispatch_ctr) - - jz counter_is_zero - /* try a fast lookup in the translation cache */ - TT_LOOKUP(%ebx, fast_lookup_failed) - - /* Found a match. Call the tce.payload field (+VG_CODE_OFFSET) */ - addl $VG_CODE_OFFSET, %ebx - call *%ebx - - /* - %eax holds destination (original) address. - %ebp indicates further details of the control transfer - requested to the address in %eax. - - If ebp == & VG_(baseBlock), just jump next to %eax. - - If ebp == VG_EBP_JMP_SYSCALL, do a system call before - continuing at eax. - - If ebp == VG_EBP_JMP_CLIENTREQ, do a client request before - continuing at eax. - - If %ebp has any other value, we panic. - */ - - cmpl $VG_(baseBlock), %ebp - jz dispatch_boring - - jmp dispatch_exceptional - - -fast_lookup_failed: - /* %EIP is up to date here since dispatch_boring dominates */ - addl $1, VG_(dispatch_ctr) - movl $VG_TRC_INNER_FASTMISS, %eax - jmp run_innerloop_exit - -counter_is_zero: - /* %EIP is up to date here since dispatch_boring dominates */ - addl $1, VG_(dispatch_ctr) - movl $VG_TRC_INNER_COUNTERZERO, %eax - jmp run_innerloop_exit - -run_innerloop_exit: - movb VG_(clo_pointercheck), %bl - testb %bl,%bl - jz 1f - - /* restore %fs */ - popl %fs - -1: popl %ebp - popl %edi - popl %esi - popl %edx - popl %ecx - popl %ebx - ret - - - -/* Other ways of getting out of the inner loop. Placed out-of-line to - make it look cleaner. -*/ -dispatch_exceptional: - /* this is jumped to only, not fallen-through from above */ - cmpl $VG_TRC_INNER_COUNTERZERO, %ebp - jz counter_is_zero - - /* save %eax in %EIP and defer to sched */ - movl VGOFF_(m_eip), %esi - movl %eax, VG_(baseBlock)(,%esi, 4) - movl %ebp, %eax - jmp run_innerloop_exit - - -.data -panic_msg_ebp: -.ascii "vg_dispatch: %ebp has invalid value!" -.byte 0 -.text - -/* Let the linker know we don't need an executable stack */ -.section .note.GNU-stack,"",@progbits - -##--------------------------------------------------------------------## -##--- end vg_dispatch.S ---## -##--------------------------------------------------------------------## diff --git a/VEX/head20041019/coregrind/vg_dummy_profile.c b/VEX/head20041019/coregrind/vg_dummy_profile.c deleted file mode 100644 index a44133e1c..000000000 --- a/VEX/head20041019/coregrind/vg_dummy_profile.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Dummy profiling machinery -- overridden by tools when they ---*/ -/*--- want profiling. ---*/ -/*--- vg_dummy_profile.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" - -static void vgp_die(void) -{ - VG_(printf)( - "\nProfiling error:\n" - " The --profile=yes option was specified, but the tool\n" - " wasn't built for profiling. #include \"vg_profile.c\"\n" - " into the tool and rebuild to allow profiling.\n\n"); - VG_(exit)(1); -} - -void VGP_(register_profile_event) ( Int n, Char* name ) -{ -} - -void VGP_(init_profiling) ( void ) -{ - vgp_die(); -} - -void VGP_(done_profiling) ( void ) -{ - VG_(core_panic)("done_profiling(), but not compiled for profiling??"); -} - -void VGP_(pushcc) ( UInt cc ) -{ - vgp_die(); -} - -void VGP_(popcc) ( UInt cc ) -{ - vgp_die(); -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_dummy_profile.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_dwarf.c b/VEX/head20041019/coregrind/vg_dwarf.c deleted file mode 100644 index aff343f8d..000000000 --- a/VEX/head20041019/coregrind/vg_dwarf.c +++ /dev/null @@ -1,834 +0,0 @@ -/*--------------------------------------------------------------------*/ -/*--- Read DWARF2 debug info. vg_dwarf.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" -#include "vg_symtab2.h" - - -/* Structure found in the .debug_line section. */ -typedef struct -{ - UChar li_length [4]; - UChar li_version [2]; - UChar li_prologue_length [4]; - UChar li_min_insn_length [1]; - UChar li_default_is_stmt [1]; - UChar li_line_base [1]; - UChar li_line_range [1]; - UChar li_opcode_base [1]; -} -DWARF2_External_LineInfo; - -typedef struct -{ - UInt li_length; - UShort li_version; - UInt li_prologue_length; - UChar li_min_insn_length; - UChar li_default_is_stmt; - Int li_line_base; - UChar li_line_range; - UChar li_opcode_base; -} -DWARF2_Internal_LineInfo; - -/* Line number opcodes. */ -enum dwarf_line_number_ops - { - DW_LNS_extended_op = 0, - DW_LNS_copy = 1, - DW_LNS_advance_pc = 2, - DW_LNS_advance_line = 3, - DW_LNS_set_file = 4, - DW_LNS_set_column = 5, - DW_LNS_negate_stmt = 6, - DW_LNS_set_basic_block = 7, - DW_LNS_const_add_pc = 8, - DW_LNS_fixed_advance_pc = 9, - /* DWARF 3. */ - DW_LNS_set_prologue_end = 10, - DW_LNS_set_epilogue_begin = 11, - DW_LNS_set_isa = 12 - }; - -/* Line number extended opcodes. */ -enum dwarf_line_number_x_ops - { - DW_LNE_end_sequence = 1, - DW_LNE_set_address = 2, - DW_LNE_define_file = 3 - }; - -typedef struct State_Machine_Registers -{ - /* Information for the last statement boundary. - * Needed to calculate statement lengths. */ - Addr last_address; - UInt last_file; - UInt last_line; - - Addr address; - UInt file; - UInt line; - UInt column; - Int is_stmt; - Int basic_block; - Int end_sequence; - /* This variable hold the number of the last entry seen - in the File Table. */ - UInt last_file_entry; -} SMR; - - -static -UInt read_leb128 ( UChar* data, Int* length_return, Int sign ) -{ - UInt result = 0; - UInt num_read = 0; - Int shift = 0; - UChar byte; - - do - { - byte = * data ++; - num_read ++; - - result |= (byte & 0x7f) << shift; - - shift += 7; - - } - while (byte & 0x80); - - if (length_return != NULL) - * length_return = num_read; - - if (sign && (shift < 32) && (byte & 0x40)) - result |= -1 << shift; - - return result; -} - - -static SMR state_machine_regs; - -static -void reset_state_machine ( Int is_stmt ) -{ - if (0) VG_(printf)("smr.a := %p (reset)\n", 0 ); - state_machine_regs.last_address = 0; - state_machine_regs.last_file = 1; - state_machine_regs.last_line = 1; - state_machine_regs.address = 0; - state_machine_regs.file = 1; - state_machine_regs.line = 1; - state_machine_regs.column = 0; - state_machine_regs.is_stmt = is_stmt; - state_machine_regs.basic_block = 0; - state_machine_regs.end_sequence = 0; - state_machine_regs.last_file_entry = 0; -} - -/* Handled an extend line op. Returns true if this is the end - of sequence. */ -static -int process_extended_line_op( SegInfo *si, Char*** fnames, - UChar* data, Int is_stmt, Int pointer_size) -{ - UChar op_code; - Int bytes_read; - UInt len; - UChar * name; - Addr adr; - - len = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - - if (len == 0) - { - VG_(message)(Vg_UserMsg, - "badly formed extended line op encountered!\n"); - return bytes_read; - } - - len += bytes_read; - op_code = * data ++; - - if (0) VG_(printf)("dwarf2: ext OPC: %d\n", op_code); - - switch (op_code) - { - case DW_LNE_end_sequence: - if (0) VG_(printf)("1001: si->o %p, smr.a %p\n", - si->offset, state_machine_regs.address ); - state_machine_regs.end_sequence = 1; /* JRS: added for compliance - with spec; is pointless due to reset_state_machine below - */ - if (state_machine_regs.is_stmt) { - if (state_machine_regs.last_address) - VG_(addLineInfo) (si, (*fnames)[state_machine_regs.last_file], - si->offset + state_machine_regs.last_address, - si->offset + state_machine_regs.address, - state_machine_regs.last_line, 0); - } - reset_state_machine (is_stmt); - break; - - case DW_LNE_set_address: - /* XXX: Pointer size could be 8 */ - vg_assert(pointer_size == 4); - adr = *((Addr *)data); - if (0) VG_(printf)("smr.a := %p\n", adr ); - state_machine_regs.address = adr; - break; - - case DW_LNE_define_file: - ++ state_machine_regs.last_file_entry; - name = data; - if (*fnames == NULL) - *fnames = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof (UInt) * 2); - else - *fnames = VG_(arena_realloc)( - VG_AR_SYMTAB, *fnames, VG_MIN_MALLOC_SZB, - sizeof(UInt) - * (state_machine_regs.last_file_entry + 1)); - (*fnames)[state_machine_regs.last_file_entry] = VG_(addStr) (si,name, -1); - data += VG_(strlen) ((char *) data) + 1; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - break; - - default: - break; - } - - return len; -} - - -void VG_(read_debuginfo_dwarf2) ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz ) -{ - DWARF2_External_LineInfo * external; - DWARF2_Internal_LineInfo info; - UChar * standard_opcodes; - UChar * data = dwarf2; - UChar * end = dwarf2 + dwarf2_sz; - UChar * end_of_sequence; - Char ** fnames = NULL; - - /* Fails due to gcc padding ... - vg_assert(sizeof(DWARF2_External_LineInfo) - == sizeof(DWARF2_Internal_LineInfo)); - */ - - while (data < end) - { - external = (DWARF2_External_LineInfo *) data; - - /* Check the length of the block. */ - info.li_length = * ((UInt *)(external->li_length)); - - if (info.li_length == 0xffffffff) - { - VG_(symerr)("64-bit DWARF line info is not supported yet."); - break; - } - - if (info.li_length + sizeof (external->li_length) > dwarf2_sz) - { - VG_(symerr)("DWARF line info appears to be corrupt " - "- the section is too small"); - return; - } - - /* Check its version number. */ - info.li_version = * ((UShort *) (external->li_version)); - if (info.li_version != 2) - { - VG_(symerr)("Only DWARF version 2 line info " - "is currently supported."); - return; - } - - info.li_prologue_length = * ((UInt *) (external->li_prologue_length)); - info.li_min_insn_length = * ((UChar *)(external->li_min_insn_length)); - - info.li_default_is_stmt = True; - /* WAS: = * ((UChar *)(external->li_default_is_stmt)); */ - /* Josef Weidendorfer (20021021) writes: - - It seems to me that the Intel Fortran compiler generates - bad DWARF2 line info code: It sets "is_stmt" of the state - machine in the the line info reader to be always - false. Thus, there is never a statement boundary generated - and therefore never a instruction range/line number - mapping generated for valgrind. - - Please have a look at the DWARF2 specification, Ch. 6.2 - (x86.ddj.com/ftp/manuals/tools/dwarf.pdf). Perhaps I - understand this wrong, but I don't think so. - - I just had a look at the GDB DWARF2 reader... They - completely ignore "is_stmt" when recording line info ;-) - That's the reason "objdump -S" works on files from the the - intel fortran compiler. - */ - - - /* JRS: changed (UInt*) to (UChar*) */ - info.li_line_base = * ((UChar *)(external->li_line_base)); - - info.li_line_range = * ((UChar *)(external->li_line_range)); - info.li_opcode_base = * ((UChar *)(external->li_opcode_base)); - - if (0) VG_(printf)("dwarf2: line base: %d, range %d, opc base: %d\n", - info.li_line_base, info.li_line_range, info.li_opcode_base); - - /* Sign extend the line base field. */ - info.li_line_base <<= 24; - info.li_line_base >>= 24; - - end_of_sequence = data + info.li_length - + sizeof (external->li_length); - - reset_state_machine (info.li_default_is_stmt); - - /* Read the contents of the Opcodes table. */ - standard_opcodes = data + sizeof (* external); - - /* Read the contents of the Directory table. */ - data = standard_opcodes + info.li_opcode_base - 1; - - if (* data == 0) - { - } - else - { - /* We ignore the directory table, since gcc gives the entire - path as part of the filename */ - while (* data != 0) - { - data += VG_(strlen) ((char *) data) + 1; - } - } - - /* Skip the NUL at the end of the table. */ - if (*data != 0) { - VG_(symerr)("can't find NUL at end of DWARF2 directory table"); - return; - } - data ++; - - /* Read the contents of the File Name table. */ - if (* data == 0) - { - } - else - { - while (* data != 0) - { - UChar * name; - Int bytes_read; - - ++ state_machine_regs.last_file_entry; - name = data; - /* Since we don't have realloc (0, ....) == malloc (...) - semantics, we need to malloc the first time. */ - - if (fnames == NULL) - fnames = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof (UInt) * 2); - else - fnames = VG_(arena_realloc)(VG_AR_SYMTAB, fnames, - VG_MIN_MALLOC_SZB, - sizeof(UInt) - * (state_machine_regs.last_file_entry + 1)); - data += VG_(strlen) ((Char *) data) + 1; - fnames[state_machine_regs.last_file_entry] = VG_(addStr) (si,name, -1); - - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - } - } - - /* Skip the NUL at the end of the table. */ - if (*data != 0) { - VG_(symerr)("can't find NUL at end of DWARF2 file name table"); - return; - } - data ++; - - /* Now display the statements. */ - - while (data < end_of_sequence) - { - UChar op_code; - Int adv; - Int bytes_read; - - op_code = * data ++; - - if (0) VG_(printf)("dwarf2: OPC: %d\n", op_code); - - if (op_code >= info.li_opcode_base) - { - Int advAddr; - op_code -= info.li_opcode_base; - adv = (op_code / info.li_line_range) - * info.li_min_insn_length; - advAddr = adv; - state_machine_regs.address += adv; - if (0) VG_(printf)("smr.a += %p\n", adv ); - adv = (op_code % info.li_line_range) + info.li_line_base; - if (0) VG_(printf)("1002: si->o %p, smr.a %p\n", - si->offset, state_machine_regs.address ); - state_machine_regs.line += adv; - - if (state_machine_regs.is_stmt) { - /* only add a statement if there was a previous boundary */ - if (state_machine_regs.last_address) - VG_(addLineInfo) (si, fnames[state_machine_regs.last_file], - si->offset + state_machine_regs.last_address, - si->offset + state_machine_regs.address, - state_machine_regs.last_line, 0); - state_machine_regs.last_address = state_machine_regs.address; - state_machine_regs.last_file = state_machine_regs.file; - state_machine_regs.last_line = state_machine_regs.line; - } - } - else switch (op_code) - { - case DW_LNS_extended_op: - data += process_extended_line_op ( - si, &fnames, data, - info.li_default_is_stmt, sizeof (Addr)); - break; - - case DW_LNS_copy: - if (0) VG_(printf)("1002: si->o %p, smr.a %p\n", - si->offset, state_machine_regs.address ); - if (state_machine_regs.is_stmt) { - /* only add a statement if there was a previous boundary */ - if (state_machine_regs.last_address) - VG_(addLineInfo) (si, fnames[state_machine_regs.last_file], - si->offset + state_machine_regs.last_address, - si->offset + state_machine_regs.address, - state_machine_regs.last_line, 0); - state_machine_regs.last_address = state_machine_regs.address; - state_machine_regs.last_file = state_machine_regs.file; - state_machine_regs.last_line = state_machine_regs.line; - } - state_machine_regs.basic_block = 0; /* JRS added */ - break; - - case DW_LNS_advance_pc: - adv = info.li_min_insn_length - * read_leb128 (data, & bytes_read, 0); - data += bytes_read; - state_machine_regs.address += adv; - if (0) VG_(printf)("smr.a += %p\n", adv ); - break; - - case DW_LNS_advance_line: - adv = read_leb128 (data, & bytes_read, 1); - data += bytes_read; - state_machine_regs.line += adv; - break; - - case DW_LNS_set_file: - adv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - state_machine_regs.file = adv; - break; - - case DW_LNS_set_column: - adv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - state_machine_regs.column = adv; - break; - - case DW_LNS_negate_stmt: - adv = state_machine_regs.is_stmt; - adv = ! adv; - state_machine_regs.is_stmt = adv; - break; - - case DW_LNS_set_basic_block: - state_machine_regs.basic_block = 1; - break; - - case DW_LNS_const_add_pc: - adv = (((255 - info.li_opcode_base) / info.li_line_range) - * info.li_min_insn_length); - state_machine_regs.address += adv; - if (0) VG_(printf)("smr.a += %p\n", adv ); - break; - - case DW_LNS_fixed_advance_pc: - /* XXX: Need something to get 2 bytes */ - adv = *((UShort *)data); - data += 2; - state_machine_regs.address += adv; - if (0) VG_(printf)("smr.a += %p\n", adv ); - break; - - case DW_LNS_set_prologue_end: - break; - - case DW_LNS_set_epilogue_begin: - break; - - case DW_LNS_set_isa: - adv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - break; - - default: - { - int j; - for (j = standard_opcodes[op_code - 1]; j > 0 ; --j) - { - read_leb128 (data, &bytes_read, 0); - data += bytes_read; - } - } - break; - } - } - VG_(arena_free)(VG_AR_SYMTAB, fnames); - fnames = NULL; - } -} - - -/*------------------------------------------------------------*/ -/*--- Read DWARF1 format line number info. ---*/ -/*------------------------------------------------------------*/ - -/* DWARF1 appears to be redundant, but nevertheless the Lahey Fortran - compiler generates it. -*/ - -/* The following three enums (dwarf_tag, dwarf_form, dwarf_attribute) - are taken from the file include/elf/dwarf.h in the GNU gdb-6.0 - sources, which are Copyright 1992, 1993, 1995, 1999 Free Software - Foundation, Inc and naturally licensed under the GNU General Public - License version 2 or later. -*/ - -/* Tag names and codes. */ - -enum dwarf_tag { - TAG_padding = 0x0000, - TAG_array_type = 0x0001, - TAG_class_type = 0x0002, - TAG_entry_point = 0x0003, - TAG_enumeration_type = 0x0004, - TAG_formal_parameter = 0x0005, - TAG_global_subroutine = 0x0006, - TAG_global_variable = 0x0007, - /* 0x0008 -- reserved */ - /* 0x0009 -- reserved */ - TAG_label = 0x000a, - TAG_lexical_block = 0x000b, - TAG_local_variable = 0x000c, - TAG_member = 0x000d, - /* 0x000e -- reserved */ - TAG_pointer_type = 0x000f, - TAG_reference_type = 0x0010, - TAG_compile_unit = 0x0011, - TAG_string_type = 0x0012, - TAG_structure_type = 0x0013, - TAG_subroutine = 0x0014, - TAG_subroutine_type = 0x0015, - TAG_typedef = 0x0016, - TAG_union_type = 0x0017, - TAG_unspecified_parameters = 0x0018, - TAG_variant = 0x0019, - TAG_common_block = 0x001a, - TAG_common_inclusion = 0x001b, - TAG_inheritance = 0x001c, - TAG_inlined_subroutine = 0x001d, - TAG_module = 0x001e, - TAG_ptr_to_member_type = 0x001f, - TAG_set_type = 0x0020, - TAG_subrange_type = 0x0021, - TAG_with_stmt = 0x0022, - - /* GNU extensions */ - - TAG_format_label = 0x8000, /* for FORTRAN 77 and Fortran 90 */ - TAG_namelist = 0x8001, /* For Fortran 90 */ - TAG_function_template = 0x8002, /* for C++ */ - TAG_class_template = 0x8003 /* for C++ */ -}; - -/* Form names and codes. */ - -enum dwarf_form { - FORM_ADDR = 0x1, - FORM_REF = 0x2, - FORM_BLOCK2 = 0x3, - FORM_BLOCK4 = 0x4, - FORM_DATA2 = 0x5, - FORM_DATA4 = 0x6, - FORM_DATA8 = 0x7, - FORM_STRING = 0x8 -}; - -/* Attribute names and codes. */ - -enum dwarf_attribute { - AT_sibling = (0x0010|FORM_REF), - AT_location = (0x0020|FORM_BLOCK2), - AT_name = (0x0030|FORM_STRING), - AT_fund_type = (0x0050|FORM_DATA2), - AT_mod_fund_type = (0x0060|FORM_BLOCK2), - AT_user_def_type = (0x0070|FORM_REF), - AT_mod_u_d_type = (0x0080|FORM_BLOCK2), - AT_ordering = (0x0090|FORM_DATA2), - AT_subscr_data = (0x00a0|FORM_BLOCK2), - AT_byte_size = (0x00b0|FORM_DATA4), - AT_bit_offset = (0x00c0|FORM_DATA2), - AT_bit_size = (0x00d0|FORM_DATA4), - /* (0x00e0|FORM_xxxx) -- reserved */ - AT_element_list = (0x00f0|FORM_BLOCK4), - AT_stmt_list = (0x0100|FORM_DATA4), - AT_low_pc = (0x0110|FORM_ADDR), - AT_high_pc = (0x0120|FORM_ADDR), - AT_language = (0x0130|FORM_DATA4), - AT_member = (0x0140|FORM_REF), - AT_discr = (0x0150|FORM_REF), - AT_discr_value = (0x0160|FORM_BLOCK2), - /* (0x0170|FORM_xxxx) -- reserved */ - /* (0x0180|FORM_xxxx) -- reserved */ - AT_string_length = (0x0190|FORM_BLOCK2), - AT_common_reference = (0x01a0|FORM_REF), - AT_comp_dir = (0x01b0|FORM_STRING), - AT_const_value_string = (0x01c0|FORM_STRING), - AT_const_value_data2 = (0x01c0|FORM_DATA2), - AT_const_value_data4 = (0x01c0|FORM_DATA4), - AT_const_value_data8 = (0x01c0|FORM_DATA8), - AT_const_value_block2 = (0x01c0|FORM_BLOCK2), - AT_const_value_block4 = (0x01c0|FORM_BLOCK4), - AT_containing_type = (0x01d0|FORM_REF), - AT_default_value_addr = (0x01e0|FORM_ADDR), - AT_default_value_data2 = (0x01e0|FORM_DATA2), - AT_default_value_data4 = (0x01e0|FORM_DATA4), - AT_default_value_data8 = (0x01e0|FORM_DATA8), - AT_default_value_string = (0x01e0|FORM_STRING), - AT_friends = (0x01f0|FORM_BLOCK2), - AT_inline = (0x0200|FORM_STRING), - AT_is_optional = (0x0210|FORM_STRING), - AT_lower_bound_ref = (0x0220|FORM_REF), - AT_lower_bound_data2 = (0x0220|FORM_DATA2), - AT_lower_bound_data4 = (0x0220|FORM_DATA4), - AT_lower_bound_data8 = (0x0220|FORM_DATA8), - AT_private = (0x0240|FORM_STRING), - AT_producer = (0x0250|FORM_STRING), - AT_program = (0x0230|FORM_STRING), - AT_protected = (0x0260|FORM_STRING), - AT_prototyped = (0x0270|FORM_STRING), - AT_public = (0x0280|FORM_STRING), - AT_pure_virtual = (0x0290|FORM_STRING), - AT_return_addr = (0x02a0|FORM_BLOCK2), - AT_abstract_origin = (0x02b0|FORM_REF), - AT_start_scope = (0x02c0|FORM_DATA4), - AT_stride_size = (0x02e0|FORM_DATA4), - AT_upper_bound_ref = (0x02f0|FORM_REF), - AT_upper_bound_data2 = (0x02f0|FORM_DATA2), - AT_upper_bound_data4 = (0x02f0|FORM_DATA4), - AT_upper_bound_data8 = (0x02f0|FORM_DATA8), - AT_virtual = (0x0300|FORM_STRING), - - /* GNU extensions. */ - - AT_sf_names = (0x8000|FORM_DATA4), - AT_src_info = (0x8010|FORM_DATA4), - AT_mac_info = (0x8020|FORM_DATA4), - AT_src_coords = (0x8030|FORM_DATA4), - AT_body_begin = (0x8040|FORM_ADDR), - AT_body_end = (0x8050|FORM_ADDR) -}; - -/* end of enums taken from gdb-6.0 sources */ - -void VG_(read_debuginfo_dwarf1) ( - SegInfo* si, - UChar* dwarf1d, Int dwarf1d_sz, - UChar* dwarf1l, Int dwarf1l_sz ) -{ - UInt stmt_list; - Bool stmt_list_found; - Int die_offset, die_szb, at_offset; - UShort die_kind, at_kind; - UChar* at_base; - UChar* src_filename; - - if (0) - VG_(printf)("read_debuginfo_dwarf1 ( %p, %d, %p, %d )\n", - dwarf1d, dwarf1d_sz, dwarf1l, dwarf1l_sz ); - - /* This loop scans the DIEs. */ - die_offset = 0; - while (True) { - if (die_offset >= dwarf1d_sz) break; - - die_szb = *(Int*)(dwarf1d + die_offset); - die_kind = *(UShort*)(dwarf1d + die_offset + 4); - - /* We're only interested in compile_unit DIEs; ignore others. */ - if (die_kind != TAG_compile_unit) { - die_offset += die_szb; - continue; - } - - if (0) - VG_(printf)("compile-unit DIE: offset %d, tag 0x%x, size %d\n", - die_offset, (Int)die_kind, die_szb ); - - /* We've got a compile_unit DIE starting at (dwarf1d + - die_offset+6). Try and find the AT_name and AT_stmt_list - attributes. Then, finally, we can read the line number info - for this source file. */ - - /* The next 3 are set as we find the relevant attrs. */ - src_filename = NULL; - stmt_list_found = False; - stmt_list = 0; - - /* This loop scans the Attrs inside compile_unit DIEs. */ - at_base = dwarf1d + die_offset + 6; - at_offset = 0; - while (True) { - if (at_offset >= die_szb-6) break; - - at_kind = *(UShort*)(at_base + at_offset); - if (0) VG_(printf)("atoffset %d, attag 0x%x\n", - at_offset, (Int)at_kind ); - at_offset += 2; /* step over the attribute itself */ - /* We have to examine the attribute to figure out its - length. */ - switch (at_kind) { - case AT_stmt_list: - case AT_language: - case AT_sibling: - if (at_kind == AT_stmt_list) { - stmt_list_found = True; - stmt_list = *(Int*)(at_base+at_offset); - } - at_offset += 4; break; - case AT_high_pc: - case AT_low_pc: - at_offset += sizeof(void*); break; - case AT_name: - case AT_producer: - case AT_comp_dir: - /* Zero terminated string, step over it. */ - if (at_kind == AT_name) - src_filename = at_base + at_offset; - while (at_offset < die_szb-6 && at_base[at_offset] != 0) - at_offset++; - at_offset++; - break; - default: - VG_(printf)("Unhandled DWARF-1 attribute 0x%x\n", - (Int)at_kind ); - VG_(core_panic)("Unhandled DWARF-1 attribute"); - } /* switch (at_kind) */ - } /* looping over attributes */ - - /* So, did we find the required stuff for a line number table in - this DIE? If yes, read it. */ - if (stmt_list_found /* there is a line number table */ - && src_filename != NULL /* we know the source filename */ - ) { - /* Table starts: - Length: - 4 bytes, includes the entire table - Base address: - unclear (4? 8?), assuming native pointer size here. - Then a sequence of triples - (source line number -- 32 bits - source line column -- 16 bits - address delta -- 32 bits) - */ - Addr base; - Int len; - Char* curr_filenm; - UChar* ptr; - UInt prev_line, prev_delta; - - curr_filenm = VG_(addStr) ( si, src_filename, -1 ); - prev_line = prev_delta = 0; - - ptr = dwarf1l + stmt_list; - len = *(Int*)ptr; ptr += sizeof(Int); - base = (Addr)(*(void**)ptr); ptr += sizeof(void*); - len -= (sizeof(Int) + sizeof(void*)); - while (len > 0) { - UInt line; - UShort col; - UInt delta; - line = *(UInt*)ptr; ptr += sizeof(UInt); - col = *(UShort*)ptr; ptr += sizeof(UShort); - delta = *(UShort*)ptr; ptr += sizeof(UInt); - if (0) VG_(printf)("line %d, col %d, delta %d\n", - line, (Int)col, delta ); - len -= (sizeof(UInt) + sizeof(UShort) + sizeof(UInt)); - - if (delta > 0 && prev_line > 0) { - if (0) VG_(printf) (" %d %d-%d\n", - prev_line, prev_delta, delta-1); - VG_(addLineInfo) ( si, curr_filenm, - base + prev_delta, base + delta, - prev_line, 0 ); - } - prev_line = line; - prev_delta = delta; - } - } - - /* Move on the the next DIE. */ - die_offset += die_szb; - - } /* Looping over DIEs */ - -} - - -/*--------------------------------------------------------------------*/ -/*--- end vg_dwarf.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_errcontext.c b/VEX/head20041019/coregrind/vg_errcontext.c deleted file mode 100644 index 5a2274ec5..000000000 --- a/VEX/head20041019/coregrind/vg_errcontext.c +++ /dev/null @@ -1,1021 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Management of error messages. vg_errcontext.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" - -/*------------------------------------------------------------*/ -/*--- Globals ---*/ -/*------------------------------------------------------------*/ - -/* The list of error contexts found, both suppressed and unsuppressed. - Initially empty, and grows as errors are detected. */ -static Error* vg_errors = NULL; - -/* The list of suppression directives, as read from the specified - suppressions file. */ -static Supp* vg_suppressions = NULL; - -/* Running count of unsuppressed errors detected. */ -static UInt n_errs_found = 0; - -/* Running count of suppressed errors detected. */ -static UInt n_errs_suppressed = 0; - -/* forwards ... */ -static Supp* is_suppressible_error ( Error* err ); - - -/*------------------------------------------------------------*/ -/*--- Error type ---*/ -/*------------------------------------------------------------*/ - -/* Note: it is imperative this doesn't overlap with (0..) at all, as tools - * effectively extend it by defining their own enums in the (0..) range. */ -typedef - enum { - PThreadErr = -1, // Pthreading error - } - CoreErrorKind; - -/* Errors. Extensible (via the 'extra' field). Tools can use a normal - enum (with element values in the normal range (0..)) for `ekind'. - Functions for getting/setting the tool-relevant fields are in - include/tool.h. - - When errors are found and recorded with VG_(maybe_record_error)(), all - the tool must do is pass in the four parameters; core will - allocate/initialise the error record. -*/ -struct _Error { - struct _Error* next; - // NULL if unsuppressed; or ptr to suppression record. - Supp* supp; - Int count; - ThreadId tid; - - // The tool-specific part - ExeContext* where; // Initialised by core - Int ekind; // Used by ALL. Must be in the range (0..) - Addr addr; // Used frequently - Char* string; // Used frequently - void* extra; // For any tool-specific extras -}; - -ExeContext* VG_(get_error_where) ( Error* err ) -{ - return err->where; -} - -ErrorKind VG_(get_error_kind) ( Error* err ) -{ - return err->ekind; -} - -Addr VG_(get_error_address) ( Error* err ) -{ - return err->addr; -} - -Char* VG_(get_error_string) ( Error* err ) -{ - return err->string; -} - -void* VG_(get_error_extra) ( Error* err ) -{ - return err->extra; -} - -UInt VG_(get_n_errs_found)( void ) -{ - return n_errs_found; -} - -/*------------------------------------------------------------*/ -/*--- Suppression type ---*/ -/*------------------------------------------------------------*/ - -/* Note: it is imperative this doesn't overlap with (0..) at all, as tools - * effectively extend it by defining their own enums in the (0..) range. */ -typedef - enum { - PThreadSupp = -1, /* Matches PThreadErr */ - } - CoreSuppKind; - -/* For each caller specified for a suppression, record the nature of - the caller name. Not of interest to tools. */ -typedef - enum { - ObjName, /* Name is of an shared object file. */ - FunName /* Name is of a function. */ - } - SuppLocTy; - -/* Suppressions. Tools can get/set tool-relevant parts with functions - declared in include/tool.h. Extensible via the 'extra' field. - Tools can use a normal enum (with element values in the normal range - (0..)) for `skind'. */ -struct _Supp { - struct _Supp* next; - Int count; // The number of times this error has been suppressed. - Char* sname; // The name by which the suppression is referred to. - /* First two (name of fn where err occurs, and immediate caller) - * are mandatory; extra two are optional. */ - SuppLocTy caller_ty[VG_N_SUPP_CALLERS]; - Char* caller [VG_N_SUPP_CALLERS]; - - /* The tool-specific part */ - SuppKind skind; // What kind of suppression. Must use the range (0..). - Char* string; // String -- use is optional. NULL by default. - void* extra; // Anything else -- use is optional. NULL by default. -}; - -SuppKind VG_(get_supp_kind) ( Supp* su ) -{ - return su->skind; -} - -Char* VG_(get_supp_string) ( Supp* su ) -{ - return su->string; -} - -void* VG_(get_supp_extra) ( Supp* su ) -{ - return su->extra; -} - - -void VG_(set_supp_kind) ( Supp* su, SuppKind skind ) -{ - su->skind = skind; -} - -void VG_(set_supp_string) ( Supp* su, Char* string ) -{ - su->string = string; -} - -void VG_(set_supp_extra) ( Supp* su, void* extra ) -{ - su->extra = extra; -} - - -/*------------------------------------------------------------*/ -/*--- Helper fns ---*/ -/*------------------------------------------------------------*/ - -/* Compare error contexts, to detect duplicates. Note that if they - are otherwise the same, the faulting addrs and associated rwoffsets - are allowed to be different. */ -static Bool eq_Error ( VgRes res, Error* e1, Error* e2 ) -{ - if (e1->ekind != e2->ekind) - return False; - if (!VG_(eq_ExeContext)(res, e1->where, e2->where)) - return False; - - switch (e1->ekind) { - case PThreadErr: - vg_assert(VG_(needs).core_errors); - if (e1->string == e2->string) - return True; - if (0 == VG_(strcmp)(e1->string, e2->string)) - return True; - return False; - default: - if (VG_(needs).skin_errors) - return SK_(eq_SkinError)(res, e1, e2); - else { - VG_(printf)("\nUnhandled error type: %u. VG_(needs).skin_errors\n" - "probably needs to be set.\n", - e1->ekind); - VG_(skin_panic)("unhandled error type"); - } - } -} - -static void pp_Error ( Error* err, Bool printCount ) -{ - if (printCount) - VG_(message)(Vg_UserMsg, "Observed %d times:", err->count ); - if (err->tid > 1) - VG_(message)(Vg_UserMsg, "Thread %d:", err->tid ); - - switch (err->ekind) { - case PThreadErr: - vg_assert(VG_(needs).core_errors); - VG_(message)(Vg_UserMsg, "%s", err->string ); - VG_(pp_ExeContext)(err->where); - break; - default: - if (VG_(needs).skin_errors) - SK_(pp_SkinError)( err ); - else { - VG_(printf)("\nUnhandled error type: %u. VG_(needs).skin_errors\n" - "probably needs to be set?\n", - err->ekind); - VG_(skin_panic)("unhandled error type"); - } - } -} - -/* Figure out if we want to perform a given action for this error, possibly - by asking the user. */ -Bool VG_(is_action_requested) ( Char* action, Bool* clo ) -{ - Char ch, ch2; - Int res; - - if (*clo == False) - return False; - - VG_(message)(Vg_UserMsg, ""); - - again: - VG_(printf)( - "==%d== " - "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ", - VG_(getpid)(), action - ); - - res = VG_(read)(VG_(clo_input_fd), &ch, 1); - if (res != 1) goto ioerror; - /* res == 1 */ - if (ch == '\n') return False; - if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y' - && ch != 'C' && ch != 'c') goto again; - - res = VG_(read)(VG_(clo_input_fd), &ch2, 1); - if (res != 1) goto ioerror; - if (ch2 != '\n') goto again; - - /* No, don't want to do action. */ - if (ch == 'n' || ch == 'N') return False; - /* Yes, want to do action. */ - if (ch == 'y' || ch == 'Y') return True; - /* No, don't want to do action, and don't ask again either. */ - vg_assert(ch == 'c' || ch == 'C'); - - ioerror: - *clo = False; - return False; -} - - -/* I've gone all object-oriented... initialisation depends on where the - error comes from: - - - If from generated code (tst == NULL), the %EIP/%EBP values that we - need in order to attach GDB are picked up out of VG_(baseBlock) rather - than from the thread table (vg_threads in vg_scheduler.c). - - - If not from generated code but in response to requests passed back to - the scheduler (tst != NULL), we pick up %EIP/%EBP values from the - stored thread state, not from VG_(baseBlock). -*/ -static __inline__ -void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a, - Char* s, void* extra, ExeContext* where ) -{ - sk_assert(tid < VG_N_THREADS); - - /* Core-only parts */ - err->next = NULL; - err->supp = NULL; - err->count = 1; - err->tid = tid; - if (NULL == where) - err->where = VG_(get_ExeContext)( tid ); - else - err->where = where; - - /* Tool-relevant parts */ - err->ekind = ekind; - err->addr = a; - err->extra = extra; - err->string = s; - - /* sanity... */ - vg_assert( tid < VG_N_THREADS ); -} - -static void gen_suppression(Error* err) -{ - Int i; - static UChar buf[M_VG_ERRTXT]; - Bool main_done = False; - ExeContext* ec = VG_(get_error_where)(err); - Int stop_at = VG_(clo_backtrace_size); - - if (stop_at > 4) stop_at = 4; /* At most four names */ - vg_assert(stop_at > 0); - - VG_(printf)("{\n"); - VG_(printf)(" \n"); - - if (PThreadErr == err->ekind) { - VG_(printf)(" core:PThread\n"); - - } else { - Char* name = SK_(get_error_name)(err); - if (NULL == name) { - VG_(message)(Vg_UserMsg, - "(tool does not allow error to be suppressed)"); - return; - } - VG_(printf)(" %s:%s\n", VG_(details).name, name); - SK_(print_extra_suppression_info)(err); - } - - /* This loop condensed from VG_(mini_stack_dump)() */ - i = 0; - do { - Addr eip = ec->ips[i]; - if (i > 0) - eip -= MIN_INSTR_SIZE; // point to calling line - if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { - // Stop after "main"; if main() is recursive, stop after last main(). - - if ( ! VG_(clo_show_below_main)) { - if (VG_STREQ(buf, "main")) - main_done = True; - else if (main_done) - break; - } - VG_(printf)(" fun:%s\n", buf); - } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { - VG_(printf)(" obj:%s\n", buf); - } else { - VG_(printf)(" ???:??? " - "# unknown, suppression will not work, sorry\n"); - } - i++; - } while (i < stop_at && ec->ips[i] != 0); - - VG_(printf)("}\n"); -} - -static -void do_actions_on_error(Error* err, Bool allow_db_attach) -{ - /* Perhaps we want a debugger attach at this point? */ - if (allow_db_attach && - VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) - { - VG_(printf)("starting debugger\n"); - VG_(start_debugger)( err->tid ); - } - /* Or maybe we want to generate the error's suppression? */ - if (VG_(is_action_requested)( "Print suppression", - & VG_(clo_gen_suppressions) )) { - gen_suppression(err); - } -} - -/* Shared between VG_(maybe_record_error)() and VG_(unique_error)(), - just for pretty printing purposes. */ -static Bool is_first_shown_context = True; - -/* Top-level entry point to the error management subsystem. - All detected errors are notified here; this routine decides if/when the - user should see the error. */ -void VG_(maybe_record_error) ( ThreadId tid, - ErrorKind ekind, Addr a, Char* s, void* extra ) -{ - Error err; - Error* p; - Error* p_prev; - UInt extra_size; - VgRes exe_res = Vg_MedRes; - static Bool stopping_message = False; - static Bool slowdown_message = False; - static Int vg_n_errs_shown = 0; - - /* After M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have - been found, or M_VG_COLLECT_NO_ERRORS_AFTER_FOUND total errors - have been found, just refuse to collect any more. This stops - the burden of the error-management system becoming excessive in - extremely buggy programs, although it does make it pretty - pointless to continue the Valgrind run after this point. */ - if (VG_(clo_error_limit) - && (vg_n_errs_shown >= M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN - || n_errs_found >= M_VG_COLLECT_NO_ERRORS_AFTER_FOUND)) { - if (!stopping_message) { - VG_(message)(Vg_UserMsg, ""); - - if (vg_n_errs_shown >= M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN) { - VG_(message)(Vg_UserMsg, - "More than %d different errors detected. " - "I'm not reporting any more.", - M_VG_COLLECT_NO_ERRORS_AFTER_SHOWN ); - } else { - VG_(message)(Vg_UserMsg, - "More than %d total errors detected. " - "I'm not reporting any more.", - M_VG_COLLECT_NO_ERRORS_AFTER_FOUND ); - } - - VG_(message)(Vg_UserMsg, - "Final error counts will be inaccurate. Go fix your program!"); - VG_(message)(Vg_UserMsg, - "Rerun with --error-limit=no to disable this cutoff. Note"); - VG_(message)(Vg_UserMsg, - "that errors may occur in your program without prior warning from"); - VG_(message)(Vg_UserMsg, - "Valgrind, because errors are no longer being displayed."); - VG_(message)(Vg_UserMsg, ""); - stopping_message = True; - } - return; - } - - /* After M_VG_COLLECT_ERRORS_SLOWLY_AFTER different errors have - been found, be much more conservative about collecting new - ones. */ - if (vg_n_errs_shown >= M_VG_COLLECT_ERRORS_SLOWLY_AFTER) { - exe_res = Vg_LowRes; - if (!slowdown_message) { - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "More than %d errors detected. Subsequent errors", - M_VG_COLLECT_ERRORS_SLOWLY_AFTER); - VG_(message)(Vg_UserMsg, - "will still be recorded, but in less detail than before."); - slowdown_message = True; - } - } - - /* Build ourselves the error */ - construct_error ( &err, tid, ekind, a, s, extra, NULL ); - - /* First, see if we've got an error record matching this one. */ - p = vg_errors; - p_prev = NULL; - while (p != NULL) { - if (eq_Error(exe_res, p, &err)) { - /* Found it. */ - p->count++; - if (p->supp != NULL) { - /* Deal correctly with suppressed errors. */ - p->supp->count++; - n_errs_suppressed++; - } else { - n_errs_found++; - } - - /* Move p to the front of the list so that future searches - for it are faster. */ - if (p_prev != NULL) { - vg_assert(p_prev->next == p); - p_prev->next = p->next; - p->next = vg_errors; - vg_errors = p; - } - - return; - } - p_prev = p; - p = p->next; - } - - /* Didn't see it. Copy and add. */ - - /* OK, we're really going to collect it. The context is on the stack and - will disappear shortly, so we must copy it. First do the main - (non-`extra') part. - - Then SK_(update_extra) can update the `extra' part. This is for when - there are more details to fill in which take time to work out but - don't affect our earlier decision to include the error -- by - postponing those details until now, we avoid the extra work in the - case where we ignore the error. Ugly. - - Then, if there is an `extra' part, copy it too, using the size that - SK_(update_extra) returned. Also allow for people using the void* - extra field for a scalar value like an integer. - */ - - /* copy main part */ - p = VG_(arena_malloc)(VG_AR_ERRORS, sizeof(Error)); - *p = err; - - /* update `extra', for non-core errors (core ones don't use 'extra') */ - if (VG_(needs).skin_errors && PThreadErr != ekind) { - extra_size = SK_(update_extra)(p); - - /* copy block pointed to by `extra', if there is one */ - if (NULL != p->extra && 0 != extra_size) { - void* new_extra = VG_(malloc)(extra_size); - VG_(memcpy)(new_extra, p->extra, extra_size); - p->extra = new_extra; - } - } - - p->next = vg_errors; - p->supp = is_suppressible_error(&err); - vg_errors = p; - if (p->supp == NULL) { - n_errs_found++; - if (!is_first_shown_context) - VG_(message)(Vg_UserMsg, ""); - pp_Error(p, False); - is_first_shown_context = False; - vg_n_errs_shown++; - do_actions_on_error(p, /*allow_db_attach*/True); - } else { - n_errs_suppressed++; - p->supp->count++; - } -} - -/* Second top-level entry point to the error management subsystem, for - errors that the tool wants to report immediately, eg. because they're - guaranteed to only happen once. This avoids all the recording and - comparing stuff. But they can be suppressed; returns True if it is - suppressed. Bool `print_error' dictates whether to print the error. - Bool `count_error' dictates whether to count the error in n_errs_found. -*/ -Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s, - void* extra, ExeContext* where, Bool print_error, - Bool allow_db_attach, Bool count_error ) -{ - Error err; - - /* Build ourselves the error */ - construct_error ( &err, tid, ekind, a, s, extra, where ); - - /* Unless it's suppressed, we're going to show it. Don't need to make - a copy, because it's only temporary anyway. - - Then update the `extra' part with SK_(update_extra), because that can - have an affect on whether it's suppressed. Ignore the size return - value of SK_(update_extra), because we're not copying `extra'. */ - (void)SK_(update_extra)(&err); - - if (NULL == is_suppressible_error(&err)) { - if (count_error) - n_errs_found++; - - if (print_error) { - if (!is_first_shown_context) - VG_(message)(Vg_UserMsg, ""); - pp_Error(&err, False); - is_first_shown_context = False; - } - do_actions_on_error(&err, allow_db_attach); - - return False; - - } else { - n_errs_suppressed++; - return True; - } -} - - -/*------------------------------------------------------------*/ -/*--- Exported fns ---*/ -/*------------------------------------------------------------*/ - -/* These are called not from generated code but from the scheduler */ - -void VG_(record_pthread_error) ( ThreadId tid, Char* msg ) -{ - if (! VG_(needs).core_errors) return; - VG_(maybe_record_error)( tid, PThreadErr, /*addr*/0, msg, /*extra*/NULL ); -} - -void VG_(show_all_errors) ( void ) -{ - Int i, n_min; - Int n_err_contexts, n_supp_contexts; - Error *p, *p_min; - Supp *su; - Bool any_supp; - - if (VG_(clo_verbosity) == 0) - return; - - n_err_contexts = 0; - for (p = vg_errors; p != NULL; p = p->next) { - if (p->supp == NULL) - n_err_contexts++; - } - - n_supp_contexts = 0; - for (su = vg_suppressions; su != NULL; su = su->next) { - if (su->count > 0) - n_supp_contexts++; - } - VG_(message)(Vg_UserMsg, - "ERROR SUMMARY: " - "%d errors from %d contexts (suppressed: %d from %d)", - n_errs_found, n_err_contexts, - n_errs_suppressed, n_supp_contexts ); - - if (VG_(clo_verbosity) <= 1) - return; - - /* Print the contexts in order of increasing error count. */ - for (i = 0; i < n_err_contexts; i++) { - n_min = (1 << 30) - 1; - p_min = NULL; - for (p = vg_errors; p != NULL; p = p->next) { - if (p->supp != NULL) continue; - if (p->count < n_min) { - n_min = p->count; - p_min = p; - } - } - if (p_min == NULL) VG_(skin_panic)("show_all_errors()"); - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "%d errors in context %d of %d:", - p_min->count, - i+1, n_err_contexts); - pp_Error( p_min, False ); - - if ((i+1 == VG_(clo_dump_error))) { - VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/, - p_min->where->ips[0], /*debugging*/True); - } - - p_min->count = 1 << 30; - } - - if (n_supp_contexts > 0) - VG_(message)(Vg_DebugMsg, ""); - any_supp = False; - for (su = vg_suppressions; su != NULL; su = su->next) { - if (su->count > 0) { - any_supp = True; - VG_(message)(Vg_DebugMsg, "supp: %4d %s", su->count, su->sname); - } - } - - if (n_err_contexts > 0) { - if (any_supp) - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "IN SUMMARY: " - "%d errors from %d contexts (suppressed: %d from %d)", - n_errs_found, n_err_contexts, n_errs_suppressed, - n_supp_contexts ); - VG_(message)(Vg_UserMsg, ""); - } -} - -/*------------------------------------------------------------*/ -/*--- Standard suppressions ---*/ -/*------------------------------------------------------------*/ - -/* Get a non-blank, non-comment line of at most nBuf chars from fd. - Skips leading spaces on the line. Return True if EOF was hit instead. -*/ - -#define VG_ISSPACE(ch) (((ch)==' ') || ((ch)=='\n') || ((ch)=='\t')) - -Bool VG_(get_line) ( Int fd, Char* buf, Int nBuf ) -{ - Char ch; - Int n, i; - while (True) { - /* First, read until a non-blank char appears. */ - while (True) { - n = VG_(read)(fd, &ch, 1); - if (n == 1 && !VG_ISSPACE(ch)) break; - if (n == 0) return True; - } - - /* Now, read the line into buf. */ - i = 0; - buf[i++] = ch; buf[i] = 0; - while (True) { - n = VG_(read)(fd, &ch, 1); - if (n == 0) return False; /* the next call will return True */ - if (ch == '\n') break; - if (i > 0 && i == nBuf-1) i--; - buf[i++] = ch; buf[i] = 0; - } - while (i > 1 && VG_ISSPACE(buf[i-1])) { - i--; buf[i] = 0; - }; - - /* VG_(printf)("The line is `%s'\n", buf); */ - /* Ok, we have a line. If a non-comment line, return. - If a comment line, start all over again. */ - if (buf[0] != '#') return False; - } -} - - -/* *p_caller contains the raw name of a caller, supposedly either - fun:some_function_name or - obj:some_object_name. - Set *p_ty accordingly and advance *p_caller over the descriptor - (fun: or obj:) part. - Returns False if failed. -*/ -static Bool setLocationTy ( Char** p_caller, SuppLocTy* p_ty ) -{ - if (VG_(strncmp)(*p_caller, "fun:", 4) == 0) { - (*p_caller) += 4; - *p_ty = FunName; - return True; - } - if (VG_(strncmp)(*p_caller, "obj:", 4) == 0) { - (*p_caller) += 4; - *p_ty = ObjName; - return True; - } - VG_(printf)("location should start with fun: or obj:\n"); - return False; -} - - -/* Look for "tool" in a string like "tool1,tool2,tool3" */ -static __inline__ -Bool tool_name_present(Char *name, Char *names) -{ - Bool found; - Char *s = NULL; /* Shut gcc up */ - Int len = VG_(strlen)(name); - - found = (NULL != (s = VG_(strstr)(names, name)) && - (s == names || *(s-1) == ',') && - (*(s+len) == ',' || *(s+len) == '\0') - ); - - return found; -} - -/* Read suppressions from the file specified in vg_clo_suppressions - and place them in the suppressions list. If there's any difficulty - doing this, just give up -- there's no point in trying to recover. -*/ -static void load_one_suppressions_file ( Char* filename ) -{ -# define N_BUF 200 - Int fd, i; - Bool eof; - Char buf[N_BUF+1]; - Char* tool_names; - Char* supp_name; - - fd = VG_(open)( filename, VKI_O_RDONLY, 0 ); - if (fd < 0) { - VG_(message)(Vg_UserMsg, "FATAL: can't open suppressions file `%s'", - filename ); - VG_(exit)(1); - } - - while (True) { - /* Assign and initialise the two suppression halves (core and tool) */ - Supp* supp; - supp = VG_(arena_malloc)(VG_AR_CORE, sizeof(Supp)); - supp->count = 0; - for (i = 0; i < VG_N_SUPP_CALLERS; i++) supp->caller[i] = NULL; - supp->string = supp->extra = NULL; - - eof = VG_(get_line) ( fd, buf, N_BUF ); - if (eof) break; - - if (!VG_STREQ(buf, "{")) goto syntax_error; - - eof = VG_(get_line) ( fd, buf, N_BUF ); - if (eof || VG_STREQ(buf, "}")) goto syntax_error; - supp->sname = VG_(arena_strdup)(VG_AR_CORE, buf); - - eof = VG_(get_line) ( fd, buf, N_BUF ); - - if (eof) goto syntax_error; - - /* Check it has the "skin1,skin2,...:supp" form (look for ':') */ - i = 0; - while (True) { - if (buf[i] == ':') break; - if (buf[i] == '\0') goto syntax_error; - i++; - } - buf[i] = '\0'; /* Replace ':', splitting into two strings */ - - tool_names = & buf[0]; - supp_name = & buf[i+1]; - - /* Is it a core suppression? */ - if (VG_(needs).core_errors && tool_name_present("core", tool_names)) - { - if (VG_STREQ(supp_name, "PThread")) - supp->skind = PThreadSupp; - else - goto syntax_error; - } - - /* Is it a tool suppression? */ - else if (VG_(needs).skin_errors && - tool_name_present(VG_(details).name, tool_names)) - { - if (SK_(recognised_suppression)(supp_name, supp)) - { - /* Do nothing, function fills in supp->skind */ - } else - goto syntax_error; - } - - else { - /* Ignore rest of suppression */ - while (True) { - eof = VG_(get_line) ( fd, buf, N_BUF ); - if (eof) goto syntax_error; - if (VG_STREQ(buf, "}")) - break; - } - continue; - } - - if (VG_(needs).skin_errors && - !SK_(read_extra_suppression_info)(fd, buf, N_BUF, supp)) - goto syntax_error; - - /* "i > 0" ensures at least one caller read. */ - for (i = 0; i <= VG_N_SUPP_CALLERS; i++) { - eof = VG_(get_line) ( fd, buf, N_BUF ); - if (eof) goto syntax_error; - if (i > 0 && VG_STREQ(buf, "}")) - break; - if (i == VG_N_SUPP_CALLERS) - break; - supp->caller[i] = VG_(arena_strdup)(VG_AR_CORE, buf); - if (!setLocationTy(&(supp->caller[i]), &(supp->caller_ty[i]))) - goto syntax_error; - } - - /* make sure to grab the '}' if the num callers is >= - VG_N_SUPP_CALLERS */ - if (!VG_STREQ(buf, "}")) { - do { - eof = VG_(get_line) ( fd, buf, N_BUF ); - } while (!eof && !VG_STREQ(buf, "}")); - } - - supp->next = vg_suppressions; - vg_suppressions = supp; - } - VG_(close)(fd); - return; - - syntax_error: - if (eof) { - VG_(message)(Vg_UserMsg, - "FATAL: in suppressions file `%s': unexpected EOF", - filename ); - } else { - VG_(message)(Vg_UserMsg, - "FATAL: in suppressions file: `%s': syntax error on: %s", - filename, buf ); - } - VG_(close)(fd); - VG_(message)(Vg_UserMsg, "exiting now."); - VG_(exit)(1); - -# undef N_BUF -} - - -void VG_(load_suppressions) ( void ) -{ - Int i; - vg_suppressions = NULL; - for (i = 0; i < VG_(clo_n_suppressions); i++) { - if (VG_(clo_verbosity) > 1) { - VG_(message)(Vg_UserMsg, "Reading suppressions file: %s", - VG_(clo_suppressions)[i] ); - } - load_one_suppressions_file( VG_(clo_suppressions)[i] ); - } -} - -/* Return the name of an erring fn in a way which is useful - for comparing against the contents of a suppressions file. - Doesn't demangle the fn name, because we want to refer to - mangled names in the suppressions file. -*/ -static void get_objname_fnname ( Addr a, Char* obj_buf, Int n_obj_buf, - Char* fun_buf, Int n_fun_buf ) -{ - (void)VG_(get_objname) ( a, obj_buf, n_obj_buf ); - (void)VG_(get_fnname_nodemangle)( a, fun_buf, n_fun_buf ); -} - -static __inline__ -Bool supp_matches_error(Supp* su, Error* err) -{ - switch (su->skind) { - case PThreadSupp: - return (err->ekind == PThreadErr); - default: - if (VG_(needs).skin_errors) { - return SK_(error_matches_suppression)(err, su); - } else { - VG_(printf)( - "\nUnhandled suppression type: %u. VG_(needs).skin_errors\n" - "probably needs to be set.\n", - err->ekind); - VG_(skin_panic)("unhandled suppression type"); - } - } -} - -static __inline__ -Bool supp_matches_callers(Supp* su, Char caller_obj[][M_VG_ERRTXT], - Char caller_fun[][M_VG_ERRTXT]) -{ - Int i; - - for (i = 0; i < VG_N_SUPP_CALLERS && su->caller[i] != NULL; i++) { - switch (su->caller_ty[i]) { - case ObjName: if (VG_(string_match)(su->caller[i], - caller_obj[i])) break; - return False; - case FunName: if (VG_(string_match)(su->caller[i], - caller_fun[i])) break; - return False; - default: VG_(skin_panic)("supp_matches_callers"); - } - } - - /* If we reach here, it's a match */ - return True; -} - -/* Does an error context match a suppression? ie is this a suppressible - error? If so, return a pointer to the Supp record, otherwise NULL. - Tries to minimise the number of symbol searches since they are expensive. -*/ -static Supp* is_suppressible_error ( Error* err ) -{ - Int i; - - static Char caller_obj[VG_N_SUPP_CALLERS][M_VG_ERRTXT]; - static Char caller_fun[VG_N_SUPP_CALLERS][M_VG_ERRTXT]; - - Supp* su; - - /* get_objname_fnname() writes the function name and object name if - it finds them in the debug info. So the strings in the suppression - file should match these. - */ - - /* Initialise these strs so they are always safe to compare, even - if get_objname_fnname doesn't write anything to them. */ - for (i = 0; i < VG_N_SUPP_CALLERS; i++) - caller_obj[i][0] = caller_fun[i][0] = 0; - - for (i = 0; i < VG_N_SUPP_CALLERS && i < VG_(clo_backtrace_size); i++) { - get_objname_fnname ( err->where->ips[i], caller_obj[i], M_VG_ERRTXT, - caller_fun[i], M_VG_ERRTXT ); - } - - /* See if the error context matches any suppression. */ - for (su = vg_suppressions; su != NULL; su = su->next) { - if (supp_matches_error(su, err) && - supp_matches_callers(su, caller_obj, caller_fun)) { - return su; - } - } - return NULL; /* no matches */ -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_errcontext.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_execontext.c b/VEX/head20041019/coregrind/vg_execontext.c deleted file mode 100644 index b0a402b43..000000000 --- a/VEX/head20041019/coregrind/vg_execontext.c +++ /dev/null @@ -1,380 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Storage, and equality on, execution contexts (backtraces). ---*/ -/*--- vg_execontext.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" - - -/*------------------------------------------------------------*/ -/*--- Low-level ExeContext storage. ---*/ -/*------------------------------------------------------------*/ - -/* The idea is only to ever store any one context once, so as to save - space and make exact comparisons faster. */ - -static ExeContext* vg_ec_list[VG_N_EC_LISTS]; - -/* Stats only: the number of times the system was searched to locate a - context. */ -static UInt vg_ec_searchreqs; - -/* Stats only: the number of full context comparisons done. */ -static UInt vg_ec_searchcmps; - -/* Stats only: total number of stored contexts. */ -static UInt vg_ec_totstored; - -/* Number of 2, 4 and (fast) full cmps done. */ -static UInt vg_ec_cmp2s; -static UInt vg_ec_cmp4s; -static UInt vg_ec_cmpAlls; - - -/*------------------------------------------------------------*/ -/*--- Exported functions. ---*/ -/*------------------------------------------------------------*/ - - -/* Initialise this subsystem. */ -static void init_ExeContext_storage ( void ) -{ - Int i; - static Bool init_done = False; - if (init_done) - return; - vg_ec_searchreqs = 0; - vg_ec_searchcmps = 0; - vg_ec_totstored = 0; - vg_ec_cmp2s = 0; - vg_ec_cmp4s = 0; - vg_ec_cmpAlls = 0; - for (i = 0; i < VG_N_EC_LISTS; i++) - vg_ec_list[i] = NULL; - init_done = True; -} - - -/* Print stats. */ -void VG_(print_ExeContext_stats) ( void ) -{ - init_ExeContext_storage(); - VG_(message)(Vg_DebugMsg, - "exectx: %d lists, %d contexts (avg %d per list)", - VG_N_EC_LISTS, vg_ec_totstored, - vg_ec_totstored / VG_N_EC_LISTS - ); - VG_(message)(Vg_DebugMsg, - "exectx: %d searches, %d full compares (%d per 1000)", - vg_ec_searchreqs, vg_ec_searchcmps, - vg_ec_searchreqs == 0 - ? 0 - : (UInt)( (((ULong)vg_ec_searchcmps) * 1000) - / ((ULong)vg_ec_searchreqs )) - ); - VG_(message)(Vg_DebugMsg, - "exectx: %d cmp2, %d cmp4, %d cmpAll", - vg_ec_cmp2s, vg_ec_cmp4s, vg_ec_cmpAlls - ); -} - - -/* Print an ExeContext. */ -void VG_(pp_ExeContext) ( ExeContext* e ) -{ - init_ExeContext_storage(); - VG_(mini_stack_dump) ( e->ips, VG_(clo_backtrace_size) ); -} - - -/* Compare two ExeContexts, comparing all callers. */ -Bool VG_(eq_ExeContext) ( VgRes res, ExeContext* e1, ExeContext* e2 ) -{ - if (e1 == NULL || e2 == NULL) - return False; - switch (res) { - case Vg_LowRes: - /* Just compare the top two callers. */ - vg_ec_cmp2s++; - if (e1->ips[0] != e2->ips[0] - || e1->ips[1] != e2->ips[1]) return False; - return True; - - case Vg_MedRes: - /* Just compare the top four callers. */ - vg_ec_cmp4s++; - if (e1->ips[0] != e2->ips[0]) return False; - - if (VG_(clo_backtrace_size) < 2) return True; - if (e1->ips[1] != e2->ips[1]) return False; - - if (VG_(clo_backtrace_size) < 3) return True; - if (e1->ips[2] != e2->ips[2]) return False; - - if (VG_(clo_backtrace_size) < 4) return True; - if (e1->ips[3] != e2->ips[3]) return False; - return True; - - case Vg_HighRes: - vg_ec_cmpAlls++; - /* Compare them all -- just do pointer comparison. */ - if (e1 != e2) return False; - return True; - - default: - VG_(core_panic)("VG_(eq_ExeContext): unrecognised VgRes"); - } -} - - -/* Take a snapshot of the client's stack, putting the up to 'n_ips' IPs - into 'ips'. In order to be thread-safe, we pass in the thread's IP - and FP. Returns number of IPs put in 'ips'. */ -static UInt stack_snapshot2 ( Addr* ips, UInt n_ips, Addr ip, Addr fp, - Addr fp_min, Addr fp_max_orig ) -{ - Int i; - Addr fp_max; - UInt n_found = 0; - - VGP_PUSHCC(VgpExeContext); - - /* First snaffle IPs from the client's stack into ips[0 .. n_ips-1], - putting zeroes in when the trail goes cold, which we guess to be when - FP is not a reasonable stack location. We also assert that FP - increases down the chain. */ - - // Gives shorter stack trace for tests/badjump.c - // JRS 2002-aug-16: I don't think this is a big deal; looks ok for - // most "normal" backtraces. - // NJN 2002-sep-05: traces for pthreaded programs are particularly bad. - - // JRS 2002-sep-17: hack, to round up fp_max to the end of the - // current page, at least. Dunno if it helps. - // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again - fp_max = (fp_max_orig + VKI_BYTES_PER_PAGE - 1) - & ~(VKI_BYTES_PER_PAGE - 1); - fp_max -= sizeof(Addr); - - /* Assertion broken before main() is reached in pthreaded programs; the - * offending stack traces only have one item. --njn, 2002-aug-16 */ - /* vg_assert(fp_min <= fp_max);*/ - - if (fp_min + 4000000 <= fp_max) { - /* If the stack is ridiculously big, don't poke around ... but - don't bomb out either. Needed to make John Regehr's - user-space threads package work. JRS 20021001 */ - ips[0] = ip; - i = 1; - } else { - /* Get whatever we safely can ... */ - ips[0] = ip; - fp = FIRST_STACK_FRAME(fp); - for (i = 1; i < n_ips; i++) { - if (!(fp_min <= fp && fp <= fp_max)) { - //VG_(printf)("... out of range %p\n", fp); - break; /* fp gone baaaad */ - } - // NJN 2002-sep-17: monotonicity doesn't work -- gives wrong traces... - // if (fp >= ((UInt*)fp)[0]) { - // VG_(printf)("nonmonotonic\n"); - // break; /* fp gone nonmonotonic */ - // } - ips[i] = STACK_FRAME_RET(fp); /* ret addr */ - fp = STACK_FRAME_NEXT(fp); /* old fp */ - //VG_(printf)(" %p\n", ips[i]); - } - } - n_found = i; - - /* Put zeroes in the rest. */ - for (; i < n_ips; i++) { - ips[i] = 0; - } - VGP_POPCC(VgpExeContext); - - return n_found; -} - -/* This guy is the head honcho here. Take a snapshot of the client's - stack. Search our collection of ExeContexts to see if we already - have it, and if not, allocate a new one. Either way, return a - pointer to the context. If there is a matching context we - guarantee to not allocate a new one. Thus we never store - duplicates, and so exact equality can be quickly done as equality - on the returned ExeContext* values themselves. Inspired by Hugs's - Text type. -*/ -ExeContext* VG_(get_ExeContext2) ( Addr ip, Addr fp, - Addr fp_min, Addr fp_max_orig ) -{ - Int i; - Addr ips[VG_DEEPEST_BACKTRACE]; - Bool same; - UInt hash; - ExeContext* new_ec; - ExeContext* list; - - VGP_PUSHCC(VgpExeContext); - - init_ExeContext_storage(); - vg_assert(VG_(clo_backtrace_size) >= 1 - && VG_(clo_backtrace_size) <= VG_DEEPEST_BACKTRACE); - - stack_snapshot2( ips, VG_(clo_backtrace_size), - ip, fp, fp_min, fp_max_orig ); - - /* Now figure out if we've seen this one before. First hash it so - as to determine the list number. */ - - hash = 0; - for (i = 0; i < VG_(clo_backtrace_size); i++) { - hash ^= (UInt)ips[i]; - hash = (hash << 29) | (hash >> 3); - } - hash = hash % VG_N_EC_LISTS; - - /* And (the expensive bit) look a matching entry in the list. */ - - vg_ec_searchreqs++; - - list = vg_ec_list[hash]; - - while (True) { - if (list == NULL) break; - vg_ec_searchcmps++; - same = True; - for (i = 0; i < VG_(clo_backtrace_size); i++) { - if (list->ips[i] != ips[i]) { - same = False; - break; - } - } - if (same) break; - list = list->next; - } - - if (list != NULL) { - /* Yay! We found it. */ - VGP_POPCC(VgpExeContext); - return list; - } - - /* Bummer. We have to allocate a new context record. */ - vg_ec_totstored++; - - new_ec = VG_(arena_malloc)( VG_AR_EXECTXT, - sizeof(struct _ExeContext *) - + VG_(clo_backtrace_size) * sizeof(Addr) ); - - for (i = 0; i < VG_(clo_backtrace_size); i++) - new_ec->ips[i] = ips[i]; - - new_ec->next = vg_ec_list[hash]; - vg_ec_list[hash] = new_ec; - - VGP_POPCC(VgpExeContext); - return new_ec; -} - -void get_needed_regs(ThreadId tid, Addr* ip, Addr* fp, Addr* sp, - Addr* stack_highest_word) -{ - if (VG_(is_running_thread)(tid)) { - /* thread currently in baseblock */ - *ip = BASEBLOCK_INSTR_PTR; - *fp = BASEBLOCK_FRAME_PTR; - *sp = BASEBLOCK_STACK_PTR; - *stack_highest_word = VG_(threads)[tid].stack_highest_word; - } else { - /* thread in thread table */ - ThreadState* tst = & VG_(threads)[ tid ]; - *ip = ARCH_INSTR_PTR(tst->arch); - *fp = ARCH_FRAME_PTR(tst->arch); - *sp = ARCH_STACK_PTR(tst->arch); - *stack_highest_word = tst->stack_highest_word; - } - - /* Nasty little hack to deal with sysinfo syscalls - if libc is - using the sysinfo page for syscalls (the TLS version does), then - ip will always appear to be in that page when doing a syscall, - not the actual libc function doing the syscall. This check sees - if IP is within the syscall code, and pops the return address - off the stack so that ip is placed within the library function - calling the syscall. This makes stack backtraces much more - useful. */ - if (*ip >= VG_(client_trampoline_code)+VG_(tramp_syscall_offset) && - *ip < VG_(client_trampoline_code)+VG_(trampoline_code_length) && - VG_(is_addressable)(*sp, sizeof(Addr))) { - *ip = *(Addr *)*sp; - *sp += sizeof(Addr); - } -} - -ExeContext* VG_(get_ExeContext) ( ThreadId tid ) -{ - Addr ip, fp, sp, stack_highest_word; - - get_needed_regs(tid, &ip, &fp, &sp, &stack_highest_word); - return VG_(get_ExeContext2)(ip, fp, sp, stack_highest_word); -} - -/* Take a snapshot of the client's stack, putting the up to 'n_ips' - instruction pointers into 'ips'. In order to be thread-safe, we pass in - the thread's IP and FP. Returns number of IPs put in 'ips'. */ -UInt VG_(stack_snapshot) ( ThreadId tid, Addr* ips, UInt n_ips ) -{ - Addr ip, fp, sp, stack_highest_word; - - get_needed_regs(tid, &ip, &fp, &sp, &stack_highest_word); - return stack_snapshot2(ips, n_ips, ip, fp, sp, stack_highest_word); -} - - -Addr VG_(get_EIP_from_ExeContext) ( ExeContext* e, UInt n ) -{ - if (n > VG_(clo_backtrace_size)) return 0; - return e->ips[n]; -} - -Addr VG_(get_EIP) ( ThreadId tid ) -{ - Addr ret; - - if (VG_(is_running_thread)(tid)) - ret = BASEBLOCK_INSTR_PTR; - else - ret = ARCH_INSTR_PTR(VG_(threads)[ tid ].arch); - - return ret; -} - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_from_ucode.c b/VEX/head20041019/coregrind/vg_from_ucode.c deleted file mode 100644 index f4fb7ede4..000000000 --- a/VEX/head20041019/coregrind/vg_from_ucode.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- The JITter: translate ucode back to x86 code. ---*/ -/*--- vg_from_ucode.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" - -void VG_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, UInt val ) -{ - ThreadState* tst; - - vg_assert(VG_(is_valid_tid)(tid)); - tst = & VG_(threads)[tid]; - if (0) - VG_(printf)("set_thread_shadow_archreg(%d, %d, 0x%x)\n", - tid, archreg, val); - switch (archreg) { - case R_EAX: tst->arch.vex_shadow.guest_EAX = val; break; - case R_ECX: tst->arch.vex_shadow.guest_ECX = val; break; - case R_EDX: tst->arch.vex_shadow.guest_EDX = val; break; - case R_EBX: tst->arch.vex_shadow.guest_EBX = val; break; - case R_ESP: tst->arch.vex_shadow.guest_ESP = val; break; - case R_EBP: tst->arch.vex_shadow.guest_EBP = val; break; - case R_ESI: tst->arch.vex_shadow.guest_ESI = val; break; - case R_EDI: tst->arch.vex_shadow.guest_EDI = val; break; - default: VG_(core_panic)( "set_thread_shadow_archreg"); - } -} - -UInt VG_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg ) -{ - ThreadState* tst; - - vg_assert(VG_(is_valid_tid)(tid)); - tst = & VG_(threads)[tid]; - - VG_(printf)("get_thread_shadow_archreg(%d, %d)\n", - tid, archreg); - - switch (archreg) { - case R_EAX: return tst->arch.vex_shadow.guest_EAX; - case R_ECX: return tst->arch.vex_shadow.guest_ECX; - case R_EDX: return tst->arch.vex_shadow.guest_EDX; - case R_EBX: return tst->arch.vex_shadow.guest_EBX; - case R_ESP: return tst->arch.vex_shadow.guest_ESP; - case R_EBP: return tst->arch.vex_shadow.guest_EBP; - case R_ESI: return tst->arch.vex_shadow.guest_ESI; - case R_EDI: return tst->arch.vex_shadow.guest_EDI; - default: VG_(core_panic)( "get_thread_shadow_archreg"); - } -} - -/* Return the baseBlock index for the specified shadow register */ -static Int shadow_reg_index ( Int arch ) -{ - VG_(printf)("shadow_reg_index(%d)\n", - arch); - switch (arch) { - case R_EAX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EAX)/4; - case R_ECX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ECX)/4; - case R_EDX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EDX)/4; - case R_EBX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EBX)/4; - case R_ESP: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ESP)/4; - case R_EBP: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EBP)/4; - case R_ESI: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ESI)/4; - case R_EDI: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EDI)/4; - default: VG_(core_panic)( "shadow_reg_index"); - } -} - -/* Accessing shadow arch. registers */ -UInt VG_(get_shadow_archreg) ( UInt archreg ) -{ - return VG_(baseBlock)[ shadow_reg_index(archreg) ]; -} - - -/*--------------------------------------------------------------------*/ -/*--- end vg_from_ucode.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_hashtable.c b/VEX/head20041019/coregrind/vg_hashtable.c deleted file mode 100644 index 8b19cf73a..000000000 --- a/VEX/head20041019/coregrind/vg_hashtable.c +++ /dev/null @@ -1,180 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A separately chained hash table. vg_hashtable.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core.h" - -/*--------------------------------------------------------------------*/ -/*--- Declarations ---*/ -/*--------------------------------------------------------------------*/ - -/* Holds malloc'd but not freed blocks. Static, so zero-inited by default. */ - -#define VG_N_CHAINS 4999 /* a prime number */ - -#define VG_CHAIN_NO(aa) (((UInt)(aa)) % VG_N_CHAINS) - -/*--------------------------------------------------------------------*/ -/*--- Functions ---*/ -/*--------------------------------------------------------------------*/ - -VgHashTable VG_(HT_construct)(void) -{ - /* Initialises to zero, ie. all entries NULL */ - return VG_(calloc)(VG_N_CHAINS, sizeof(VgHashNode*)); -} - -Int VG_(HT_count_nodes) ( VgHashTable table ) -{ - VgHashNode* node; - UInt chain; - Int n = 0; - - for (chain = 0; chain < VG_N_CHAINS; chain++) - for (node = table[chain]; node != NULL; node = node->next) - n++; - return n; -} - -/* Puts a new, heap allocated VgHashNode, into the malloclist. */ -void VG_(HT_add_node) ( VgHashTable table, VgHashNode* node ) -{ - UInt chain = VG_CHAIN_NO(node->key); - node->next = table[chain]; - table[chain] = node; -} - -/* Looks up a VgHashNode in the table. Also returns the address of - the previous node's `next' pointer which allows it to be removed from the - list later without having to look it up again. */ -VgHashNode* VG_(HT_get_node) ( VgHashTable table, UInt key, - /*OUT*/VgHashNode*** next_ptr ) -{ - VgHashNode *prev, *curr; - Int chain; - - chain = VG_CHAIN_NO(key); - - prev = NULL; - curr = table[chain]; - while (True) { - if (curr == NULL) - break; - if (key == curr->key) - break; - prev = curr; - curr = curr->next; - } - - if (NULL == prev) - *next_ptr = & table[chain]; - else - *next_ptr = & prev->next; - - return curr; -} - -/* Allocates a suitably-sized array, copies all the malloc'd block - shadows into it, then returns both the array and the size of it. This is - used by the memory-leak detector. -*/ -VgHashNode** VG_(HT_to_array) ( VgHashTable table, /*OUT*/ UInt* n_shadows ) -{ - UInt i, j; - VgHashNode** arr; - VgHashNode* node; - - *n_shadows = 0; - for (i = 0; i < VG_N_CHAINS; i++) { - for (node = table[i]; node != NULL; node = node->next) { - (*n_shadows)++; - } - } - if (*n_shadows == 0) - return NULL; - - arr = VG_(malloc)( *n_shadows * sizeof(VgHashNode*) ); - - j = 0; - for (i = 0; i < VG_N_CHAINS; i++) { - for (node = table[i]; node != NULL; node = node->next) { - arr[j++] = node; - } - } - vg_assert(j == *n_shadows); - - return arr; -} - -/* Return the first VgHashNode satisfying the predicate p. */ -VgHashNode* VG_(HT_first_match) ( VgHashTable table, - Bool (*p) ( VgHashNode*, void* ), - void* d ) -{ - UInt i; - VgHashNode* node; - - for (i = 0; i < VG_N_CHAINS; i++) - for (node = table[i]; node != NULL; node = node->next) - if ( p(node, d) ) - return node; - - return NULL; -} - -void VG_(HT_apply_to_all_nodes)( VgHashTable table, - void (*f)(VgHashNode*, void*), - void* d ) -{ - UInt i; - VgHashNode* node; - - for (i = 0; i < VG_N_CHAINS; i++) { - for (node = table[i]; node != NULL; node = node->next) { - f(node, d); - } - } -} - -void VG_(HT_destruct)(VgHashTable table) -{ - UInt i; - VgHashNode* node; - - for (i = 0; i < VG_N_CHAINS; i++) { - for (node = table[i]; node != NULL; node = node->next) { - VG_(free)(node); - } - } - VG_(free)(table); -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_hashtable.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_helpers.S b/VEX/head20041019/coregrind/vg_helpers.S deleted file mode 100644 index 1afac18cf..000000000 --- a/VEX/head20041019/coregrind/vg_helpers.S +++ /dev/null @@ -1,348 +0,0 @@ -##--------------------------------------------------------------------## -##--- Support routines for the JITter output. ---## -##--- vg_helpers.S ---## -##--------------------------------------------------------------------## - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "core_asm.h" - -/* ------------------ SIMULATED CPU HELPERS ------------------ */ -/* A stubs for a return which we want to catch: a signal return. - returns and pthread returns. In the latter case, the thread's - return value is in %EAX, so we pass this as the first argument - to the request. In both cases we use the user request mechanism. - You need to to read the definition of VALGRIND_MAGIC_SEQUENCE - in valgrind.h to make sense of this. - - This isn't used in-place. It is copied into the client address space - at an arbitary address. Therefore, this code must be completely - position-independent. -*/ -.global VG_(trampoline_code_start) -.global VG_(trampoline_code_length) -.global VG_(tramp_sigreturn_offset) -.global VG_(tramp_syscall_offset) - -VG_(trampoline_code_start): -sigreturn_start: - subl $20, %esp # allocate arg block - movl %esp, %edx # %edx == &_zzq_args[0] - movl $VG_USERREQ__SIGNAL_RETURNS, 0(%edx) # request - movl $0, 4(%edx) # arg1 - movl $0, 8(%edx) # arg2 - movl $0, 12(%edx) # arg3 - movl $0, 16(%edx) # arg4 - movl %edx, %eax - # and now the magic sequence itself: - roll $29, %eax - roll $3, %eax - rorl $27, %eax - rorl $5, %eax - roll $13, %eax - roll $19, %eax - # should never get here - ud2 - - # We can point our sysinfo stuff here - .align 16 -syscall_start: - int $0x80 - ret -tramp_code_end: - -.data -VG_(trampoline_code_length): - .long tramp_code_end - VG_(trampoline_code_start) -VG_(tramp_sigreturn_offset): - .long sigreturn_start - VG_(trampoline_code_start) -VG_(tramp_syscall_offset): - .long syscall_start - VG_(trampoline_code_start) -.text - - -/* ------------------ REAL CPU HELPERS ------------------ */ -/* The rest of this lot run on the real CPU. */ - -/* Various helper routines, for instructions which are just too - darn tedious for the JITter to output code in-line: - - * integer division - * integer multiplication - * setting and getting obscure eflags - * double-length shifts - * eight byte compare and exchange - - All routines use a standard calling convention designed for - calling from translations, in which the incoming args are - underneath the return address, the callee saves _all_ registers, - and the incoming parameters can be modified, to return results. -*/ - -/* Fetch the time-stamp-ctr reg. - On entry: - dummy, replaced by %EAX value - dummy, replaced by %EDX value - RA <- %esp -*/ -.global VG_(helper_RDTSC) -VG_(helper_RDTSC): - pushl %eax - pushl %edx - rdtsc - movl %edx, 12(%esp) - movl %eax, 16(%esp) - popl %edx - popl %eax - ret - -/* - Fetch a byte/word/dword from given port - On entry: - size 1, 2 or 4 - port, replaced by result - RA -*/ -.global VG_(helper_IN) -VG_(helper_IN): - pushl %eax - pushl %edx - movl 16(%esp), %eax - movl 12(%esp), %edx - - pushfl - cmpl $4, %eax - je in_dword - cmpl $2, %eax - je in_word -in_byte: - inb (%dx), %al - jmp in_done -in_word: - in (%dx), %ax - jmp in_done -in_dword: - inl (%dx),%eax -in_done: - popfl - movl %eax,12(%esp) - popl %edx - popl %eax - ret - -/* - Write a byte/word/dword to given port - On entry: - size 1, 2 or 4 - port - value - RA -*/ -.global VG_(helper_OUT) -VG_(helper_OUT): - pushl %eax - pushl %edx - movl 16(%esp), %edx - movl 12(%esp), %eax - - pushfl - cmpl $4, 20(%esp) - je out_dword - cmpl $2, 20(%esp) - je out_word -out_byte: - outb %al,(%dx) - jmp out_done -out_word: - out %ax,(%dx) - jmp out_done -out_dword: - outl %eax,(%dx) -out_done: - popfl - popl %edx - popl %eax - ret - - -/* Do the CPUID instruction. - On entry: - dummy, replaced by %EAX value - dummy, replaced by %EBX value - dummy, replaced by %ECX value - dummy, replaced by %EDX value - RA <- %esp - - We save registers and package up the args so we can call a C helper - for all this. -*/ -.global VG_(helper_CPUID) -VG_(helper_CPUID): - pushl %ebp - movl %esp,%ebp - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - pushl %edi - pushf - - lea 2*4(%ebp),%eax /* &edx */ - pushl %eax - addl $4,%eax /* &ecx */ - pushl %eax - addl $4,%eax /* &ebx */ - pushl %eax - addl $4,%eax /* &eax */ - pushl %eax - pushl (%eax) /* eax */ - - call VG_(helperc_CPUID) - addl $20,%esp - - popf - popl %edi - popl %esi - popl %edx - popl %ecx - popl %ebx - popl %eax - popl %ebp - ret - - -/* Do %al = DAS(%al). Note that the passed param has %AL as the least - significant 8 bits, since it was generated with GETB %AL, - some-temp. Fortunately %al is the least significant 8 bits of - %eax anyway, which is why it's safe to work with %eax as a - whole. - - On entry: - value of %eax - RA <- %esp -*/ -.global VG_(helper_DAS) -VG_(helper_DAS): - pushl %eax - movl 8(%esp), %eax - das - movl %eax, 8(%esp) - popl %eax - ret - - -/* Similarly, do %al = DAA(%al). */ -.global VG_(helper_DAA) -VG_(helper_DAA): - pushl %eax - movl 8(%esp), %eax - daa - movl %eax, 8(%esp) - popl %eax - ret - - -/* Similarly, do %ax = AAS(%ax). */ -.global VG_(helper_AAS) -VG_(helper_AAS): - pushl %eax - movl 8(%esp), %eax - aas - movl %eax, 8(%esp) - popl %eax - ret - - -/* Similarly, do %ax = AAA(%ax). */ -.global VG_(helper_AAA) -VG_(helper_AAA): - pushl %eax - movl 8(%esp), %eax - aaa - movl %eax, 8(%esp) - popl %eax - ret - - -/* Similarly, do %ax = AAD(%ax). */ -.global VG_(helper_AAD) -VG_(helper_AAD): - pushl %eax - movl 8(%esp), %eax - aad - movl %eax, 8(%esp) - popl %eax - ret - - -/* Similarly, do %ax = AAM(%ax). */ -.global VG_(helper_AAM) -VG_(helper_AAM): - pushl %eax - movl 8(%esp), %eax - aam - movl %eax, 8(%esp) - popl %eax - ret - - - -/* Eight byte compare and exchange. */ -.globl VG_(helper_cmpxchg8b) -VG_(helper_cmpxchg8b): - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - movl 20(%esp), %eax - movl 24(%esp), %edx - movl 28(%esp), %ebx - movl 32(%esp), %ecx - cmpxchg8b 36(%esp) - movl %eax, 20(%esp) - movl %edx, 24(%esp) - movl %ebx, 28(%esp) - movl %ecx, 32(%esp) - popl %edx - popl %ecx - popl %ebx - popl %eax - ret - - -/* Undefined instruction (generates SIGILL) */ -.globl VG_(helper_undefined_instruction) -VG_(helper_undefined_instruction): -1: ud2 - jmp 1b - -/* Let the linker know we don't need an executable stack */ -.section .note.GNU-stack,"",@progbits - -##--------------------------------------------------------------------## -##--- end vg_helpers.S ---## -##--------------------------------------------------------------------## diff --git a/VEX/head20041019/coregrind/vg_instrument.c b/VEX/head20041019/coregrind/vg_instrument.c deleted file mode 100644 index 3203d1132..000000000 --- a/VEX/head20041019/coregrind/vg_instrument.c +++ /dev/null @@ -1,261 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Higher-level UCode sequence builders ---*/ -/*--- vg_instrument.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* We only import tool.h here, because this file only provides functions - for doing things that could be done directly by the tool -- it's just to - make tools' lives easier, rather than let them do something they - couldn't otherwise do. */ -#include "tool.h" - - -void VG_(lit_to_reg)(UCodeBlock* cb, UInt lit, UInt t) -{ - uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t); - uLiteral(cb, lit); -} - -UInt VG_(lit_to_newreg)(UCodeBlock* cb, UInt lit) -{ - VG_(skin_panic)("lit_to_newreg"); -#if 0 - UInt t = newTemp(cb); - uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t); - uLiteral(cb, lit); - return t; -#endif -} - -// f() -void VG_(ccall_0_0)(UCodeBlock* cb, Addr f) -{ - uInstr0(cb, CCALL, 0); - uCCall(cb, f, 0, 0, /*retval*/False); -} - -// f(reg) -void VG_(ccall_R_0)(UCodeBlock* cb, Addr f, UInt t1, UInt regparms_n) -{ - sk_assert(regparms_n <= 1); - uInstr1(cb, CCALL, 0, TempReg, t1); - uCCall(cb, f, 1, regparms_n, /*retval*/False); -} - -// f(lit) -void VG_(ccall_L_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - VG_(ccall_R_0)(cb, f, t1, regparms_n); -} - -// reg = f(reg) -void VG_(ccall_R_R)(UCodeBlock* cb, Addr f, UInt t1, UInt t_ret, - UInt regparms_n) -{ - sk_assert(regparms_n <= 1); - sk_assert(t1 < VG_(get_num_temps)(cb)); // help catch lits accidentally passed in - uInstr3(cb, CCALL, 0, TempReg, t1, NoValue, 0, TempReg, t_ret); - uCCall(cb, f, 1, regparms_n, /*retval*/True); -} - -// reg = f(lit) -void VG_(ccall_L_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt t_ret, - UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - VG_(ccall_R_R)(cb, f, t1, t_ret, regparms_n); -} - -// f(reg, reg) -void VG_(ccall_RR_0)(UCodeBlock* cb, Addr f, UInt t1, UInt t2, UInt regparms_n) -{ - sk_assert(regparms_n <= 2); - sk_assert(t1 < VG_(get_num_temps)(cb)); - sk_assert(t2 < VG_(get_num_temps)(cb)); - uInstr2(cb, CCALL, 0, TempReg, t1, TempReg, t2); - uCCall(cb, f, 2, regparms_n, /*retval*/False); -} - -// f(reg, lit) -void VG_(ccall_RL_0)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2, - UInt regparms_n) -{ - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n); -} - -// f(lit, reg) -void VG_(ccall_LR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2, - UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n); -} - -// f(lit, lit) -void VG_(ccall_LL_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2, - UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - VG_(ccall_RR_0)(cb, f, t1, t2, regparms_n); -} - -// reg = f(reg, reg) -void VG_(ccall_RR_R)(UCodeBlock* cb, Addr f, UInt t1, UInt t2, UInt t_ret, - UInt regparms_n) -{ - sk_assert(regparms_n <= 2); - sk_assert(t1 < VG_(get_num_temps)(cb)); - sk_assert(t2 < VG_(get_num_temps)(cb)); - uInstr3(cb, CCALL, 0, TempReg, t1, TempReg, t2, TempReg, t_ret); - uCCall(cb, f, 2, regparms_n, /*retval*/True); -} - -// reg = f(reg, lit) -void VG_(ccall_RL_R)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2, UInt t_ret, - UInt regparms_n) -{ - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n); -} - -// reg = f(lit, reg) -void VG_(ccall_LR_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2, UInt t_ret, - UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n); -} - -// reg = f(lit, lit) -void VG_(ccall_LL_R)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2, UInt t_ret, - UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit2); - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - VG_(ccall_RR_R)(cb, f, t1, t2, t_ret, regparms_n); -} - -// f(reg, reg, reg) -void VG_(ccall_RRR_0)(UCodeBlock* cb, Addr f, UInt t1, UInt t2, - UInt t3, UInt regparms_n) -{ - sk_assert(regparms_n <= 3); - sk_assert(t1 < VG_(get_num_temps)(cb)); - sk_assert(t2 < VG_(get_num_temps)(cb)); - sk_assert(t3 < VG_(get_num_temps)(cb)); - uInstr3(cb, CCALL, 0, TempReg, t1, TempReg, t2, TempReg, t3); - uCCall(cb, f, 3, regparms_n, /*retval*/False); -} - -// f(reg, lit, lit) -void VG_(ccall_RLL_0)(UCodeBlock* cb, Addr f, UInt t1, UInt lit2, - UInt lit3, UInt regparms_n) -{ - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - UInt t3 = VG_(lit_to_newreg)(cb, lit3); - VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n); -} - -// f(lit, reg, reg) -void VG_(ccall_LRR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt t2, - UInt t3, UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n); -} - -// f(lit, lit, reg) -void VG_(ccall_LLR_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2, - UInt t3, UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n); -} - -// f(lit, lit, lit) -void VG_(ccall_LLL_0)(UCodeBlock* cb, Addr f, UInt lit1, UInt lit2, - UInt lit3, UInt regparms_n) -{ - UInt t1 = VG_(lit_to_newreg)(cb, lit1); - UInt t2 = VG_(lit_to_newreg)(cb, lit2); - UInt t3 = VG_(lit_to_newreg)(cb, lit3); - VG_(ccall_RRR_0)(cb, f, t1, t2, t3, regparms_n); -} - -void VG_(reg_to_globvar)(UCodeBlock* cb, UInt t, UInt* globvar_ptr) -{ - Int t_gv = VG_(lit_to_newreg)(cb, (UInt)globvar_ptr); - uInstr2(cb, STORE, 4, TempReg, t, TempReg, t_gv); -} - -void VG_(lit_to_globvar)(UCodeBlock* cb, UInt lit, UInt* globvar_ptr) -{ - Int t_lit = VG_(lit_to_newreg)(cb, lit); - VG_(reg_to_globvar)(cb, t_lit, globvar_ptr); -} - -/*-------------------------------------------------------------------- - Old versions of these functions, for backwards compatibility - --------------------------------------------------------------------*/ - -void VG_(call_helper_0_0)(UCodeBlock* cb, Addr f) -{ - VG_(ccall_0_0)(cb, f); -} - -void VG_(call_helper_1_0)(UCodeBlock* cb, Addr f, UInt arg1, UInt regparms_n) -{ - VG_(ccall_L_0)(cb, f, arg1, regparms_n); -} - -void VG_(call_helper_2_0)(UCodeBlock* cb, Addr f, UInt arg1, UInt arg2, - UInt regparms_n) -{ - VG_(ccall_LL_0)(cb, f, arg1, arg2, regparms_n); -} - -void VG_(set_global_var)(UCodeBlock* cb, Addr globvar_ptr, UInt val) -{ - VG_(lit_to_globvar)(cb, val, (UInt*)globvar_ptr); -} - -void VG_(set_global_var_tempreg)(UCodeBlock* cb, Addr globvar_ptr, UInt t_val) -{ - VG_(reg_to_globvar)(cb, t_val, (UInt*)globvar_ptr); -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_instrument.c ---*/ -/*--------------------------------------------------------------------*/ - - diff --git a/VEX/head20041019/coregrind/vg_intercept.c.base b/VEX/head20041019/coregrind/vg_intercept.c.base deleted file mode 100644 index b76d3b9a0..000000000 --- a/VEX/head20041019/coregrind/vg_intercept.c.base +++ /dev/null @@ -1,128 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Intercepts for various libc functions we want to capture ---*/ -/*--- (mostly for threading purposes). vg_intercept.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - - -/* --------------------------------------------------------------------- - ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. It is - intended for various reasons as drop-in replacements for libc - functions. These functions are not called directly - they're the - targets of code redirection. They're named weirdly so that the - intercept code can find them when the shared object is initially - loaded. - ------------------------------------------------------------------ */ - -/* - The gory details: Symbols in this file are mangled by a preprocessor - to produce a special symbol name. All symbols that need this handling - should be passed to a special VG_INTERCEPT macro. This macro takes - two arguments: a library name and a function name. These specify the - function and the library that contains it that we need to intercept. - For example: - - int VG_INTERCEPT(soname:libc.so.6, raise)(int sig) { ... } - - This example says that the "raise" function in the shared object - libc.so.6 should be intercepted and redirected to the following piece - of code. - - Internally, what's happening here is that this intercept gets turned - into a special magic symbol name, with the ':' and '.' parts replaced - by escapes, and a special prefix stuck on front. When we slurp in - an object file, we scan the symbol table for the magic prefixes, - demangle any symbols found and set up the intercepts that way. - - This is the safest way to do this, because we're not relying on - intercepts being set up by code that may be called after other code - that need the intercepts has had a chance to run. - */ - -#include "valgrind.h" -#include "core.h" -#include -#include - -int VG_INTERCEPT(soname:libc.so.6, raise)(int sig) -{ - return kill(getpid(), sig); -} - -int VG_INTERCEPT(soname:libc.so.6, __libc_raise)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), - visibility("protected"))); - -int VG_INTERCEPT(soname:libc.so.6, __GI_raise)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), - visibility("protected"))); - -int VG_INTERCEPT(soname:libc.so.6, __raise)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), - visibility("protected"))); - -/* Don't alias, so there's no chance that "gsignal" will appear in a - message instead of "raise" */ -int VG_INTERCEPT(soname:libc.so.6, gsignal)(int sig) -{ - return VG_INTERCEPT(soname:libc.so.6, raise)(sig); -} - -int VG_INTERCEPT(soname:libc.so.6, __libc_gsignal)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), - visibility("protected"))); - -int VG_INTERCEPT(soname:libc.so.6, __GI_gsignal)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), - visibility("protected"))); - -int VG_INTERCEPT(soname:libc.so.6, __gsignal)(int) - __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), - visibility("protected"))); - -/* --------------------------------------------------------------------- - Hook for running __libc_freeres once the program exits. - ------------------------------------------------------------------ */ - -void VG_WRAPPER(freeres)( void ) -{ - int res; -#ifndef __UCLIBC__ - extern void __libc_freeres(void); - __libc_freeres(); -#endif - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__LIBC_FREERES_DONE, 0, 0, 0, 0); - /*NOTREACHED*/ - *(int *)0 = 'x'; -} - -/*--------------------------------------------------------------------*/ -/*--- end vg_intercept.c ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/coregrind/vg_libpthread.c b/VEX/head20041019/coregrind/vg_libpthread.c deleted file mode 100644 index a10eaf05d..000000000 --- a/VEX/head20041019/coregrind/vg_libpthread.c +++ /dev/null @@ -1,3521 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A replacement for the standard libpthread.so. ---*/ -/*--- vg_libpthread.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* ALL THIS CODE RUNS ON THE SIMULATED CPU. - - This is a replacement for the standard libpthread.so. It is loaded - as part of the client's image (if required) and directs pthread - calls through to Valgrind's request mechanism. - - A couple of caveats. - - 1. Since it's a binary-compatible replacement for an existing library, - we must take care to used exactly the same data layouts, etc, as - the standard pthread.so does. - - 2. Since this runs as part of the client, there are no specific - restrictions on what headers etc we can include, so long as - this libpthread.so does not end up having dependencies on .so's - which the real one doesn't. - - Later ... it appears we cannot call file-related stuff in libc here, - perhaps fair enough. Be careful what you call from here. Even exit() - doesn't work (gives infinite recursion and then stack overflow); hence - myexit(). Also fprintf doesn't seem safe. -*/ - -#include "valgrind.h" /* For the request-passing mechanism */ -#include "core.h" /* For the VG_USERREQ__* constants */ - -#define __USE_UNIX98 -#include -#include -#undef __USE_UNIX98 - -#define __USE_GNU -#include -#undef __USE_GNU - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -# define strong_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((alias (#name))); - -# define weak_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); - - -/* --------------------------------------------------------------------- - Our own definition of types that vary between LinuxThreads and NPTL. - ------------------------------------------------------------------ */ - -/* Moving from LinuxThreads to NPTL, several crucial types (eg. - pthread_mutex_t, pthread_mutexattr_t, etc) in pthreadtypes.h were changed - in binary-compatible, but source-incompatible, ways. We can similarly - use any layout we want, so long as it's binary-compatible. However, we - can no longer use the LinuxThreads types, because they won't work on NPTL - systems. Thus, we have to introduce a layer of indirection, and define - our own versions of these types (vg_pthread_mutex_t, etc). NPTL does - pretty much the same thing, and it keeps many of its internal types - secret. - - We can layout our types however we want, as long as we put the small - number of fields in the right place for binary compatibility (eg. - mutex->kind). To make life easy, our versions have the exact same layout - as the LinuxThreads ones; only the type names and field names are - different (they differ only by include "vg" at the start). - - In our implementation of the pthread operations (pthread_mutex_lock(), - pthread_mutexattr_settype(), etc) we always cast the standard pthread - types to our own types, (eg. pthread_mutex_t --> vg_pthread_mutex_t), - before working with them. - - Note that we have various mutexes (and condvars) in this file that have the - type pthread_mutex_t (and pthread_cond_t). That is fine, because they - are always only handled by calling the standard pthread functions (eg. - pthread_mutex_lock()) on them. Phew. - - WARNING: as a result of all this, we should *never* access these standard - pthread types as is; they *must* be converted to the vg_pthread_foo_t - equivalent. It would be nice if this was enforced... (but compilation - on NPTL-only systems should fail if this rule isn't followed...?) -*/ - -#include // for 'struct __sched_param' - -typedef struct __vg_pthread_attr_s -{ - int __vg_detachstate; - int __vg_schedpolicy; - struct __sched_param __vg_schedparam; - int __vg_inheritsched; - int __vg_scope; - size_t __vg_guardsize; - int __vg_stackaddr_set; - void *__vg_stackaddr; - size_t __vg_stacksize; -} vg_pthread_attr_t; - -typedef struct -{ - int __vg_mutexkind; -} vg_pthread_mutexattr_t; - -typedef struct _vg_pthread_rwlock_t -{ - struct _vg_pthread_fastlock __vg_rw_lock; /* Lock to guarantee mutual exclusion */ - int __vg_rw_readers; /* Number of readers */ - /*_pthread_descr*/ void* __vg_rw_writer; /* Identity of writer, or NULL if none */ - /*_pthread_descr*/ void* __vg_rw_read_waiting; /* Threads waiting for reading */ - /*_pthread_descr*/ void* __vg_rw_write_waiting; /* Threads waiting for writing */ - int __vg_rw_kind; /* Reader/Writer preference selection */ - int __vg_rw_pshared; /* Shared between processes or not */ -} vg_pthread_rwlock_t; - -typedef struct -{ - int __vg_lockkind; - int __vg_pshared; -} vg_pthread_rwlockattr_t; - -/* Converting pthread types to vg_pthread types. We always check that the - passed-in type is as big as ours, for safety. We also zero the pointer - to the original struct, to ensure we don't accidentally use it again. */ - -#define CONVERT(foo, x, vg_x) \ - my_assert(sizeof(*x) >= sizeof(vg_pthread_##foo##_t)); \ - vg_x = (vg_pthread_##foo##_t*)x; \ - x = 0; // ensure we don't accidentally use x again! - - -/* --------------------------------------------------------------------- - Our own definition of types that only exist in NPTL. - ------------------------------------------------------------------ */ - -#ifndef HAVE___PTHREAD_UNWIND_BUF_T - -typedef struct -{ - struct - { - jmp_buf __cancel_jmp_buf; - int __mask_was_saved; - } __cancel_jmp_buf[1]; - void *__pad[4]; -} __pthread_unwind_buf_t __attribute__ ((__aligned__)); - -#endif - -/* --------------------------------------------------------------------- - Forwardses. - ------------------------------------------------------------------ */ - -#define WEAK __attribute__((weak)) - -static -__inline__ -int is_kerror ( int res ) -{ - if (res >= -4095 && res <= -1) - return 1; - else - return 0; -} - - -#ifdef GLIBC_2_3 - /* kludge by JRS (not from glibc) ... */ - typedef void* __locale_t; - - /* Copied from locale/locale.h in glibc-2.2.93 sources */ - /* This value can be passed to `uselocale' and may be returned by - it. Passing this value to any other function has undefined - behavior. */ -# define LC_GLOBAL_LOCALE ((__locale_t) -1L) - extern __locale_t __uselocale ( __locale_t ); -#endif - -static void -init_global_thread_specific_state ( void ); - -static void -init_thread_specific_state ( void ); - -static void -set_ret_val ( void* ); -static void * -get_ret_val ( void ); - -/* --------------------------------------------------------------------- - Helpers. We have to be pretty self-sufficient. - ------------------------------------------------------------------ */ - -/* Number of times any given error message is printed. */ -#define N_MOANS 3 - -/* Extract from Valgrind the value of VG_(clo_trace_pthread_level). - Returns 0 (none) if not running on Valgrind. */ -static -int get_pt_trace_level ( void ) -{ - int res; - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__GET_PTHREAD_TRACE_LEVEL, - 0, 0, 0, 0); - return res; -} - -/* Don't do anything if we're not under Valgrind */ -static __inline__ -void ensure_valgrind ( char* caller ) -{ - if (!RUNNING_ON_VALGRIND) { - const char msg[] = "Warning: this libpthread.so should only be run with Valgrind\n"; - VG_(do_syscall)(__NR_write, 2, msg, sizeof(msg)-1); - VG_(do_syscall)(__NR_exit, 1); - } -} - -/* While we're at it ... hook our own startup function into this - game. */ - -static -__attribute__((noreturn)) -void barf ( const char* str ) -{ - char buf[1000]; - strcpy(buf, "\nvalgrind's libpthread.so: "); - strcat(buf, str); - strcat(buf, "\nPlease report this bug at: "); - strcat(buf, VG_BUGS_TO); - strcat(buf, "\n\n"); - VALGRIND_INTERNAL_PRINTF(buf); - _exit(1); - /* We have to persuade gcc into believing this doesn't return. */ - while (1) { }; -} - - -static void cat_n_send ( char* s1, char* s2, char* s3 ) -{ -# define N_BUF 1000 - int i; - char buf[N_BUF]; - if (get_pt_trace_level() >= 0) { - i = 0; - while (*s1) { - if (i >= N_BUF) break; - buf[i++] = *s1++; - } - while (*s2) { - if (i >= N_BUF) break; - buf[i++] = *s2++; - } - while (*s3) { - if (i >= N_BUF) break; - buf[i++] = *s3++; - } - buf[i] = 0; - VALGRIND_INTERNAL_PRINTF(buf); - } -# undef N_BUF -} - -static void oh_dear ( char* fn, char* aux, char* s ) -{ - cat_n_send ( "warning: Valgrind's ", fn, s ); - if (NULL != aux) - cat_n_send ( " ", aux, "" ); - cat_n_send ( " your program may misbehave as a result", "", "" ); -} - -static void ignored ( char* fn, char* aux ) -{ - oh_dear ( fn, aux, " does nothing" ); -} - -static void kludged ( char* fn, char* aux ) -{ - oh_dear ( fn, aux, " is incomplete" ); -} - - -__attribute__((noreturn)) -void vgPlain_unimp ( char* fn ) -{ - cat_n_send ( "valgrind's libpthread.so: UNIMPLEMENTED FUNCTION: ", fn, "" ); - barf("unimplemented function"); -} - - -static -void my_assert_fail ( const Char* expr, const Char* file, Int line, const Char* fn ) -{ - char buf[1000]; - static Bool entered = False; - if (entered) - _exit(2); - entered = True; - sprintf(buf, "\n%s: %s:%d (%s): Assertion `%s' failed.\n", - "valgrind", file, line, fn, expr ); - cat_n_send ( "", buf, "" ); - sprintf(buf, "Please report this bug at: %s\n\n", VG_BUGS_TO); - cat_n_send ( "", buf, "" ); - _exit(1); -} - -#define MY__STRING(__str) #__str - -#define my_assert(expr) \ - ((void) ((expr) ? 0 : \ - (my_assert_fail (MY__STRING(expr), \ - __FILE__, __LINE__, \ - __PRETTY_FUNCTION__), 0))) - -static -void my_free ( void* ptr ) -{ -#if 0 - int res; - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__FREE, ptr, 0, 0, 0); - my_assert(res == 0); -#else - free(ptr); -#endif -} - - -static -void* my_malloc ( int nbytes ) -{ - void* res; -#if 0 - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__MALLOC, nbytes, 0, 0, 0); -#else - res = malloc(nbytes); -#endif - my_assert(res != (void*)0); - return res; -} - - - -/* --------------------------------------------------------------------- - Pass pthread_ calls to Valgrind's request mechanism. - ------------------------------------------------------------------ */ - - -/* --------------------------------------------------- - Ummm .. - ------------------------------------------------ */ - -static -void pthread_error ( const char* msg ) -{ - int res; - VALGRIND_MAGIC_SEQUENCE(res, 0, - VG_USERREQ__PTHREAD_ERROR, - msg, 0, 0, 0); -} - - -/* --------------------------------------------------- - Here so it can be inlined without complaint. - ------------------------------------------------ */ - -__inline__ -pthread_t pthread_self(void) -{ - int tid; - ensure_valgrind("pthread_self"); - VALGRIND_MAGIC_SEQUENCE(tid, 0 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - if (tid < 1 || tid >= VG_N_THREADS) - barf("pthread_self: invalid ThreadId"); - return tid; -} - - -/* --------------------------------------------------- - THREAD ATTRIBUTES - ------------------------------------------------ */ - -int pthread_attr_init(pthread_attr_t *attr) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - - /* Just initialise the fields which we might look at. */ - vg_attr->__vg_detachstate = PTHREAD_CREATE_JOINABLE; - /* Linuxthreads sets this field to the value __getpagesize(), so I - guess the following is OK. */ - vg_attr->__vg_guardsize = VKI_BYTES_PER_PAGE; - /* No special stack yet. */ - vg_attr->__vg_stackaddr = 0; - vg_attr->__vg_stacksize = VG_PTHREAD_STACK_SIZE; - return 0; -} - -int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - - if (detachstate != PTHREAD_CREATE_JOINABLE - && detachstate != PTHREAD_CREATE_DETACHED) { - pthread_error("pthread_attr_setdetachstate: " - "detachstate is invalid"); - return EINVAL; - } - vg_attr->__vg_detachstate = detachstate; - return 0; -} - -int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - *detachstate = vg_attr->__vg_detachstate; - return 0; -} - -int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) -{ - static int moans = N_MOANS; - if (moans-- > 0) - kludged("pthread_attr_getinheritsched", NULL); - *inherit = PTHREAD_EXPLICIT_SCHED; - return 0; -} - -int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) -{ - static int moans = N_MOANS; - if (moans-- > 0) - ignored("pthread_attr_setinheritsched", NULL); - return 0; -} - -WEAK -int pthread_attr_setstacksize (pthread_attr_t *attr, - size_t stacksize) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - vg_attr->__vg_stacksize = stacksize; - return 0; -} - - -/* This is completely bogus. */ -int pthread_attr_getschedparam(const pthread_attr_t *attr, - struct sched_param *param) -{ - static int moans = N_MOANS; - if (moans-- > 0) - kludged("pthread_attr_getschedparam", NULL); -# ifdef HAVE_SCHED_PRIORITY - if (param) param->sched_priority = 0; /* who knows */ -# else - if (param) param->__sched_priority = 0; /* who knows */ -# endif - return 0; -} - -int pthread_attr_setschedparam(pthread_attr_t *attr, - const struct sched_param *param) -{ - static int moans = N_MOANS; - if (moans-- > 0) - ignored("pthread_attr_setschedparam", "(scheduling not changeable)"); - return 0; -} - -int pthread_attr_destroy(pthread_attr_t *attr) -{ - static int moans = N_MOANS; - if (moans-- > 0) - ignored("pthread_attr_destroy", NULL); - return 0; -} - -/* These are no-ops, as with LinuxThreads. */ -int pthread_attr_setscope ( pthread_attr_t *attr, int scope ) -{ - ensure_valgrind("pthread_attr_setscope"); - if (scope == PTHREAD_SCOPE_SYSTEM) - return 0; - pthread_error("pthread_attr_setscope: " - "invalid or unsupported scope"); - if (scope == PTHREAD_SCOPE_PROCESS) - return ENOTSUP; - return EINVAL; -} - -int pthread_attr_getscope ( const pthread_attr_t *attr, int *scope ) -{ - ensure_valgrind("pthread_attr_setscope"); - if (scope) - *scope = PTHREAD_SCOPE_SYSTEM; - return 0; -} - - -/* Pretty bogus. Avoid if possible. */ -int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) -{ - StackInfo si; - int res; - int detached; - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - - ensure_valgrind("pthread_getattr_np"); - kludged("pthread_getattr_np", NULL); - vg_attr->__vg_detachstate = PTHREAD_CREATE_JOINABLE; - vg_attr->__vg_schedpolicy = SCHED_OTHER; - vg_attr->__vg_schedparam.sched_priority = 0; - vg_attr->__vg_inheritsched = PTHREAD_EXPLICIT_SCHED; - vg_attr->__vg_scope = PTHREAD_SCOPE_SYSTEM; - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__GET_STACK_INFO, - thread, &si, 0, 0 ); - vg_attr->__vg_guardsize = si.guardsize; - vg_attr->__vg_stackaddr = (void *)si.base; - vg_attr->__vg_stackaddr_set = 0; - vg_attr->__vg_stacksize = si.size; - VALGRIND_MAGIC_SEQUENCE(detached, (-1) /* default */, - VG_USERREQ__SET_OR_GET_DETACH, - 2 /* get */, thread, 0, 0); - my_assert(detached == 0 || detached == 1); - if (detached) - vg_attr->__vg_detachstate = PTHREAD_CREATE_DETACHED; - return 0; -} - - -WEAK -int pthread_attr_getstack ( const pthread_attr_t * attr, - void ** stackaddr, - size_t *stacksize ) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - ensure_valgrind("pthread_attr_getstack"); - if (stackaddr) - *stackaddr = vg_attr->__vg_stackaddr; - if (stacksize) - *stacksize = vg_attr->__vg_stacksize; - return 0; -} - -WEAK -int pthread_attr_getstackaddr ( const pthread_attr_t * attr, - void ** stackaddr ) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - ensure_valgrind("pthread_attr_getstackaddr"); - if (stackaddr) - *stackaddr = vg_attr->__vg_stackaddr; - return 0; -} - -WEAK -int pthread_attr_getstacksize ( const pthread_attr_t * attr, - size_t * stacksize ) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - ensure_valgrind("pthread_attr_getstacksize"); - if (stacksize) - *stacksize = vg_attr->__vg_stacksize; - return 0; -} - -int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR) - return EINVAL; - vg_attr->__vg_schedpolicy = policy; - return 0; -} - -int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - *policy = vg_attr->__vg_schedpolicy; - return 0; -} - - -WEAK -int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - vg_attr->__vg_guardsize = guardsize; - return 0; -} - -WEAK -int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) -{ - vg_pthread_attr_t* vg_attr; - CONVERT(attr, attr, vg_attr); - *guardsize = vg_attr->__vg_guardsize; - return 0; -} - -/* Again, like LinuxThreads. */ - -static int concurrency_current_level = 0; - -WEAK -int pthread_setconcurrency(int new_level) -{ - if (new_level < 0) - return EINVAL; - else { - concurrency_current_level = new_level; - return 0; - } -} - -WEAK -int pthread_getconcurrency(void) -{ - return concurrency_current_level; -} - - - -/* --------------------------------------------------- - Helper functions for running a thread - and for clearing up afterwards. - ------------------------------------------------ */ - -typedef void *(*__attribute__ ((stdcall)) REGPARM(3) allocate_tls_t) (void *result); -typedef void (*__attribute__ ((stdcall)) REGPARM(3) deallocate_tls_t) (void *tcb, int dealloc_tcb); - -static allocate_tls_t allocate_tls = NULL; -static deallocate_tls_t deallocate_tls = NULL; - -static -int get_gs() -{ - int gs; - - asm volatile ("movw %%gs, %w0" : "=q" (gs)); - - return gs & 0xffff; -} - -static -void set_gs( int gs ) -{ - asm volatile ("movw %w0, %%gs" :: "q" (gs)); -} - -static -void *get_tcb() -{ - void *tcb; - - asm volatile ("movl %%gs:0, %0" : "=r" (tcb)); - - return tcb; -} - -/* All exiting threads eventually pass through here, bearing the - return value, or PTHREAD_CANCELED, in ret_val. */ -static -__attribute__((noreturn)) -void thread_exit_wrapper ( void* ret_val ) -{ - int detached, res; - CleanupEntry cu; - pthread_key_t key; - void** specifics_ptr; - - /* Run this thread's key finalizers. Really this should be run - PTHREAD_DESTRUCTOR_ITERATIONS times. */ - for (key = 0; key < VG_N_THREAD_KEYS; key++) { - VALGRIND_MAGIC_SEQUENCE(res, (-2) /* default */, - VG_USERREQ__GET_KEY_D_AND_S, - key, &cu, 0, 0 ); - if (res == 0) { - /* valid key */ - my_assert(cu.type == VgCt_Function); - if (cu.data.function.fn && cu.data.function.arg) - cu.data.function.fn /* destructor for key */ - ( cu.data.function.arg /* specific for key for this thread */ ); - continue; - } - my_assert(res == -1); - } - - /* Free up my specifics space, if any. */ - VALGRIND_MAGIC_SEQUENCE(specifics_ptr, 3 /* default */, - VG_USERREQ__PTHREAD_GETSPECIFIC_PTR, - pthread_self(), 0, 0, 0); - my_assert(specifics_ptr != (void**)3); - my_assert(specifics_ptr != (void**)1); /* 1 means invalid thread */ - if (specifics_ptr != NULL) - my_free(specifics_ptr); - - /* Free up any TLS data */ - if ((get_gs() & 7) == 3 && pthread_self() > 1) { - my_assert(deallocate_tls != NULL); - deallocate_tls(get_tcb(), 1); - } - - /* Decide on my final disposition. */ - VALGRIND_MAGIC_SEQUENCE(detached, (-1) /* default */, - VG_USERREQ__SET_OR_GET_DETACH, - 2 /* get */, pthread_self(), 0, 0); - my_assert(detached == 0 || detached == 1); - - if (detached) { - /* Detached; I just quit right now. */ - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__QUIT, 0, 0, 0, 0); - } else { - /* Not detached; so I wait for a joiner. */ - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__WAIT_JOINER, ret_val, 0, 0, 0); - } - /* NOTREACHED */ - barf("thread_exit_wrapper: still alive?!"); -} - - -/* This function is a wrapper function for running a thread. It runs - the root function specified in pthread_create, and then, should the - root function return a value, it arranges to run the thread's - cleanup handlers and exit correctly. */ - -/* Struct used to convey info from pthread_create to thread_wrapper. - Must be careful not to pass to the child thread any pointers to - objects which might be on the parent's stack. */ -typedef - struct { - int attr__detachstate; - void* tls_data; - int tls_segment; - unsigned long sysinfo; - void* (*root_fn) ( void* ); - void* arg; - sigset_t sigmask; - } - NewThreadInfo; - -/* Struct used to describe a TDB header, copied from glibc. */ -typedef - struct { - void *tcb; - void *dtv; - void *self; - int multiple_threads; - unsigned long sysinfo; - } - tcbhead_t; - -/* This is passed to the VG_USERREQ__APPLY_IN_NEW_THREAD and so must - not return. Note that this runs in the new thread, not the - parent. */ -static -__attribute__((noreturn)) -void thread_wrapper ( NewThreadInfo* info ) -{ - int attr__detachstate; - void* tls_data; - int tls_segment; - unsigned long sysinfo; - void* (*root_fn) ( void* ); - void* arg; - void* ret_val; - __pthread_unwind_buf_t ub; - - attr__detachstate = info->attr__detachstate; - tls_data = info->tls_data; - tls_segment = info->tls_segment; - sysinfo = info->sysinfo; - root_fn = info->root_fn; - arg = info->arg; - - if (tls_data) { - tcbhead_t *tcb = tls_data; - struct vki_modify_ldt_ldt_s ldt_info; - - /* Fill in the TCB header */ - tcb->tcb = tcb; - tcb->self = tcb; - tcb->multiple_threads = 1; - tcb->sysinfo = sysinfo; - - /* Fill in an LDT descriptor */ - ldt_info.entry_number = tls_segment; - ldt_info.base_addr = (unsigned long)tls_data; - ldt_info.limit = 0xfffff; - ldt_info.seg_32bit = 1; - ldt_info.contents = 0; - ldt_info.read_exec_only = 0; - ldt_info.limit_in_pages = 1; - ldt_info.seg_not_present = 0; - ldt_info.useable = 1; - ldt_info.reserved = 0; - - /* Install the thread area */ - VG_(do_syscall)(__NR_set_thread_area, &ldt_info); - - /* Setup the GS segment register */ - set_gs(ldt_info.entry_number * 8 + 3); - } - - /* Minimally observe the attributes supplied. */ - if (attr__detachstate != PTHREAD_CREATE_DETACHED - && attr__detachstate != PTHREAD_CREATE_JOINABLE) - pthread_error("thread_wrapper: invalid attr->__detachstate"); - if (attr__detachstate == PTHREAD_CREATE_DETACHED) - pthread_detach(pthread_self()); - - /* Initialise thread specific state */ - init_thread_specific_state(); - - /* Now that everything is set up, restore our signal mask (we're - ready to accept signals) */ - sigprocmask(SIG_SETMASK, &info->sigmask, NULL); - - /* Free up the arg block that pthread_create malloced. */ - my_free(info); - - - if (setjmp(ub.__cancel_jmp_buf[0].__cancel_jmp_buf) == 0) { - CleanupEntry cu; - int res; - - cu.type = VgCt_Longjmp; - cu.data.longjmp.ub = &ub; - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_PUSH, - &cu, 0, 0, 0); - - /* The root function might not return. But if it does we simply - move along to thread_exit_wrapper. All other ways out for the - thread (cancellation, or calling pthread_exit) lead there - too. */ - ret_val = root_fn(arg); - } - else { - ret_val = get_ret_val(); - } - - thread_exit_wrapper(ret_val); - /* NOTREACHED */ -} - - -/* --------------------------------------------------- - CLEANUP STACKS - ------------------------------------------------ */ - -void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer, - void (*__routine) (void *), - void *__arg) -{ - int res; - CleanupEntry cu; - ensure_valgrind("_pthread_cleanup_push"); - cu.type = VgCt_Function; - cu.data.function.fn = __routine; - cu.data.function.arg = __arg; - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_PUSH, - &cu, 0, 0, 0); - my_assert(res == 0); -} - - -void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer, - void (*__routine) (void *), - void *__arg) -{ - /* As _pthread_cleanup_push, but first save the thread's original - cancellation type in __buffer and set it to Deferred. */ - int orig_ctype; - ensure_valgrind("_pthread_cleanup_push_defer"); - /* Set to Deferred, and put the old cancellation type in res. */ - my_assert(-1 != PTHREAD_CANCEL_DEFERRED); - my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS); - my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int)); - VALGRIND_MAGIC_SEQUENCE(orig_ctype, (-1) /* default */, - VG_USERREQ__SET_CANCELTYPE, - PTHREAD_CANCEL_DEFERRED, 0, 0, 0); - my_assert(orig_ctype != -1); - *((int*)(__buffer)) = orig_ctype; - /* Now push the cleanup. */ - _pthread_cleanup_push(NULL, __routine, __arg); -} - - -void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer, - int __execute) -{ - int res; - CleanupEntry cu; - ensure_valgrind("_pthread_cleanup_push"); - cu.type = VgCt_None; /* paranoia */ - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_POP, - &cu, 0, 0, 0); - my_assert(cu.type == VgCt_Function); - if (res == 0) { - /* pop succeeded */ - if (__execute) { - cu.data.function.fn ( cu.data.function.arg ); - } - return; - } - if (res == -1) { - /* stack underflow */ - return; - } - barf("_pthread_cleanup_pop"); -} - - -void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer, - int __execute) -{ - int orig_ctype, fake_ctype; - /* As _pthread_cleanup_pop, but after popping/running the handler, - restore the thread's original cancellation type from the first - word of __buffer. */ - _pthread_cleanup_pop(NULL, __execute); - orig_ctype = *((int*)(__buffer)); - my_assert(orig_ctype == PTHREAD_CANCEL_DEFERRED - || orig_ctype == PTHREAD_CANCEL_ASYNCHRONOUS); - my_assert(-1 != PTHREAD_CANCEL_DEFERRED); - my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS); - my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int)); - VALGRIND_MAGIC_SEQUENCE(fake_ctype, (-1) /* default */, - VG_USERREQ__SET_CANCELTYPE, - orig_ctype, 0, 0, 0); - my_assert(fake_ctype == PTHREAD_CANCEL_DEFERRED); -} - - -REGPARM(1) -void __pthread_register_cancel (__pthread_unwind_buf_t *__buf) -{ - int res; - CleanupEntry cu; - ensure_valgrind("__pthread_register_cancel"); - cu.type = VgCt_Longjmp; - cu.data.longjmp.ub = __buf; - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_PUSH, - &cu, 0, 0, 0); - my_assert(res == 0); -} - - -REGPARM(1) -void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf) -{ - /* As __pthread_register cancel, but save the thread's original - cancellation type and set it to Deferred. */ - int res; - CleanupEntry cu; - ensure_valgrind("__pthread_register_cancel_defer"); - cu.type = VgCt_Longjmp; - cu.data.longjmp.ub = __buf; - /* Set to Deferred, and save the old cancellation type. */ - my_assert(-1 != PTHREAD_CANCEL_DEFERRED); - my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS); - my_assert(sizeof(struct _pthread_cleanup_buffer) >= sizeof(int)); - VALGRIND_MAGIC_SEQUENCE(cu.data.longjmp.ctype, (-1) /* default */, - VG_USERREQ__SET_CANCELTYPE, - PTHREAD_CANCEL_DEFERRED, 0, 0, 0); - my_assert(cu.data.longjmp.ctype != -1); - /* Now push the cleanup. */ - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_PUSH, - &cu, 0, 0, 0); - my_assert(res == 0); -} - - -REGPARM(1) -void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf) -{ - int res; - CleanupEntry cu; - ensure_valgrind("__pthread_unregister_cancel"); - cu.type = VgCt_None; /* paranoia */ - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_POP, - &cu, 0, 0, 0); - my_assert(cu.type == VgCt_Longjmp); - my_assert(cu.data.longjmp.ub == __buf); - return; -} - - -REGPARM(1) -void __pthread_unregister_restore (__pthread_unwind_buf_t *__buf) -{ - int res; - CleanupEntry cu; - int fake_ctype; - /* As __pthread_unregister_cancel, but after popping/running the - handler, restore the thread's original cancellation type. */ - ensure_valgrind("__pthread_unregister_cancel_restore"); - cu.type = VgCt_None; /* paranoia */ - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_POP, - &cu, 0, 0, 0); - my_assert(cu.type == VgCt_Longjmp); - my_assert(cu.data.longjmp.ub == __buf); - /* Restore the original cancellation type. */ - my_assert(cu.data.longjmp.ctype == PTHREAD_CANCEL_DEFERRED - || cu.data.longjmp.ctype == PTHREAD_CANCEL_ASYNCHRONOUS); - my_assert(-1 != PTHREAD_CANCEL_DEFERRED); - my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS); - VALGRIND_MAGIC_SEQUENCE(fake_ctype, (-1) /* default */, - VG_USERREQ__SET_CANCELTYPE, - cu.data.longjmp.ctype, 0, 0, 0); - my_assert(fake_ctype == PTHREAD_CANCEL_DEFERRED); - return; -} - -REGPARM(1) -__attribute ((__noreturn__)) -void __pthread_unwind (__pthread_unwind_buf_t *__buf) -{ - int res; - CleanupEntry cu; - while (1) { - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__CLEANUP_POP, - &cu, 0, 0, 0); - my_assert(res == 0); - if (cu.type == VgCt_Longjmp) break; - if (0) printf("running cleanup handler"); - my_assert(cu.type == VgCt_Function); - cu.data.function.fn ( cu.data.function.arg ); - } - my_assert(cu.type == VgCt_Longjmp); - my_assert(__buf == NULL || __buf == cu.data.longjmp.ub); - __buf = cu.data.longjmp.ub; - longjmp(__buf->__cancel_jmp_buf[0].__cancel_jmp_buf, 1); - /* NOTREACHED */ -} - - -REGPARM(1) -__attribute ((__noreturn__)) -void __pthread_unwind_next (__pthread_unwind_buf_t *__buf) -{ - __pthread_unwind(NULL); - /* NOTREACHED */ -} - - -/* --------------------------------------------------- - THREADs - ------------------------------------------------ */ - -static void __valgrind_pthread_yield ( void ) -{ - int res; - ensure_valgrind("pthread_yield"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_YIELD, 0, 0, 0, 0); -} - -WEAK -int pthread_yield ( void ) -{ - __valgrind_pthread_yield(); - return 0; -} - - -int pthread_equal(pthread_t thread1, pthread_t thread2) -{ - return thread1 == thread2 ? 1 : 0; -} - - -/* Bundle up the args into a malloc'd block and create a new thread - consisting of thread_wrapper() applied to said malloc'd block. */ -int -pthread_create (pthread_t *__restrict __thredd, - __const pthread_attr_t *__restrict __attr, - void *(*__start_routine) (void *), - void *__restrict __arg) -{ - int tid_child; - NewThreadInfo* info; - int gs; - StackInfo si; - vg_pthread_attr_t* __vg_attr; - CONVERT(attr, __attr, __vg_attr); - - ensure_valgrind("pthread_create"); - - /* make sure the tsd keys, and hence locale info, for the root - thread are initialised before we get into complications making - new threads. */ - init_global_thread_specific_state(); - - /* Allocate space for the arg block. thread_wrapper will free - it. */ - info = my_malloc(sizeof(NewThreadInfo)); - my_assert(info != NULL); - - if (__vg_attr) - info->attr__detachstate = __vg_attr->__vg_detachstate; - else - info->attr__detachstate = PTHREAD_CREATE_JOINABLE; - - gs = get_gs(); - - if ((gs & 7) == 3) { - tcbhead_t *tcb = get_tcb(); - - if (allocate_tls == NULL || deallocate_tls == NULL) { - allocate_tls = (allocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_allocate_tls"); - deallocate_tls = (deallocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_deallocate_tls"); - } - - my_assert(allocate_tls != NULL); - - info->tls_data = allocate_tls(NULL); - info->tls_segment = gs >> 3; - info->sysinfo = tcb->sysinfo; - - tcb->multiple_threads = 1; - } else { - info->tls_data = NULL; - info->tls_segment = -1; - info->sysinfo = 0; - } - - info->root_fn = __start_routine; - info->arg = __arg; - sigprocmask(SIG_SETMASK, NULL, &info->sigmask); - - if (__attr) { - si.base = (Addr)__vg_attr->__vg_stackaddr; - si.size = __vg_attr->__vg_stacksize; - si.guardsize = __vg_attr->__vg_guardsize; - } else { - si.base = (Addr)NULL; - si.size = VG_PTHREAD_STACK_SIZE; - si.guardsize = VKI_BYTES_PER_PAGE; - } - - VALGRIND_MAGIC_SEQUENCE(tid_child, VG_INVALID_THREADID /* default */, - VG_USERREQ__APPLY_IN_NEW_THREAD, - &thread_wrapper, info, &si, 0); - my_assert(tid_child != VG_INVALID_THREADID); - - if (__thredd) - *__thredd = tid_child; - - return 0; /* success */ -} - - -int -pthread_join (pthread_t __th, void **__thread_return) -{ - int res; - ensure_valgrind("pthread_join"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_JOIN, - __th, __thread_return, 0, 0); - return res; -} - - -void pthread_exit(void *retval) -{ - ensure_valgrind("pthread_exit"); - set_ret_val(retval); - __pthread_unwind(NULL); -} - - -int pthread_detach(pthread_t th) -{ - int res; - ensure_valgrind("pthread_detach"); - /* First we enquire as to the current detach state. */ - VALGRIND_MAGIC_SEQUENCE(res, (-2) /* default */, - VG_USERREQ__SET_OR_GET_DETACH, - 2 /* get */, th, 0, 0); - if (res == -1) { - /* not found */ - pthread_error("pthread_detach: " - "invalid target thread"); - return ESRCH; - } - if (res == 1) { - /* already detached */ - pthread_error("pthread_detach: " - "target thread is already detached"); - return EINVAL; - } - if (res == 0) { - VALGRIND_MAGIC_SEQUENCE(res, (-2) /* default */, - VG_USERREQ__SET_OR_GET_DETACH, - 1 /* set */, th, 0, 0); - my_assert(res == 0); - return 0; - } - barf("pthread_detach"); -} - - -/* --------------------------------------------------- - MUTEX ATTRIBUTES - ------------------------------------------------ */ - -int __pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - vg_pthread_mutexattr_t* vg_attr; - CONVERT(mutexattr, attr, vg_attr); - vg_attr->__vg_mutexkind = PTHREAD_MUTEX_ERRORCHECK_NP; - return 0; -} - -int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) -{ - vg_pthread_mutexattr_t* vg_attr; - CONVERT(mutexattr, attr, vg_attr); - - switch (type) { -# ifndef GLIBC_2_1 - case PTHREAD_MUTEX_TIMED_NP: - case PTHREAD_MUTEX_ADAPTIVE_NP: -# endif -# ifdef GLIBC_2_1 - case PTHREAD_MUTEX_FAST_NP: -# endif - case PTHREAD_MUTEX_RECURSIVE_NP: - case PTHREAD_MUTEX_ERRORCHECK_NP: - vg_attr->__vg_mutexkind = type; - return 0; - default: - pthread_error("pthread_mutexattr_settype: " - "invalid type"); - return EINVAL; - } -} - -int __pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) -{ - vg_pthread_mutexattr_t* vg_attr; - CONVERT(mutexattr, attr, vg_attr); - - *type = vg_attr->__vg_mutexkind; - - return 0; -} - -int __pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - return 0; -} - -int __pthread_mutexattr_setpshared ( pthread_mutexattr_t* attr, int pshared) -{ - if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) - return EINVAL; - - /* For now it is not possible to shared a conditional variable. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return ENOSYS; - - return 0; -} - - -/* --------------------------------------------------- - MUTEXes - ------------------------------------------------ */ - -int __pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutexattr) -{ - vg_pthread_mutex_t* vg_mutex; - vg_pthread_mutexattr_t* vg_mutexattr; - CONVERT(mutex, mutex, vg_mutex); - CONVERT(mutexattr, mutexattr, vg_mutexattr); - - vg_mutex->__vg_m_count = 0; - vg_mutex->__vg_m_owner = (/*_pthread_descr*/void*)VG_INVALID_THREADID; - vg_mutex->__vg_m_kind = PTHREAD_MUTEX_ERRORCHECK_NP; - if (vg_mutexattr) - vg_mutex->__vg_m_kind = vg_mutexattr->__vg_mutexkind; - return 0; -} - - -int __pthread_mutex_lock(pthread_mutex_t *mutex) -{ - int res; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_MUTEX_LOCK, - vg_mutex, 0, 0, 0); - return res; -} - - -int __pthread_mutex_timedlock(pthread_mutex_t *mutex, - const struct timespec *abstime ) -{ - int res; - unsigned int ms_now, ms_end; - struct timeval timeval_now; - unsigned long long int ull_ms_now_after_1970; - unsigned long long int ull_ms_end_after_1970; - unsigned long long int ull_ms_now; - unsigned long long int ull_ms_end; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - VALGRIND_MAGIC_SEQUENCE(ms_now, 0xFFFFFFFF /* default */, - VG_USERREQ__READ_MILLISECOND_TIMER, - 0, 0, 0, 0); - my_assert(ms_now != 0xFFFFFFFF); - res = gettimeofday(&timeval_now, NULL); - my_assert(res == 0); - - ull_ms_now_after_1970 - = 1000ULL * ((unsigned long long int)(timeval_now.tv_sec)) - + ((unsigned long long int)(timeval_now.tv_usec / 1000)); - ull_ms_end_after_1970 - = 1000ULL * ((unsigned long long int)(abstime->tv_sec)) - + ((unsigned long long int)(abstime->tv_nsec / 1000000)); - if (ull_ms_end_after_1970 < ull_ms_now_after_1970) - ull_ms_end_after_1970 = ull_ms_now_after_1970; - ull_ms_now = ((unsigned long long int)(ms_now)); - ull_ms_end = ull_ms_now + (ull_ms_end_after_1970 - ull_ms_now_after_1970); - if (ull_ms_end >= (unsigned long long int)(0xFFFFFFFFUL)) { - /* use 0xFFFFFFFEUL because 0xFFFFFFFFUL is reserved for no timeout - (the fine difference between a long wait and a possible abort - due to a detected deadlock). - */ - ms_end = 0xFFFFFFFEUL; - } else { - ms_end = (unsigned int)(ull_ms_end); - } - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_MUTEX_TIMEDLOCK, - vg_mutex, ms_end, 0, 0); - return res; -} - - -int __pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - int res; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_MUTEX_TRYLOCK, - vg_mutex, 0, 0, 0); - return res; -} - - -int __pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - int res; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_MUTEX_UNLOCK, - vg_mutex, 0, 0, 0); - return res; -} - - -int __pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - /* Valgrind doesn't hold any resources on behalf of the mutex, so no - need to involve it. */ - if (vg_mutex->__vg_m_count > 0) { - /* Oh, the horror. glibc's internal use of pthreads "knows" - that destroying a lock does an implicit unlock. Make it - explicit. */ - __pthread_mutex_unlock( (pthread_mutex_t*)vg_mutex ); - pthread_error("pthread_mutex_destroy: mutex is still in use"); - return EBUSY; - } - vg_mutex->__vg_m_count = 0; - vg_mutex->__vg_m_owner = (/*_pthread_descr*/void*)VG_INVALID_THREADID; - vg_mutex->__vg_m_kind = PTHREAD_MUTEX_ERRORCHECK_NP; - return 0; -} - - -/* --------------------------------------------------- - CONDITION VARIABLES - ------------------------------------------------ */ - -/* LinuxThreads supports no attributes for conditions. Hence ... */ - -int pthread_condattr_init(pthread_condattr_t *attr) -{ - return 0; -} - -int pthread_condattr_destroy(pthread_condattr_t *attr) -{ - return 0; -} - -int pthread_cond_init( pthread_cond_t *cond, - const pthread_condattr_t *cond_attr) -{ - vg_pthread_cond_t* vg_cond; - CONVERT(cond, cond, vg_cond); - vg_cond->__vg_c_waiting = (/*_pthread_descr*/void*)VG_INVALID_THREADID; - return 0; -} - -int pthread_cond_destroy(pthread_cond_t *cond) -{ - /* should check that no threads are waiting on this CV */ - static int moans = N_MOANS; - if (moans-- > 0) - kludged("pthread_cond_destroy", - "(it doesn't check if the cond is waited on)" ); - return 0; -} - -/* --------------------------------------------------- - SCHEDULING - ------------------------------------------------ */ - -/* This is completely bogus. */ -int pthread_getschedparam(pthread_t target_thread, - int *policy, - struct sched_param *param) -{ - static int moans = N_MOANS; - if (moans-- > 0) - kludged("pthread_getschedparam", NULL); - if (policy) *policy = SCHED_OTHER; -# ifdef HAVE_SCHED_PRIORITY - if (param) param->sched_priority = 0; /* who knows */ -# else - if (param) param->__sched_priority = 0; /* who knows */ -# endif - return 0; -} - -int pthread_setschedparam(pthread_t target_thread, - int policy, - const struct sched_param *param) -{ - static int moans = N_MOANS; - if (moans-- > 0) - ignored("pthread_setschedparam", "(scheduling not changeable)"); - return 0; -} - -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - int res; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - ensure_valgrind("pthread_cond_wait"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_COND_WAIT, - cond, vg_mutex, 0, 0); - return res; -} - -int pthread_cond_timedwait ( pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime ) -{ - int res; - unsigned int ms_now, ms_end; - struct timeval timeval_now; - unsigned long long int ull_ms_now_after_1970; - unsigned long long int ull_ms_end_after_1970; - unsigned long long int ull_ms_now; - unsigned long long int ull_ms_end; - vg_pthread_mutex_t* vg_mutex; - CONVERT(mutex, mutex, vg_mutex); - - ensure_valgrind("pthread_cond_timedwait"); - VALGRIND_MAGIC_SEQUENCE(ms_now, 0xFFFFFFFF /* default */, - VG_USERREQ__READ_MILLISECOND_TIMER, - 0, 0, 0, 0); - my_assert(ms_now != 0xFFFFFFFF); - res = gettimeofday(&timeval_now, NULL); - my_assert(res == 0); - - ull_ms_now_after_1970 - = 1000ULL * ((unsigned long long int)(timeval_now.tv_sec)) - + ((unsigned long long int)(timeval_now.tv_usec / 1000)); - ull_ms_end_after_1970 - = 1000ULL * ((unsigned long long int)(abstime->tv_sec)) - + ((unsigned long long int)(abstime->tv_nsec / 1000000)); - if (ull_ms_end_after_1970 < ull_ms_now_after_1970) - ull_ms_end_after_1970 = ull_ms_now_after_1970; - ull_ms_now = ((unsigned long long int)(ms_now)); - ull_ms_end = ull_ms_now + (ull_ms_end_after_1970 - ull_ms_now_after_1970); - if (ull_ms_end >= (unsigned long long int)(0xFFFFFFFFUL)) { - /* use 0xFFFFFFFEUL because 0xFFFFFFFFUL is reserved for no timeout - (the fine difference between a long wait and a possible abort - due to a detected deadlock). - */ - ms_end = 0xFFFFFFFEUL; - } else { - ms_end = (unsigned int)(ull_ms_end); - } - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_COND_TIMEDWAIT, - cond, vg_mutex, ms_end, 0); - return res; -} - - -int pthread_cond_signal(pthread_cond_t *cond) -{ - int res; - ensure_valgrind("pthread_cond_signal"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_COND_SIGNAL, - cond, 0, 0, 0); - return res; -} - -int pthread_cond_broadcast(pthread_cond_t *cond) -{ - int res; - ensure_valgrind("pthread_cond_broadcast"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_COND_BROADCAST, - cond, 0, 0, 0); - return res; -} - - -/* --------------------------------------------------- - CANCELLATION - ------------------------------------------------ */ - -int pthread_setcancelstate(int state, int *oldstate) -{ - int res; - ensure_valgrind("pthread_setcancelstate"); - if (state != PTHREAD_CANCEL_ENABLE - && state != PTHREAD_CANCEL_DISABLE) { - pthread_error("pthread_setcancelstate: " - "invalid state"); - return EINVAL; - } - my_assert(-1 != PTHREAD_CANCEL_ENABLE); - my_assert(-1 != PTHREAD_CANCEL_DISABLE); - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__SET_CANCELSTATE, - state, 0, 0, 0); - my_assert(res != -1); - if (oldstate) - *oldstate = res; - return 0; -} - -int pthread_setcanceltype(int type, int *oldtype) -{ - int res; - ensure_valgrind("pthread_setcanceltype"); - if (type != PTHREAD_CANCEL_DEFERRED - && type != PTHREAD_CANCEL_ASYNCHRONOUS) { - pthread_error("pthread_setcanceltype: " - "invalid type"); - return EINVAL; - } - my_assert(-1 != PTHREAD_CANCEL_DEFERRED); - my_assert(-1 != PTHREAD_CANCEL_ASYNCHRONOUS); - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__SET_CANCELTYPE, - type, 0, 0, 0); - my_assert(res != -1); - if (oldtype) - *oldtype = res; - return 0; -} - -int pthread_cancel(pthread_t thread) -{ - int res; - ensure_valgrind("pthread_cancel"); - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__SET_CANCELPEND, - thread, &pthread_exit, 0, 0); - my_assert(res != -1); - return res; -} - -static -void __my_pthread_testcancel(void) -{ - int res; - ensure_valgrind("__my_pthread_testcancel"); - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__TESTCANCEL, - 0, 0, 0, 0); - my_assert(res == 0); -} - -void pthread_testcancel ( void ) -{ - __my_pthread_testcancel(); -} - - -/* Not really sure what this is for. I suspect for doing the POSIX - requirements for fork() and exec(). We do this internally anyway - whenever those syscalls are observed, so this could be superfluous, - but hey ... -*/ -void __pthread_kill_other_threads_np ( void ) -{ - int res; - ensure_valgrind("__pthread_kill_other_threads_np"); - VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */, - VG_USERREQ__NUKE_OTHER_THREADS, - 0, 0, 0, 0); - my_assert(res == 0); -} - - -/* --------------------------------------------------- - SIGNALS - ------------------------------------------------ */ - -#include - -int pthread_sigmask(int how, const sigset_t *newmask, - sigset_t *oldmask) -{ - int res; - - /* A bit subtle, because the scheduler expects newmask and oldmask - to be vki_sigset_t* rather than sigset_t*, and the two are - different. Fortunately the first 64 bits of a sigset_t are - exactly a vki_sigset_t, so we just pass the pointers through - unmodified. Haaaack! - - Also mash the how value so that the SIG_ constants from glibc - constants to VKI_ constants, so that the former do not have to - be included into vg_scheduler.c. */ - - ensure_valgrind("pthread_sigmask"); - - switch (how) { - case SIG_SETMASK: how = VKI_SIG_SETMASK; break; - case SIG_BLOCK: how = VKI_SIG_BLOCK; break; - case SIG_UNBLOCK: how = VKI_SIG_UNBLOCK; break; - default: pthread_error("pthread_sigmask: invalid how"); - return EINVAL; - } - - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_SIGMASK, - how, newmask, oldmask, 0); - - /* The scheduler tells us of any memory violations. */ - return res == 0 ? 0 : EFAULT; -} - -int sigwait ( const sigset_t* set, int* sig ) -{ - int res; - siginfo_t si; - - __my_pthread_testcancel(); - - si.si_signo = 0; - res = sigtimedwait(set, &si, NULL); - *sig = si.si_signo; - - return 0; /* always returns 0 */ -} - - -int pthread_kill(pthread_t thread, int signo) -{ - int res; - ensure_valgrind("pthread_kill"); - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_KILL, - thread, signo, 0, 0); - return res; -} - - -/* Copied verbatim from Linuxthreads */ -/* Redefine raise() to send signal to calling thread only, - as per POSIX 1003.1c */ -int raise (int sig) -{ - int retcode = pthread_kill(pthread_self(), sig); - if (retcode == 0) { - return 0; - } else { - *(__errno_location()) = retcode; - return -1; - } -} - - - -/* --------------------------------------------------- - THREAD-SPECIFICs - ------------------------------------------------ */ - -static -int key_is_valid (pthread_key_t key) -{ - int res; - VALGRIND_MAGIC_SEQUENCE(res, 2 /* default */, - VG_USERREQ__PTHREAD_KEY_VALIDATE, - key, 0, 0, 0); - my_assert(res != 2); - return res; -} - - -/* Returns NULL if thread is invalid. Otherwise, if the thread - already has a specifics area, return that. Otherwise allocate it - one. */ -static -void** get_or_allocate_specifics_ptr ( pthread_t thread ) -{ - int res, i; - void** specifics_ptr; - ensure_valgrind("get_or_allocate_specifics_ptr"); - - /* Returns zero if the thread has no specific_ptr. One if thread - is invalid. Otherwise, the specific_ptr value. This is - allocated with my_malloc and so is aligned and cannot be - confused with 1 or 3. */ - VALGRIND_MAGIC_SEQUENCE(specifics_ptr, 3 /* default */, - VG_USERREQ__PTHREAD_GETSPECIFIC_PTR, - thread, 0, 0, 0); - my_assert(specifics_ptr != (void**)3); - - if (specifics_ptr == (void**)1) - return NULL; /* invalid thread */ - - if (specifics_ptr != NULL) - return specifics_ptr; /* already has a specifics ptr. */ - - /* None yet ... allocate a new one. Should never fail. */ - specifics_ptr = my_malloc( VG_N_THREAD_KEYS * sizeof(void*) ); - my_assert(specifics_ptr != NULL); - - VALGRIND_MAGIC_SEQUENCE(res, -1 /* default */, - VG_USERREQ__PTHREAD_SETSPECIFIC_PTR, - specifics_ptr, 0, 0, 0); - my_assert(res == 0); - - /* POSIX sez: "Upon thread creation, the value NULL shall be - associated with all defined keys in the new thread." This - allocation is in effect a delayed allocation of the specific - data for a thread, at its first-use. Hence we initialise it - here. */ - for (i = 0; i < VG_N_THREAD_KEYS; i++) { - specifics_ptr[i] = NULL; - } - - return specifics_ptr; -} - - -int __pthread_key_create(pthread_key_t *key, - void (*destr_function) (void *)) -{ - void** specifics_ptr; - int res, i; - ensure_valgrind("pthread_key_create"); - - /* This writes *key if successful. It should never fail. */ - VALGRIND_MAGIC_SEQUENCE(res, 1 /* default */, - VG_USERREQ__PTHREAD_KEY_CREATE, - key, destr_function, 0, 0); - - if (res == 0) { - /* POSIX sez: "Upon key creation, the value NULL shall be - associated with the new key in all active threads." */ - for (i = 0; i < VG_N_THREADS; i++) { - specifics_ptr = get_or_allocate_specifics_ptr(i); - /* we get NULL if i is an invalid thread. */ - if (specifics_ptr != NULL) - specifics_ptr[*key] = NULL; - } - } - - return res; -} - -int pthread_key_delete(pthread_key_t key) -{ - int res; - ensure_valgrind("pthread_key_delete"); - if (!key_is_valid(key)) - return EINVAL; - VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, - VG_USERREQ__PTHREAD_KEY_DELETE, - key, 0, 0, 0); - my_assert(res == 0); - return 0; -} - -int __pthread_setspecific(pthread_key_t key, const void *pointer) -{ - void** specifics_ptr; - ensure_valgrind("pthread_setspecific"); - - if (!key_is_valid(key)) - return EINVAL; - - specifics_ptr = get_or_allocate_specifics_ptr(pthread_self()); - specifics_ptr[key] = (void*)pointer; - return 0; -} - -void * __pthread_getspecific(pthread_key_t key) -{ - void** specifics_ptr; - ensure_valgrind("pthread_getspecific"); - - if (!key_is_valid(key)) - return NULL; - - specifics_ptr = get_or_allocate_specifics_ptr(pthread_self()); - return specifics_ptr[key]; -} - - -/* --------------------------------------------------- - ONCEry - ------------------------------------------------ */ - -/* This protects reads and writes of the once_control variable - supplied. It is never held whilst any particular initialiser is - running. */ -static pthread_mutex_t once_masterlock = PTHREAD_MUTEX_INITIALIZER; - -/* Initialiser needs to be run. */ -#define P_ONCE_NOT_DONE ((PTHREAD_ONCE_INIT) + 0) - -/* Initialiser currently running. */ -#define P_ONCE_RUNNING ((PTHREAD_ONCE_INIT) + 1) - -/* Initialiser has completed. */ -#define P_ONCE_COMPLETED ((PTHREAD_ONCE_INIT) + 2) - -int __pthread_once ( pthread_once_t *once_control, - void (*init_routine) (void) ) -{ - int res; - int done; - -# define TAKE_LOCK \ - res = __pthread_mutex_lock(&once_masterlock); \ - my_assert(res == 0); - -# define RELEASE_LOCK \ - res = __pthread_mutex_unlock(&once_masterlock); \ - my_assert(res == 0); - - void cleanup(void *v) { - TAKE_LOCK; - *once_control = P_ONCE_NOT_DONE; - RELEASE_LOCK; - } - - ensure_valgrind("pthread_once"); - - /* Grab the lock transiently, so we can safely see what state this - once_control is in. */ - - TAKE_LOCK; - - switch (*once_control) { - - case P_ONCE_NOT_DONE: - /* Not started. Change state to indicate running, drop the - lock and run. */ - *once_control = P_ONCE_RUNNING; - _pthread_cleanup_push(NULL, cleanup, NULL); - RELEASE_LOCK; - init_routine(); - /* re-take the lock, and set state to indicate done. */ - TAKE_LOCK; - _pthread_cleanup_pop(NULL, False); - *once_control = P_ONCE_COMPLETED; - RELEASE_LOCK; - break; - - case P_ONCE_RUNNING: - /* This is the tricky case. The initialiser is running in - some other thread, but we have to delay this thread till - the other one completes. So we sort-of busy wait. In - fact it makes sense to yield now, because what we want to - happen is for the thread running the initialiser to - complete ASAP. */ - RELEASE_LOCK; - done = 0; - while (1) { - /* Let others run for a while. */ - __valgrind_pthread_yield(); - /* Grab the lock and see if we're done waiting. */ - TAKE_LOCK; - if (*once_control == P_ONCE_COMPLETED) - done = 1; - RELEASE_LOCK; - if (done) - break; - } - break; - - case P_ONCE_COMPLETED: - default: - /* Easy. It's already done. Just drop the lock. */ - RELEASE_LOCK; - break; - } - - return 0; - -# undef TAKE_LOCK -# undef RELEASE_LOCK -} - -#undef P_ONCE_NOT_DONE -#undef P_ONCE_RUNNING -#undef P_ONCE_COMPLETED - - -/* --------------------------------------------------- - MISC - ------------------------------------------------ */ - -static pthread_mutex_t pthread_atfork_lock - = PTHREAD_MUTEX_INITIALIZER; - -int __pthread_atfork ( void (*prepare)(void), - void (*parent)(void), - void (*child)(void) ) -{ - int n, res; - ForkHandlerEntry entry; - - ensure_valgrind("pthread_atfork"); - __pthread_mutex_lock(&pthread_atfork_lock); - - /* Fetch old counter */ - VALGRIND_MAGIC_SEQUENCE(n, -2 /* default */, - VG_USERREQ__GET_FHSTACK_USED, - 0, 0, 0, 0); - my_assert(n >= 0 && n < VG_N_FORKHANDLERSTACK); - if (n == VG_N_FORKHANDLERSTACK-1) - barf("pthread_atfork: VG_N_FORKHANDLERSTACK is too low; " - "increase and recompile"); - - /* Add entry */ - entry.prepare = *prepare; - entry.parent = *parent; - entry.child = *child; - VALGRIND_MAGIC_SEQUENCE(res, -2 /* default */, - VG_USERREQ__SET_FHSTACK_ENTRY, - n, &entry, 0, 0); - my_assert(res == 0); - - /* Bump counter */ - VALGRIND_MAGIC_SEQUENCE(res, -2 /* default */, - VG_USERREQ__SET_FHSTACK_USED, - n+1, 0, 0, 0); - my_assert(res == 0); - - __pthread_mutex_unlock(&pthread_atfork_lock); - return 0; -} - - -#ifdef GLIBC_2_3 -/* This seems to be a hook which appeared in glibc-2.3.2. */ -int __register_atfork ( void (*prepare)(void), - void (*parent)(void), - void (*child)(void) ) -{ - return __pthread_atfork(prepare,parent,child); -} -#endif - -WEAK -void __pthread_initialize ( void ) -{ - ensure_valgrind("__pthread_initialize"); -} - - -/* --------------------------------------------------- - LIBRARY-PRIVATE THREAD SPECIFIC STATE - ------------------------------------------------ */ - -#include - -/* The allowable libc TSD keys (indices) from glibc source. */ -enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, - _LIBC_TSD_KEY_DL_ERROR, - _LIBC_TSD_KEY_RPC_VARS, - _LIBC_TSD_KEY_LOCALE, - _LIBC_TSD_KEY_CTYPE_B, - _LIBC_TSD_KEY_CTYPE_TOLOWER, - _LIBC_TSD_KEY_CTYPE_TOUPPER, - _LIBC_TSD_KEY_N }; - -typedef - struct { - void *ret_val; - int *errno_ptr; - int *h_errno_ptr; - struct __res_state *res_state_ptr; - int errno_data; - int h_errno_data; - struct __res_state res_state_data; - void *libc_specifics[_LIBC_TSD_KEY_N]; - } - ThreadSpecificState; - -static ThreadSpecificState thread_specific_state[VG_N_THREADS]; - -/* Auto-initialising subsystem. global_init_done is set - after initialisation. global_init_done_mx guards it. */ -static int global_init_done = 0; -static pthread_mutex_t global_init_done_mx = PTHREAD_MUTEX_INITIALIZER; - -static -void cleanup_root(void *arg) -{ - thread_exit_wrapper(get_ret_val()); - /* NOTREACHED */ -} - -static void __attribute__((constructor)) -init_global_thread_specific_state ( void ) -{ - int res; - - /* Don't fall into deadlock if we get called again whilst we still - hold the lock, via the __uselocale() call herein. */ - if (global_init_done != 0) - return; - - /* Take the lock. */ - res = __pthread_mutex_lock(&global_init_done_mx); - if (res != 0) barf("init_global_thread_specific_state: lock"); - - /* Now test again, to be sure there is no mistake. */ - if (global_init_done != 0) { - res = __pthread_mutex_unlock(&global_init_done_mx); - if (res != 0) barf("init_global_thread_specific_state: unlock(1)"); - return; - } - - /* assert that we are the root thread. */ - my_assert(pthread_self() == 1); - - /* Signify init done - we shouldn't really do this until after - the call to init_thread_specific_state() but that routine makes - a call to __uselocale() that may bring us back here as that - routine will call __libc_tsd_set() which will call us. - - We can get away with marking the init as done now because - the important bits of init_thread_specific_state() are done - before the call to __uselocale() is made. */ - global_init_done = 1; - - /* Initialise thread specific data for the root thread. */ - init_thread_specific_state(); - - /* Install a cleanup routine to handle the root thread exiting */ - _pthread_cleanup_push(NULL, cleanup_root, NULL); - - /* Unlock and return. */ - res = __pthread_mutex_unlock(&global_init_done_mx); - if (res != 0) barf("init_global_thread_specific_state: unlock"); -} - -static void -init_thread_specific_state ( void ) -{ - int tid = pthread_self(); - int i; - - /* No return value yet */ - thread_specific_state[tid].ret_val = NULL; - - /* Initialise the errno and resolver state pointers. */ - thread_specific_state[tid].errno_ptr = NULL; - thread_specific_state[tid].h_errno_ptr = NULL; - thread_specific_state[tid].res_state_ptr = NULL; - - /* Initialise the per-thread libc data. */ - for (i = 0; i < _LIBC_TSD_KEY_N; i++) { - thread_specific_state[tid].libc_specifics[i] = NULL; - } - -# ifdef GLIBC_2_3 - /* Set this thread's locale to the global (default) locale. A hack - in support of glibc-2.3. - */ - __uselocale(LC_GLOBAL_LOCALE); -# endif -} - -static void -set_ret_val ( void* ret_val ) -{ - int tid; - VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - thread_specific_state[tid].ret_val = ret_val; -} - -static void * -get_ret_val ( void ) -{ - int tid; - VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - return thread_specific_state[tid].ret_val; -} - -int* __errno_location ( void ) -{ - int tid; - - ensure_valgrind("__errno_location"); - VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - /* 'cos I'm paranoid ... */ - if (tid < 1 || tid >= VG_N_THREADS) - barf("__errno_location: invalid ThreadId"); - if (thread_specific_state[tid].errno_ptr == NULL) { - if ((get_gs() & 7) == 3) - thread_specific_state[tid].errno_ptr = dlsym(RTLD_DEFAULT, "errno"); - else if (tid == 1) - thread_specific_state[tid].errno_ptr = dlvsym(RTLD_DEFAULT, "errno", "GLIBC_2.0"); - else - thread_specific_state[tid].errno_ptr = &thread_specific_state[tid].errno_data; - } - return thread_specific_state[tid].errno_ptr; -} - -int* __h_errno_location ( void ) -{ - int tid; - /* ensure_valgrind("__h_errno_location"); */ - VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - /* 'cos I'm paranoid ... */ - if (tid < 1 || tid >= VG_N_THREADS) - barf("__h_errno_location: invalid ThreadId"); - if (thread_specific_state[tid].h_errno_ptr == NULL) { - if ((get_gs() & 7) == 3) - thread_specific_state[tid].h_errno_ptr = dlsym(RTLD_DEFAULT, "h_errno"); - else if (tid == 1) - thread_specific_state[tid].h_errno_ptr = dlvsym(RTLD_DEFAULT, "h_errno", "GLIBC_2.0"); - else - thread_specific_state[tid].h_errno_ptr = &thread_specific_state[tid].h_errno_data; - } - return thread_specific_state[tid].h_errno_ptr; -} - -struct __res_state* __res_state ( void ) -{ - int tid; - /* ensure_valgrind("__res_state"); */ - VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */, - VG_USERREQ__PTHREAD_GET_THREADID, - 0, 0, 0, 0); - /* 'cos I'm paranoid ... */ - if (tid < 1 || tid >= VG_N_THREADS) - barf("__res_state: invalid ThreadId"); - if (thread_specific_state[tid].res_state_ptr == NULL) { - if ((get_gs() & 7) == 3) { - struct __res_state **resp = dlsym(RTLD_DEFAULT, "__resp"); - - thread_specific_state[tid].res_state_ptr = *resp; - } else if (tid == 1) { - thread_specific_state[tid].res_state_ptr = dlvsym(RTLD_DEFAULT, "_res", "GLIBC_2.0"); - } else { - thread_specific_state[tid].res_state_ptr = &thread_specific_state[tid].res_state_data; - } - } - return thread_specific_state[tid].res_state_ptr; -} - - -/* --------------------------------------------------- - LIBC-PRIVATE SPECIFIC DATA - ------------------------------------------------ */ - -static int -libc_internal_tsd_set ( enum __libc_tsd_key_t key, - const void * pointer ) -{ - int tid = pthread_self(); - /* printf("SET SET SET key %d ptr %p\n", key, pointer); */ - if (key < _LIBC_TSD_KEY_MALLOC || key >= _LIBC_TSD_KEY_N) - barf("libc_internal_tsd_set: invalid key"); - init_global_thread_specific_state(); - thread_specific_state[tid].libc_specifics[key] = (void *)pointer; - return 0; -} - -static void * -libc_internal_tsd_get ( enum __libc_tsd_key_t key ) -{ - int tid = pthread_self(); - /* printf("GET GET GET key %d\n", key); */ - if (key < _LIBC_TSD_KEY_MALLOC || key >= _LIBC_TSD_KEY_N) - barf("libc_internal_tsd_get: invalid key"); - init_global_thread_specific_state(); - return thread_specific_state[tid].libc_specifics[key]; -} - - -int (*__libc_internal_tsd_set) - (enum __libc_tsd_key_t key, const void * pointer) - = libc_internal_tsd_set; - -void* (*__libc_internal_tsd_get) - (enum __libc_tsd_key_t key) - = libc_internal_tsd_get; - - -#ifdef GLIBC_2_3 -/* This one was first spotted be me in the glibc-2.2.93 sources. */ -static void** -libc_internal_tsd_address ( enum __libc_tsd_key_t key ) -{ - int tid = pthread_self(); - /* printf("ADDR ADDR ADDR key %d\n", key); */ - if (key < _LIBC_TSD_KEY_MALLOC || key >= _LIBC_TSD_KEY_N) - barf("libc_internal_tsd_address: invalid key"); - init_global_thread_specific_state(); - return &thread_specific_state[tid].libc_specifics[key]; -} - -void ** (*__libc_internal_tsd_address) - (enum __libc_tsd_key_t key) - = libc_internal_tsd_address; -#endif - - -/* --------------------------------------------------------------------- - These are here (I think) because they are deemed cancellation - points by POSIX. For the moment we'll simply pass the call along - to the corresponding thread-unaware (?) libc routine. - ------------------------------------------------------------------ */ - -static void *libpthread_handle; - -#define FORWARD(name, altname, args...) \ - ({ \ - static name##_t name##_ptr = NULL; \ - if (libpthread_handle == NULL) { \ - libpthread_handle = dlopen("libpthread.so.0", RTLD_LAZY); \ - my_assert(libpthread_handle != NULL); \ - } \ - if (name##_ptr == NULL) { \ - if ((name##_ptr = (name##_t)dlsym(RTLD_NEXT, #name)) == NULL) \ - name##_ptr = (name##_t)dlsym(RTLD_DEFAULT, #altname); \ - my_assert(name##_ptr != NULL && name##_ptr != dlsym(libpthread_handle, #name)); \ - } \ - name##_ptr(args); \ - }) - -typedef -int (*sigaction_t) - (int signum, - const struct sigaction *act, - struct sigaction *oldact); -int sigaction(int signum, - const struct sigaction *act, - struct sigaction *oldact) -{ - __my_pthread_testcancel(); -#ifdef GLIBC_2_1 - return FORWARD(sigaction, __sigaction, signum, act, oldact); -#else - return FORWARD(sigaction, __libc_sigaction, signum, act, oldact); -#endif -} - -typedef -int (*accept_t)(int fd, struct sockaddr *addr, socklen_t *len); - -WEAK -int accept(int fd, struct sockaddr *addr, socklen_t *len) -{ - __my_pthread_testcancel(); - return FORWARD(accept, __libc_accept, fd, addr, len); -} - -typedef -int (*connect_t)(int sockfd, - const struct sockaddr *serv_addr, - socklen_t addrlen); -WEAK -int connect(int sockfd, - const struct sockaddr *serv_addr, - socklen_t addrlen) -{ - __my_pthread_testcancel(); - return FORWARD(connect, __libc_connect, sockfd, serv_addr, addrlen); -} - - -typedef -int (*fcntl_t)(int fd, int cmd, long arg); -WEAK -int fcntl(int fd, int cmd, long arg) -{ - __my_pthread_testcancel(); - return FORWARD(fcntl, __libc_fcntl, fd, cmd, arg); -} - - -typedef -ssize_t (*write_t)(int fd, const void *buf, size_t count); -WEAK -ssize_t write(int fd, const void *buf, size_t count) -{ - __my_pthread_testcancel(); - return FORWARD(write, __libc_write, fd, buf, count); -} - - -typedef -ssize_t (*read_t)(int fd, void *buf, size_t count); -WEAK -ssize_t read(int fd, void *buf, size_t count) -{ - __my_pthread_testcancel(); - return FORWARD(read, __libc_read, fd, buf, count); -} - -typedef -int (*open64_t)(const char *pathname, int flags, mode_t mode); -/* WEAK */ -int open64(const char *pathname, int flags, mode_t mode) -{ - return FORWARD(open64, __libc_open64, pathname, flags, mode); -} - -typedef -int (*open_t)(const char *pathname, int flags, mode_t mode); -/* WEAK */ -int open(const char *pathname, int flags, mode_t mode) -{ - return FORWARD(open, __libc_open, pathname, flags, mode); -} - -typedef -int (*close_t)(int fd); -WEAK -int close(int fd) -{ - __my_pthread_testcancel(); - return FORWARD(close, __libc_close, fd); -} - - -typedef -pid_t (*waitpid_t)(pid_t pid, int *status, int options); -WEAK -pid_t waitpid(pid_t pid, int *status, int options) -{ - __my_pthread_testcancel(); - return FORWARD(waitpid, __libc_waitpid, pid, status, options); -} - - -typedef -int (*__nanosleep_t)(const struct timespec *req, struct timespec *rem); -WEAK -int __nanosleep(const struct timespec *req, struct timespec *rem) -{ - __my_pthread_testcancel(); - return FORWARD(__nanosleep, __libc_nanosleep, req, rem); -} - -typedef -int (*pause_t)(void); -WEAK -int pause(void) -{ - __my_pthread_testcancel(); - return FORWARD(pause, __libc_pause); -} - - -typedef -int (*__tcdrain_t)(int fd); -WEAK -int __tcdrain(int fd) -{ - __my_pthread_testcancel(); - return FORWARD(__tcdrain, __libc_tcdrain, fd); -} - - -typedef -int (*fsync_t)(int fd); -WEAK -int fsync(int fd) -{ - __my_pthread_testcancel(); - return FORWARD(fsync, __libc_fsync, fd); -} - - -typedef -off_t (*lseek_t)(int fildes, off_t offset, int whence); -WEAK -off_t lseek(int fildes, off_t offset, int whence) -{ - __my_pthread_testcancel(); - return FORWARD(lseek, __libc_lseek, fildes, offset, whence); -} - - -typedef -__off64_t (*lseek64_t)(int fildes, __off64_t offset, int whence); -WEAK -__off64_t lseek64(int fildes, __off64_t offset, int whence) -{ - __my_pthread_testcancel(); - return FORWARD(lseek64, __libc_lseek64, fildes, offset, whence); -} - - -typedef -ssize_t (*__pread64_t) (int __fd, void *__buf, size_t __nbytes, - __off64_t __offset); -ssize_t __pread64 (int __fd, void *__buf, size_t __nbytes, - __off64_t __offset) -{ - __my_pthread_testcancel(); - return FORWARD(__pread64, __libc_pread64, __fd, __buf, __nbytes, __offset); -} - - -typedef -ssize_t (*__pwrite64_t) (int __fd, const void *__buf, size_t __nbytes, - __off64_t __offset); -ssize_t __pwrite64 (int __fd, const void *__buf, size_t __nbytes, - __off64_t __offset) -{ - __my_pthread_testcancel(); - return FORWARD(__pwrite64, __libc_pwrite64, __fd, __buf, __nbytes, __offset); -} - - -typedef -ssize_t (*pwrite_t)(int fd, const void *buf, size_t count, off_t offset); -WEAK -ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) -{ - __my_pthread_testcancel(); - return FORWARD(pwrite, __libc_pwrite, fd, buf, count, offset); -} - - -typedef -ssize_t (*pread_t)(int fd, void *buf, size_t count, off_t offset); -WEAK -ssize_t pread(int fd, void *buf, size_t count, off_t offset) -{ - __my_pthread_testcancel(); - return FORWARD(pread, __libc_pread, fd, buf, count, offset); -} - -typedef -int (*recv_t)(int s, void *msg, size_t len, int flags); -WEAK -int recv(int s, void *msg, size_t len, int flags) -{ - __my_pthread_testcancel(); - return FORWARD(recv, __libc_recv, s, msg, len, flags); -} - -typedef -int (*send_t)(int s, const void *msg, size_t len, int flags); -WEAK -int send(int s, const void *msg, size_t len, int flags) -{ - __my_pthread_testcancel(); - return FORWARD(send, __libc_send, s, msg, len, flags); -} - - -typedef -int (*sendmsg_t)(int s, const struct msghdr *msg, int flags); -WEAK -int sendmsg(int s, const struct msghdr *msg, int flags) -{ - __my_pthread_testcancel(); - return FORWARD(sendmsg, __libc_sendmsg, s, msg, flags); -} - - -typedef -int (*recvmsg_t)(int s, struct msghdr *msg, int flags); -WEAK -int recvmsg(int s, struct msghdr *msg, int flags) -{ - __my_pthread_testcancel(); - return FORWARD(recvmsg, __libc_recvmsg, s, msg, flags); -} - - -typedef -int (*recvfrom_t)(int s, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -WEAK -int recvfrom(int s, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - __my_pthread_testcancel(); - return FORWARD(recvfrom, __libc_recfrom, s, buf, len, flags, from, fromlen); -} - - -typedef -int (*sendto_t)(int s, const void *msg, size_t len, int flags, - const struct sockaddr *to, socklen_t tolen); -WEAK -int sendto(int s, const void *msg, size_t len, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - __my_pthread_testcancel(); - return FORWARD(sendto, __libc_sendto, s, msg, len, flags, to, tolen); -} - - -typedef -int (*system_t)(const char* str); -WEAK -int system(const char* str) -{ - __my_pthread_testcancel(); - return FORWARD(system, __libc_system, str); -} - - -typedef -pid_t (*wait_t)(int *status); -WEAK -pid_t wait(int *status) -{ - __my_pthread_testcancel(); - return FORWARD(wait, __libc_wait, status); -} - - -typedef -int (*msync_t)(const void *start, size_t length, int flags); -WEAK -int msync(const void *start, size_t length, int flags) -{ - __my_pthread_testcancel(); - return FORWARD(msync, __libc_msync, start, length, flags); -} - -strong_alias(close, __close) -strong_alias(fcntl, __fcntl) -strong_alias(lseek, __lseek) -strong_alias(open, __open) -strong_alias(open64, __open64) -strong_alias(read, __read) -strong_alias(wait, __wait) -strong_alias(write, __write) -strong_alias(connect, __connect) -strong_alias(send, __send) -strong_alias(pause, __pause) - -weak_alias (__pread64, pread64) -weak_alias (__pwrite64, pwrite64) -weak_alias(__nanosleep, nanosleep) -weak_alias(__tcdrain, tcdrain) - - -typedef -void (*longjmp_t)(jmp_buf env, int val) __attribute((noreturn)); -/* not weak: WEAK */ -void longjmp(jmp_buf env, int val) -{ - FORWARD(longjmp, __libc_longjmp, env, val); -} - - -typedef void (*siglongjmp_t) (sigjmp_buf env, int val) - __attribute__ ((noreturn)); -void siglongjmp(sigjmp_buf env, int val) -{ - kludged("siglongjmp", "(it ignores cleanup handlers)"); - FORWARD(siglongjmp, __libc_siglongjmp, env, val); -} - - -/*--- fork and its helper ---*/ - -static -void run_fork_handlers ( int what ) -{ - ForkHandlerEntry entry; - int n_h, n_handlers, i, res; - - my_assert(what == 0 || what == 1 || what == 2); - - /* Fetch old counter */ - VALGRIND_MAGIC_SEQUENCE(n_handlers, -2 /* default */, - VG_USERREQ__GET_FHSTACK_USED, - 0, 0, 0, 0); - my_assert(n_handlers >= 0 && n_handlers < VG_N_FORKHANDLERSTACK); - - /* Prepare handlers (what == 0) are called in opposite order of - calls to pthread_atfork. Parent and child handlers are called - in the same order as calls to pthread_atfork. */ - if (what == 0) - n_h = n_handlers - 1; - else - n_h = 0; - - for (i = 0; i < n_handlers; i++) { - VALGRIND_MAGIC_SEQUENCE(res, -2 /* default */, - VG_USERREQ__GET_FHSTACK_ENTRY, - n_h, &entry, 0, 0); - my_assert(res == 0); - switch (what) { - case 0: if (entry.prepare) entry.prepare(); - n_h--; break; - case 1: if (entry.parent) entry.parent(); - n_h++; break; - case 2: if (entry.child) entry.child(); - n_h++; break; - default: barf("run_fork_handlers: invalid what"); - } - } - - if (what != 0 /* prepare */) { - /* Empty out the stack. */ - VALGRIND_MAGIC_SEQUENCE(res, -2 /* default */, - VG_USERREQ__SET_FHSTACK_USED, - 0, 0, 0, 0); - my_assert(res == 0); - } -} - -typedef -pid_t (*__fork_t)(void); -pid_t __fork(void) -{ - pid_t pid; - __my_pthread_testcancel(); - __pthread_mutex_lock(&pthread_atfork_lock); - - run_fork_handlers(0 /* prepare */); - pid = FORWARD(__fork, __libc_fork); - if (pid == 0) { - /* I am the child */ - run_fork_handlers(2 /* child */); - __pthread_mutex_unlock(&pthread_atfork_lock); - __pthread_mutex_init(&pthread_atfork_lock, NULL); - } else { - /* I am the parent */ - run_fork_handlers(1 /* parent */); - __pthread_mutex_unlock(&pthread_atfork_lock); - } - return pid; -} - - -pid_t __vfork(void) -{ - return __fork(); -} - - - -/* --------------------------------------------------------------------- - Hacky implementation of semaphores. - ------------------------------------------------------------------ */ - -#include - -typedef - struct { - pthread_mutex_t se_mx; - pthread_cond_t se_cv; - int count; - int waiters; - } - vg_sem_t; - -#define SEM_CHECK_MAGIC 0x5b1d0772 - -typedef - struct { - union { - vg_sem_t* p; - int i; - } shadow; - int err_check; - } - user_sem_t; - - -static vg_sem_t* se_new ( sem_t* orig ) -{ - user_sem_t* u_sem = (user_sem_t*)orig; - vg_sem_t* vg_sem; - - vg_sem = my_malloc(sizeof(vg_sem_t)); - - u_sem->shadow.p = vg_sem; - u_sem->err_check = u_sem->shadow.i ^ SEM_CHECK_MAGIC; - - return vg_sem; -} - -static vg_sem_t* se_lookup ( sem_t* orig ) -{ - user_sem_t* u_sem = (user_sem_t*) orig; - - if(!u_sem->shadow.p || ((u_sem->shadow.i ^ SEM_CHECK_MAGIC) != u_sem->err_check)) - return NULL; - - return u_sem->shadow.p; -} - -static void se_free( sem_t* orig ) -{ - user_sem_t* u_sem = (user_sem_t*) orig; - - my_free(u_sem->shadow.p); - - u_sem->shadow.p = NULL; - u_sem->err_check = 0; - - return; -} - -int sem_init(sem_t *sem, int pshared, unsigned int value) -{ - int res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_init"); - if (pshared != 0) { - pthread_error("sem_init: unsupported pshared value"); - *(__errno_location()) = ENOSYS; - return -1; - } - vg_sem = se_new(sem); - - res = pthread_mutex_init(&vg_sem->se_mx, NULL); - my_assert(res == 0); - res = pthread_cond_init(&vg_sem->se_cv, NULL); - my_assert(res == 0); - vg_sem->count = value; - vg_sem->waiters = 0; - return 0; -} - -int sem_wait ( sem_t* sem ) -{ - int res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_wait"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_wait: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - while (vg_sem->count == 0) { - ++vg_sem->waiters; - res = pthread_cond_wait(&vg_sem->se_cv, &vg_sem->se_mx); - --vg_sem->waiters; - my_assert(res == 0); - } - vg_sem->count--; - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - return 0; -} - -int sem_post ( sem_t* sem ) -{ - int res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_post"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_post: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - if (vg_sem->count == 0) { - vg_sem->count++; - res = pthread_cond_broadcast(&vg_sem->se_cv); - my_assert(res == 0); - } else { - vg_sem->count++; - } - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - return 0; -} - - -int sem_trywait ( sem_t* sem ) -{ - int ret, res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_trywait"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_trywait: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - if (vg_sem->count > 0) { - vg_sem->count--; - ret = 0; - } else { - ret = -1; - *(__errno_location()) = EAGAIN; - } - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - return ret; -} - - -int sem_getvalue(sem_t* sem, int * sval) -{ - int res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_getvalue"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_getvalue: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - *sval = vg_sem->count; - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - return 0; -} - - -int sem_destroy(sem_t * sem) -{ - /* if someone waiting on this semaphore, errno = EBUSY, return -1 */ - vg_sem_t* vg_sem; - int res; - ensure_valgrind("sem_destroy"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_destroy: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - if (vg_sem->waiters > 0) - { - *(__errno_location()) = EBUSY; - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - return -1; - } - res = pthread_cond_destroy(&vg_sem->se_cv); - my_assert(res == 0); - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0); - res = pthread_mutex_destroy(&vg_sem->se_mx); - my_assert(res == 0); - se_free(sem); - return 0; -} - - -int sem_timedwait(sem_t* sem, const struct timespec *abstime) -{ - int res; - vg_sem_t* vg_sem; - ensure_valgrind("sem_timedwait"); - vg_sem = se_lookup(sem); - if(!vg_sem) { - pthread_error("sem_timedwait: semaphore overwritten or not initialized"); - *(__errno_location()) = EINVAL; - return -1; - } - res = __pthread_mutex_lock(&vg_sem->se_mx); - my_assert(res == 0); - while ( vg_sem->count == 0 && res != ETIMEDOUT ) { - ++vg_sem->waiters; - res = pthread_cond_timedwait(&vg_sem->se_cv, &vg_sem->se_mx, abstime); - --vg_sem->waiters; - } - if ( vg_sem->count > 0 ) { - vg_sem->count--; - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0 ); - return 0; - } else { - res = __pthread_mutex_unlock(&vg_sem->se_mx); - my_assert(res == 0 ); - *(__errno_location()) = ETIMEDOUT; - return -1; - } -} - - -/* --------------------------------------------------------------------- - Reader-writer locks. - ------------------------------------------------------------------ */ - -typedef - struct { - int prefer_w; /* != 0 --> prefer writer */ - int nwait_r; /* # of waiting readers */ - int nwait_w; /* # of waiting writers */ - pthread_cond_t cv_r; /* for signalling readers */ - pthread_cond_t cv_w; /* for signalling writers */ - pthread_mutex_t mx; - int status; - /* allowed range for status: >= -1. -1 means 1 writer currently - active, >= 0 means N readers currently active. */ - } - vg_rwlock_t; - - -static pthread_mutex_t rw_new_mx = PTHREAD_MUTEX_INITIALIZER; - -#define RWLOCK_CHECK_MAGIC 0xb5d17027 - - -static void init_vg_rwlock ( vg_rwlock_t* vg_rwl ) -{ - int res = 0; - vg_rwl->prefer_w = 1; - vg_rwl->nwait_r = 0; - vg_rwl->nwait_w = 0; - vg_rwl->status = 0; - res = pthread_mutex_init(&vg_rwl->mx, NULL); - res |= pthread_cond_init(&vg_rwl->cv_r, NULL); - res |= pthread_cond_init(&vg_rwl->cv_w, NULL); - my_assert(res == 0); -} - -static vg_rwlock_t* rw_new ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - vg_pthread_rwlock_t* vg_orig; - CONVERT(rwlock, orig, vg_orig); - - res = __pthread_mutex_lock(&rw_new_mx); - my_assert(res == 0); - - rwl = my_malloc(sizeof(vg_rwlock_t)); - - vg_orig->__vg_rw_writer = rwl; - vg_orig->__vg_rw_read_waiting = (void *)((Addr)rwl ^ RWLOCK_CHECK_MAGIC); - - init_vg_rwlock(rwl); - if (vg_orig->__vg_rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP) - rwl->prefer_w = 0; - - res = __pthread_mutex_unlock(&rw_new_mx); - my_assert(res == 0); - - return rwl; -} - -static vg_rwlock_t* rw_lookup ( pthread_rwlock_t* orig ) -{ - vg_rwlock_t* rwl; - vg_pthread_rwlock_t* vg_orig; - CONVERT(rwlock, orig, vg_orig); - - if (vg_orig->__vg_rw_writer == NULL) - rwl = rw_new ((pthread_rwlock_t*)vg_orig); - else if (((Addr)vg_orig->__vg_rw_writer ^ RWLOCK_CHECK_MAGIC) == (Addr)vg_orig->__vg_rw_read_waiting) - rwl = vg_orig->__vg_rw_writer; - else - rwl = NULL; - - return rwl; -} - -static void rw_free ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - vg_pthread_rwlock_t* vg_orig; - CONVERT(rwlock, orig, vg_orig); - - rwl = vg_orig->__vg_rw_writer; - - vg_orig->__vg_rw_writer = NULL; - vg_orig->__vg_rw_read_waiting = NULL; - - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - - res = pthread_cond_destroy(&rwl->cv_w); - res |= pthread_cond_destroy(&rwl->cv_r); - res |= pthread_mutex_destroy(&rwl->mx); - my_assert(res == 0); - - my_free(rwl); - - return; -} - -int pthread_rwlock_init ( pthread_rwlock_t* orig, - const pthread_rwlockattr_t* attr ) -{ - vg_rwlock_t* rwl; - vg_pthread_rwlock_t* vg_orig; - vg_pthread_rwlockattr_t* vg_attr; - CONVERT(rwlock, orig, vg_orig); - CONVERT(rwlockattr, attr, vg_attr); - - if (0) printf ("pthread_rwlock_init\n"); - /* Install the lock preference; the remapper needs to know it. */ - if (vg_attr) - vg_orig->__vg_rw_kind = vg_attr->__vg_lockkind; - else - vg_orig->__vg_rw_kind = PTHREAD_RWLOCK_DEFAULT_NP; - /* Allocate the shadow */ - rwl = rw_new ((pthread_rwlock_t *)vg_orig); - return 0; -} - - -static -void pthread_rwlock_rdlock_CANCEL_HDLR ( void* rwl_v ) -{ - vg_rwlock_t* rwl = (vg_rwlock_t*)rwl_v; - rwl->nwait_r--; - pthread_mutex_unlock (&rwl->mx); -} - - -int pthread_rwlock_rdlock ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - - if (0) printf ("pthread_rwlock_rdlock\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_rdlock: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status < 0) { - my_assert(rwl->status == -1); - rwl->nwait_r++; - pthread_cleanup_push( pthread_rwlock_rdlock_CANCEL_HDLR, rwl ); - while (1) { - if (rwl->status == 0) break; - res = pthread_cond_wait(&rwl->cv_r, &rwl->mx); - my_assert(res == 0); - } - pthread_cleanup_pop(0); - rwl->nwait_r--; - } - my_assert(rwl->status >= 0); - rwl->status++; - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return 0; -} - - -int pthread_rwlock_tryrdlock ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - - if (0) printf ("pthread_rwlock_tryrdlock\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_tryrdlock: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status == -1) { - /* Writer active; we have to give up. */ - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return EBUSY; - } - /* Success */ - my_assert(rwl->status >= 0); - rwl->status++; - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return 0; -} - - -static -void pthread_rwlock_wrlock_CANCEL_HDLR ( void* rwl_v ) -{ - vg_rwlock_t* rwl = (vg_rwlock_t*)rwl_v; - rwl->nwait_w--; - pthread_mutex_unlock (&rwl->mx); -} - - -int pthread_rwlock_wrlock ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - - if (0) printf ("pthread_rwlock_wrlock\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_wrlock: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status != 0) { - rwl->nwait_w++; - pthread_cleanup_push( pthread_rwlock_wrlock_CANCEL_HDLR, rwl ); - while (1) { - if (rwl->status == 0) break; - res = pthread_cond_wait(&rwl->cv_w, &rwl->mx); - my_assert(res == 0); - } - pthread_cleanup_pop(0); - rwl->nwait_w--; - } - my_assert(rwl->status == 0); - rwl->status = -1; - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return 0; -} - - -int pthread_rwlock_trywrlock ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - if (0) printf ("pthread_wrlock_trywrlock\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_trywrlock: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status != 0) { - /* Reader(s) or a writer active; we have to give up. */ - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return EBUSY; - } - /* Success */ - my_assert(rwl->status == 0); - rwl->status = -1; - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return 0; -} - - -int pthread_rwlock_unlock ( pthread_rwlock_t* orig ) -{ - int res; - vg_rwlock_t* rwl; - if (0) printf ("pthread_rwlock_unlock\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_unlock: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status == 0) { - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return EPERM; - } - my_assert(rwl->status != 0); - if (rwl->status == -1) { - rwl->status = 0; - } else { - my_assert(rwl->status > 0); - rwl->status--; - } - - my_assert(rwl->status >= 0); - - if (rwl->prefer_w) { - - /* Favour waiting writers, if any. */ - if (rwl->nwait_w > 0) { - /* Writer(s) are waiting. */ - if (rwl->status == 0) { - /* We can let a writer in. */ - res = pthread_cond_signal(&rwl->cv_w); - my_assert(res == 0); - } else { - /* There are still readers active. Do nothing; eventually - they will disappear, at which point a writer will be - admitted. */ - } - } - else - /* No waiting writers. */ - if (rwl->nwait_r > 0) { - /* Let in a waiting reader. */ - res = pthread_cond_signal(&rwl->cv_r); - my_assert(res == 0); - } - - } else { - - /* Favour waiting readers, if any. */ - if (rwl->nwait_r > 0) { - /* Reader(s) are waiting; let one in. */ - res = pthread_cond_signal(&rwl->cv_r); - my_assert(res == 0); - } - else - /* No waiting readers. */ - if (rwl->nwait_w > 0 && rwl->status == 0) { - /* We have waiting writers and no active readers; let a - writer in. */ - res = pthread_cond_signal(&rwl->cv_w); - my_assert(res == 0); - } - } - - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return 0; -} - - -int pthread_rwlock_destroy ( pthread_rwlock_t *orig ) -{ - int res; - vg_rwlock_t* rwl; - if (0) printf ("pthread_rwlock_destroy\n"); - rwl = rw_lookup (orig); - if(!rwl) { - pthread_error("pthread_rwlock_destroy: lock overwritten or not initialized"); - return EINVAL; - } - res = __pthread_mutex_lock(&rwl->mx); - my_assert(res == 0); - if (rwl->status != 0 || rwl->nwait_r > 0 || rwl->nwait_w > 0) { - res = __pthread_mutex_unlock(&rwl->mx); - my_assert(res == 0); - return EBUSY; - } - rw_free (orig); - return 0; -} - - -/* Copied directly from LinuxThreads. */ -int -pthread_rwlockattr_init (pthread_rwlockattr_t *attr) -{ - vg_pthread_rwlockattr_t* vg_attr; - CONVERT(rwlockattr, attr, vg_attr); - vg_attr->__vg_lockkind = 0; - vg_attr->__vg_pshared = PTHREAD_PROCESS_PRIVATE; - return 0; -} - -/* Copied directly from LinuxThreads. */ -int -pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr) -{ - return 0; -} - -/* Copied directly from LinuxThreads. */ -int -pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared) -{ - vg_pthread_rwlockattr_t* vg_attr; - CONVERT(rwlockattr, attr, vg_attr); - - if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) - return EINVAL; - - /* For now it is not possible to shared a conditional variable. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return ENOSYS; - - vg_attr->__vg_pshared = pshared; - - return 0; -} - - - -/* --------------------------------------------------------------------- - Manage the allocation and use of RT signals. The Valgrind core - uses one. glibc needs us to implement this to make RT signals - work; things just seem to crash if we don't. - ------------------------------------------------------------------ */ -int __libc_current_sigrtmin (void) -{ - int res; - - VALGRIND_MAGIC_SEQUENCE(res, 0, - VG_USERREQ__GET_SIGRT_MIN, - 0, 0, 0, 0); - - return res; -} - -int __libc_current_sigrtmax (void) -{ - int res; - - VALGRIND_MAGIC_SEQUENCE(res, 0, - VG_USERREQ__GET_SIGRT_MAX, - 0, 0, 0, 0); - - return res; -} - -int __libc_allocate_rtsig (int high) -{ - int res; - - VALGRIND_MAGIC_SEQUENCE(res, 0, - VG_USERREQ__ALLOC_RTSIG, - high, 0, 0, 0); - - return res; -} - -/* --------------------------------------------------------------------- - B'stard. - ------------------------------------------------------------------ */ -strong_alias(__pthread_mutex_lock, pthread_mutex_lock) -strong_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock) -strong_alias(__pthread_mutex_trylock, pthread_mutex_trylock) -strong_alias(__pthread_mutex_unlock, pthread_mutex_unlock) -strong_alias(__pthread_mutexattr_init, pthread_mutexattr_init) - weak_alias(__pthread_mutexattr_settype, pthread_mutexattr_settype) - weak_alias(__pthread_mutexattr_gettype, pthread_mutexattr_gettype) - weak_alias(__pthread_mutexattr_setpshared, pthread_mutexattr_setpshared) -strong_alias(__pthread_mutex_init, pthread_mutex_init) -strong_alias(__pthread_mutexattr_destroy, pthread_mutexattr_destroy) -strong_alias(__pthread_mutex_destroy, pthread_mutex_destroy) -strong_alias(__pthread_once, pthread_once) -strong_alias(__pthread_atfork, pthread_atfork) -strong_alias(__pthread_key_create, pthread_key_create) -strong_alias(__pthread_getspecific, pthread_getspecific) -strong_alias(__pthread_setspecific, pthread_setspecific) - -#ifndef GLIBC_2_1 -strong_alias(sigaction, __sigaction) -#endif - -weak_alias(__fork, fork) -weak_alias(__vfork, vfork) -weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np) - -/*--------------------------------------------------*/ - -weak_alias(pthread_rwlock_rdlock, __pthread_rwlock_rdlock) -weak_alias(pthread_rwlock_unlock, __pthread_rwlock_unlock) -weak_alias(pthread_rwlock_wrlock, __pthread_rwlock_wrlock) - -weak_alias(pthread_rwlock_destroy, __pthread_rwlock_destroy) -weak_alias(pthread_rwlock_init, __pthread_rwlock_init) -weak_alias(pthread_rwlock_tryrdlock, __pthread_rwlock_tryrdlock) -weak_alias(pthread_rwlock_trywrlock, __pthread_rwlock_trywrlock) - - -#ifndef __UCLIBC__ -/* These are called as part of stdio to lock the FILE structure for MT - programs. Unfortunately, the lock is not always a pthreads lock - - the NPTL version uses a lighter-weight lock which uses futex - directly (and uses a structure which is smaller than - pthread_mutex). So basically, this is completely broken on recent - glibcs. */ - -#undef _IO_flockfile -void _IO_flockfile ( _IO_FILE * file ) -{ - pthread_mutex_lock(file->_lock); -} -strong_alias(_IO_flockfile, __flockfile); -weak_alias(_IO_flockfile, flockfile); - -#undef _IO_funlockfile -void _IO_funlockfile ( _IO_FILE * file ) -{ - pthread_mutex_unlock(file->_lock); -} -strong_alias(_IO_funlockfile, __funlockfile); -weak_alias(_IO_funlockfile, funlockfile); -#endif - - -/* This doesn't seem to be needed to simulate libpthread.so's external - interface, but many people complain about its absence. */ - -strong_alias(__pthread_mutexattr_settype, __pthread_mutexattr_setkind_np) -weak_alias(__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np) - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_libpthread.vs b/VEX/head20041019/coregrind/vg_libpthread.vs deleted file mode 100644 index afc76ed3f..000000000 --- a/VEX/head20041019/coregrind/vg_libpthread.vs +++ /dev/null @@ -1,201 +0,0 @@ - GLIBC_2.0 { - pthread_join; pthread_self; pthread_equal; - pthread_exit; pthread_detach; - - pthread_getschedparam; pthread_setschedparam; - - pthread_attr_destroy; - pthread_attr_getdetachstate; pthread_attr_setdetachstate; - pthread_attr_getschedparam; pthread_attr_setschedparam; - pthread_attr_getschedpolicy; pthread_attr_setschedpolicy; - pthread_attr_getinheritsched; pthread_attr_setinheritsched; - pthread_attr_getscope; pthread_attr_setscope; - - pthread_mutex_init; pthread_mutex_destroy; - pthread_mutex_lock; pthread_mutex_trylock; pthread_mutex_unlock; - - pthread_mutexattr_init; pthread_mutexattr_destroy; - - # Don't version these, because it doesn't matter for Valgrind's libpthread - #pthread_cond_init; pthread_cond_destroy; - #pthread_cond_wait; pthread_cond_timedwait; - #pthread_cond_signal; pthread_cond_broadcast; - - pthread_condattr_destroy; pthread_condattr_init; - - pthread_cancel; pthread_testcancel; - pthread_setcancelstate; pthread_setcanceltype; - - pthread_sigmask; pthread_kill; - - pthread_key_create; pthread_key_delete; - pthread_getspecific; pthread_setspecific; - - pthread_once; - - pthread_atfork; - - flockfile; funlockfile; ftrylockfile; - - # Non-standard POSIX1.x functions. - pthread_mutexattr_getkind_np; pthread_mutexattr_setkind_np; - - # Protected names for functions used in other shared objects. - __pthread_mutex_init; __pthread_mutex_destroy; - __pthread_mutex_lock; __pthread_mutex_trylock; __pthread_mutex_unlock; - __pthread_mutexattr_init; __pthread_mutexattr_destroy; - __pthread_mutexattr_settype; - __pthread_key_create; __pthread_getspecific; __pthread_setspecific; - __pthread_once; __pthread_atfork; - _IO_flockfile; _IO_ftrylockfile; _IO_funlockfile; - - # Hidden entry point (through macros). - #_pthread_cleanup_pop; _pthread_cleanup_pop_restore; _pthread_cleanup_push; - #_pthread_cleanup_push_defer; - - # Semaphores. - #sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait; - - # Special fork handling. - fork; __fork; vfork; - - # Cancellation points. - close; __close; fcntl; __fcntl; read; __read; write; __write; accept; - connect; __connect; recv; recvfrom; recvmsg; send; __send; sendmsg; sendto; - fsync; lseek; __lseek; msync; nanosleep; open; __open; pause; tcdrain; - system; wait; __wait; waitpid; - - # Hidden entry point (through macros). - _pthread_cleanup_push; _pthread_cleanup_pop; - _pthread_cleanup_push_defer; _pthread_cleanup_pop_restore; - - pthread_kill_other_threads_np; - - # The error functions. - __errno_location; __h_errno_location; - - # Functions which previously have been overwritten. - sigwait; sigaction; __sigaction; _exit; _Exit; longjmp; siglongjmp; - raise; - }; - - GLIBC_2.1 { - pthread_create; - pthread_attr_init; - - pthread_attr_getguardsize; pthread_attr_setguardsize; - pthread_attr_getstackaddr; pthread_attr_setstackaddr; - pthread_attr_getstacksize; pthread_attr_setstacksize; - - pthread_mutexattr_gettype; pthread_mutexattr_settype; - - pthread_rwlock_init; pthread_rwlock_destroy; - pthread_rwlock_rdlock; pthread_rwlock_wrlock; pthread_rwlock_unlock; - pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock; - - pthread_rwlockattr_init; pthread_rwlockattr_destroy; - pthread_rwlockattr_getpshared; pthread_rwlockattr_setpshared; - pthread_rwlockattr_getkind_np; pthread_rwlockattr_setkind_np; - - pthread_getconcurrency; pthread_setconcurrency; - - # Semaphores. - #sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait; - - __libc_current_sigrtmin; __libc_current_sigrtmax; - __libc_allocate_rtsig; - } GLIBC_2.0; - - GLIBC_2.1.1 { - sem_close; sem_open; sem_unlink; - } GLIBC_2.1; - - GLIBC_2.1.2 { - __vfork; - } GLIBC_2.1.1; - - GLIBC_2.2 { - pthread_mutexattr_getpshared; pthread_mutexattr_setpshared; - - pthread_condattr_getpshared; pthread_condattr_setpshared; - - # New functions from IEEE Std. 1003.1-2001. - pthread_mutex_timedlock; - - pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock; - - pthread_attr_getstack; pthread_attr_setstack; - - pthread_spin_destroy; pthread_spin_init; pthread_spin_lock; - pthread_spin_trylock; pthread_spin_unlock; - - pthread_barrier_init; pthread_barrier_destroy; pthread_barrier_wait; - pthread_barrierattr_destroy; pthread_barrierattr_init; - pthread_barrierattr_setpshared; - - sem_timedwait; - - pthread_yield; - - pthread_getcpuclockid; - - # Cancellation points. - lseek64; open64; __open64; pread; pread64; __pread64; pwrite; pwrite64; - __pwrite64; - - # Names used internally. - __pthread_rwlock_init; __pthread_rwlock_destroy; - __pthread_rwlock_rdlock; __pthread_rwlock_tryrdlock; - __pthread_rwlock_wrlock; __pthread_rwlock_trywrlock; - __pthread_rwlock_unlock; - - __res_state; - } GLIBC_2.1.2; - - GLIBC_2.2.3 { - # Extensions. - pthread_getattr_np; - } GLIBC_2.2; - - GLIBC_2.2.6 { - # Cancellation wrapper - __nanosleep; - } GLIBC_2.2.3; - - GLIBC_2.3.2 { - # Changed pthread_cond_t. - # Don't version these, because it doesn't matter for Valgrind's libpthread - #pthread_cond_init; pthread_cond_destroy; - #pthread_cond_wait; pthread_cond_timedwait; - #pthread_cond_signal; pthread_cond_broadcast; - } GLIBC_2.2.6; - - GLIBC_2.3.3 { - # 1003.1-2001 function accidentally left out in 2.2. - pthread_barrierattr_getpshared; - - # Unix CS option. - pthread_condattr_getclock; pthread_condattr_setclock; - - # Proposed API extensions. - pthread_tryjoin_np; pthread_timedjoin_np; - - # New cancellation cleanup handling. - __pthread_register_cancel; __pthread_unregister_cancel; - __pthread_register_cancel_defer; __pthread_unregister_cancel_restore; - __pthread_unwind_next; - __pthread_cleanup_routine; - - # New affinity interfaces. - pthread_getaffinity_np; pthread_setaffinity_np; - pthread_attr_getaffinity_np; pthread_attr_setaffinity_np; - } GLIBC_2.3.2; - - GLIBC_PRIVATE { - global: - __pthread_initialize_minimal; __pthread_cleanup_upto; - __pthread_clock_gettime; __pthread_clock_settime; - __pthread_unwind; - local: - __pthread_clock_gettime_*; __pthread_clock_settime_*; - }; diff --git a/VEX/head20041019/coregrind/vg_libpthread_unimp.c b/VEX/head20041019/coregrind/vg_libpthread_unimp.c deleted file mode 100644 index f40c57d9c..000000000 --- a/VEX/head20041019/coregrind/vg_libpthread_unimp.c +++ /dev/null @@ -1,250 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Give dummy bindings for everything the real libpthread.so ---*/ -/*--- binds. vg_libpthread_unimp.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* --------------------------------------------------------------------- - ALL THIS CODE RUNS ON THE SIMULATED CPU. - Give a binding for everything the real libpthread.so binds. - ------------------------------------------------------------------ */ - -# define strong_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((alias (#name))); - -# define weak_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); - -# define symbol_version(real, name, version) \ - __asm__(".symver " #real "," #name "@" #version) - -# define default_symbol_version(real, name, version) \ - __asm__(".symver " #real "," #name "@@" #version) - -extern void vgPlain_unimp ( char* ); -#define unimp(str) vgPlain_unimp(str) - -//void _IO_flockfile ( void ) { unimp("_IO_flockfile"); } -void _IO_ftrylockfile ( void ) { unimp("_IO_ftrylockfile"); } -//void _IO_funlockfile ( void ) { unimp("_IO_funlockfile"); } -//void __close ( void ) { unimp("__close"); } -//void __connect ( void ) { unimp("__connect"); } -//void __errno_location ( void ) { unimp("__errno_location"); } -//void __fcntl ( void ) { unimp("__fcntl"); } -//void __fork ( void ) { unimp("__fork"); } -//void __h_errno_location ( void ) { unimp("__h_errno_location"); } -//void __libc_allocate_rtsig ( void ) { unimp("__libc_allocate_rtsig"); } -//void __libc_current_sigrtmax ( void ) { unimp("__libc_current_sigrtmax"); } -//void __libc_current_sigrtmin ( void ) { unimp("__libc_current_sigrtmin"); } -//void __lseek ( void ) { unimp("__lseek"); } -//void __open ( void ) { unimp("__open"); } -//void __open64 ( void ) { unimp("__open64"); } -//void __pread64 ( void ) { unimp("__pread64"); } -//void __pthread_atfork ( void ) { unimp("__pthread_atfork"); } -//void __pthread_getspecific ( void ) { unimp("__pthread_getspecific"); } -//void __pthread_key_create ( void ) { unimp("__pthread_key_create"); } -//void __pthread_kill_other_threads_np ( void ) { unimp("__pthread_kill_other_threads_np"); } -//void __pthread_mutex_destroy ( void ) { unimp("__pthread_mutex_destroy"); } -//void __pthread_mutex_init ( void ) { unimp("__pthread_mutex_init"); } -//void __pthread_mutex_lock ( void ) { unimp("__pthread_mutex_lock"); } -//void __pthread_mutex_trylock ( void ) { unimp("__pthread_mutex_trylock"); } -//void __pthread_mutex_unlock ( void ) { unimp("__pthread_mutex_unlock"); } -//void __pthread_mutexattr_destroy ( void ) { unimp("__pthread_mutexattr_destroy"); } -//void __pthread_mutexattr_init ( void ) { unimp("__pthread_mutexattr_init"); } -//void __pthread_mutexattr_settype ( void ) { unimp("__pthread_mutexattr_settype"); } -//void __pthread_once ( void ) { unimp("__pthread_once"); } -//void __pthread_setspecific ( void ) { unimp("__pthread_setspecific"); } -//void __pwrite64 ( void ) { unimp("__pwrite64"); } -//void __read ( void ) { unimp("__read"); } -//void __res_state ( void ) { unimp("__res_state"); } -//void __send ( void ) { unimp("__send"); } -//void __sigaction ( void ) { unimp("__sigaction"); } -//--//void __vfork ( void ) { unimp("__vfork"); } -//void __wait ( void ) { unimp("__wait"); } -//void __write ( void ) { unimp("__write"); } -//void _pthread_cleanup_pop ( void ) { unimp("_pthread_cleanup_pop"); } -//void _pthread_cleanup_pop_restore ( void ) { unimp("_pthread_cleanup_pop_restore"); } -//void _pthread_cleanup_push ( void ) { unimp("_pthread_cleanup_push"); } -//void _pthread_cleanup_push_defer ( void ) { unimp("_pthread_cleanup_push_defer"); } -//void longjmp ( void ) { unimp("longjmp"); } -//void pthread_atfork ( void ) { unimp("pthread_atfork"); } -//void pthread_attr_destroy ( void ) { unimp("pthread_attr_destroy"); } -//void pthread_attr_getdetachstate ( void ) { unimp("pthread_attr_getdetachstate"); } -//void pthread_attr_getinheritsched ( void ) { unimp("pthread_attr_getinheritsched"); } -//void pthread_attr_getschedparam ( void ) { unimp("pthread_attr_getschedparam"); } -//void pthread_attr_getschedpolicy ( void ) { unimp("pthread_attr_getschedpolicy"); } -//void pthread_attr_getscope ( void ) { unimp("pthread_attr_getscope"); } - -//void pthread_attr_setdetachstate ( void ) { unimp("pthread_attr_setdetachstate"); } -//void pthread_attr_setinheritsched ( void ) { unimp("pthread_attr_setinheritsched"); } -//void pthread_attr_setschedparam ( void ) { unimp("pthread_attr_setschedparam"); } -//void pthread_attr_setschedpolicy ( void ) { unimp("pthread_attr_setschedpolicy"); } -//void pthread_attr_setscope ( void ) { unimp("pthread_attr_setscope"); } -void pthread_barrier_destroy ( void ) { unimp("pthread_barrier_destroy"); } -void pthread_barrier_init ( void ) { unimp("pthread_barrier_init"); } -void pthread_barrier_wait ( void ) { unimp("pthread_barrier_wait"); } -void pthread_barrierattr_destroy ( void ) { unimp("pthread_barrierattr_destroy"); } -void pthread_barrierattr_init ( void ) { unimp("pthread_barrierattr_init"); } -void pthread_barrierattr_setpshared ( void ) { unimp("pthread_barrierattr_setpshared"); } -//void pthread_cancel ( void ) { unimp("pthread_cancel"); } -//void pthread_cond_broadcast ( void ) { unimp("pthread_cond_broadcast"); } -//void pthread_cond_destroy ( void ) { unimp("pthread_cond_destroy"); } -//void pthread_cond_init ( void ) { unimp("pthread_cond_init"); } -//void pthread_cond_signal ( void ) { unimp("pthread_cond_signal"); } -//void pthread_cond_timedwait ( void ) { unimp("pthread_cond_timedwait"); } -//void pthread_cond_wait ( void ) { unimp("pthread_cond_wait"); } -//void pthread_condattr_destroy ( void ) { unimp("pthread_condattr_destroy"); } -void pthread_condattr_getpshared ( void ) { unimp("pthread_condattr_getpshared"); } -//void pthread_condattr_init ( void ) { unimp("pthread_condattr_init"); } -void pthread_condattr_setpshared ( void ) { unimp("pthread_condattr_setpshared"); } -//void pthread_detach ( void ) { unimp("pthread_detach"); } -//void pthread_equal ( void ) { unimp("pthread_equal"); } -//void pthread_exit ( void ) { unimp("pthread_exit"); } -//void pthread_getattr_np ( void ) { unimp("pthread_getattr_np"); } -void pthread_getcpuclockid ( void ) { unimp("pthread_getcpuclockid"); } -//void pthread_getschedparam ( void ) { unimp("pthread_getschedparam"); } -//void pthread_getspecific ( void ) { unimp("pthread_getspecific"); } -//void pthread_join ( void ) { unimp("pthread_join"); } -//void pthread_key_create ( void ) { unimp("pthread_key_create"); } -//void pthread_key_delete ( void ) { unimp("pthread_key_delete"); } -//void pthread_kill ( void ) { unimp("pthread_kill"); } -//void pthread_mutex_destroy ( void ) { unimp("pthread_mutex_destroy"); } -//void pthread_mutex_init ( void ) { unimp("pthread_mutex_init"); } -//void pthread_mutex_lock ( void ) { unimp("pthread_mutex_lock"); } -//void pthread_mutex_timedlock ( void ) { unimp("pthread_mutex_timedlock"); } -//void pthread_mutex_trylock ( void ) { unimp("pthread_mutex_trylock"); } -//void pthread_mutex_unlock ( void ) { unimp("pthread_mutex_unlock"); } -//void pthread_mutexattr_destroy ( void ) { unimp("pthread_mutexattr_destroy"); } -//void pthread_mutexattr_init ( void ) { unimp("pthread_mutexattr_init"); } -//void pthread_once ( void ) { unimp("pthread_once"); } -//void pthread_rwlock_destroy ( void ) { unimp("pthread_rwlock_destroy"); } -//void pthread_rwlock_init ( void ) { unimp("pthread_rwlock_init"); } -//void pthread_rwlock_rdlock ( void ) { unimp("pthread_rwlock_rdlock"); } -void pthread_rwlock_timedrdlock ( void ) { unimp("pthread_rwlock_timedrdlock"); } -void pthread_rwlock_timedwrlock ( void ) { unimp("pthread_rwlock_timedwrlock"); } -//void pthread_rwlock_tryrdlock ( void ) { unimp("pthread_rwlock_tryrdlock"); } -//void pthread_rwlock_trywrlock ( void ) { unimp("pthread_rwlock_trywrlock"); } -//void pthread_rwlock_unlock ( void ) { unimp("pthread_rwlock_unlock"); } -//void pthread_rwlock_wrlock ( void ) { unimp("pthread_rwlock_wrlock"); } -//void pthread_rwlockattr_destroy ( void ) { unimp("pthread_rwlockattr_destroy"); } -void pthread_rwlockattr_getkind_np ( void ) { unimp("pthread_rwlockattr_getkind_np"); } -void pthread_rwlockattr_getpshared ( void ) { unimp("pthread_rwlockattr_getpshared"); } -//void pthread_rwlockattr_init ( void ) { unimp("pthread_rwlockattr_init"); } -void pthread_rwlockattr_setkind_np ( void ) { unimp("pthread_rwlockattr_setkind_np"); } -//void pthread_rwlockattr_setpshared ( void ) { unimp("pthread_rwlockattr_setpshared"); } -//void pthread_self ( void ) { unimp("pthread_self"); } -//void pthread_setcancelstate ( void ) { unimp("pthread_setcancelstate"); } -//void pthread_setcanceltype ( void ) { unimp("pthread_setcanceltype"); } -//void pthread_setschedparam ( void ) { unimp("pthread_setschedparam"); } -//void pthread_setspecific ( void ) { unimp("pthread_setspecific"); } -//void pthread_sigmask ( void ) { unimp("pthread_sigmask"); } -//void pthread_testcancel ( void ) { unimp("pthread_testcancel"); } -//void raise ( void ) { unimp("raise"); } -void sem_close ( void ) { unimp("sem_close"); } -void sem_open ( void ) { unimp("sem_open"); } -//void sem_timedwait ( void ) { unimp("sem_timedwait"); } -void sem_unlink ( void ) { unimp("sem_unlink"); } -//void sigaction ( void ) { unimp("sigaction"); } -//void siglongjmp ( void ) { unimp("siglongjmp"); } -//void sigwait ( void ) { unimp("sigwait"); } - -void __pthread_clock_gettime_private ( void ) { unimp("__pthread_clock_gettime"); } -void __pthread_clock_settime_private ( void ) { unimp("__pthread_clock_settime"); } -strong_alias(__pthread_clock_gettime_private, __pthread_clock_gettime_223); -strong_alias(__pthread_clock_settime_private, __pthread_clock_settime_223); -symbol_version(__pthread_clock_gettime_223, __pthread_clock_gettime, GLIBC_2.2.3); -symbol_version(__pthread_clock_settime_223, __pthread_clock_settime, GLIBC_2.2.3); -default_symbol_version(__pthread_clock_gettime_private, __pthread_clock_gettime, GLIBC_PRIVATE); -default_symbol_version(__pthread_clock_settime_private, __pthread_clock_settime, GLIBC_PRIVATE); - - - -//weak_alias(pthread_rwlock_destroy, __pthread_rwlock_destroy) -//weak_alias(pthread_rwlock_init, __pthread_rwlock_init) -//weak_alias(pthread_rwlock_tryrdlock, __pthread_rwlock_tryrdlock) -//weak_alias(pthread_rwlock_trywrlock, __pthread_rwlock_trywrlock) -//weak_alias(pthread_rwlock_wrlock, __pthread_rwlock_wrlock) -weak_alias(_IO_ftrylockfile, ftrylockfile) - -//__attribute__((weak)) void pread ( void ) { vgPlain_unimp("pread"); } -//__attribute__((weak)) void pwrite ( void ) { vgPlain_unimp("pwrite"); } -//__attribute__((weak)) void msync ( void ) { vgPlain_unimp("msync"); } -//__attribute__((weak)) void pause ( void ) { vgPlain_unimp("pause"); } -//__attribute__((weak)) void recvfrom ( void ) { vgPlain_unimp("recvfrom"); } -//__attribute__((weak)) void recvmsg ( void ) { vgPlain_unimp("recvmsg"); } -//__attribute__((weak)) void sendmsg ( void ) { vgPlain_unimp("sendmsg"); } -//__attribute__((weak)) void tcdrain ( void ) { vgPlain_unimp("tcdrain"); } -//--//__attribute__((weak)) void vfork ( void ) { vgPlain_unimp("vfork"); } - -//__attribute__((weak)) void pthread_attr_getguardsize ( void ) -// { vgPlain_unimp("pthread_attr_getguardsize"); } -//__attribute__((weak)) void pthread_attr_getstack ( void ) -// { vgPlain_unimp("pthread_attr_getstack"); } -__attribute__((weak)) void pthread_attr_getstackaddr ( void ) - { vgPlain_unimp("pthread_attr_getstackaddr"); } -__attribute__((weak)) void pthread_attr_getstacksize ( void ) - { vgPlain_unimp("pthread_attr_getstacksize"); } -//__attribute__((weak)) void pthread_attr_setguardsize ( void ) -// { vgPlain_unimp("pthread_attr_setguardsize"); } -__attribute__((weak)) void pthread_attr_setstack ( void ) - { vgPlain_unimp("pthread_attr_setstack"); } -__attribute__((weak)) void pthread_attr_setstackaddr ( void ) - { vgPlain_unimp("pthread_attr_setstackaddr"); } -//__attribute__((weak)) void pthread_attr_setstacksize ( void ) -// { vgPlain_unimp("pthread_attr_setstacksize"); } -//__attribute__((weak)) void pthread_getconcurrency ( void ) -// { vgPlain_unimp("pthread_getconcurrency"); } -//__attribute__((weak)) void pthread_kill_other_threads_np ( void ) -// { vgPlain_unimp("pthread_kill_other_threads_np"); } -__attribute__((weak)) void pthread_mutexattr_getkind_np ( void ) - { vgPlain_unimp("pthread_mutexattr_getkind_np"); } -__attribute__((weak)) void pthread_mutexattr_getpshared ( void ) - { vgPlain_unimp("pthread_mutexattr_getpshared"); } -//__attribute__((weak)) void pthread_mutexattr_gettype ( void ) -// { vgPlain_unimp("pthread_mutexattr_gettype"); } -__attribute__((weak)) void pthread_mutexattr_setkind_np ( void ) - { vgPlain_unimp("pthread_mutexattr_setkind_np"); } -//__attribute__((weak)) void pthread_mutexattr_setpshared ( void ) -// { vgPlain_unimp("pthread_mutexattr_setpshared"); } -//__attribute__((weak)) void pthread_setconcurrency ( void ) -// { vgPlain_unimp("pthread_setconcurrency"); } -//__attribute__((weak)) void pthread_spin_destroy ( void ) -// { vgPlain_unimp("pthread_spin_destroy"); } -//__attribute__((weak)) void pthread_spin_init ( void ) -// { vgPlain_unimp("pthread_spin_init"); } -//__attribute__((weak)) void pthread_spin_lock ( void ) -// { vgPlain_unimp("pthread_spin_lock"); } -//__attribute__((weak)) void pthread_spin_trylock ( void ) -// { vgPlain_unimp("pthread_spin_trylock"); } -//__attribute__((weak)) void pthread_spin_unlock ( void ) -// { vgPlain_unimp("pthread_spin_unlock"); } - - -/*--------------------------------------------------------------------*/ -/*--- end vg_libpthread_unimp.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/coregrind/vg_main.c b/VEX/head20041019/coregrind/vg_main.c deleted file mode 100644 index 8eda2adea..000000000 --- a/VEX/head20041019/coregrind/vg_main.c +++ /dev/null @@ -1,2964 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Startup: the real stuff vg_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#define _FILE_OFFSET_BITS 64 - -#include "core.h" -#include "ume.h" -#include "../../pub/libvex.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef AT_DCACHEBSIZE -#define AT_DCACHEBSIZE 19 -#endif /* AT_DCACHEBSIZE */ - -#ifndef AT_ICACHEBSIZE -#define AT_ICACHEBSIZE 20 -#endif /* AT_ICACHEBSIZE */ - -#ifndef AT_UCACHEBSIZE -#define AT_UCACHEBSIZE 21 -#endif /* AT_UCACHEBSIZE */ - -#ifndef AT_SYSINFO -#define AT_SYSINFO 32 -#endif /* AT_SYSINFO */ - -#ifndef AT_SYSINFO_EHDR -#define AT_SYSINFO_EHDR 33 -#endif /* AT_SYSINFO_EHDR */ - -#ifndef AT_SECURE -#define AT_SECURE 23 /* secure mode boolean */ -#endif /* AT_SECURE */ - -/* redzone gap between client address space and shadow */ -#define REDZONE_SIZE (1 * 1024*1024) - -/* size multiple for client address space */ -#define CLIENT_SIZE_MULTIPLE (1 * 1024*1024) - -/* Proportion of client space for its heap (rest is for mmaps + stack) */ -#define CLIENT_HEAP_PROPORTION 0.333 - -/*====================================================================*/ -/*=== Global entities not referenced from generated code ===*/ -/*====================================================================*/ - -/* --------------------------------------------------------------------- - Startup stuff - ------------------------------------------------------------------ */ -/* linker-defined base address */ -extern char kickstart_base; - -/* Client address space, lowest to highest (see top of ume.c) */ -Addr VG_(client_base); /* client address space limits */ -Addr VG_(client_end); -Addr VG_(client_mapbase); -Addr VG_(client_trampoline_code); -Addr VG_(clstk_base); -Addr VG_(clstk_end); - -Addr VG_(brk_base); /* start of brk */ -Addr VG_(brk_limit); /* current brk */ - -Addr VG_(shadow_base); /* tool's shadow memory */ -Addr VG_(shadow_end); - -Addr VG_(valgrind_base); /* valgrind's address range */ - -// Note that VG_(valgrind_last) names the last byte of the section, whereas -// the VG_(*_end) vars name the byte one past the end of the section. -Addr VG_(valgrind_last); - -vki_rlimit VG_(client_rlimit_data); -vki_rlimit VG_(client_rlimit_stack); - -/* This is set early to indicate whether this CPU has the - SSE/fxsave/fxrestor features. */ -Bool VG_(have_ssestate); - -/* stage1 (main) executable */ -static Int vgexecfd = -1; - -/* client executable */ -Int VG_(clexecfd) = -1; - -/* Path to library directory */ -const Char *VG_(libdir) = VG_LIBDIR; - -/* our argc/argv */ -static Int vg_argc; -static Char **vg_argv; - -/* PID of the main thread */ -Int VG_(main_pid); - -/* PGRP of process */ -Int VG_(main_pgrp); - -/* Application-visible file descriptor limits */ -Int VG_(fd_soft_limit) = -1; -Int VG_(fd_hard_limit) = -1; - -/* As deduced from esp_at_startup, the client's argc, argv[] and - envp[] as extracted from the client's stack at startup-time. */ -Int VG_(client_argc); -Char** VG_(client_argv); -Char** VG_(client_envp); - -/* --------------------------------------------------------------------- - Running stuff - ------------------------------------------------------------------ */ - -/* Counts downwards in VG_(run_innerloop). */ -UInt VG_(dispatch_ctr); - -/* 64-bit counter for the number of basic blocks done. */ -ULong VG_(bbs_done) = 0; - -/* Tell the logging mechanism whether we are logging to a file - descriptor or a socket descriptor. */ -Bool VG_(logging_to_filedes) = True; - - -/*====================================================================*/ -/*=== Counters, for profiling purposes only ===*/ -/*====================================================================*/ - -// These ones maintained by vg_dispatch.S -UInt VG_(bb_enchain_count) = 0; // Number of chain operations done -UInt VG_(bb_dechain_count) = 0; // Number of unchain operations done -UInt VG_(unchained_jumps_done) = 0; // Number of unchained jumps done - -/* Counts pertaining to internal sanity checking. */ -static UInt sanity_fast_count = 0; -static UInt sanity_slow_count = 0; - -static void print_all_stats ( void ) -{ - // Translation stats - VG_(print_tt_tc_stats)(); - VG_(message)(Vg_DebugMsg, - "chainings: %d chainings, %d unchainings.", - VG_(bb_enchain_count), VG_(bb_dechain_count) ); - VG_(message)(Vg_DebugMsg, - " dispatch: %llu jumps (bb entries); of them %u (%lu%%) unchained.", - VG_(bbs_done), - VG_(unchained_jumps_done), - ((ULong)(100) * (ULong)(VG_(unchained_jumps_done))) - / ( VG_(bbs_done)==0 ? 1 : VG_(bbs_done) ) - ); - - // Scheduler stats - VG_(print_scheduler_stats)(); - - // Reg-alloc stats - VG_(print_reg_alloc_stats)(); - VG_(message)(Vg_DebugMsg, - " sanity: %d cheap, %d expensive checks.", - sanity_fast_count, sanity_slow_count ); - - // C call stats - //VG_(print_ccall_stats)(); - - // UInstr histogram - //if (VG_(clo_verbosity) > 3) - // VG_(print_UInstr_histogram)(); - - // Memory stats - if (VG_(clo_verbosity) > 2) { - VG_(message)(Vg_DebugMsg, ""); - VG_(message)(Vg_DebugMsg, - "------ Valgrind's internal memory use stats follow ------" ); - VG_(sanity_check_malloc_all)(); - VG_(print_all_arena_stats)(); - VG_(message)(Vg_DebugMsg, ""); - VG_(message)(Vg_DebugMsg, - "------ Valgrind's ExeContext management stats follow ------" ); - VG_(print_ExeContext_stats)(); - } -} - - -/*====================================================================*/ -/*=== Miscellaneous global functions ===*/ -/*====================================================================*/ - -static Int ptrace_setregs(Int pid, ThreadId tid) -{ - if (VG_(is_running_thread)( tid )) - return VGA_(ptrace_setregs_from_BB)(pid); - else - return VGA_(ptrace_setregs_from_tst)(pid, &VG_(threads)[tid].arch); -} - -/* Start debugger and get it to attach to this process. Called if the - user requests this service after an error has been shown, so she can - poke around and look at parameters, memory, etc. You can't - meaningfully get the debugger to continue the program, though; to - continue, quit the debugger. */ -void VG_(start_debugger) ( Int tid ) -{ - Int pid; - - if ((pid = fork()) == 0) { - ptrace(PTRACE_TRACEME, 0, NULL, NULL); - VG_(kkill)(VG_(getpid)(), VKI_SIGSTOP); - - } else if (pid > 0) { - Int status; - Int res; - - if ((res = VG_(waitpid)(pid, &status, 0)) == pid && - WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP && - ptrace_setregs(pid, tid) == 0 && - kill(pid, SIGSTOP) == 0 && - ptrace(PTRACE_DETACH, pid, NULL, 0) == 0) { - Char pidbuf[15]; - Char file[30]; - Char buf[100]; - Char *bufptr; - Char *cmdptr; - - VG_(sprintf)(pidbuf, "%d", pid); - VG_(sprintf)(file, "/proc/%d/fd/%d", pid, VG_(clexecfd)); - - bufptr = buf; - cmdptr = VG_(clo_db_command); - - while (*cmdptr) { - switch (*cmdptr) { - case '%': - switch (*++cmdptr) { - case 'f': - VG_(memcpy)(bufptr, file, VG_(strlen)(file)); - bufptr += VG_(strlen)(file); - cmdptr++; - break; - case 'p': - VG_(memcpy)(bufptr, pidbuf, VG_(strlen)(pidbuf)); - bufptr += VG_(strlen)(pidbuf); - cmdptr++; - break; - default: - *bufptr++ = *cmdptr++; - break; - } - break; - default: - *bufptr++ = *cmdptr++; - break; - } - } - - *bufptr++ = '\0'; - - VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s", buf); - res = VG_(system)(buf); - if (res == 0) { - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "Debugger has detached. Valgrind regains control. We continue."); - } else { - VG_(message)(Vg_UserMsg, "Apparently failed!"); - VG_(message)(Vg_UserMsg, ""); - } - } - - VG_(kkill)(pid, VKI_SIGKILL); - VG_(waitpid)(pid, &status, 0); - } -} - - -/* Print some helpful-ish text about unimplemented things, and give - up. */ -void VG_(unimplemented) ( Char* msg ) -{ - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "Valgrind detected that your program requires"); - VG_(message)(Vg_UserMsg, - "the following unimplemented functionality:"); - VG_(message)(Vg_UserMsg, " %s", msg); - VG_(message)(Vg_UserMsg, - "This may be because the functionality is hard to implement,"); - VG_(message)(Vg_UserMsg, - "or because no reasonable program would behave this way,"); - VG_(message)(Vg_UserMsg, - "or because nobody has yet needed it. In any case, let us know at"); - VG_(message)(Vg_UserMsg, - "%s and/or try to work around the problem, if you can.", VG_BUGS_TO); - VG_(message)(Vg_UserMsg, - ""); - VG_(message)(Vg_UserMsg, - "Valgrind has to exit now. Sorry. Bye!"); - VG_(message)(Vg_UserMsg, - ""); - VG_(pp_sched_status)(); - VG_(exit)(1); -} - -Addr VG_(get_stack_pointer) ( void ) -{ - return BASEBLOCK_STACK_PTR; -} - -/* Debugging thing .. can be called from assembly with OYNK macro. */ -void VG_(oynk) ( Int n ) -{ - OINK(n); -} - -/* Initialize the PID and PGRP of scheduler LWP; this is also called - in any new children after fork. */ -static void newpid(ThreadId unused) -{ - /* PID of scheduler LWP */ - VG_(main_pid) = VG_(getpid)(); - VG_(main_pgrp) = VG_(getpgrp)(); -} - -/*====================================================================*/ -/*=== Check we were launched by stage 1 ===*/ -/*====================================================================*/ - -/* Look for our AUXV table */ -int scan_auxv(void* init_sp) -{ - const struct ume_auxv *auxv = find_auxv((int *)init_sp); - int padfile = -1, found = 0; - - for (; auxv->a_type != AT_NULL; auxv++) - switch(auxv->a_type) { - case AT_UME_PADFD: - padfile = auxv->u.a_val; - found |= 1; - break; - - case AT_UME_EXECFD: - vgexecfd = auxv->u.a_val; - found |= 2; - break; - } - - if ( found != (1|2) ) { - fprintf(stderr, "valgrind: stage2 must be launched by stage1\n"); - exit(127); - } - vg_assert(padfile >= 0); - return padfile; -} - - -/*====================================================================*/ -/*=== Address space determination ===*/ -/*====================================================================*/ - -static void layout_remaining_space(Addr argc_addr, float ratio) -{ - Int ires; - void* vres; - addr_t client_size, shadow_size; - - VG_(valgrind_base) = (addr_t)&kickstart_base; - VG_(valgrind_last) = ROUNDUP(argc_addr, 0x10000) - 1; // stack - - // This gives the client the largest possible address space while - // taking into account the tool's shadow needs. - client_size = ROUNDDN((VG_(valgrind_base)-REDZONE_SIZE) / (1.+ratio), - CLIENT_SIZE_MULTIPLE); - VG_(client_base) = CLIENT_BASE; - VG_(client_end) = VG_(client_base) + client_size; - /* where !FIXED mmap goes */ - VG_(client_mapbase) = VG_(client_base) + - PGROUNDDN((addr_t)(client_size * CLIENT_HEAP_PROPORTION)); - - VG_(shadow_base) = VG_(client_end) + REDZONE_SIZE; - VG_(shadow_end) = VG_(valgrind_base); - shadow_size = VG_(shadow_end) - VG_(shadow_base); - -#define SEGSIZE(a,b) ((VG_(b) - VG_(a))/(1024*1024)) - - if (0) - VG_(printf)( - "client_base %8x (%dMB)\n" - "client_mapbase %8x (%dMB)\n" - "client_end %8x (%dMB)\n" - "shadow_base %8x (%dMB)\n" - "shadow_end %8x\n" - "valgrind_base %8x (%dMB)\n" - "valgrind_last %8x\n", - VG_(client_base), SEGSIZE(client_base, client_mapbase), - VG_(client_mapbase), SEGSIZE(client_mapbase, client_end), - VG_(client_end), SEGSIZE(client_end, shadow_base), - VG_(shadow_base), SEGSIZE(shadow_base, shadow_end), - VG_(shadow_end), - VG_(valgrind_base), SEGSIZE(valgrind_base, valgrind_last), - VG_(valgrind_last) - ); - -#undef SEGSIZE - - // Ban redzone - vres = mmap((void *)VG_(client_end), REDZONE_SIZE, PROT_NONE, - MAP_FIXED|MAP_ANON|MAP_PRIVATE|MAP_NORESERVE, -1, 0); - vg_assert((void*)-1 != vres); - - // Make client hole - ires = munmap((void*)VG_(client_base), client_size); - vg_assert(0 == ires); - - // Map shadow memory. - // Initially all inaccessible, incrementally initialized as it is used - if (shadow_size != 0) { - vres = mmap((char *)VG_(shadow_base), shadow_size, PROT_NONE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED|MAP_NORESERVE, -1, 0); - if ((void*)-1 == vres) { - fprintf(stderr, - "valgrind: Could not allocate address space (%p bytes)\n" - "valgrind: for shadow memory\n" - "valgrind: Possible causes:\n" - "valgrind: - For some systems (especially under RedHat 8), Valgrind\n" - "valgrind: needs at least 1.5GB swap space.\n" - "valgrind: - Or, your virtual memory size may be limited (check\n" - "valgrind: with 'ulimit -v').\n" - "valgrind: - Or, your system may use a kernel that provides only a\n" - "valgrind: too-small (eg. 2GB) user address space.\n" - , (void*)shadow_size - ); - exit(1); - } - } -} - -/*====================================================================*/ -/*=== Command line setup ===*/ -/*====================================================================*/ - -/* Nb: malloc'd memory never freed -- kept throughout like argv, envp */ -static char* get_file_clo(char* dir) -{ -# define FLEN 512 - Int fd, n; - struct stat s1; - char* f_clo = NULL; - char filename[FLEN]; - - snprintf(filename, FLEN, "%s/.valgrindrc", ( NULL == dir ? "" : dir ) ); - fd = VG_(open)(filename, 0, VKI_S_IRUSR); - if ( fd > 0 ) { - if ( 0 == fstat(fd, &s1) ) { - f_clo = malloc(s1.st_size+1); - vg_assert(f_clo); - n = read(fd, f_clo, s1.st_size); - if (n == -1) n = 0; - f_clo[n] = '\0'; - } - close(fd); - } - return f_clo; -# undef FLEN -} - -#define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n') - -static Int count_args(char* s) -{ - Int n = 0; - if (s) { - char* cp = s; - while (True) { - // We have alternating sequences: blanks, non-blanks, blanks... - // count the non-blanks sequences. - while ( ISSPACE(*cp) ) cp++; - if ( !*cp ) break; - n++; - while ( !ISSPACE(*cp) && *cp ) cp++; - } - } - return n; -} - -/* add args out of environment, skipping multiple spaces and -- args */ -static char** copy_args( char* s, char** to ) -{ - if (s) { - char* cp = s; - while (True) { - // We have alternating sequences: blanks, non-blanks, blanks... - // copy the non-blanks sequences, and add terminating '\0' - while ( ISSPACE(*cp) ) cp++; - if ( !*cp ) break; - *to++ = cp; - while ( !ISSPACE(*cp) && *cp ) cp++; - if ( *cp ) *cp++ = '\0'; // terminate if necessary - if (VG_STREQ(to[-1], "--")) to--; // undo any '--' arg - } - } - return to; -} - -#undef ISSPACE - -// Augment command line with arguments from environment and .valgrindrc -// files. -static void augment_command_line(Int* vg_argc_inout, char*** vg_argv_inout) -{ - int vg_argc0 = *vg_argc_inout; - char** vg_argv0 = *vg_argv_inout; - - char* env_clo = getenv(VALGRINDOPTS); - char* f1_clo = get_file_clo( getenv("HOME") ); - char* f2_clo = get_file_clo("."); - - /* copy any extra args from file or environment, if present */ - if ( (env_clo && *env_clo) || (f1_clo && *f1_clo) || (f2_clo && *f2_clo) ) { - /* ' ' separated extra options */ - char **from; - char **to; - int orig_arg_count, env_arg_count, f1_arg_count, f2_arg_count; - - for ( orig_arg_count = 0; vg_argv0[orig_arg_count]; orig_arg_count++ ); - - env_arg_count = count_args(env_clo); - f1_arg_count = count_args(f1_clo); - f2_arg_count = count_args(f2_clo); - - if (0) - printf("extra-argc=%d %d %d\n", - env_arg_count, f1_arg_count, f2_arg_count); - - /* +2: +1 for null-termination, +1 for added '--' */ - from = vg_argv0; - vg_argv0 = malloc( (orig_arg_count + env_arg_count + f1_arg_count - + f2_arg_count + 2) * sizeof(char **)); - vg_assert(vg_argv0); - to = vg_argv0; - - /* copy argv[0] */ - *to++ = *from++; - - /* Copy extra args from env var and file, in the order: ~/.valgrindrc, - * $VALGRIND_OPTS, ./.valgrindrc -- more local options are put later - * to override less local ones. */ - to = copy_args(f1_clo, to); - to = copy_args(env_clo, to); - to = copy_args(f2_clo, to); - - /* copy original arguments, stopping at command or -- */ - while (*from) { - if (**from != '-') - break; - if (VG_STREQ(*from, "--")) { - from++; /* skip -- */ - break; - } - *to++ = *from++; - } - - /* add -- */ - *to++ = "--"; - - vg_argc0 = to - vg_argv0; - - /* copy rest of original command line, then NULL */ - while (*from) *to++ = *from++; - *to = NULL; - } - - *vg_argc_inout = vg_argc0; - *vg_argv_inout = vg_argv0; -} - -#define VG_CLO_SEP '\01' - -static void get_command_line( int argc, char** argv, - Int* vg_argc_out, Char*** vg_argv_out, - char*** cl_argv_out ) -{ - int vg_argc0; - char** vg_argv0; - char** cl_argv; - char* env_clo = getenv(VALGRINDCLO); - - if (env_clo != NULL && *env_clo != '\0') { - char *cp; - char **cpp; - - /* OK, VALGRINDCLO is set, which means we must be a child of another - Valgrind process using --trace-children, so we're getting all our - arguments from VALGRINDCLO, and the entire command line belongs to - the client (including argv[0]) */ - vg_argc0 = 1; /* argv[0] */ - for (cp = env_clo; *cp; cp++) - if (*cp == VG_CLO_SEP) - vg_argc0++; - - vg_argv0 = malloc(sizeof(char **) * (vg_argc0 + 1)); - vg_assert(vg_argv0); - - cpp = vg_argv0; - - *cpp++ = "valgrind"; /* nominal argv[0] */ - *cpp++ = env_clo; - - // Replace the VG_CLO_SEP args separator with '\0' - for (cp = env_clo; *cp; cp++) { - if (*cp == VG_CLO_SEP) { - *cp++ = '\0'; /* chop it up in place */ - *cpp++ = cp; - } - } - *cpp = NULL; - cl_argv = argv; - - } else { - /* Count the arguments on the command line. */ - vg_argv0 = argv; - - for (vg_argc0 = 1; vg_argc0 < argc; vg_argc0++) { - if (argv[vg_argc0][0] != '-') /* exe name */ - break; - if (VG_STREQ(argv[vg_argc0], "--")) { /* dummy arg */ - vg_argc0++; - break; - } - } - cl_argv = &argv[vg_argc0]; - - /* Get extra args from VALGRIND_OPTS and .valgrindrc files. - Note we don't do this if getting args from VALGRINDCLO, as - those extra args will already be present in VALGRINDCLO. */ - augment_command_line(&vg_argc0, &vg_argv0); - } - - if (0) { - Int i; - for (i = 0; i < vg_argc0; i++) - printf("vg_argv0[%d]=\"%s\"\n", i, vg_argv0[i]); - } - - *vg_argc_out = vg_argc0; - *vg_argv_out = (Char**)vg_argv0; - *cl_argv_out = cl_argv; -} - - -/*====================================================================*/ -/*=== Environment and stack setup ===*/ -/*====================================================================*/ - -/* Scan a colon-separated list, and call a function on each element. - The string must be mutable, because we insert a temporary '\0', but - the string will end up unmodified. (*func) should return True if it - doesn't need to see any more. - - This routine will return True if (*func) returns True and False if - it reaches the end of the list without that happening. -*/ -static Bool scan_colsep(char *colsep, Bool (*func)(const char *)) -{ - char *cp, *entry; - int end; - - if (colsep == NULL || - *colsep == '\0') - return False; - - entry = cp = colsep; - - do { - end = (*cp == '\0'); - - if (*cp == ':' || *cp == '\0') { - char save = *cp; - - *cp = '\0'; - if ((*func)(entry)) { - *cp = save; - return True; - } - *cp = save; - entry = cp+1; - } - cp++; - } while(!end); - - return False; -} - -static Bool contains(const char *p) { - if (VG_STREQ(p, VG_(libdir))) { - return True; - } - return False; -} - -/* Prepare the client's environment. This is basically a copy of our - environment, except: - 1. LD_LIBRARY_PATH=$VALGRINDLIB:$LD_LIBRARY_PATH - 2. LD_PRELOAD=$VALGRINDLIB/vg_inject.so:($VALGRINDLIB/vgpreload_TOOL.so:)?$LD_PRELOAD - - If any of these is missing, then it is added. - - Yummy. String hacking in C. - - If this needs to handle any more variables it should be hacked - into something table driven. - */ -static char **fix_environment(char **origenv, const char *preload) -{ - static const char inject_so[] = "vg_inject.so"; - static const char ld_library_path[] = "LD_LIBRARY_PATH="; - static const char ld_preload[] = "LD_PRELOAD="; - static const char valgrind_clo[] = VALGRINDCLO "="; - static const int ld_library_path_len = sizeof(ld_library_path)-1; - static const int ld_preload_len = sizeof(ld_preload)-1; - static const int valgrind_clo_len = sizeof(valgrind_clo)-1; - int ld_preload_done = 0; - int ld_library_path_done = 0; - char *inject_path; - int inject_path_len; - int vgliblen = strlen(VG_(libdir)); - char **cpp; - char **ret; - int envc; - const int preloadlen = (preload == NULL) ? 0 : strlen(preload); - - /* Find the vg_inject.so; also make room for the tool preload - library */ - inject_path_len = sizeof(inject_so) + vgliblen + preloadlen + 16; - inject_path = malloc(inject_path_len); - vg_assert(inject_path); - - if (preload) - snprintf(inject_path, inject_path_len, "%s/%s:%s", - VG_(libdir), inject_so, preload); - else - snprintf(inject_path, inject_path_len, "%s/%s", - VG_(libdir), inject_so); - - /* Count the original size of the env */ - envc = 0; /* trailing NULL */ - for (cpp = origenv; cpp && *cpp; cpp++) - envc++; - - /* Allocate a new space */ - ret = malloc(sizeof(char *) * (envc+3+1)); /* 3 new entries + NULL */ - vg_assert(ret); - - /* copy it over */ - for (cpp = ret; *origenv; ) - *cpp++ = *origenv++; - *cpp = NULL; - - vg_assert(envc == (cpp - ret)); - - /* Walk over the new environment, mashing as we go */ - for (cpp = ret; cpp && *cpp; cpp++) { - if (memcmp(*cpp, ld_library_path, ld_library_path_len) == 0) { - /* If the LD_LIBRARY_PATH already contains libdir, then don't - bother adding it again, even if it isn't the first (it - seems that the Java runtime will keep reexecing itself - unless its paths are at the front of LD_LIBRARY_PATH) */ - if (!scan_colsep(*cpp + ld_library_path_len, contains)) { - int len = strlen(*cpp) + vgliblen*2 + 16; - char *cp = malloc(len); - vg_assert(cp); - - snprintf(cp, len, "%s%s:%s", - ld_library_path, VG_(libdir), - (*cpp)+ld_library_path_len); - - *cpp = cp; - } - - ld_library_path_done = 1; - } else if (memcmp(*cpp, ld_preload, ld_preload_len) == 0) { - int len = strlen(*cpp) + inject_path_len; - char *cp = malloc(len); - vg_assert(cp); - - snprintf(cp, len, "%s%s:%s", - ld_preload, inject_path, (*cpp)+ld_preload_len); - - *cpp = cp; - - ld_preload_done = 1; - } else if (memcmp(*cpp, valgrind_clo, valgrind_clo_len) == 0) { - *cpp = ""; - } - } - - /* Add the missing bits */ - - if (!ld_library_path_done) { - int len = ld_library_path_len + vgliblen*2 + 16; - char *cp = malloc(len); - vg_assert(cp); - - snprintf(cp, len, "%s%s", ld_library_path, VG_(libdir)); - - ret[envc++] = cp; - } - - if (!ld_preload_done) { - int len = ld_preload_len + inject_path_len; - char *cp = malloc(len); - vg_assert(cp); - - snprintf(cp, len, "%s%s", - ld_preload, inject_path); - - ret[envc++] = cp; - } - - ret[envc] = NULL; - - return ret; -} - -extern char **environ; /* our environment */ -//#include - -/* Add a string onto the string table, and return its address */ -static char *copy_str(char **tab, const char *str) -{ - char *cp = *tab; - char *orig = cp; - - while(*str) - *cp++ = *str++; - *cp++ = '\0'; - - if (0) - printf("copied %p \"%s\" len %d\n", orig, orig, cp-orig); - - *tab = cp; - - return orig; -} - -/* - This sets up the client's initial stack, containing the args, - environment and aux vector. - - The format of the stack is: - - higher address +-----------------+ - | Trampoline code | - +-----------------+ - | | - : string table : - | | - +-----------------+ - | AT_NULL | - - - - | auxv | - +-----------------+ - | NULL | - - - - | envp | - +-----------------+ - | NULL | - - - - | argv | - +-----------------+ - | argc | - lower address +-----------------+ <- esp - | undefined | - : : - */ -static Addr setup_client_stack(void* init_sp, - char **orig_argv, char **orig_envp, - const struct exeinfo *info, - UInt** client_auxv) -{ - void* res; - char **cpp; - char *strtab; /* string table */ - char *stringbase; - addr_t *ptr; - struct ume_auxv *auxv; - const struct ume_auxv *orig_auxv; - const struct ume_auxv *cauxv; - unsigned stringsize; /* total size of strings in bytes */ - unsigned auxsize; /* total size of auxv in bytes */ - int argc; /* total argc */ - int envc; /* total number of env vars */ - unsigned stacksize; /* total client stack size */ - addr_t cl_esp; /* client stack base (initial esp) */ - - /* use our own auxv as a prototype */ - orig_auxv = find_auxv(init_sp); - - /* ==================== compute sizes ==================== */ - - /* first of all, work out how big the client stack will be */ - stringsize = 0; - - /* paste on the extra args if the loader needs them (ie, the #! - interpreter and its argument) */ - argc = 0; - if (info->interp_name != NULL) { - argc++; - stringsize += strlen(info->interp_name) + 1; - } - if (info->interp_args != NULL) { - argc++; - stringsize += strlen(info->interp_args) + 1; - } - - /* now scan the args we're given... */ - for (cpp = orig_argv; *cpp; cpp++) { - argc++; - stringsize += strlen(*cpp) + 1; - } - - /* ...and the environment */ - envc = 0; - for (cpp = orig_envp; cpp && *cpp; cpp++) { - envc++; - stringsize += strlen(*cpp) + 1; - } - - /* now, how big is the auxv? */ - auxsize = sizeof(*auxv); /* there's always at least one entry: AT_NULL */ - for (cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) { - if (cauxv->a_type == AT_PLATFORM) - stringsize += strlen(cauxv->u.a_ptr) + 1; - auxsize += sizeof(*cauxv); - } - - /* OK, now we know how big the client stack is */ - stacksize = - sizeof(int) + /* argc */ - sizeof(char **)*argc + /* argv */ - sizeof(char **) + /* terminal NULL */ - sizeof(char **)*envc + /* envp */ - sizeof(char **) + /* terminal NULL */ - auxsize + /* auxv */ - ROUNDUP(stringsize, sizeof(int)) +/* strings (aligned) */ - VKI_BYTES_PER_PAGE; /* page for trampoline code */ - - // decide where stack goes! - VG_(clstk_end) = VG_(client_end); - - VG_(client_trampoline_code) = VG_(clstk_end) - VKI_BYTES_PER_PAGE; - - /* cl_esp is the client's stack pointer */ - cl_esp = VG_(clstk_end) - stacksize; - cl_esp = ROUNDDN(cl_esp, 16); /* make stack 16 byte aligned */ - - /* base of the string table (aligned) */ - stringbase = strtab = (char *)(VG_(client_trampoline_code) - ROUNDUP(stringsize, sizeof(int))); - - VG_(clstk_base) = PGROUNDDN(cl_esp); - - if (0) - printf("stringsize=%d auxsize=%d stacksize=%d\n" - "clstk_base %p\n" - "clstk_end %p\n", - stringsize, auxsize, stacksize, - (void*)VG_(clstk_base), (void*)VG_(clstk_end)); - - - /* ==================== allocate space ==================== */ - - /* allocate a stack - mmap enough space for the stack */ - res = mmap((void *)PGROUNDDN(cl_esp), VG_(clstk_end) - PGROUNDDN(cl_esp), - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); - vg_assert((void*)-1 != res); - - /* ==================== copy client stack ==================== */ - - ptr = (addr_t *)cl_esp; - - /* --- argc --- */ - *ptr++ = argc; /* client argc */ - - /* --- argv --- */ - if (info->interp_name) { - *ptr++ = (addr_t)copy_str(&strtab, info->interp_name); - free(info->interp_name); - } - if (info->interp_args) { - *ptr++ = (addr_t)copy_str(&strtab, info->interp_args); - free(info->interp_args); - } - for (cpp = orig_argv; *cpp; ptr++, cpp++) { - *ptr = (addr_t)copy_str(&strtab, *cpp); - } - *ptr++ = 0; - - /* --- envp --- */ - VG_(client_envp) = (Char **)ptr; - for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) - *ptr = (addr_t)copy_str(&strtab, *cpp); - *ptr++ = 0; - - /* --- auxv --- */ - auxv = (struct ume_auxv *)ptr; - *client_auxv = (UInt *)auxv; - - for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) { - /* copy the entry... */ - *auxv = *orig_auxv; - - /* ...and fix up the copy */ - switch(auxv->a_type) { - case AT_PHDR: - if (info->phdr == 0) - auxv->a_type = AT_IGNORE; - else - auxv->u.a_val = info->phdr; - break; - - case AT_PHNUM: - if (info->phdr == 0) - auxv->a_type = AT_IGNORE; - else - auxv->u.a_val = info->phnum; - break; - - case AT_BASE: - if (info->interp_base == 0) - auxv->a_type = AT_IGNORE; - else - auxv->u.a_val = info->interp_base; - break; - - case AT_PLATFORM: /* points to a platform description string */ - auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr); - break; - - case AT_ENTRY: - auxv->u.a_val = info->entry; - break; - - case AT_IGNORE: - case AT_EXECFD: - case AT_PHENT: - case AT_PAGESZ: - case AT_FLAGS: - case AT_NOTELF: - case AT_UID: - case AT_EUID: - case AT_GID: - case AT_EGID: - case AT_CLKTCK: - case AT_HWCAP: - case AT_FPUCW: - case AT_DCACHEBSIZE: - case AT_ICACHEBSIZE: - case AT_UCACHEBSIZE: - /* All these are pointerless, so we don't need to do anything - about them. */ - break; - - case AT_SECURE: - /* If this is 1, then it means that this program is running - suid, and therefore the dynamic linker should be careful - about LD_PRELOAD, etc. However, since stage1 (the thing - the kernel actually execve's) should never be SUID, and we - need LD_PRELOAD/LD_LIBRARY_PATH to work for the client, we - set AT_SECURE to 0. */ - auxv->u.a_val = 0; - break; - - case AT_SYSINFO: - /* Leave this unmolested for now, but we'll update it later - when we set up the client trampoline code page */ - break; - - case AT_SYSINFO_EHDR: - /* Trash this, because we don't reproduce it */ - auxv->a_type = AT_IGNORE; - break; - - default: - /* stomp out anything we don't know about */ - if (0) - printf("stomping auxv entry %d\n", auxv->a_type); - auxv->a_type = AT_IGNORE; - break; - - } - } - *auxv = *orig_auxv; - vg_assert(auxv->a_type == AT_NULL); - - /* --- trampoline page --- */ - VG_(memcpy)( (void *)VG_(client_trampoline_code), - &VG_(trampoline_code_start), VG_(trampoline_code_length) ); - - vg_assert((strtab-stringbase) == stringsize); - - /* We know the initial ESP is pointing at argc/argv */ - VG_(client_argc) = *(Int*)cl_esp; - VG_(client_argv) = (Char**)(cl_esp + sizeof(Int)); - - return cl_esp; -} - -/*====================================================================*/ -/*=== Find executable ===*/ -/*====================================================================*/ - -static const char* executable_name; - -static Bool match_executable(const char *entry) { - char buf[strlen(entry) + strlen(executable_name) + 2]; - - /* empty PATH element means . */ - if (*entry == '\0') - entry = "."; - - snprintf(buf, sizeof(buf), "%s/%s", entry, executable_name); - - if (access(buf, R_OK|X_OK) == 0) { - executable_name = strdup(buf); - vg_assert(NULL != executable_name); - return True; - } - return False; -} - -static const char* find_executable(const char* exec) -{ - vg_assert(NULL != exec); - executable_name = exec; - if (strchr(executable_name, '/') == NULL) { - /* no '/' - we need to search the path */ - char *path = getenv("PATH"); - scan_colsep(path, match_executable); - } - return executable_name; -} - - -/*====================================================================*/ -/*=== Loading tools ===*/ -/*====================================================================*/ - -static void list_tools(void) -{ - DIR *dir = opendir(VG_(libdir)); - struct dirent *de; - int first = 1; - - if (dir == NULL) { - fprintf(stderr, "Can't open %s: %s (installation problem?)\n", - VG_(libdir), strerror(errno)); - return; - } - - while ((de = readdir(dir)) != NULL) { - int len = strlen(de->d_name); - - /* look for vgskin_TOOL.so names */ - if (len > (7+1+3) && /* "vgskin_" + at least 1-char toolname + ".so" */ - strncmp(de->d_name, "vgskin_", 7) == 0 && - VG_STREQ(de->d_name + len - 3, ".so")) { - if (first) { - fprintf(stderr, "Available tools:\n"); - first = 0; - } - de->d_name[len-3] = '\0'; - fprintf(stderr, "\t%s\n", de->d_name+7); - } - } - - closedir(dir); - - if (first) - fprintf(stderr, "No tools available in \"%s\" (installation problem?)\n", - VG_(libdir)); -} - - -/* Find and load a tool, and check it looks ok. Also looks to see if there's - * a matching vgpreload_*.so file, and returns its name in *preloadpath. */ -static void load_tool( const char *toolname, void** handle_out, - ToolInfo** toolinfo_out, char **preloadpath_out ) -{ - Bool ok; - int len = strlen(VG_(libdir)) + strlen(toolname)*2 + 16; - char buf[len]; - void* handle; - ToolInfo* toolinfo; - char* preloadpath = NULL; - Int* vg_malloc_redzonep; - - // XXX: allowing full paths for --tool option -- does it make sense? - // Doesn't allow for vgpreload_.so. - - if (strchr(toolname, '/') != 0) { - /* toolname contains '/', and so must be a pathname */ - handle = dlopen(toolname, RTLD_NOW); - } else { - /* just try in the libdir */ - snprintf(buf, len, "%s/vgskin_%s.so", VG_(libdir), toolname); - handle = dlopen(buf, RTLD_NOW); - - if (handle != NULL) { - snprintf(buf, len, "%s/vgpreload_%s.so", VG_(libdir), toolname); - if (access(buf, R_OK) == 0) { - preloadpath = strdup(buf); - vg_assert(NULL != preloadpath); - } - } - } - - ok = (NULL != handle); - if (!ok) { - fprintf(stderr, "Can't open tool \"%s\": %s\n", toolname, dlerror()); - goto bad_load; - } - - toolinfo = dlsym(handle, "vgSkin_tool_info"); - ok = (NULL != toolinfo); - if (!ok) { - fprintf(stderr, "Tool \"%s\" doesn't define SK_(tool_info) - " - "add VG_DETERMINE_INTERFACE_VERSION?\n", toolname); - goto bad_load; - } - - ok = (toolinfo->sizeof_ToolInfo == sizeof(*toolinfo) && - toolinfo->interface_major_version == VG_CORE_INTERFACE_MAJOR_VERSION && - toolinfo->sk_pre_clo_init != NULL); - if (!ok) { - fprintf(stderr, "Error:\n" - " Tool and core interface versions do not match.\n" - " Interface version used by core is: %d.%d (size %d)\n" - " Interface version used by tool is: %d.%d (size %d)\n" - " The major version numbers must match.\n", - VG_CORE_INTERFACE_MAJOR_VERSION, - VG_CORE_INTERFACE_MINOR_VERSION, - sizeof(*toolinfo), - toolinfo->interface_major_version, - toolinfo->interface_minor_version, - toolinfo->sizeof_ToolInfo); - fprintf(stderr, " You need to at least recompile, and possibly update,\n"); - if (VG_CORE_INTERFACE_MAJOR_VERSION > toolinfo->interface_major_version) - fprintf(stderr, " your tool to work with this version of Valgrind.\n"); - else - fprintf(stderr, " your version of Valgrind to work with this tool.\n"); - goto bad_load; - } - - // Set redzone size for V's allocator - vg_malloc_redzonep = dlsym(handle, STR(VG_(vg_malloc_redzone_szB))); - if ( NULL != vg_malloc_redzonep ) { - VG_(vg_malloc_redzone_szB) = *vg_malloc_redzonep; - } - - vg_assert(NULL != handle && NULL != toolinfo); - *handle_out = handle; - *toolinfo_out = toolinfo; - *preloadpath_out = preloadpath; - return; - - - bad_load: - if (handle != NULL) - dlclose(handle); - - fprintf(stderr, "valgrind: couldn't load tool\n"); - list_tools(); - exit(127); -} - - -/*====================================================================*/ -/*=== Command line errors ===*/ -/*====================================================================*/ - -static void abort_msg ( void ) -{ - VG_(clo_log_to) = VgLogTo_Fd; - VG_(clo_log_fd) = 2; /* stderr */ -} - -void VG_(bad_option) ( Char* opt ) -{ - abort_msg(); - VG_(printf)("valgrind: Bad option `%s'; aborting.\n", opt); - VG_(printf)("valgrind: Use --help for more information.\n"); - VG_(exit)(1); -} - -static void missing_tool_option ( void ) -{ - abort_msg(); - VG_(printf)("valgrind: Missing --tool option\n"); - list_tools(); - VG_(printf)("valgrind: Use --help for more information.\n"); - VG_(exit)(1); -} - -static void missing_prog ( void ) -{ - abort_msg(); - VG_(printf)("valgrind: no program specified\n"); - VG_(printf)("valgrind: Use --help for more information.\n"); - VG_(exit)(1); -} - -static void config_error ( Char* msg ) -{ - abort_msg(); - VG_(printf)("valgrind: Startup or configuration error:\n %s\n", msg); - VG_(printf)("valgrind: Unable to start up properly. Giving up.\n"); - VG_(exit)(1); -} - - -/*====================================================================*/ -/*=== Loading the client ===*/ -/*====================================================================*/ - -static void load_client(char* cl_argv[], const char* exec, Int need_help, - /*out*/struct exeinfo* info, /*out*/Addr* client_eip) -{ - // If they didn't specify an executable with --exec, and didn't specify - // --help, then use client argv[0] (searching $PATH if necessary). - if (NULL == exec && !need_help) { - if (cl_argv[0] == NULL || - ( NULL == (exec = find_executable(cl_argv[0])) ) ) - { - missing_prog(); - } - } - - info->map_base = VG_(client_mapbase); - info->exe_base = VG_(client_base); - info->exe_end = VG_(client_end); - info->argv = cl_argv; - - if (need_help) { - VG_(clexecfd) = -1; - // Set the minimal number of entries in 'info' to continue. - info->interp_name = NULL; - info->interp_args = NULL; - } else { - Int ret; - VG_(clexecfd) = VG_(open)(exec, VKI_O_RDONLY, VKI_S_IRUSR); - ret = do_exec(exec, info); - if (ret != 0) { - fprintf(stderr, "valgrind: do_exec(%s) failed: %s\n", - exec, strerror(ret)); - exit(127); - } - } - - /* Copy necessary bits of 'info' that were filled in */ - *client_eip = info->init_eip; - VG_(brk_base) = VG_(brk_limit) = info->brkbase; -} - -/*====================================================================*/ -/*=== Address space unpadding ===*/ -/*====================================================================*/ - -typedef struct { - char* killpad_start; - char* killpad_end; - struct stat* killpad_padstat; -} killpad_extra; - -static int killpad(char *segstart, char *segend, const char *perm, off_t off, - int maj, int min, int ino, void* ex) -{ - killpad_extra* extra = ex; - void *b, *e; - int res; - - vg_assert(NULL != extra->killpad_padstat); - - if (extra->killpad_padstat->st_dev != makedev(maj, min) || - extra->killpad_padstat->st_ino != ino) - return 1; - - if (segend <= extra->killpad_start || segstart >= extra->killpad_end) - return 1; - - if (segstart <= extra->killpad_start) - b = extra->killpad_start; - else - b = segstart; - - if (segend >= extra->killpad_end) - e = extra->killpad_end; - else - e = segend; - - res = munmap(b, (char *)e-(char *)b); - vg_assert(0 == res); - - return 1; -} - -// Remove padding of 'padfile' from a range of address space. -void as_unpad(void *start, void *end, int padfile) -{ - static struct stat padstat; - killpad_extra extra; - int res; - - vg_assert(padfile > 0); - - res = fstat(padfile, &padstat); - vg_assert(0 == res); - extra.killpad_padstat = &padstat; - extra.killpad_start = start; - extra.killpad_end = end; - foreach_map(killpad, &extra); -} - -void as_closepadfile(int padfile) -{ - int res = close(padfile); - vg_assert(0 == res); -} - - -/*====================================================================*/ -/*=== Command-line: variables, processing, etc ===*/ -/*====================================================================*/ - -/* Define, and set defaults. */ -VexControl VG_(clo_vex_control); -Bool VG_(clo_error_limit) = True; -Bool VG_(clo_db_attach) = False; -Char* VG_(clo_db_command) = VG_CLO_DEFAULT_DBCOMMAND; -Bool VG_(clo_gen_suppressions) = False; -Int VG_(clo_sanity_level) = 1; -Int VG_(clo_verbosity) = 1; -Bool VG_(clo_demangle) = True; -Bool VG_(clo_trace_children) = False; - -/* See big comment in core.h for meaning of these three. - fd is initially stdout, for --help, but gets moved to stderr by default - immediately afterwards. */ -VgLogTo VG_(clo_log_to) = VgLogTo_Fd; -Int VG_(clo_log_fd) = 1; -Char* VG_(clo_log_name) = NULL; - -Bool VG_(clo_time_stamp) = False; - -Int VG_(clo_input_fd) = 0; /* stdin */ -Int VG_(clo_n_suppressions) = 0; -Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES]; -Bool VG_(clo_profile) = False; -Bool VG_(clo_single_step) = False; -Bool VG_(clo_optimise) = True; -UChar VG_(clo_trace_codegen) = 0; // 00000000b -Bool VG_(clo_trace_syscalls) = False; -Bool VG_(clo_trace_signals) = False; -Bool VG_(clo_trace_symtab) = False; -Bool VG_(clo_trace_sched) = False; -Int VG_(clo_trace_pthread_level) = 0; -Int VG_(clo_dump_error) = 0; -Int VG_(clo_backtrace_size) = 4; -Char* VG_(clo_weird_hacks) = NULL; -Bool VG_(clo_run_libc_freeres) = True; -Bool VG_(clo_track_fds) = False; -Bool VG_(clo_chain_bb) = True; -Bool VG_(clo_show_below_main) = False; -Bool VG_(clo_pointercheck) = True; -Bool VG_(clo_branchpred) = False; - -static Bool VG_(clo_wait_for_gdb) = False; - -/* If we're doing signal routing, poll for signals every 50mS by - default. */ -Int VG_(clo_signal_polltime) = 50; - -/* These flags reduce thread wakeup latency on syscall completion and - signal delivery, respectively. The downside is possible unfairness. */ -Bool VG_(clo_lowlat_syscalls) = False; /* low-latency syscalls */ -Bool VG_(clo_lowlat_signals) = False; /* low-latency signals */ - - -void usage ( Bool debug_help ) -{ - Char* usage1 = -"usage: valgrind --tool= [options] prog-and-args\n" -"\n" -" common user options for all Valgrind tools, with defaults in [ ]:\n" -" --tool= use the Valgrind tool named \n" -" -h --help show this message\n" -" --help-debug show this message, plus debugging options\n" -" --version show version\n" -" -q --quiet run silently; only print error msgs\n" -" -v --verbose be more verbose, incl counts of errors\n" -" --trace-children=no|yes Valgrind-ise child processes? [no]\n" -" --track-fds=no|yes track open file descriptors? [no]\n" -" --time-stamp=no|yes add timestamps to log messages? [no]\n" -"\n" -" uncommon user options for all Valgrind tools:\n" -" --run-libc-freeres=no|yes free up glibc memory at exit? [yes]\n" -" --weird-hacks=hack1,hack2,... recognised hacks: lax-ioctls [none]\n" -" --signal-polltime=

Valgrind, version 2.2.0

-
This manual was last updated on 31 August 2004
-

- -

-jseward@acm.org, - njn25@cam.ac.uk
-Copyright © 2000-2004 Julian Seward, Nick Nethercote -

- -Valgrind is licensed under the GNU General Public License, version -2
- -An open-source tool for debugging and profiling Linux-x86 executables. -

- -

- -


- -

Contents of this manual

- -

Introduction

- 1.1  - An overview of Valgrind
- 1.2  - How to navigate this manual - -

- Using and understanding the Valgrind core

- 2.1  - What it does with your program
- 2.2  - Getting started
- 2.3  - The commentary
- 2.4  - Reporting of errors
- 2.5  - Suppressing errors
- 2.6  - Command-line flags for the Valgrind core
- 2.7  - The Client Request mechanism
- 2.8  - Support for POSIX pthreads
- 2.9  - Handling of signals
- 2.10  - Building and installing
- 2.11  - If you have problems
- 2.12  - Limitations
- 2.13  - How it works -- a rough overview
- 2.14  - An example run
- 2.15  - Warning messages you might see
- -

- Memcheck: a heavyweight memory checker

- -

- Cachegrind: a cache-miss profiler

- -

- Addrcheck: a lightweight memory checker

- -

- Helgrind: a data-race detector

- -

- Massif: a heap profiler

- -

-The following is not part of the user manual. It describes how you can -write tools for Valgrind, in order to make new program supervision -tools. - -

- Valgrind Tools

- -

-The following are not part of the user manual. They describe internal -details of how Valgrind works. Reading them may rot your brain. You -have been warned. - -

- The design and implementation of Valgrind

- -

10  - How Cachegrind works

- -
- - diff --git a/VEX/head20041019/docs/proxylwp.sxw b/VEX/head20041019/docs/proxylwp.sxw deleted file mode 100644 index 38ceeaf78..000000000 Binary files a/VEX/head20041019/docs/proxylwp.sxw and /dev/null differ diff --git a/VEX/head20041019/glibc-2.1.supp b/VEX/head20041019/glibc-2.1.supp deleted file mode 100644 index de93976b8..000000000 --- a/VEX/head20041019/glibc-2.1.supp +++ /dev/null @@ -1,184 +0,0 @@ -##----------------------------------------------------------------------## - -# Errors to suppress by default for glibc 2.1.3 - -# Format of this file is: -# { -# name_of_suppression -# tool_name:supp_kind -# (optional extra info for some suppression types) -# caller0 name, or /name/of/so/file.so -# caller1 name, or ditto -# (optionally: caller2 name) -# (optionally: caller3 name) -# } -# -# For Memcheck, the supp_kinds are: -# -# Param Value1 Value2 Value4 Value8 Value16 -# Free Addr1 Addr2 Addr4 Addr8 Addr16 -# Cond (previously known as Value0) -# -# and the optional extra info is: -# if Param: name of system call param -# if Free: name of free-ing fn) - -#-------- Suppress errors appearing as a result of calling -#-------- __libc_freeres() - -{ - __libc_freeres/free_mem(Addr4) - Addrcheck,Memcheck:Addr4 - fun:free_mem - fun:__libc_freeres -} - - -##----------------------------------------------------------------------## - -{ - pthread_mutex_unlock/__register_frame_info_bases - core:PThread - fun:pthread_mutex_unlock - fun:__register_frame_info_bases -} - -{ - socketcall.connect(serv_addr)/connect/*(Param) - Addrcheck,Memcheck:Param - socketcall.connect(serv_addr) - fun:connect - fun:* -} - -{ - strrchr/_dl_map_object_from_fd/_dl_map_object(Addr4) - Addrcheck,Memcheck:Addr4 - fun:strrchr - fun:_dl_map_object_from_fd - fun:_dl_map_object -} - -{ - strrchr/_dl_map_object_from_fd/_dl_map_object(Value1) - Memcheck:Value1 - fun:strrchr - fun:_dl_map_object_from_fd - fun:_dl_map_object -} - -{ - llseek(result)/lseek64/_IO_file_seek(Param) - Addrcheck,Memcheck:Param - llseek(result) - fun:lseek64 - fun:_IO_file_seek -} - -{ - __rawmemchr/_nl_*/*locale(Addr4) - Addrcheck,Memcheck:Addr4 - fun:__rawmemchr - fun:_nl_* - fun:*locale -} - -# new ones for RH62 ls -l -{ - __strchrnul/__nss_database_lookup(Cond) - Memcheck:Cond - fun:__strchrnul - fun:__nss_database_lookup -} -{ - __strchrnul/__gethostbyname_r(Cond) - Memcheck:Cond - fun:__strchrnul - fun:__gethostbyname_r -} - -{ - strrchr/_dl_map*/_dl_map*(Cond) - Memcheck:Cond - fun:strrchr - fun:_dl_map* - fun:_dl_map* -} - -{ - strchr/dl_open_worker/_dl_catch_error(Cond) - Memcheck:Cond - fun:strchr - fun:dl_open_worker - fun:_dl_catch_error -} - -{ - __rawmemchr/???/__getgrgid_r(Cond) - Memcheck:Cond - fun:__rawmemchr - fun:* - fun:__getgrgid_r -} - -{ - __rawmemchr/_nl_*/*locale*(Cond) - Memcheck:Cond - fun:__rawmemchr - fun:_nl_* - fun:*locale* -} - -{ - _dl_relocate_object/dl_open_worker(Value0) - Memcheck:Cond - fun:_dl_relocate_object - fun:dl_open_worker -} - -##----------------------------------------------------------------------## -## from a Debian machine running kernel 2.2.19 I believe -## I guess most of these are the same as above really, but -## Debian stripped their libc-2.1.3 - -{ - libc-2.1.3.so/libc-2.1.3.so/libc-2.1.3.so(Cond) - Memcheck:Cond - obj:*libc-2.1.3.so - obj:*libc-2.1.3.so - obj:*libc-2.1.3.so -} - -{ - strchr/libc-2.1.3.so(Cond) - Memcheck:Cond - fun:*strchr* - obj:*libc-2.1.3.so -} - -{ - libc-2.1.3.so/libXt.so(Cond) - Memcheck:Cond - obj:*libc-2.1.3.so - obj:*libXt.so* -} - -{ - socketcall.connect(serv_addr)/connect/*(Param) - Addrcheck,Memcheck:Param - socketcall.connect(serv_addr) - obj:*libc-2.1.3.so - obj:*libX11.so* -} - -##----------------------------------------------------------------------## -## For a leak in Valgrind's own libpthread.so :( -{ - my_malloc/get_or_allocate_specifics_ptr/pthread_key_create(Leak) - Memcheck:Leak - fun:malloc - fun:my_malloc - fun:get_or_allocate_specifics_ptr - fun:pthread_key_create -} - diff --git a/VEX/head20041019/glibc-2.2.supp b/VEX/head20041019/glibc-2.2.supp deleted file mode 100644 index e50ac438c..000000000 --- a/VEX/head20041019/glibc-2.2.supp +++ /dev/null @@ -1,459 +0,0 @@ - -##----------------------------------------------------------------------## - -# Errors to suppress by default with glibc 2.2.4 / 2.2.5 - -# Format of this file is: -# { -# name_of_suppression -# tool_name:supp_kind -# (optional extra info for some suppression types) -# caller0 name, or /name/of/so/file.so -# caller1 name, or ditto -# (optionally: caller2 name) -# (optionally: caller3 name) -# } -# -# For Memcheck, the supp_kinds are: -# -# Param Value1 Value2 Value4 Value8 Value16 -# Free Addr1 Addr2 Addr4 Addr8 Addr16 -# Cond (previously known as Value0) -# -# and the optional extra info is: -# if Param: name of system call param -# if Free: name of free-ing fn) - -#-------- For SuSE 8.2 (gcc 3.3, glibc 2.3.2) -{ - __GI___stpcpy/* - Memcheck:Cond - fun:__GI___stpcpy - fun:* -} -{ - strlen/__GI__dl_open/dlopen_doit - Memcheck:Cond - fun:strlen - fun:__GI__dl_open - fun:dlopen_doit -} -{ - strlen/_dl_signal_cerror/_dl_lookup_symbol_internal/do_dlsym - Memcheck:Cond - fun:_dl_signal_cerror - fun:_dl_lookup_symbol_internal - fun:do_dlsym -} - - -#-------- For R H 8.0 -{ - elf_dynamic_do_rel.7/_dl_relocate_object_internal/dl_open_worker(Cond) - Memcheck:Cond - fun:elf_dynamic_do_rel.7 - fun:_dl_relocate_object_internal - fun:dl_open_worker -} - - -#-------- For R H 7.3 on i686 -{ - _dl_relocate_object*/*libc-2.2.?.so/_dl_catch_error*(Cond) - Memcheck:Cond - fun:_dl_relocate_object* - obj:*libc-2.2.?.so - fun:_dl_catch_error* -} - - -#-------- SuSE 8.1 stuff (gcc-3.2, glibc-2.2.5 + SuSE's hacks) -{ - __stpcpy/* - Memcheck:Cond - fun:__stpcpy - fun:* -} -{ - strlen/decompose_rpath/_dl_map_object - Memcheck:Cond - fun:strlen - fun:decompose_rpath - fun:_dl_map_object -} -{ - strlen/_dl_sym/dlsym_doit - Memcheck:Cond - fun:strlen - fun:_dl_sym - fun:dlsym_doit -} -{ - trecurse/__gconv_release_shlib(Addr4) - Addrcheck,Memcheck:Addr4 - fun:trecurse - fun:__gconv_release_shlib -} -{ - do_release_shlib/trecurse(Addr4) - Addrcheck,Memcheck:Addr4 - fun:do_release_shlib - fun:trecurse -} - -#-------- R H Limbo (glibc-2.2.90) stuff -{ - elf_dynamic_do_rela.8/_dl_relocate_object_internal - Memcheck:Cond - fun:elf_dynamic_do_rela.8 - fun:_dl_relocate_object_internal -} - -{ - __strnlen/_nl_make_l10nflist(Cond) - Memcheck:Cond - fun:__strnlen - fun:_nl_make_l10nflist -} - -{ - __strnlen/*vfprintf* - Memcheck:Cond - fun:__strnlen - fun:*vfprintf* -} - -{ - libXaw.so.7.0(Cond) - Memcheck:Cond - obj:*libXaw.so.7.0 -} - -#-------- Suppress errors appearing as a result of calling -#-------- __libc_freeres() - -{ - __twalk/*(Addr4) - Addrcheck,Memcheck:Addr4 - fun:__twalk -} - -{ - do_release_shlib/__twalk(Addr4) - Addrcheck,Memcheck:Addr4 - fun:do_release_shlib - fun:__twalk -} - -{ - __libc_freeres/free_mem/free(Free) - Addrcheck,Memcheck:Free - fun:free - fun:free_mem - fun:__libc_freeres -} - -#-------- Data races -{ - _dl_lookup_symbol/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_symbol - fun:fixup - fun:_dl_runtime_resolve -} - -{ - _dl_lookup_versioned_symbol/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_versioned_symbol - fun:fixup - fun:_dl_runtime_resolve -} - -{ - _dl_lookup_versioned_symbol_internal/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_versioned_symbol_internal - fun:fixup - fun:_dl_runtime_resolve -} - -{ - _dl_fini/exit/__libc_start_main - Helgrind:Eraser - fun:_dl_fini - fun:exit - fun:__libc_start_main -} - -#-------- Threading bugs? -# glibc 'knows' that destroying a locked mutex will unlock it -{ - pthread_error/pthread_mutex_destroy/__closedir - core:PThread - fun:pthread_error - fun:pthread_mutex_destroy - fun:__closedir -} - -{ - pthread_error/pthread_mutex_destroy/_IO_default_finish - core:PThread - fun:pthread_error - fun:pthread_mutex_destroy - fun:_IO_default_finish* -} - -{ - pthread_mutex_unlock/_IO_funlockfile - core:PThread - fun:pthread_mutex_unlock - fun:_IO_funlockfile -} - -# even more glibc suppressions ? -{ - libc-2.2.4.so/libc-2.2.4.so/libc-2.2.4.so(Cond) - Memcheck:Cond - obj:*libc-2.2.?.so - obj:*libc-2.2.?.so - obj:*libc-2.2.?.so -} -{ - libc-2.2.4.so/libc-2.2.4.so/libc-2.2.4.so(Value4) - Memcheck:Value4 - obj:*libc-2.2.?.so - obj:*libc-2.2.?.so - obj:*libc-2.2.?.so -} - -##### glibc 2.2.5 stuff perhaps? -##### suppressions for coolo -{ - strchr/dl_open_worker(Cond) - Memcheck:Cond - fun:strchr - fun:dl_open_worker -} -{ - __rawmemchr(Cond) - Memcheck:Cond - fun:__rawmemchr -} -{ - _IO_vfprintf/__strnlen(Cond) - Memcheck:Cond - fun:__strnlen - fun:_IO_vfprintf -} -{ - __strchrnul/gethostbyname*(Cond) - Memcheck:Cond - fun:__strchrnul - fun:gethostbyname* -} - - -##---- -{ - strlen/*dl_map_object*(Cond) - Memcheck:Cond - fun:strlen - fun:*dl_map_object* -} - -{ - strlen/*dl_open_worker*(Cond) - Memcheck:Cond - fun:strlen - fun:*dl_open_worker* -} - -{ - *rawmemchr*/*nss*(Cond) - Memcheck:Cond - fun:*rawmemchr* - fun:*nss* -} - -{ - *strchrnul*/*nss*(Cond) - Memcheck:Cond - fun:*strchrnul* - fun:*nss* -} - -# gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98) -# on Red Hat 7.2 (x86) miscompiles __mpn_construct_double in -# __mpn_construct_double (../sysdeps/ieee754/dbl-64/mpn2dbl.c:45) -# (glibc-2.2.4) to read and write below %esp. Hence the following -# two: -{ - __mpn_construct_double/*(Addr4) - Addrcheck,Memcheck:Addr4 - fun:__mpn_construct_double - fun:* -} -{ - __mpn_construct_double/*(Addr8) - Addrcheck,Memcheck:Addr8 - fun:__mpn_construct_double - fun:* -} - -# More of the same (gcc bug, I'm pretty sure) -{ - __fabs/*(Addr4) - Addrcheck,Memcheck:Addr4 - fun:__fabs - fun:* -} -{ - __fabs/*(Addr8) - Addrcheck,Memcheck:Addr8 - fun:__fabs - fun:* -} - - -# Not sure what this is about ... but anyway -{ - pthread_sighandler/*(Addr4) - Addrcheck,Memcheck:Addr4 - fun:pthread_sighandler - fun:* -} - - -# More glibc stuff, AFAICS - -{ - __strnlen/__argz_stringify/_nl_make_l10nflist(Cond) - Memcheck:Cond - fun:__strnlen - fun:__argz_stringify - fun:_nl_make_l10nflist -} - -#-------------- -{ - _dl_relocate_object*/dl_open_worker/_dl_catch_error*(Cond) - Memcheck:Cond - fun:_dl_relocate_object* - fun:dl_open_worker - fun:_dl_catch_error* -} -{ - _dl_relocate_object/libc-2.2.4.so/_dl_catch_error(Cond) - Memcheck:Cond - fun:_dl_relocate_object - obj:*libc-2.2.?.so - fun:_dl_catch_error -} -{ - _dl_relocate_object/dl_main(Cond) - Memcheck:Cond - fun:_dl_relocate_object - fun:dl_main -} -{ - _dl_relocate_object_internal/dl_main(Cond) - Memcheck:Cond - fun:_dl_relocate_object_internal - fun:dl_main -} - -{ - strrchr/_dl_map_object_from_fd/_dl_map_object(Cond) - Memcheck:Cond - fun:strrchr - fun:_dl_map_object_from_fd - fun:_dl_map_object -} - -{ - _dl_init/ld-2.2.4.so(Cond) - Memcheck:Cond - fun:_dl_start - obj:/lib/ld-2.2.4.so -} - -#------------------- -{ - socketcall.connect(serv_addr)/connect/* - Addrcheck,Memcheck:Param - socketcall.connect(serv_addr) - fun:connect - fun:* -} -{ - socketcall.connect(serv_addr)/libc-2.2.4.so/libc-2.2.4.so - Addrcheck,Memcheck:Param - socketcall.connect(serv_addr) - obj:*libc-2.2.?.so - obj:*libc-2.2.?.so -} - -#---------------------- -{ - write(buf)/write/libX11.so.6.2/libX11.so.6.2(Param) - Addrcheck,Memcheck:Param - write(buf) - fun:write - obj:/usr/X11R6/lib/libX11.so.6.2 - obj:/usr/X11R6/lib/libX11.so.6.2 -} -{ - write(buf)/libc-2.2.4.so/libX11.so.6.2/libX11.so.6.2(Param) - Addrcheck,Memcheck:Param - write(buf) - obj:*libc-2.2.?.so - obj:/usr/X11R6/lib/libX11.so.6.2 - obj:/usr/X11R6/lib/libX11.so.6.2 -} - -#{ -# llseek(result)/lseek64/_IO_file_seek(Param) -# Param -# llseek(result) -# fun:lseek64 -# fun:_IO_file_seek -#} - -{ - writev(vector[...])/__writev/libX11.so.6.2/libX11.so.6.2 - Addrcheck,Memcheck:Param - writev(vector[...]) - fun:__writev - obj:/usr/X11R6/lib/libX11.so.6.2 - obj:/usr/X11R6/lib/libX11.so.6.2 -} - -#---------------- -{ - __rawmemchr/libXt.so.6.0/libXt.so.6.0 - Memcheck:Cond - fun:__rawmemchr - obj:/usr/X11R6/lib/libXt.so.6.0 - obj:/usr/X11R6/lib/libXt.so.6.0 -} -{ - libc-2.2.4.so/libXt.so.6.0/libXt.so.6.0 - Memcheck:Cond - obj:*libc-2.2.?.so - obj:/usr/X11R6/lib/libXt.so.6.0 - obj:/usr/X11R6/lib/libXt.so.6.0 -} - -##----------------------------------------------------------------------## -## For a leak in Valgrind's own libpthread.so :( -{ - my_malloc/get_or_allocate_specifics_ptr/pthread_key_create(Leak) - Memcheck:Leak - fun:malloc - fun:my_malloc - fun:get_or_allocate_specifics_ptr - fun:pthread_key_create -} - - diff --git a/VEX/head20041019/glibc-2.3.supp b/VEX/head20041019/glibc-2.3.supp deleted file mode 100644 index 4d0161cd7..000000000 --- a/VEX/head20041019/glibc-2.3.supp +++ /dev/null @@ -1,235 +0,0 @@ - -##----------------------------------------------------------------------## - -# Errors to suppress by default with glibc 2.3.x - -# Format of this file is: -# { -# name_of_suppression -# tool_name:supp_kind -# (optional extra info for some suppression types) -# caller0 name, or /name/of/so/file.so -# caller1 name, or ditto -# (optionally: caller2 name) -# (optionally: caller3 name) -# } -# -# For Memcheck, the supp_kinds are: -# -# Param Value1 Value2 Value4 Value8 Value16 -# Free Addr1 Addr2 Addr4 Addr8 Addr16 -# Cond (previously known as Value0) -# -# and the optional extra info is: -# if Param: name of system call param -# if Free: name of free-ing fn) - -{ - __GI___stpcpy/* - Memcheck:Cond - fun:__GI___stpcpy - fun:* -} -{ - strlen/__GI__dl_open/dlopen_doit - Memcheck:Cond - fun:strlen - fun:__GI__dl_open - fun:dlopen_doit -} -{ - strlen/_dl_signal_cerror/_dl_lookup_symbol_internal/do_dlsym - Memcheck:Cond - fun:_dl_signal_cerror - fun:_dl_lookup_symbol_internal - fun:do_dlsym -} -{ - strlen/*dl_map_object*(Cond) - Memcheck:Cond - fun:strlen - fun:*dl_map_object* -} - -{ - strlen/*dl_open_worker*(Cond) - Memcheck:Cond - fun:strlen - fun:*dl_open_worker* -} -{ - strlen/_dl_sym/dlsym_doit - Memcheck:Cond - fun:strlen - fun:_dl_sym - fun:dlsym_doit -} -{ - realpath is inefficiently coded - Addrcheck,Memcheck:Overlap - fun:memcpy - fun:realpath* -} - -{ - realpath stupidity part II - Addrcheck,Memcheck:Overlap - fun:strcpy - fun:realpath* -} -{ - strlen/decompose_rpath/_dl_map_object - Memcheck:Cond - fun:strlen - fun:decompose_rpath - fun:*dl_map_object* -} -{ - stpcpy/_dl_sym* - Memcheck:Cond - fun:__stpcpy - fun:_dl_* -} - -#-------- For R H 8.0 -{ - elf_dynamic_do_rel.7/_dl_relocate_object_internal/dl_open_worker(Cond) - Memcheck:Cond - fun:elf_dynamic_do_rel.7 - fun:_dl_relocate_object_internal - fun:dl_open_worker -} -{ - dl_relocate/dl_open_worker - Memcheck:Cond - fun:_dl_relocate_object_internal - fun:dl_open_worker -} - -#-------- glibc 2.3.2/ Fedora Core 1 -{ - dl_relocate/dl_main - Memcheck:Cond - fun:_dl_relocate_object_internal - fun:dl_main -} - -#-------- glibc 2.3.3/ Fedora Core 2 -{ - dl_relocate_object/dl_main - Memcheck:Cond - fun:_dl_relocate_object - fun:dl_main -} -{ - _dl_relocate_object/dl_open_worker - Memcheck:Cond - fun:_dl_relocate_object - fun:dl_open_worker -} - -#-------- Data races -{ - _dl_lookup_symbol_internal/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_symbol_internal - fun:fixup - fun:_dl_runtime_resolve -} -{ - _dl_lookup_symbol_x/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_symbol_x - fun:fixup - fun:_dl_runtime_resolve -} -{ - _dl_lookup_versioned_symbol_internal/fixup/_dl_runtime_resolve - Helgrind:Eraser - fun:_dl_lookup_versioned_symbol_internal - fun:fixup - fun:_dl_runtime_resolve -} -{ - _dl_lookup_versioned_symbol/ld-2.3.2.so/ld-2.3.2.so - Helgrind:Eraser - fun:_dl_lookup_versioned_symbol - obj:/lib/ld-2.3.2.so - obj:/lib/ld-2.3.2.so -} -{ - _dl_fini - Helgrind:Eraser - fun:_dl_fini -} - -#-------- Threading bugs? -# glibc 'knows' that destroying a locked mutex will unlock it -{ - pthread_error/pthread_mutex_destroy/__closedir - core:PThread - fun:pthread_error - fun:pthread_mutex_destroy - fun:__closedir -} - -{ - pthread_error/pthread_mutex_destroy/_IO_default_finish - core:PThread - fun:pthread_error - fun:pthread_mutex_destroy - fun:_IO_default_finish* -} - -{ - pthread_mutex_unlock/_IO_funlockfile - core:PThread - fun:pthread_mutex_unlock - fun:_IO_funlockfile -} - -##----------------------------------------------------------------------## -## For a leak in Valgrind's own libpthread.so :( -{ - my_malloc/get_or_allocate_specifics_ptr/pthread_key_create(Leak) - Memcheck:Leak - fun:malloc - fun:my_malloc - fun:get_or_allocate_specifics_ptr - fun:pthread_key_create -} - -##----------------------------------------------------------------------## -## Bugs in helper library supplied with Intel Icc 7.0 (65) -## in /opt/intel/compiler70/ia32/lib/libcxa.so.3 -{ - Intel compiler70/ia32/lib/libcxa.so.3 below-esp accesses - Addrcheck,Memcheck:Addr4 - obj:/opt/intel/compiler70/ia32/lib/libcxa.so.3 -} - -##----------------------------------------------------------------------## -## SuSE 9 after FV changes (post 2.1.0) - -{ - strlen/_dl_init_paths/dl_main/_dl_sysdep_start(Cond) - Memcheck:Cond - fun:strlen - fun:_dl_init_paths - fun:dl_main - fun:_dl_sysdep_start -} - -{ - Ugly strchr error in /lib/ld-2.3.2.so - Memcheck:Cond - obj:/lib/ld-2.3.2.so -} - -##----------------------------------------------------------------------## -## SuSE 9.1 with post 2.1.2 -{ - Ugly strchr error in /lib/ld-2.3.3.so - Memcheck:Cond - obj:/lib/ld-2.3.3.so -} diff --git a/VEX/head20041019/helgrind/.cvsignore b/VEX/head20041019/helgrind/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/helgrind/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/helgrind/CVS/Entries b/VEX/head20041019/helgrind/CVS/Entries deleted file mode 100644 index 1b4161fbc..000000000 --- a/VEX/head20041019/helgrind/CVS/Entries +++ /dev/null @@ -1,6 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:32 2002// -/Makefile.am/1.49/Wed Sep 1 23:20:48 2004// -/helgrind.h/1.7/Sun Jan 4 16:43:22 2004// -/hg_main.c/1.84/Tue Sep 7 10:17:01 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/helgrind/CVS/Repository b/VEX/head20041019/helgrind/CVS/Repository deleted file mode 100644 index 7b861a38d..000000000 --- a/VEX/head20041019/helgrind/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/helgrind diff --git a/VEX/head20041019/helgrind/CVS/Root b/VEX/head20041019/helgrind/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/helgrind/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/helgrind/CVS/Template b/VEX/head20041019/helgrind/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/Makefile.am b/VEX/head20041019/helgrind/Makefile.am deleted file mode 100644 index 68aa37fd8..000000000 --- a/VEX/head20041019/helgrind/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -val_PROGRAMS = vgskin_helgrind.so vgpreload_helgrind.so - -vgskin_helgrind_so_SOURCES = hg_main.c -vgskin_helgrind_so_LDFLAGS = -shared - -vgpreload_helgrind_so_SOURCES = -vgpreload_helgrind_so_LDADD = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_helgrind_so_DEPENDENCIES = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_helgrind_so_LDFLAGS = -shared -Wl,-z,interpose,-z,initfirst - -hgincludedir = $(includedir)/valgrind - -hginclude_HEADERS = helgrind.h - diff --git a/VEX/head20041019/helgrind/docs/.cvsignore b/VEX/head20041019/helgrind/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/helgrind/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/helgrind/docs/CVS/Entries b/VEX/head20041019/helgrind/docs/CVS/Entries deleted file mode 100644 index 13e4e9f41..000000000 --- a/VEX/head20041019/helgrind/docs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Thu Oct 3 10:07:33 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:05 2004// -/hg_main.html/1.4/Fri Nov 14 17:47:53 2003// -D diff --git a/VEX/head20041019/helgrind/docs/CVS/Repository b/VEX/head20041019/helgrind/docs/CVS/Repository deleted file mode 100644 index ce80b6dab..000000000 --- a/VEX/head20041019/helgrind/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/helgrind/docs diff --git a/VEX/head20041019/helgrind/docs/CVS/Root b/VEX/head20041019/helgrind/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/helgrind/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/helgrind/docs/CVS/Template b/VEX/head20041019/helgrind/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/docs/Makefile.am b/VEX/head20041019/helgrind/docs/Makefile.am deleted file mode 100644 index 54b4b1bd3..000000000 --- a/VEX/head20041019/helgrind/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = hg_main.html diff --git a/VEX/head20041019/helgrind/docs/hg_main.html b/VEX/head20041019/helgrind/docs/hg_main.html deleted file mode 100644 index 74ee451e9..000000000 --- a/VEX/head20041019/helgrind/docs/hg_main.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - Helgrind: a data-race detector - - - -

6  Helgrind: a data-race detector

- -To use this tool, you must specify --tool=helgrind on the -Valgrind command line. -

- -Helgrind is a Valgrind tool for detecting data races in C and C++ programs -that use the Pthreads library. -

-It uses the Eraser algorithm described in -

- Eraser: A Dynamic Data Race Detector for Multithreaded Programs
- Stefan Savage, Michael Burrows, Greg Nelson, Patrick Sobalvarro and - Thomas Anderson
- ACM Transactions on Computer Systems, 15(4):391-411
- November 1997. -
- -We also incorporate significant improvements from this paper: - -
- Runtime Checking of Multithreaded Applications with Visual Threads - Jerry J. Harrow, Jr.
- Proceedings of the 7th International SPIN Workshop on Model Checking of - Software
- Stanford, California, USA
- August 2000
- LNCS 1885, pp331--342
- K. Havelund, J. Penix, and W. Visser, editors.
-
- -

-Basically what Helgrind does is to look for memory locations which are -accessed by more than one thread. For each such location, Helgrind -records which of the program's (pthread_mutex_)locks were held by the -accessing thread at the time of the access. The hope is to discover -that there is indeed at least one lock which is used by all threads to -protect that location. If no such lock can be found, then there is -(apparently) no consistent locking strategy being applied for that -location, and so a possible data race might result. -

-Helgrind also allows for "thread segment lifetimes". If the execution of two -threads cannot overlap -- for example, if your main thread waits on another -thread with a pthread_join() operation -- they can both access the -same variable without holding a lock. -

-There's a lot of other sophistication in Helgrind, aimed at -reducing the number of false reports, and at producing useful error -reports. We hope to have more documentation one day... - - - - diff --git a/VEX/head20041019/helgrind/helgrind.h b/VEX/head20041019/helgrind/helgrind.h deleted file mode 100644 index 593b8a82b..000000000 --- a/VEX/head20041019/helgrind/helgrind.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (helgrind.h) only. The entire rest of Valgrind is licensed - under the terms of the GNU General Public License, version 2. See - the COPYING file in the source distribution for details. - - ---------------------------------------------------------------- - - This file is part of helgrind, a Valgrind tool for detecting - data races in threaded programs. - - Copyright (C) 2002-2004 Nicholas Nethercote. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (helgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - -#ifndef __HELGRIND_H -#define __HELGRIND_H - -#include "valgrind.h" - -typedef - enum { - VG_USERREQ__HG_CLEAN_MEMORY = VG_USERREQ_SKIN_BASE('H','G'), - VG_USERREQ__HG_KNOWN_RACE - } Vg_HelgrindClientRequest; - -/* Clean memory state. This makes Helgrind forget everything it knew - about the specified memory range, and resets it to virgin. This is - particularly useful for memory allocators who wish to recycle - memory. */ -#define VALGRIND_HG_CLEAN_MEMORY(_qzz_start, _qzz_len) \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__HG_CLEAN_MEMORY, \ - _qzz_start, _qzz_len, 0, 0); \ - (void)0; \ - } while(0) - -/* Mark memory as known racy. This puts the memory range specified - into the error state, so that data race errors are not reported - against it. */ -#define VALGRIND_HG_KNOWN_RACE(_qzz_start, _qzz_len) \ - do { \ - unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__HG_KNOWN_RACE, \ - _qzz_start, _qzz_len, 0, 0); \ - (void)0; \ - } while(0) - -#endif /* __HELGRIND_H */ diff --git a/VEX/head20041019/helgrind/hg_main.c b/VEX/head20041019/helgrind/hg_main.c deleted file mode 100644 index ff869bd4e..000000000 --- a/VEX/head20041019/helgrind/hg_main.c +++ /dev/null @@ -1,3419 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Helgrind: checking for data races in threaded programs. ---*/ -/*--- hg_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Helgrind, a Valgrind tool for detecting - data races in threaded programs. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" -#include "helgrind.h" - -static UInt n_eraser_warnings = 0; -static UInt n_lockorder_warnings = 0; - -/*------------------------------------------------------------*/ -/*--- Debug guff ---*/ -/*------------------------------------------------------------*/ - -#define DEBUG_LOCK_TABLE 0 /* Print lock table at end */ - -#define DEBUG_MAKE_ACCESSES 0 /* Print make_access() calls */ -#define DEBUG_LOCKS 0 /* Print lock()/unlock() calls and locksets */ -#define DEBUG_NEW_LOCKSETS 0 /* Print new locksets when created */ -#define DEBUG_ACCESSES 0 /* Print reads, writes */ -#define DEBUG_MEM_LOCKSET_CHANGES 0 - /* Print when an address's lockset - changes; only useful with - DEBUG_ACCESSES */ -#define SLOW_ASSERTS 0 /* do expensive asserts */ -#define DEBUG_VIRGIN_READS 0 /* Dump around address on VIRGIN reads */ - -#if SLOW_ASSERTS -#define SK_ASSERT(x) sk_assert(x) -#else -#define SK_ASSERT(x) -#endif - -/* heavyweight LockSet sanity checking: - 0 == never - 1 == after important ops - 2 == As 1 and also after pthread_mutex_* ops (excessively slow) - */ -#define LOCKSET_SANITY 0 - -/* Rotate an unsigned quantity left */ -#define ROTL(x, n) (((x) << (n)) | ((x) >> ((sizeof(x)*8)-(n)))) - -/* round a up to the next multiple of N. N must be a power of 2 */ -#define ROUNDUP(a, N) ((a + N - 1) & ~(N-1)) - -/* Round a down to the next multiple of N. N must be a power of 2 */ -#define ROUNDDN(a, N) ((a) & ~(N-1)) - -/*------------------------------------------------------------*/ -/*--- Command line options ---*/ -/*------------------------------------------------------------*/ - -static enum { - EC_None, - EC_Some, - EC_All -} clo_execontext = EC_None; - -static Bool clo_priv_stacks = False; - -/*------------------------------------------------------------*/ -/*--- Crude profiling machinery. ---*/ -/*------------------------------------------------------------*/ - -// PPP: work out if I want this - -#define PROF_EVENT(x) -#if 0 -#ifdef VG_PROFILE_MEMORY - -#define N_PROF_EVENTS 150 - -static UInt event_ctr[N_PROF_EVENTS]; - -void VGE_(done_prof_mem) ( void ) -{ - Int i; - for (i = 0; i < N_PROF_EVENTS; i++) { - if ((i % 10) == 0) - VG_(printf)("\n"); - if (event_ctr[i] > 0) - VG_(printf)( "prof mem event %2d: %d\n", i, event_ctr[i] ); - } - VG_(printf)("\n"); -} - -#define PROF_EVENT(ev) \ - do { sk_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \ - event_ctr[ev]++; \ - } while (False); - -#else - -//static void init_prof_mem ( void ) { } -// void VG_(done_prof_mem) ( void ) { } - -#define PROF_EVENT(ev) /* */ - -#endif /* VG_PROFILE_MEMORY */ - -/* Event index. If just the name of the fn is given, this means the - number of calls to the fn. Otherwise it is the specified event. - - [PPP: snip event numbers...] -*/ -#endif /* 0 */ - - -/*------------------------------------------------------------*/ -/*--- Data defns. ---*/ -/*------------------------------------------------------------*/ - -typedef - struct _HG_Chunk { - struct _HG_Chunk* next; - Addr data; /* ptr to actual block */ - Int size; /* size requested */ - ExeContext* where; /* where it was allocated */ - ThreadId tid; /* allocating thread */ - } - HG_Chunk; - -typedef enum - { Vge_VirginInit, Vge_NonVirginInit, Vge_SegmentInit, Vge_Error } - VgeInitStatus; - - -/* Should add up to 32 to fit in one word */ -#define OTHER_BITS 30 -#define STATE_BITS 2 - -#define ESEC_MAP_WORDS 16384 /* Words per secondary map */ - -/* This is for indicating that a memory block has been initialised but not - * really directly by a particular thread... (eg. text/data initialised - * automatically at startup). - * Must be different to virgin_word.other */ -#define TID_INDICATING_NONVIRGIN 1 - -/* Magic packed TLS used for error suppression; if word state is Excl - and tid is this, then it means all access are OK without changing - state and without raising any more errors */ -#define TLSP_INDICATING_ALL ((1 << OTHER_BITS) - 1) - -/* Number of entries must fit in STATE_BITS bits */ -typedef enum { Vge_Virgin, Vge_Excl, Vge_Shar, Vge_SharMod } pth_state; - -static inline const Char *pp_state(pth_state st) -{ - const Char *ret; - - switch(st) { - case Vge_Virgin: ret = "virgin"; break; - case Vge_Excl: ret = "exclusive"; break; - case Vge_Shar: ret = "shared RO"; break; - case Vge_SharMod: ret = "shared RW"; break; - default: ret = "???"; - } - return ret; -} - -typedef - struct { - /* gcc arranges this bitfield with state in the 2LSB and other - in the 30MSB, which is what we want */ - UInt state:STATE_BITS; - UInt other:OTHER_BITS; - } shadow_word; - -#define SW(st, other) ((shadow_word) { st, other }) - -typedef - struct { - shadow_word swords[ESEC_MAP_WORDS]; - } - ESecMap; - -static ESecMap* primary_map[ 65536 ]; -static ESecMap distinguished_secondary_map; - -static const shadow_word virgin_sword = SW(Vge_Virgin, 0); -static const shadow_word error_sword = SW(Vge_Excl, TLSP_INDICATING_ALL); - -#define VGE_IS_DISTINGUISHED_SM(smap) \ - ((smap) == &distinguished_secondary_map) - -#define ENSURE_MAPPABLE(addr,caller) \ - do { \ - if (VGE_IS_DISTINGUISHED_SM(primary_map[(addr) >> 16])) { \ - primary_map[(addr) >> 16] = alloc_secondary_map(caller); \ - /*VG_(printf)("new 2map because of %p\n", addr);*/ \ - } \ - } while(0) - - -/* Parallel map which contains execution contexts when words last - changed state (if required) */ - -typedef struct EC_EIP { - union u_ec_eip { - Addr eip; - ExeContext *ec; - } uu_ec_eip; - UInt state:STATE_BITS; - UInt tls:OTHER_BITS; /* packed TLS */ -} EC_EIP; - -#define NULL_EC_EIP ((EC_EIP){ { 0 }, 0, 0}) - -#define EIP(eip, prev, tls) ((EC_EIP) { (union u_ec_eip)(eip), (prev).state, packTLS(tls) }) -#define EC(ec, prev, tls) ((EC_EIP) { (union u_ec_eip)(ec), (prev).state, packTLS(tls) }) - -static inline UInt packEC(ExeContext *ec) -{ - SK_ASSERT(((UInt)ec & ((1 << STATE_BITS)-1)) == 0); - return ((UInt)ec) >> STATE_BITS; -} - -static inline ExeContext *unpackEC(UInt i) -{ - return (ExeContext *)(i << STATE_BITS); -} - -/* Lose 2 LSB of eip */ -static inline UInt packEIP(Addr eip) -{ - return ((UInt)eip) >> STATE_BITS; -} - -static inline Addr unpackEIP(UInt i) -{ - return (Addr)(i << STATE_BITS); -} - -typedef struct { - EC_EIP execontext[ESEC_MAP_WORDS]; -} ExeContextMap; - -static ExeContextMap** execontext_map; - -static inline void setExeContext(Addr a, EC_EIP ec) -{ - UInt idx = (a >> 16) & 0xffff; - UInt off = (a >> 2) & 0x3fff; - - if (execontext_map[idx] == NULL) { - execontext_map[idx] = VG_(malloc)(sizeof(ExeContextMap)); - VG_(memset)(execontext_map[idx], 0, sizeof(ExeContextMap)); - } - - execontext_map[idx]->execontext[off] = ec; -} - -static inline EC_EIP getExeContext(Addr a) -{ - UInt idx = (a >> 16) & 0xffff; - UInt off = (a >> 2) & 0x3fff; - EC_EIP ec = NULL_EC_EIP; - - if (execontext_map[idx] != NULL) - ec = execontext_map[idx]->execontext[off]; - - return ec; -} - -/*------------------------------------------------------------*/ -/*--- Thread lifetime segments ---*/ -/*------------------------------------------------------------*/ - -/* - * This mechanism deals with the common case of a parent thread - * creating a structure for a child thread, and then passing ownership - * of the structure to that thread. It similarly copes with a child - * thread passing information back to another thread waiting to join - * on it. - * - * Each thread's lifetime can be partitioned into segments. Those - * segments are arranged to form an interference graph which indicates - * whether two thread lifetime segments can possibly be concurrent. - * If not, then memory with is exclusively accessed by one TLS can be - * passed on to another TLS without an error occurring, and without - * moving it from Excl state. - * - * At present this only considers thread creation and join as - * synchronisation events for creating new lifetime segments, but - * others may be possible (like mutex operations). - */ - -typedef struct _ThreadLifeSeg ThreadLifeSeg; - -struct _ThreadLifeSeg { - ThreadId tid; - ThreadLifeSeg *prior[2]; /* Previous lifetime segments */ - UInt refcount; /* Number of memory locations pointing here */ - UInt mark; /* mark used for graph traversal */ - ThreadLifeSeg *next; /* list of all TLS */ -}; - -static ThreadLifeSeg *all_tls; -static UInt tls_since_gc; -#define TLS_SINCE_GC 10000 - -/* current mark used for TLS graph traversal */ -static UInt tlsmark; - -static ThreadLifeSeg *thread_seg[VG_N_THREADS]; - - -static void tls_gc(void) -{ - /* XXX later. Walk through all TLSs and look for ones with 0 - refcount and remove them from the structure and free them. - Could probably get rid of ThreadLifeSeg.refcount and simply use - mark-sweep from the shadow table. */ - VG_(printf)("WRITEME: TLS GC\n"); -} - -static void newTLS(ThreadId tid) -{ - static const Bool debug = False; - ThreadLifeSeg *tls; - - /* Initial NULL */ - if (thread_seg[tid] == NULL) { - tls = VG_(malloc)(sizeof(*tls)); - tls->tid = tid; - tls->prior[0] = tls->prior[1] = NULL; - tls->refcount = 0; - tls->mark = tlsmark-1; - - tls->next = all_tls; - all_tls = tls; - tls_since_gc++; - - thread_seg[tid] = tls; - return; - } - - /* Previous TLS was unused, so just recycle */ - if (thread_seg[tid]->refcount == 0) { - if (debug) - VG_(printf)("newTLS; recycling TLS %p for tid %u\n", - thread_seg[tid], tid); - return; - } - - /* Use existing TLS for this tid as a prior for new TLS */ - tls = VG_(malloc)(sizeof(*tls)); - tls->tid = tid; - tls->prior[0] = thread_seg[tid]; - tls->prior[1] = NULL; - tls->refcount = 0; - tls->mark = tlsmark-1; - - tls->next = all_tls; - all_tls = tls; - if (++tls_since_gc > TLS_SINCE_GC) { - tls_gc(); - tls_since_gc = 0; - } - - if (debug) - VG_(printf)("newTLS: made new TLS %p for tid %u (prior %p(%u))\n", - tls, tid, tls->prior[0], tls->prior[0]->tid); - - thread_seg[tid] = tls; -} - -/* clear out a TLS for a thread that's died */ -static void clearTLS(ThreadId tid) -{ - newTLS(tid); - - thread_seg[tid]->prior[0] = NULL; - thread_seg[tid]->prior[1] = NULL; -} - -static void addPriorTLS(ThreadId tid, ThreadId prior) -{ - static const Bool debug = False; - ThreadLifeSeg *tls = thread_seg[tid]; - - if (debug) - VG_(printf)("making TLS %p(%u) prior to TLS %p(%u)\n", - thread_seg[prior], prior, tls, tid); - - sk_assert(thread_seg[tid] != NULL); - sk_assert(thread_seg[prior] != NULL); - - if (tls->prior[0] == NULL) - tls->prior[0] = thread_seg[prior]; - else { - sk_assert(tls->prior[1] == NULL); - tls->prior[1] = thread_seg[prior]; - } -} - -/* Return True if prior is definitely not concurrent with tls */ -static Bool tlsIsDisjoint(const ThreadLifeSeg *tls, - const ThreadLifeSeg *prior) -{ - Bool isPrior(const ThreadLifeSeg *t) { - if (t == NULL || t->mark == tlsmark) - return False; - - if (t == prior) - return True; - - ((ThreadLifeSeg *)t)->mark = tlsmark; - - return isPrior(t->prior[0]) || isPrior(t->prior[1]); - } - tlsmark++; /* new traversal mark */ - - return isPrior(tls); -} - -static inline UInt packTLS(ThreadLifeSeg *tls) -{ - SK_ASSERT(((UInt)tls & ((1 << STATE_BITS)-1)) == 0); - return ((UInt)tls) >> STATE_BITS; -} - -static inline ThreadLifeSeg *unpackTLS(UInt i) -{ - return (ThreadLifeSeg *)(i << STATE_BITS); -} - -/*------------------------------------------------------------*/ -/*--- Low-level support for memory tracking. ---*/ -/*------------------------------------------------------------*/ - -/* - All reads and writes are recorded in the memory map, which - records the state of all memory in the process. The memory map is - organised like that for normal Valgrind, except each that everything - is done at word-level instead of byte-level, and each word has only - one word of shadow (instead of 36 bits). - - As for normal Valgrind there is a distinguished secondary map. But we're - working at word-granularity, so it has 16k word entries instead of 64k byte - entries. Lookup is done as follows: - - bits 31..16: primary map lookup - bits 15.. 2: secondary map lookup - bits 1.. 0: ignored -*/ - - -/*------------------------------------------------------------*/ -/*--- Basic bitmap management, reading and writing. ---*/ -/*------------------------------------------------------------*/ - -/* Allocate and initialise a secondary map, marking all words as virgin. */ - -/* Just a value that isn't a real pointer */ -#define SEC_MAP_ACCESS (shadow_word*)0x99 - - -static -ESecMap* alloc_secondary_map ( __attribute__ ((unused)) Char* caller ) -{ - ESecMap* map; - UInt i; - //PROF_EVENT(10); PPP - - // Mark all words as virgin. - map = (ESecMap *)VG_(shadow_alloc)(sizeof(ESecMap)); - for (i = 0; i < ESEC_MAP_WORDS; i++) - map->swords[i] = virgin_sword; - - return map; -} - - -/* Set a word. The byte give by 'a' could be anywhere in the word -- the whole - * word gets set. */ -static /* __inline__ */ -void set_sword ( Addr a, shadow_word sword ) -{ - ESecMap* sm; - shadow_word *oldsw; - - //PROF_EVENT(23); PPP - ENSURE_MAPPABLE(a, "VGE_(set_sword)"); - - /* Use bits 31..16 for primary, 15..2 for secondary lookup */ - sm = primary_map[a >> 16]; - sk_assert(sm != &distinguished_secondary_map); - oldsw = &sm->swords[(a & 0xFFFC) >> 2]; - if (oldsw->state == Vge_Excl && oldsw->other != TLSP_INDICATING_ALL) { - ThreadLifeSeg *tls = unpackTLS(oldsw->other); - tls->refcount--; - } - - if (sword.state == Vge_Excl && sword.other != TLSP_INDICATING_ALL) { - ThreadLifeSeg *tls = unpackTLS(sword.other); - tls->refcount++; - } - - sm->swords[(a & 0xFFFC) >> 2] = sword; - - if (VGE_IS_DISTINGUISHED_SM(sm)) { - VG_(printf)("wrote to distinguished 2ndary map! 0x%x\n", a); - // XXX: may be legit, but I want to know when it happens --njn - VG_(skin_panic)("wrote to distinguished 2ndary map!"); - } -} - - -static __inline__ -shadow_word* get_sword_addr ( Addr a ) -{ - /* Use bits 31..16 for primary, 15..2 for secondary lookup */ - ESecMap* sm = primary_map[a >> 16]; - UInt sm_off = (a & 0xFFFC) >> 2; - - if (VGE_IS_DISTINGUISHED_SM(sm)) { - VG_(printf)("accessed distinguished 2ndary map! 0x%x\n", a); - // XXX: may be legit, but I want to know when it happens --njn - //VG_(skin_panic)("accessed distinguished 2ndary map!"); - return SEC_MAP_ACCESS; - } - - //PROF_EVENT(21); PPP - return & (sm->swords[sm_off]); -} - - -// SSS: rename these so they're not so similar to memcheck, unless it's -// appropriate of course - -static __inline__ -void init_virgin_sword(Addr a) -{ - if (clo_execontext != EC_None) - setExeContext(a, NULL_EC_EIP); - set_sword(a, virgin_sword); -} - -static __inline__ -void init_error_sword(Addr a) -{ - set_sword(a, error_sword); -} - -static __inline__ -void init_nonvirgin_sword(Addr a) -{ - shadow_word sword; - ThreadId tid = VG_(get_current_or_recent_tid)(); - ThreadLifeSeg *tls; - - sk_assert(tid != VG_INVALID_THREADID); - tls = thread_seg[tid]; - - sword = SW(Vge_Excl, packTLS(tls)); - set_sword(a, sword); -} - - -/* In this case, we treat it for Eraser's sake like virgin (it hasn't - * been inited by a particular thread, it's just done automatically upon - * startup), but we mark its .state specially so it doesn't look like an - * uninited read. */ -static __inline__ -void init_magically_inited_sword(Addr a) -{ - shadow_word sword; - - sk_assert(VG_INVALID_THREADID == VG_(get_current_tid)()); - - sword = SW(Vge_Virgin, TID_INDICATING_NONVIRGIN); - - set_sword(a, virgin_sword); -} - - -/*------------------------------------------------------------*/ -/*--- Implementation of lock sets. ---*/ -/*------------------------------------------------------------*/ - -typedef struct _Mutex Mutex; /* forward decl */ -typedef struct _LockSet LockSet; - -typedef enum MutexState { - MxUnknown, /* don't know */ - MxUnlocked, /* unlocked */ - MxLocked, /* locked */ - MxDead /* destroyed */ -} MutexState; - -struct _Mutex { - Addr mutexp; - Mutex *next; - - MutexState state; /* mutex state */ - ThreadId tid; /* owner */ - ExeContext *location; /* where the last change happened */ - - const LockSet *lockdep; /* set of locks we depend on */ - UInt mark; /* mark for graph traversal */ -}; - -static inline Int mutex_cmp(const Mutex *a, const Mutex *b) -{ - return a->mutexp - b->mutexp; -} - -struct _LockSet { - Int setsize; /* number of members */ - UInt hash; /* hash code */ - LockSet *next; /* next in hash chain */ - const Mutex *mutex[0]; /* locks */ -}; - -static const LockSet *emptyset; - -/* Each one is an index into the lockset table. */ -static const LockSet *thread_locks[VG_N_THREADS]; - -#define LOCKSET_HASH_SZ 1021 - -static LockSet *lockset_hash[LOCKSET_HASH_SZ]; - -/* Pack and unpack a LockSet pointer into shadow_word.other */ -static inline UInt packLockSet(const LockSet *p) -{ - UInt id; - - SK_ASSERT(((UInt)p & ((1 << STATE_BITS)-1)) == 0); - id = ((UInt)p) >> STATE_BITS; - - return id; -} - -static inline const LockSet *unpackLockSet(UInt id) -{ - return (LockSet *)(id << STATE_BITS); -} - -static -void pp_LockSet(const LockSet* p) -{ - Int i; - VG_(printf)("{ "); - for(i = 0; i < p->setsize; i++) { - const Mutex *mx = p->mutex[i]; - - VG_(printf)("%p%(y ", mx->mutexp, mx->mutexp); - } - VG_(printf)("}\n"); -} - - -static void print_LockSet(const Char *s, const LockSet *ls) -{ - VG_(printf)("%s: ", s); - pp_LockSet(ls); -} - -/* Compute the hash of a LockSet */ -static UInt hash_LockSet_w_wo(const LockSet *ls, - const Mutex *with, - const Mutex *without) -{ - Int i; - UInt hash = ls->setsize + (with != NULL) - (without != NULL); - - sk_assert(with == NULL || with != without); - - for(i = 0; with != NULL || i < ls->setsize; i++) { - const Mutex *mx = i >= ls->setsize ? NULL : ls->mutex[i]; - - if (without && mutex_cmp(without, mx) == 0) - continue; - - if (with && (mx == NULL || mutex_cmp(with, mx) < 0)) { - mx = with; - with = NULL; - i--; - } - - hash = ROTL(hash, 17); - hash ^= (UInt)mx->mutexp; - } - - return hash % LOCKSET_HASH_SZ; -} - -static inline UInt hash_LockSet_with(const LockSet *ls, const Mutex *with) -{ - UInt hash = hash_LockSet_w_wo(ls, with, NULL); - - if (0) - VG_(printf)("hash_with %p+%p -> %d\n", ls, with->mutexp, hash); - - return hash; -} - -static inline UInt hash_LockSet_without(const LockSet *ls, const Mutex *without) -{ - UInt hash = hash_LockSet_w_wo(ls, NULL, without); - - if (0) - VG_(printf)("hash_with %p-%p -> %d\n", ls, without->mutexp, hash); - - return hash; -} - -static inline UInt hash_LockSet(const LockSet *ls) -{ - UInt hash = hash_LockSet_w_wo(ls, NULL, NULL); - - if (0) - VG_(printf)("hash %p -> %d\n", ls, hash); - - return hash; -} - -static -Bool structural_eq_LockSet(const LockSet* a, const LockSet* b) -{ - Int i; - - if (a == b) - return True; - if (a->setsize != b->setsize) - return False; - - for(i = 0; i < a->setsize; i++) { - if (mutex_cmp(a->mutex[i], b->mutex[i]) != 0) - return False; - } - - return True; -} - - -/* Tricky: equivalent to (compare(insert(missing_elem, a), b)), but - * doesn't do the insertion. Returns True if they match. - */ -static Bool -weird_LockSet_equals(const LockSet* a, const LockSet* b, - const Mutex *missing_mutex) -{ - static const Bool debug = False; - Int ia, ib; - - /* Idea is to try and match each element of b against either an - element of a, or missing_mutex. */ - - if (debug) { - print_LockSet("weird_LockSet_equals a", a); - print_LockSet(" b", b); - VG_(printf)( " missing: %p%(y\n", - missing_mutex->mutexp, missing_mutex->mutexp); - } - - if ((a->setsize + 1) != b->setsize) { - if (debug) - VG_(printf)(" fastpath length mismatch -> 0\n"); - return False; - } - - /* There are three phases to this compare: - 1 the section from the start of a up to missing_mutex - 2 missing mutex itself - 3 the section after missing_mutex to the end of a - */ - - ia = 0; - ib = 0; - - /* 1: up to missing_mutex */ - for(; ia < a->setsize && mutex_cmp(a->mutex[ia], missing_mutex) < 0; ia++, ib++) { - if (debug) { - print_LockSet(" 1:a", a); - print_LockSet(" 1:b", b); - } - if (ib == b->setsize || mutex_cmp(a->mutex[ia], b->mutex[ib]) != 0) - return False; - } - - /* 2: missing_mutex itself */ - if (debug) { - VG_(printf)( " 2:missing: %p%(y\n", - missing_mutex->mutexp, missing_mutex->mutexp); - print_LockSet(" 2: b", b); - } - - sk_assert(ia == a->setsize || mutex_cmp(a->mutex[ia], missing_mutex) >= 0); - - if (ib == b->setsize || mutex_cmp(missing_mutex, b->mutex[ib]) != 0) - return False; - - ib++; - - /* 3: after missing_mutex to end */ - - for(; ia < a->setsize && ib < b->setsize; ia++, ib++) { - if (debug) { - print_LockSet(" 3:a", a); - print_LockSet(" 3:b", b); - } - if (mutex_cmp(a->mutex[ia], b->mutex[ib]) != 0) - return False; - } - - if (debug) - VG_(printf)(" ia=%d ib=%d --> %d\n", ia, ib, ia == a->setsize && ib == b->setsize); - - return ia == a->setsize && ib == b->setsize; -} - - - -static const LockSet *lookup_LockSet(const LockSet *set) -{ - UInt bucket = set->hash; - LockSet *ret; - - for(ret = lockset_hash[bucket]; ret != NULL; ret = ret->next) - if (set == ret || structural_eq_LockSet(set, ret)) - return ret; - - return NULL; -} - -static const LockSet *lookup_LockSet_with(const LockSet *set, Mutex *mutex) -{ - UInt bucket = hash_LockSet_with(set, mutex); - const LockSet *ret; - - for(ret = lockset_hash[bucket]; ret != NULL; ret = ret->next) - if (weird_LockSet_equals(set, ret, mutex)) - return ret; - - return NULL; -} - -static const LockSet *lookup_LockSet_without(const LockSet *set, Mutex *mutex) -{ - UInt bucket = hash_LockSet_without(set, mutex); - const LockSet *ret; - - for(ret = lockset_hash[bucket]; ret != NULL; ret = ret->next) - if (weird_LockSet_equals(ret, set, mutex)) - return ret; - - return NULL; -} - -static void insert_LockSet(LockSet *set) -{ - UInt hash = hash_LockSet(set); - - set->hash = hash; - - sk_assert(lookup_LockSet(set) == NULL); - - set->next = lockset_hash[hash]; - lockset_hash[hash] = set; -} - -static inline -LockSet *alloc_LockSet(UInt setsize) -{ - LockSet *ret = VG_(malloc)(sizeof(*ret) + sizeof(Mutex *) * setsize); - ret->setsize = setsize; - return ret; -} - -static inline -void free_LockSet(LockSet *p) -{ - /* assert: not present in hash */ - VG_(free)(p); -} - -static -void pp_all_LockSets ( void ) -{ - Int i; - Int sets, buckets; - - sets = buckets = 0; - for (i = 0; i < LOCKSET_HASH_SZ; i++) { - const LockSet *ls = lockset_hash[i]; - Bool first = True; - - for(; ls != NULL; ls = ls->next) { - if (first) { - buckets++; - VG_(printf)("[%4d] = ", i); - } else - VG_(printf)(" "); - - sets++; - first = False; - pp_LockSet(ls); - } - } - - VG_(printf)("%d distinct LockSets in %d buckets\n", sets, buckets); -} - -static inline Bool isempty(const LockSet *ls) -{ - return ls == NULL || ls->setsize == 0; -} - -static Bool ismember(const LockSet *ls, const Mutex *mx) -{ - Int i; - - /* XXX use binary search */ - for(i = 0; i < ls->setsize; i++) - if (mutex_cmp(mx, ls->mutex[i]) == 0) - return True; - - return False; -} - -/* Check invariants: - - all locksets are unique - - each set is an array in strictly increasing order of mutex addr -*/ -static -void sanity_check_locksets ( const Char* caller ) -{ - Int i; - const Char *badness; - LockSet *ls; - - for(i = 0; i < LOCKSET_HASH_SZ; i++) { - - for(ls = lockset_hash[i]; ls != NULL; ls = ls->next) { - const Mutex *prev; - Int j; - - if (hash_LockSet(ls) != ls->hash) { - badness = "mismatched hash"; - goto bad; - } - if (ls->hash != (UInt)i) { - badness = "wrong bucket"; - goto bad; - } - if (lookup_LockSet(ls) != ls) { - badness = "non-unique set"; - goto bad; - } - - prev = ls->mutex[0]; - for(j = 1; j < ls->setsize; j++) { - if (mutex_cmp(prev, ls->mutex[j]) >= 0) { - badness = "mutexes out of order"; - goto bad; - } - } - } - } - return; - - bad: - VG_(printf)("sanity_check_locksets: " - "i = %d, ls=%p badness = %s, caller = %s\n", - i, ls, badness, caller); - pp_all_LockSets(); - VG_(skin_panic)("sanity_check_locksets"); -} - -static -LockSet *add_LockSet(const LockSet *ls, const Mutex *mx) -{ - static const Bool debug = False; - LockSet *ret = NULL; - Int i, j; - - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - VG_(printf)("add-IN mutex %p%(y\n", mx->mutexp, mx->mutexp); - print_LockSet("add-IN", ls); - } - - if (debug || LOCKSET_SANITY) - sanity_check_locksets("add-IN"); - - sk_assert(!ismember(ls, mx)); - - ret = alloc_LockSet(ls->setsize+1); - - for(i = j = 0; i < ls->setsize; i++) { - if (debug) - VG_(printf)("i=%d j=%d ls->mutex[i]=%p mx=%p\n", - i, j, ls->mutex[i]->mutexp, mx ? mx->mutexp : 0); - if (mx && mutex_cmp(mx, ls->mutex[i]) < 0) { - ret->mutex[j++] = mx; - mx = NULL; - } - ret->mutex[j++] = ls->mutex[i]; - } - - /* not added in loop - must be after */ - if (mx) - ret->mutex[j++] = mx; - - sk_assert(j == ret->setsize); - - if (debug || LOCKSET_SANITY) { - print_LockSet("add-OUT", ret); - sanity_check_locksets("add-OUT"); - } - return ret; -} - -/* Builds ls with mx removed. mx should actually be in ls! - (a checked assertion). Resulting set should not already - exist in the table (unchecked). -*/ -static -LockSet *remove_LockSet ( const LockSet *ls, const Mutex *mx ) -{ - static const Bool debug = False; - LockSet *ret = NULL; - Int i, j; - - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - print_LockSet("remove-IN", ls); - } - - if (debug || LOCKSET_SANITY) - sanity_check_locksets("remove-IN"); - - sk_assert(ismember(ls, mx)); - - ret = alloc_LockSet(ls->setsize-1); - - for(i = j = 0; i < ls->setsize; i++) { - if (mutex_cmp(ls->mutex[i], mx) == 0) - continue; - ret->mutex[j++] = ls->mutex[i]; - } - - sk_assert(j == ret->setsize); - - if (debug || LOCKSET_SANITY) { - print_LockSet("remove-OUT", ret); - sanity_check_locksets("remove-OUT"); - } - return ret; -} - - -/* Builds the intersection, and then unbuilds it if it's already in the table. - */ -static const LockSet *_intersect(const LockSet *a, const LockSet *b) -{ - static const Bool debug = False; - Int iret; - Int ia, ib; - Int size; - LockSet *ret; - const LockSet *found; - - if (debug || LOCKSET_SANITY) - sanity_check_locksets("intersect-IN"); - - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - print_LockSet("intersect a", a); - print_LockSet("intersect b", b); - } - - /* count the size of the new set */ - size = 0; - ia = ib = 0; - for(size = ia = ib = 0; ia < a->setsize && ib < b->setsize; ) { - if (mutex_cmp(a->mutex[ia], b->mutex[ib]) == 0) { - size++; - ia++; - ib++; - } else if (mutex_cmp(a->mutex[ia], b->mutex[ib]) < 0) { - ia++; - } else { - sk_assert(mutex_cmp(a->mutex[ia], b->mutex[ib]) > 0); - ib++; - } - } - - /* Build the intersection of the two sets */ - ret = alloc_LockSet(size); - for (iret = ia = ib = 0; ia < a->setsize && ib < b->setsize; ) { - if (mutex_cmp(a->mutex[ia], b->mutex[ib]) == 0) { - sk_assert(iret < ret->setsize); - ret->mutex[iret++] = a->mutex[ia]; - ia++; - ib++; - } else if (mutex_cmp(a->mutex[ia], b->mutex[ib]) < 0) { - ia++; - } else { - sk_assert(mutex_cmp(a->mutex[ia], b->mutex[ib]) > 0); - ib++; - } - } - - ret->hash = hash_LockSet(ret); - - /* Now search for it in the table, adding it if not seen before */ - found = lookup_LockSet(ret); - - if (found != NULL) { - free_LockSet(ret); - } else { - insert_LockSet(ret); - found = ret; - } - - if (debug || LOCKSET_SANITY) { - print_LockSet("intersect-OUT", found); - sanity_check_locksets("intersect-OUT"); - } - - return found; -} - -/* inline the fastpath */ -static inline const LockSet *intersect(const LockSet *a, const LockSet *b) -{ - static const Bool debug = False; - - /* Fast case -- when the two are the same */ - if (a == b) { - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - print_LockSet("intersect-same fastpath", a); - } - return a; - } - - if (isempty(a) || isempty(b)) { - if (debug) - VG_(printf)("intersect empty fastpath\n"); - return emptyset; - } - - return _intersect(a, b); -} - - -static const LockSet *ls_union(const LockSet *a, const LockSet *b) -{ - static const Bool debug = False; - Int iret; - Int ia, ib; - Int size; - LockSet *ret; - const LockSet *found; - - if (debug || LOCKSET_SANITY) - sanity_check_locksets("union-IN"); - - /* Fast case -- when the two are the same */ - if (a == b) { - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - print_LockSet("union-same fastpath", a); - } - return a; - } - - if (isempty(a)) { - if (debug) - print_LockSet("union a=empty b", b); - return b; - } - if (isempty(b)) { - if (debug) - print_LockSet("union b=empty a", a); - return a; - } - - if (debug || DEBUG_MEM_LOCKSET_CHANGES) { - print_LockSet("union a", a); - print_LockSet("union b", b); - } - - /* count the size of the new set */ - for(size = ia = ib = 0; (ia < a->setsize) || (ib < b->setsize); ) { - Int cmp; - - if ((ia < a->setsize) && (ib < b->setsize)) - cmp = mutex_cmp(a->mutex[ia], b->mutex[ib]); - else if (ia == a->setsize) - cmp = 1; - else - cmp = -1; - - if (cmp == 0) { - size++; - ia++; - ib++; - } else if (cmp < 0) { - size++; - ia++; - } else { - sk_assert(cmp > 0); - size++; - ib++; - } - } - - /* Build the intersection of the two sets */ - ret = alloc_LockSet(size); - for (iret = ia = ib = 0; (ia < a->setsize) || (ib < b->setsize); ) { - Int cmp; - sk_assert(iret < ret->setsize); - - if ((ia < a->setsize) && (ib < b->setsize)) - cmp = mutex_cmp(a->mutex[ia], b->mutex[ib]); - else if (ia == a->setsize) - cmp = 1; - else - cmp = -1; - - if (cmp == 0) { - ret->mutex[iret++] = a->mutex[ia]; - ia++; - ib++; - } else if (cmp < 0) { - ret->mutex[iret++] = a->mutex[ia]; - ia++; - } else { - sk_assert(cmp > 0); - ret->mutex[iret++] = b->mutex[ib]; - ib++; - } - } - - sk_assert(iret == ret->setsize); - - ret->hash = hash_LockSet(ret); - - /* Now search for it in the table, adding it if not seen before */ - found = lookup_LockSet(ret); - - if (found != NULL) { - if (debug) - print_LockSet("union found existing set", found); - free_LockSet(ret); - } else { - if (debug) - print_LockSet("union inserting new set", ret); - insert_LockSet(ret); - found = ret; - } - - if (debug || LOCKSET_SANITY) { - print_LockSet("union-OUT", found); - sanity_check_locksets("union-OUT"); - } - - return found; -} - -/*------------------------------------------------------------*/ -/*--- Implementation of mutex structure. ---*/ -/*------------------------------------------------------------*/ - -static UInt graph_mark; /* current mark we're using for graph traversal */ - -static void record_mutex_error(ThreadId tid, Mutex *mutex, - Char *str, ExeContext *ec); -static void record_lockgraph_error(ThreadId tid, Mutex *mutex, - const LockSet *lockset_holding, - const LockSet *lockset_prev); - -static void set_mutex_state(Mutex *mutex, MutexState state, ThreadId tid); - -#define M_MUTEX_HASHSZ 1021 - -static Mutex *mutex_hash[M_MUTEX_HASHSZ]; -static UInt total_mutexes; - -static const Char *pp_MutexState(MutexState st) -{ - switch(st) { - case MxLocked: return "Locked"; - case MxUnlocked: return "Unlocked"; - case MxDead: return "Dead"; - case MxUnknown: return "Unknown"; - } - return "???"; -} - -static void pp_all_mutexes() -{ - Int i; - Int locks, buckets; - - locks = buckets = 0; - for(i = 0; i < M_MUTEX_HASHSZ; i++) { - Mutex *mx; - Bool first = True; - - for(mx = mutex_hash[i]; mx != NULL; mx = mx->next) { - if (first) { - buckets++; - VG_(printf)("[%4d] = ", i); - } else - VG_(printf)(" "); - locks++; - first = False; - VG_(printf)("%p [%8s] -> %p%(y\n", - mx, pp_MutexState(mx->state), mx->mutexp, mx->mutexp); - } - } - - VG_(printf)("%d locks in %d buckets (%d allocated)\n", - locks, buckets, total_mutexes); -} - -/* find or create a Mutex for a program's mutex use */ -static Mutex *get_mutex(Addr mutexp) -{ - UInt bucket = ((UInt)mutexp) % M_MUTEX_HASHSZ; - Mutex *mp; - - for(mp = mutex_hash[bucket]; mp != NULL; mp = mp->next) - if (mp->mutexp == mutexp) - return mp; - - total_mutexes++; - - mp = VG_(malloc)(sizeof(*mp)); - mp->mutexp = mutexp; - mp->next = mutex_hash[bucket]; - mutex_hash[bucket] = mp; - - mp->state = MxUnknown; - mp->tid = VG_INVALID_THREADID; - mp->location = NULL; - - mp->lockdep = emptyset; - mp->mark = graph_mark - 1; - - return mp; -} - -/* Find all mutexes in a range of memory, and call the callback. - Remove the mutex from the hash if the callback returns True (mutex - structure itself is not freed, because it may be pointed to by a - LockSet. */ -static void find_mutex_range(Addr start, Addr end, Bool (*action)(Mutex *)) -{ - UInt first = start % M_MUTEX_HASHSZ; - UInt last = (end+1) % M_MUTEX_HASHSZ; - UInt i; - - /* Single pass over the hash table, looking for likely hashes */ - for(i = first; i != last; ) { - Mutex *mx; - Mutex **prev = &mutex_hash[i]; - - for(mx = mutex_hash[i]; mx != NULL; prev = &mx->next, mx = mx->next) { - if (mx->mutexp >= start && mx->mutexp < end && (*action)(mx)) - *prev = mx->next; - } - - if (++i == M_MUTEX_HASHSZ) - i = 0; - } -} - -#define MARK_LOOP (graph_mark+0) -#define MARK_DONE (graph_mark+1) - -static Bool check_cycle_inner(const Mutex *mutex, const LockSet *ls) -{ - static const Bool debug = False; - Int i; - - if (mutex->mark == MARK_LOOP) - return True; /* found cycle */ - if (mutex->mark == MARK_DONE) - return False; /* been here before, its OK */ - - ((Mutex*)mutex)->mark = MARK_LOOP; - - if (debug) - VG_(printf)("mark=%d visiting %p%(y mutex->lockset=%d\n", - graph_mark, mutex->mutexp, mutex->mutexp, mutex->lockdep); - for(i = 0; i < ls->setsize; i++) { - const Mutex *mx = ls->mutex[i]; - - if (debug) - VG_(printf)(" %y ls=%p (ls->mutex=%p%(y)\n", - mutex->mutexp, ls, - mx->mutexp, mx->mutexp); - if (check_cycle_inner(mx, mx->lockdep)) - return True; - } - ((Mutex*)mutex)->mark = MARK_DONE; - - return False; -} - -static Bool check_cycle(const Mutex *start, const LockSet* lockset) -{ - - graph_mark += 2; /* clear all marks */ - - return check_cycle_inner(start, lockset); -} - -/* test to see if a mutex state change would be problematic; this - makes no changes to the mutex state. This should be called before - the locking thread has actually blocked. */ -static void test_mutex_state(Mutex *mutex, MutexState state, ThreadId tid) -{ - static const Bool debug = False; - - if (mutex->state == MxDead) { - Char *str; - - switch(state) { - case MxLocked: str = "lock dead mutex"; break; - case MxUnlocked: str = "unlock dead mutex"; break; - default: str = "operate on dead mutex"; break; - } - - /* can't do anything legal to a destroyed mutex */ - record_mutex_error(tid, mutex, str, mutex->location); - return; - } - - switch(state) { - case MxLocked: - sk_assert(!check_cycle(mutex, mutex->lockdep)); - - if (debug) - print_LockSet("thread holding", thread_locks[tid]); - - if (check_cycle(mutex, thread_locks[tid])) - record_lockgraph_error(tid, mutex, thread_locks[tid], mutex->lockdep); - else { - mutex->lockdep = ls_union(mutex->lockdep, thread_locks[tid]); - - if (debug) { - VG_(printf)("giving mutex %p%(y lockdep = %p ", - mutex->mutexp, mutex->mutexp, mutex->lockdep); - print_LockSet("lockdep", mutex->lockdep); - } - } - break; - - case MxUnlocked: - if (debug) - print_LockSet("thread holding", thread_locks[tid]); - - if (mutex->state != MxLocked) { - record_mutex_error(tid, mutex, - "unlock non-locked mutex", mutex->location); - } - if (mutex->tid != tid) { - record_mutex_error(tid, mutex, - "unlock someone else's mutex", mutex->location); - } - break; - - case MxDead: - break; - - default: - break; - } -} - -/* Update a mutex state. Expects most error testing and reporting to - have happened in test_mutex_state(). The assumption is that no - client code is run by thread tid between test and set, either - because it is blocked or test and set are called together - atomically. - - Setting state to MxDead is the exception, since that can happen as - a result of any thread freeing memory; in this case set_mutex_state - does all the error reporting as well. -*/ -static void set_mutex_state(Mutex *mutex, MutexState state, ThreadId tid) -{ - static const Bool debug = False; - - if (debug) - VG_(printf)("\ntid %d changing mutex (%p)->%p%(y state %s -> %s\n", - tid, mutex, mutex->mutexp, mutex->mutexp, - pp_MutexState(mutex->state), pp_MutexState(state)); - - if (mutex->state == MxDead) { - /* can't do anything legal to a destroyed mutex */ - return; - } - - switch(state) { - case MxLocked: - if (mutex->state == MxLocked) { - if (mutex->tid != tid) - record_mutex_error(tid, mutex, "take lock held by someone else", - mutex->location); - else - record_mutex_error(tid, mutex, "take lock we already hold", - mutex->location); - - VG_(skin_panic)("core should have checked this\n"); - break; - } - - sk_assert(!check_cycle(mutex, mutex->lockdep)); - - mutex->tid = tid; - break; - - case MxUnlocked: - if (debug) - print_LockSet("thread holding", thread_locks[tid]); - - if (mutex->state != MxLocked || mutex->tid != tid) - break; - - mutex->tid = VG_INVALID_THREADID; - break; - - case MxDead: - if (mutex->state == MxLocked) { - /* forcably remove offending lock from thread's lockset */ - sk_assert(ismember(thread_locks[mutex->tid], mutex)); - thread_locks[mutex->tid] = remove_LockSet(thread_locks[mutex->tid], mutex); - mutex->tid = VG_INVALID_THREADID; - - record_mutex_error(tid, mutex, - "free locked mutex", mutex->location); - } - break; - - default: - break; - } - - mutex->location = VG_(get_ExeContext)(tid); - mutex->state = state; -} - -/*------------------------------------------------------------*/ -/*--- Setting and checking permissions. ---*/ -/*------------------------------------------------------------*/ - -/* only clean up dead mutexes */ -static -Bool cleanmx(Mutex *mx) { - return mx->state == MxDead; -} - -static -void set_address_range_state ( Addr a, UInt len /* in bytes */, - VgeInitStatus status ) -{ - Addr end; - -# if DEBUG_MAKE_ACCESSES - VG_(printf)("make_access: 0x%x, %u, status=%u\n", a, len, status); -# endif - //PROF_EVENT(30); PPP - - if (len == 0) - return; - - if (len > 100 * 1000 * 1000) - VG_(message)(Vg_UserMsg, - "Warning: set address range state: large range %d", - len); - - VGP_PUSHCC(VgpSARP); - - /* Remove mutexes in recycled memory range from hash */ - find_mutex_range(a, a+len, cleanmx); - - /* Memory block may not be aligned or a whole word multiple. In neat cases, - * we have to init len/4 words (len is in bytes). In nasty cases, it's - * len/4+1 words. This works out which it is by aligning the block and - * seeing if the end byte is in the same word as it is for the unaligned - * block; if not, it's the awkward case. */ - end = ROUNDUP(a + len, 4); - a = ROUNDDN(a, 4); - - /* Do it ... */ - switch (status) { - case Vge_VirginInit: - for ( ; a < end; a += 4) { - //PROF_EVENT(31); PPP - init_virgin_sword(a); - } - break; - - case Vge_NonVirginInit: - for ( ; a < end; a += 4) { - //PROF_EVENT(31); PPP - init_nonvirgin_sword(a); - } - break; - - case Vge_SegmentInit: - for ( ; a < end; a += 4) { - //PROF_EVENT(31); PPP - init_magically_inited_sword(a); - } - break; - - case Vge_Error: - for ( ; a < end; a += 4) { - //PROF_EVENT(31); PPP - init_error_sword(a); - } - break; - - default: - VG_(printf)("init_status = %u\n", status); - VG_(skin_panic)("Unexpected Vge_InitStatus"); - } - - /* Check that zero page and highest page have not been written to - -- this could happen with buggy syscall wrappers. Today - (2001-04-26) had precisely such a problem with - __NR_setitimer. */ - sk_assert(SK_(cheap_sanity_check)()); - VGP_POPCC(VgpSARP); -} - - -static void make_segment_readable ( Addr a, UInt len ) -{ - //PROF_EVENT(??); PPP - set_address_range_state ( a, len, Vge_SegmentInit ); -} - -static void make_writable ( Addr a, UInt len ) -{ - //PROF_EVENT(36); PPP - set_address_range_state( a, len, Vge_VirginInit ); -} - -static void make_readable ( Addr a, UInt len ) -{ - //PROF_EVENT(37); PPP - set_address_range_state( a, len, Vge_VirginInit ); -} - - -/* Block-copy states (needed for implementing realloc()). */ -static void copy_address_range_state(Addr src, Addr dst, UInt len) -{ - UInt i; - - //PROF_EVENT(40); PPP - for (i = 0; i < len; i += 4) { - shadow_word sword = *(get_sword_addr ( src+i )); - //PROF_EVENT(41); PPP - set_sword ( dst+i, sword ); - } -} - -// SSS: put these somewhere better -static void eraser_mem_read (Addr a, UInt data_size, ThreadId tid); -static void eraser_mem_write(Addr a, UInt data_size, ThreadId tid); - -static void eraser_mem_help_read_1(Addr a) REGPARM(1); -static void eraser_mem_help_read_2(Addr a) REGPARM(1); -static void eraser_mem_help_read_4(Addr a) REGPARM(1); -static void eraser_mem_help_read_N(Addr a, UInt size) REGPARM(2); - -static void eraser_mem_help_write_1(Addr a, UInt val) REGPARM(2); -static void eraser_mem_help_write_2(Addr a, UInt val) REGPARM(2); -static void eraser_mem_help_write_4(Addr a, UInt val) REGPARM(2); -static void eraser_mem_help_write_N(Addr a, UInt size) REGPARM(2); - -static void bus_lock(void); -static void bus_unlock(void); - -static -void eraser_pre_mem_read(CorePart part, ThreadId tid, - Char* s, Addr base, UInt size ) -{ - if (tid > 50) { VG_(printf)("pid = %d, s = `%s`, part = %d\n", tid, s, part); VG_(skin_panic)("a");} - eraser_mem_read(base, size, tid); -} - -static -void eraser_pre_mem_read_asciiz(CorePart part, ThreadId tid, - Char* s, Addr base ) -{ - eraser_mem_read(base, VG_(strlen)((Char*)base), tid); -} - -static -void eraser_pre_mem_write(CorePart part, ThreadId tid, - Char* s, Addr base, UInt size ) -{ - eraser_mem_write(base, size, tid); -} - - - -static -void eraser_new_mem_startup( Addr a, UInt len, Bool rr, Bool ww, Bool xx ) -{ - /* Ignore the permissions, just make it readable. Seems to work... */ - make_segment_readable(a, len); -} - - -static -void eraser_new_mem_heap ( Addr a, UInt len, Bool is_inited ) -{ - if (is_inited) { - make_readable(a, len); - } else { - make_writable(a, len); - } -} - -static -void eraser_set_perms (Addr a, UInt len, - Bool rr, Bool ww, Bool xx) -{ - if (rr) make_readable(a, len); - else if (ww) make_writable(a, len); - /* else do nothing */ -} - -static -void eraser_new_mem_stack_private(Addr a, UInt len) -{ - set_address_range_state(a, len, Vge_NonVirginInit); -} - -static -void eraser_new_mem_stack(Addr a, UInt len) -{ - set_address_range_state(a, len, Vge_VirginInit); -} - -/*--------------------------------------------------------------*/ -/*--- Initialise the memory audit system on program startup. ---*/ -/*--------------------------------------------------------------*/ - -static -void init_shadow_memory(void) -{ - Int i; - - for (i = 0; i < ESEC_MAP_WORDS; i++) - distinguished_secondary_map.swords[i] = virgin_sword; - - /* These entries gradually get overwritten as the used address - space expands. */ - for (i = 0; i < 65536; i++) - primary_map[i] = &distinguished_secondary_map; -} - - -/*------------------------------------------------------------*/ -/*--- malloc() et al replacements ---*/ -/*------------------------------------------------------------*/ - -static VgHashTable hg_malloc_list = NULL; - -#define N_FREED_CHUNKS 2 -static Int freechunkptr = 0; -static HG_Chunk *freechunks[N_FREED_CHUNKS]; - -/* Use a small redzone (paranoia) */ -UInt VG_(vg_malloc_redzone_szB) = 8; - - -/* Allocate a user-chunk of size bytes. Also allocate its shadow - block, make the shadow block point at the user block. Put the - shadow chunk on the appropriate list, and set all memory - protections correctly. */ - -static void add_HG_Chunk ( ThreadId tid, Addr p, UInt size ) -{ - HG_Chunk* hc; - - hc = VG_(malloc)(sizeof(HG_Chunk)); - hc->data = p; - hc->size = size; - hc->where = VG_(get_ExeContext)(tid); - hc->tid = tid; - - VG_(HT_add_node)( hg_malloc_list, (VgHashNode*)hc ); -} - -/* Allocate memory and note change in memory available */ -static __inline__ -void* alloc_and_new_mem ( Int size, UInt alignment, Bool is_zeroed ) -{ - Addr p; - - if (size < 0) return NULL; - - p = (Addr)VG_(cli_malloc)(alignment, size); - if (!p) { - return NULL; - } - if (is_zeroed) VG_(memset)((void*)p, 0, size); - add_HG_Chunk ( VG_(get_current_or_recent_tid)(), p, size ); - eraser_new_mem_heap( p, size, is_zeroed ); - - return (void*)p; -} - -void* SK_(malloc) ( Int n ) -{ - return alloc_and_new_mem ( n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(__builtin_new) ( Int n ) -{ - return alloc_and_new_mem ( n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(__builtin_vec_new) ( Int n ) -{ - return alloc_and_new_mem ( n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(memalign) ( Int align, Int n ) -{ - return alloc_and_new_mem ( n, align, /*is_zeroed*/False ); -} - -void* SK_(calloc) ( Int nmemb, Int size ) -{ - return alloc_and_new_mem ( nmemb*size, VG_(clo_alignment), - /*is_zeroed*/True ); -} - -static ThreadId deadmx_tid; - -static -Bool deadmx(Mutex *mx) { - if (mx->state != MxDead) - set_mutex_state(mx, MxDead, deadmx_tid); - - return False; -} - -static -void die_and_free_mem ( ThreadId tid, HG_Chunk* hc, - HG_Chunk** prev_chunks_next_ptr ) -{ - Addr start = hc->data; - Addr end = start + hc->size; - - /* Remove hc from the malloclist using prev_chunks_next_ptr to - avoid repeating the hash table lookup. Can't remove until at least - after free and free_mismatch errors are done because they use - describe_addr() which looks for it in malloclist. */ - *prev_chunks_next_ptr = hc->next; - - /* Record where freed */ - hc->where = VG_(get_ExeContext) ( tid ); - - /* maintain a small window so that the error reporting machinery - knows about this memory */ - if (freechunks[freechunkptr] != NULL) { - /* free HG_Chunk */ - HG_Chunk* sc1 = freechunks[freechunkptr]; - VG_(cli_free) ( (void*)(sc1->data) ); - VG_(free) ( sc1 ); - } - - freechunks[freechunkptr] = hc; - - if (++freechunkptr == N_FREED_CHUNKS) - freechunkptr = 0; - - /* mark all mutexes in range dead */ - deadmx_tid = tid; - find_mutex_range(start, end, deadmx); -} - - -static __inline__ -void handle_free ( void* p ) -{ - HG_Chunk* hc; - HG_Chunk** prev_chunks_next_ptr; - - hc = (HG_Chunk*)VG_(HT_get_node) ( hg_malloc_list, (UInt)p, - (VgHashNode***)&prev_chunks_next_ptr ); - if (hc == NULL) { - return; - } - die_and_free_mem ( VG_(get_current_or_recent_tid)(), - hc, prev_chunks_next_ptr ); -} - -void SK_(free) ( void* p ) -{ - handle_free(p); -} - -void SK_(__builtin_delete) ( void* p ) -{ - handle_free(p); -} - -void SK_(__builtin_vec_delete) ( void* p ) -{ - handle_free(p); -} - -void* SK_(realloc) ( void* p, Int new_size ) -{ - HG_Chunk *hc; - HG_Chunk **prev_chunks_next_ptr; - Int i; - ThreadId tid = VG_(get_current_or_recent_tid)(); - - /* First try and find the block. */ - hc = (HG_Chunk*)VG_(HT_get_node) ( hg_malloc_list, (UInt)p, - (VgHashNode***)&prev_chunks_next_ptr ); - - if (hc == NULL) { - return NULL; - } - - if (hc->size == new_size) { - /* size unchanged */ - hc->where = VG_(get_ExeContext)(tid); - return p; - - } else if (hc->size > new_size) { - /* new size is smaller */ - hc->size = new_size; - hc->where = VG_(get_ExeContext)(tid); - return p; - - } else { - /* new size is bigger */ - Addr p_new; - - /* Get new memory */ - p_new = (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size); - - /* First half kept and copied, second half new */ - copy_address_range_state( (Addr)p, p_new, hc->size ); - eraser_new_mem_heap ( p_new+hc->size, new_size-hc->size, - /*inited*/False ); - - /* Copy from old to new */ - for (i = 0; i < hc->size; i++) - ((UChar*)p_new)[i] = ((UChar*)p)[i]; - - /* Free old memory */ - die_and_free_mem ( tid, hc, prev_chunks_next_ptr ); - - /* this has to be after die_and_free_mem, otherwise the - former succeeds in shorting out the new block, not the - old, in the case when both are on the same list. */ - add_HG_Chunk ( tid, p_new, new_size ); - - return (void*)p_new; - } -} - -/*--------------------------------------------------------------*/ -/*--- Machinery to support sanity checking ---*/ -/*--------------------------------------------------------------*/ - -Bool SK_(cheap_sanity_check) ( void ) -{ - /* nothing useful we can rapidly check */ - return True; -} - -Bool SK_(expensive_sanity_check)(void) -{ - Int i; - - /* Make sure nobody changed the distinguished secondary. */ - for (i = 0; i < ESEC_MAP_WORDS; i++) - if (distinguished_secondary_map.swords[i].other != virgin_sword.other || - distinguished_secondary_map.swords[i].state != virgin_sword.state) - return False; - - return True; -} - - -/*--------------------------------------------------------------*/ -/*--- Instrumentation ---*/ -/*--------------------------------------------------------------*/ - -static UInt stk_ld, nonstk_ld, stk_st, nonstk_st; - -/* Create and return an instrumented version of cb_in. Free cb_in - before returning. */ -UCodeBlock* SK_(instrument) ( UCodeBlock* cb_in, Addr not_used ) -{ - UCodeBlock* cb; - Int i; - UInstr* u_in; - Int t_size = INVALID_TEMPREG; - Int ntemps; - Bool *stackref = NULL; - Bool locked = False; /* lock prefix */ - - cb = VG_(setup_UCodeBlock)(cb_in); - - /* stackref[] is used for super-simple value tracking to keep note - of which tempregs currently hold a value which is derived from - ESP or EBP, and is therefore likely stack-relative if used as - the address for LOAD or STORE. */ - ntemps = VG_(get_num_temps)(cb); - stackref = VG_(malloc)(sizeof(*stackref) * ntemps); - VG_(memset)(stackref, 0, sizeof(*stackref) * ntemps); - - for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) { - u_in = VG_(get_instr)(cb_in, i); - - switch (u_in->opcode) { - - case NOP: case CALLM_S: case CALLM_E: - break; - - case LOCK: - locked = True; - uInstr0(cb, CCALL, 0); - uCCall(cb, (Addr)bus_lock, 0, 0, False); - break; - - case JMP: case INCEIP: - if (locked) { - uInstr0(cb, CCALL, 0); - uCCall(cb, (Addr)bus_unlock, 0, 0, False); - } - locked = False; - VG_(copy_UInstr)(cb, u_in); - break; - - case GET: - sk_assert(u_in->tag1 == ArchReg); - sk_assert(u_in->tag2 == TempReg); - sk_assert(u_in->val2 < ntemps); - - stackref[u_in->val2] = (u_in->size == 4 && - (u_in->val1 == R_ESP || u_in->val1 == R_EBP)); - VG_(copy_UInstr)(cb, u_in); - break; - - case MOV: - if (u_in->size == 4 && u_in->tag1 == TempReg) { - sk_assert(u_in->tag2 == TempReg); - stackref[u_in->val2] = stackref[u_in->val1]; - } - VG_(copy_UInstr)(cb, u_in); - break; - - case LEA1: - case ADD: case SUB: - if (u_in->size == 4 && u_in->tag1 == TempReg) { - sk_assert(u_in->tag2 == TempReg); - stackref[u_in->val2] |= stackref[u_in->val1]; - } - VG_(copy_UInstr)(cb, u_in); - break; - - case LOAD: { - void (*help)(Addr); - sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size); - sk_assert(u_in->tag1 == TempReg); - - if (!clo_priv_stacks || !stackref[u_in->val1]) { - nonstk_ld++; - - switch(u_in->size) { - case 1: help = eraser_mem_help_read_1; break; - case 2: help = eraser_mem_help_read_2; break; - case 4: help = eraser_mem_help_read_4; break; - default: - VG_(skin_panic)("bad size"); - } - - /* XXX all registers should be flushed to baseblock - here */ - uInstr1(cb, CCALL, 0, TempReg, u_in->val1); - uCCall(cb, (Addr)help, 1, 1, False); - } else - stk_ld++; - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case MMX2_MemRd: - case FPU_R: { - sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size || - 8 == u_in->size || 10 == u_in->size || 108 == u_in->size); - - t_size = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size); - uLiteral(cb, (UInt)u_in->size); - - /* XXX all registers should be flushed to baseblock - here */ - uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False); - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case MMX2a1_MemRd: { - sk_assert(8 == u_in->size); - - t_size = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size); - uLiteral(cb, (UInt)u_in->size); - - /* XXX all registers should be flushed to baseblock - here */ - uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False); - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case SSE2a_MemRd: - case SSE2a1_MemRd: - case SSE3a_MemRd: - case SSE3a1_MemRd: - case SSE3ag_MemRd_RegWr: { - Int addr = (u_in->opcode == SSE3ag_MemRd_RegWr) ? u_in->val1 : u_in->val3; - - sk_assert(u_in->size == 4 || u_in->size == 8 || u_in->size == 16 || u_in->size == 512); - - t_size = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size); - uLiteral(cb, (UInt)u_in->size); - - uInstr2(cb, CCALL, 0, TempReg, addr, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False); - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case STORE: { - void (*help)(Addr, UInt); - sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size); - sk_assert(u_in->tag2 == TempReg); - - if (!clo_priv_stacks || !stackref[u_in->val2]) { - nonstk_st++; - - switch(u_in->size) { - case 1: help = eraser_mem_help_write_1; break; - case 2: help = eraser_mem_help_write_2; break; - case 4: help = eraser_mem_help_write_4; break; - default: - VG_(skin_panic)("bad size"); - } - - /* XXX all registers should be flushed to baseblock - here */ - uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, u_in->val1); - uCCall(cb, (Addr)help, 2, 2, False); - } else - stk_st++; - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case MMX2_MemWr: - case FPU_W: { - sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size || - 8 == u_in->size || 10 == u_in->size || 108 == u_in->size); - - t_size = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size); - uLiteral(cb, (UInt)u_in->size); - /* XXX all registers should be flushed to baseblock - here */ - uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_help_write_N, 2, 2, False); - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - case SSE2a_MemWr: - case SSE3a_MemWr: { - sk_assert(4 == u_in->size || 8 == u_in->size || 16 == u_in->size || - 512 == u_in->size); - - t_size = newTemp(cb); - uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size); - uLiteral(cb, (UInt)u_in->size); - /* XXX all registers should be flushed to baseblock - here */ - uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_help_write_N, 2, 2, False); - - VG_(copy_UInstr)(cb, u_in); - t_size = INVALID_TEMPREG; - break; - } - - default: - /* conservative tromping */ - if (0 && u_in->tag1 == TempReg) /* can val1 ever be dest? */ - stackref[u_in->val1] = False; - if (u_in->tag2 == TempReg) - stackref[u_in->val2] = False; - if (u_in->tag3 == TempReg) - stackref[u_in->val3] = False; - VG_(copy_UInstr)(cb, u_in); - break; - } - } - - VG_(free)(stackref); - VG_(free_UCodeBlock)(cb_in); - return cb; -} - - -/*--------------------------------------------------------------------*/ -/*--- Error and suppression handling ---*/ -/*--------------------------------------------------------------------*/ - -typedef - enum { - /* Possible data race */ - EraserSupp - } - EraserSuppKind; - -/* What kind of error it is. */ -typedef - enum { - EraserErr, /* data-race */ - MutexErr, /* mutex operations */ - LockGraphErr, /* mutex order error */ - } - EraserErrorKind; - -/* The classification of a faulting address. */ -typedef - enum { Undescribed, /* as-yet unclassified */ - Stack, - Unknown, /* classification yielded nothing useful */ - Mallocd, - Freed, - Segment - } - AddrKind; -/* Records info about a faulting address. */ -typedef - struct { - /* ALL */ - AddrKind akind; - /* Freed, Mallocd */ - Int blksize; - /* Freed, Mallocd */ - Int rwoffset; - /* Freed, Mallocd */ - ExeContext* lastchange; - ThreadId lasttid; - /* Stack */ - ThreadId stack_tid; - /* Segment */ - const Char* filename; - const Char* section; - /* True if is just-below %esp -- could be a gcc bug. */ - Bool maybe_gcc; - /* symbolic address description */ - Char *expr; - } - AddrInfo; - -/* What kind of memory access is involved in the error? */ -typedef - enum { ReadAxs, WriteAxs, ExecAxs } - AxsKind; - -/* Extra context for memory errors */ -typedef - struct { - AxsKind axskind; - Int size; - AddrInfo addrinfo; - Bool isWrite; - shadow_word prevstate; - /* MutexErr, LockGraphErr */ - Mutex *mutex; - EC_EIP lasttouched; - ThreadId lasttid; - /* LockGraphErr */ - const LockSet *held_lockset; - const LockSet *prev_lockset; - } - HelgrindError; - -static __inline__ -void clear_AddrInfo ( AddrInfo* ai ) -{ - ai->akind = Unknown; - ai->blksize = 0; - ai->rwoffset = 0; - ai->lastchange = NULL; - ai->lasttid = VG_INVALID_THREADID; - ai->filename = NULL; - ai->section = "???"; - ai->stack_tid = VG_INVALID_THREADID; - ai->maybe_gcc = False; - ai->expr = NULL; -} - -static __inline__ -void clear_HelgrindError ( HelgrindError* err_extra ) -{ - err_extra->axskind = ReadAxs; - err_extra->size = 0; - err_extra->mutex = NULL; - err_extra->lasttouched= NULL_EC_EIP; - err_extra->lasttid = VG_INVALID_THREADID; - err_extra->prev_lockset = 0; - err_extra->held_lockset = 0; - err_extra->prevstate = SW(Vge_Virgin, 0); - clear_AddrInfo ( &err_extra->addrinfo ); - err_extra->isWrite = False; -} - - - -/* Describe an address as best you can, for error messages, - putting the result in ai. */ - -/* Callback for searching malloc'd and free'd lists */ -static Bool addr_is_in_block(VgHashNode *node, void *ap) -{ - HG_Chunk* hc2 = (HG_Chunk*)node; - Addr a = *(Addr *)ap; - - return (hc2->data <= a && a < hc2->data + hc2->size); -} - -static void describe_addr ( Addr a, AddrInfo* ai ) -{ - HG_Chunk* hc; - Int i; - - /* Search for it in segments */ - { - const SegInfo *seg; - - for(seg = VG_(next_seginfo)(NULL); - seg != NULL; - seg = VG_(next_seginfo)(seg)) { - Addr base = VG_(seg_start)(seg); - UInt size = VG_(seg_size)(seg); - const UChar *filename = VG_(seg_filename)(seg); - - if (a >= base && a < base+size) { - ai->akind = Segment; - ai->blksize = size; - ai->rwoffset = a - base; - ai->filename = filename; - - switch(VG_(seg_sect_kind)(a)) { - case Vg_SectText: ai->section = "text"; break; - case Vg_SectData: ai->section = "data"; break; - case Vg_SectBSS: ai->section = "BSS"; break; - case Vg_SectGOT: ai->section = "GOT"; break; - case Vg_SectPLT: ai->section = "PLT"; break; - case Vg_SectUnknown: - default: - ai->section = "???"; break; - } - - return; - } - } - } - - /* Search for a currently malloc'd block which might bracket it. */ - hc = (HG_Chunk*)VG_(HT_first_match)(hg_malloc_list, addr_is_in_block, &a); - if (NULL != hc) { - ai->akind = Mallocd; - ai->blksize = hc->size; - ai->rwoffset = (Int)a - (Int)(hc->data); - ai->lastchange = hc->where; - ai->lasttid = hc->tid; - return; - } - - /* Look in recently freed memory */ - for(i = 0; i < N_FREED_CHUNKS; i++) { - hc = freechunks[i]; - if (hc == NULL) - continue; - - if (a >= hc->data && a < hc->data + hc->size) { - ai->akind = Freed; - ai->blksize = hc->size; - ai->rwoffset = a - hc->data; - ai->lastchange = hc->where; - ai->lasttid = hc->tid; - return; - } - } - - /* Clueless ... */ - ai->akind = Unknown; - return; -} - - -/* Updates the copy with address info if necessary. */ -UInt SK_(update_extra)(Error* err) -{ - HelgrindError* extra; - - extra = (HelgrindError*)VG_(get_error_extra)(err); - if (extra != NULL && Undescribed == extra->addrinfo.akind) { - describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) ); - } - return sizeof(HelgrindError); -} - -static void record_eraser_error ( ThreadId tid, Addr a, Bool is_write, - shadow_word prevstate ) -{ - shadow_word *sw; - HelgrindError err_extra; - - n_eraser_warnings++; - - clear_HelgrindError(&err_extra); - err_extra.isWrite = is_write; - err_extra.addrinfo.akind = Undescribed; - err_extra.prevstate = prevstate; - if (clo_execontext) - err_extra.lasttouched = getExeContext(a); - err_extra.addrinfo.expr = VG_(describe_addr)(tid, a); - - VG_(maybe_record_error)( tid, EraserErr, a, - (is_write ? "writing" : "reading"), - &err_extra); - - sw = get_sword_addr(a); - if (sw->state == Vge_Excl && sw->other != TLSP_INDICATING_ALL) { - ThreadLifeSeg *tls = unpackTLS(sw->other); - tls->refcount--; - } - - set_sword(a, error_sword); -} - -static void record_mutex_error(ThreadId tid, Mutex *mutex, - Char *str, ExeContext *ec) -{ - HelgrindError err_extra; - - clear_HelgrindError(&err_extra); - err_extra.addrinfo.akind = Undescribed; - err_extra.mutex = mutex; - err_extra.lasttouched = EC(ec, virgin_sword, thread_seg[tid]); - err_extra.lasttid = tid; - - VG_(maybe_record_error)(tid, MutexErr, - (Addr)mutex->mutexp, str, &err_extra); -} - -static void record_lockgraph_error(ThreadId tid, Mutex *mutex, - const LockSet *lockset_holding, - const LockSet *lockset_prev) -{ - HelgrindError err_extra; - - n_lockorder_warnings++; - - clear_HelgrindError(&err_extra); - err_extra.addrinfo.akind = Undescribed; - err_extra.mutex = mutex; - - err_extra.lasttouched = EC(mutex->location, virgin_sword, 0); - err_extra.held_lockset = lockset_holding; - err_extra.prev_lockset = lockset_prev; - - VG_(maybe_record_error)(tid, LockGraphErr, mutex->mutexp, "", &err_extra); -} - -Bool SK_(eq_SkinError) ( VgRes not_used, Error* e1, Error* e2 ) -{ - Char *e1s, *e2s; - - sk_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); - - switch (VG_(get_error_kind)(e1)) { - case EraserErr: - return VG_(get_error_address)(e1) == VG_(get_error_address)(e2); - - case MutexErr: - return VG_(get_error_address)(e1) == VG_(get_error_address)(e2); - } - - e1s = VG_(get_error_string)(e1); - e2s = VG_(get_error_string)(e2); - if (e1s != e2s) return False; - if (0 != VG_(strcmp)(e1s, e2s)) return False; - return True; -} - -static void pp_AddrInfo ( Addr a, AddrInfo* ai ) -{ - if (ai->expr != NULL) - VG_(message)(Vg_UserMsg, - " Address %p == %s", a, ai->expr); - - switch (ai->akind) { - case Stack: - VG_(message)(Vg_UserMsg, - " Address %p is on thread %d's stack", - a, ai->stack_tid); - break; - case Unknown: - if (ai->expr != NULL) - break; - - /* maybe_gcc is never set to True! This is a hangover from code - in Memcheck */ - if (ai->maybe_gcc) { - VG_(message)(Vg_UserMsg, - " Address %p is just below %%esp. Possibly a bug in GCC/G++", - a); - VG_(message)(Vg_UserMsg, - " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes"); - } else { - VG_(message)(Vg_UserMsg, - " Address %p is not stack'd, malloc'd or (recently) free'd", a); - } - break; - case Segment: - VG_(message)(Vg_UserMsg, - " Address %p is in %s section of %s", - a, ai->section, ai->filename); - break; - case Mallocd: - case Freed: { - UInt delta; - UChar* relative; - if (ai->rwoffset < 0) { - delta = (UInt)(- ai->rwoffset); - relative = "before"; - } else if (ai->rwoffset >= ai->blksize) { - delta = ai->rwoffset - ai->blksize; - relative = "after"; - } else { - delta = ai->rwoffset; - relative = "inside"; - } - VG_(message)(Vg_UserMsg, - " Address %p is %d bytes %s a block of size %d %s by thread %d", - a, delta, relative, - ai->blksize, - ai->akind == Mallocd ? "alloc'd" : "freed", - ai->lasttid); - - VG_(pp_ExeContext)(ai->lastchange); - break; - } - default: - VG_(skin_panic)("pp_AddrInfo"); - } -} - -static Char *lockset_str(const Char *prefix, const LockSet *lockset) -{ - Char *buf, *cp; - Int i; - - buf = VG_(malloc)((prefix == NULL ? 0 : VG_(strlen)(prefix)) + - lockset->setsize * 120 + - 1); - - cp = buf; - if (prefix) - cp += VG_(sprintf)(cp, "%s", prefix); - - for(i = 0; i < lockset->setsize; i++) - cp += VG_(sprintf)(cp, "%p%(y, ", lockset->mutex[i]->mutexp, - lockset->mutex[i]->mutexp); - - if (lockset->setsize) - cp[-2] = '\0'; - else - *cp = '\0'; - - return buf; -} - -void SK_(pp_SkinError) ( Error* err ) -{ - HelgrindError *extra = (HelgrindError *)VG_(get_error_extra)(err); - Char buf[100]; - Char *msg = buf; - const LockSet *ls; - - *msg = '\0'; - - switch(VG_(get_error_kind)(err)) { - case EraserErr: { - Addr err_addr = VG_(get_error_address)(err); - - VG_(message)(Vg_UserMsg, "Possible data race %s variable at %p %(y", - VG_(get_error_string)(err), err_addr, err_addr); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - pp_AddrInfo(err_addr, &extra->addrinfo); - - switch(extra->prevstate.state) { - case Vge_Virgin: - /* shouldn't be possible to go directly from virgin -> error */ - VG_(sprintf)(buf, "virgin!?"); - break; - - case Vge_Excl: { - ThreadLifeSeg *tls = unpackTLS(extra->prevstate.other); - - sk_assert(tls != unpackTLS(TLSP_INDICATING_ALL)); - VG_(sprintf)(buf, "exclusively owned by thread %u", tls->tid); - break; - } - - case Vge_Shar: - case Vge_SharMod: - ls = unpackLockSet(extra->prevstate.other); - - if (isempty(ls)) { - VG_(sprintf)(buf, "shared %s, no locks", - extra->prevstate.state == Vge_Shar ? "RO" : "RW"); - break; - } - - msg = lockset_str(extra->prevstate.state == Vge_Shar ? - "shared RO, locked by:" : - "shared RW, locked by:", ls); - - break; - } - - if (*msg) - VG_(message)(Vg_UserMsg, " Previous state: %s", msg); - - if (clo_execontext == EC_Some - && extra->lasttouched.uu_ec_eip.eip != 0) { - Char file[100]; - UInt line; - Addr eip = extra->lasttouched.uu_ec_eip.eip; - - VG_(message)(Vg_UserMsg, " Word at %p last changed state from %s by thread %u", - err_addr, - pp_state(extra->lasttouched.state), - unpackTLS(extra->lasttouched.tls)->tid); - - if (VG_(get_filename_linenum)(eip, file, sizeof(file), &line)) { - VG_(message)(Vg_UserMsg, " at %p: %y (%s:%u)", - eip, eip, file, line); - } else if (VG_(get_objname)(eip, file, sizeof(file))) { - VG_(message)(Vg_UserMsg, " at %p: %y (in %s)", - eip, eip, file); - } else { - VG_(message)(Vg_UserMsg, " at %p: %y", eip, eip); - } - } else if (clo_execontext == EC_All - && extra->lasttouched.uu_ec_eip.ec != NULL) { - VG_(message)(Vg_UserMsg, " Word at %p last changed state from %s in tid %u", - err_addr, - pp_state(extra->lasttouched.state), - unpackTLS(extra->lasttouched.tls)->tid); - VG_(pp_ExeContext)(extra->lasttouched.uu_ec_eip.ec); - } - break; - } - - case MutexErr: - VG_(message)(Vg_UserMsg, "Mutex problem at %p%(y trying to %s", - VG_(get_error_address)(err), - VG_(get_error_address)(err), - VG_(get_error_string)(err)); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - if (extra->lasttouched.uu_ec_eip.ec != NULL) { - VG_(message)(Vg_UserMsg, " last touched by thread %d", extra->lasttid); - VG_(pp_ExeContext)(extra->lasttouched.uu_ec_eip.ec); - } - pp_AddrInfo(VG_(get_error_address)(err), &extra->addrinfo); - break; - - case LockGraphErr: { - const LockSet *heldset = extra->held_lockset; - Addr err_addr = VG_(get_error_address)(err); - Int i; - - msg = lockset_str(NULL, heldset); - - VG_(message)(Vg_UserMsg, "Mutex %p%(y locked in inconsistent order", - err_addr, err_addr); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - VG_(message)(Vg_UserMsg, " while holding locks %s", msg); - - for(i = 0; i < heldset->setsize; i++) { - const Mutex *lsmx = heldset->mutex[i]; - - /* needs to be a recursive search+display */ - if (0 && !ismember(lsmx->lockdep, extra->mutex)) - continue; - - VG_(message)(Vg_UserMsg, " %p%(y last locked at", - lsmx->mutexp, lsmx->mutexp); - VG_(pp_ExeContext)(lsmx->location); - VG_(free)(msg); - msg = lockset_str(NULL, lsmx->lockdep); - VG_(message)(Vg_UserMsg, " while depending on locks %s", msg); - } - - break; - } - } - - if (msg != buf) - VG_(free)(msg); -} - - -Bool SK_(recognised_suppression) ( Char* name, Supp *su ) -{ - if (0 == VG_(strcmp)(name, "Eraser")) { - VG_(set_supp_kind)(su, EraserSupp); - return True; - } else { - return False; - } -} - - -Bool SK_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp* su ) -{ - /* do nothing -- no extra suppression info present. Return True to - indicate nothing bad happened. */ - return True; -} - - -Bool SK_(error_matches_suppression)(Error* err, Supp* su) -{ - sk_assert(VG_(get_supp_kind)(su) == EraserSupp); - - return (VG_(get_error_kind)(err) == EraserErr); -} - -extern Char* SK_(get_error_name) ( Error* err ) -{ - if (EraserErr == VG_(get_error_kind)(err)) { - return "Eraser"; - } else { - return NULL; /* Other errors types can't be suppressed */ - } -} - -extern void SK_(print_extra_suppression_info) ( Error* err ) -{ - /* Do nothing */ -} - -static void eraser_pre_mutex_lock(ThreadId tid, void* void_mutex) -{ - Mutex *mutex = get_mutex((Addr)void_mutex); - - test_mutex_state(mutex, MxLocked, tid); -} - -static void eraser_post_mutex_lock(ThreadId tid, void* void_mutex) -{ - static const Bool debug = False; - Mutex *mutex = get_mutex((Addr)void_mutex); - const LockSet* ls; - - set_mutex_state(mutex, MxLocked, tid); - -# if DEBUG_LOCKS - VG_(printf)("lock (%u, %p)\n", tid, mutex->mutexp); -# endif - - /* VG_(printf)("LOCK: held %d, new %p\n", thread_locks[tid], mutex); */ -# if LOCKSET_SANITY > 1 - sanity_check_locksets("eraser_post_mutex_lock-IN"); -# endif - - ls = lookup_LockSet_with(thread_locks[tid], mutex); - - if (ls == NULL) { - LockSet *newset = add_LockSet(thread_locks[tid], mutex); - insert_LockSet(newset); - ls = newset; - } - thread_locks[tid] = ls; - - if (debug || DEBUG_LOCKS) - VG_(printf)("tid %u now has lockset %p\n", tid, ls); - - if (debug || LOCKSET_SANITY > 1) - sanity_check_locksets("eraser_post_mutex_lock-OUT"); -} - - -static void eraser_post_mutex_unlock(ThreadId tid, void* void_mutex) -{ - static const Bool debug = False; - Int i = 0; - Mutex *mutex = get_mutex((Addr)void_mutex); - const LockSet *ls; - - test_mutex_state(mutex, MxUnlocked, tid); - set_mutex_state(mutex, MxUnlocked, tid); - - if (!ismember(thread_locks[tid], mutex)) - return; - - if (debug || DEBUG_LOCKS) - VG_(printf)("unlock(%u, %p%(y)\n", tid, mutex->mutexp, mutex->mutexp); - - if (debug || LOCKSET_SANITY > 1) - sanity_check_locksets("eraser_post_mutex_unlock-IN"); - - ls = lookup_LockSet_without(thread_locks[tid], mutex); - - if (ls == NULL) { - LockSet *newset = remove_LockSet(thread_locks[tid], mutex); - insert_LockSet(newset); - ls = newset; - } - - /* Update the thread's lock vector */ - if (debug || DEBUG_LOCKS) - VG_(printf)("tid %u reverts from %p to lockset %p\n", - tid, thread_locks[tid], i); - - thread_locks[tid] = ls; - - if (debug || LOCKSET_SANITY > 1) - sanity_check_locksets("eraser_post_mutex_unlock-OUT"); -} - - -/* --------------------------------------------------------------------- - Checking memory reads and writes - ------------------------------------------------------------------ */ - -/* Behaviour on reads and writes: - * - * VIR EXCL SHAR SH_MOD - * ---------------------------------------------------------------- - * rd/wr, 1st thread | - EXCL - - - * rd, new thread | - SHAR - - - * wr, new thread | - SH_MOD - - - * rd | error! - SHAR SH_MOD - * wr | EXCL - SH_MOD SH_MOD - * ---------------------------------------------------------------- - */ - -static inline -void dump_around_a(Addr a) -{ - UInt i; - shadow_word* sword; - VG_(printf)("NEARBY:\n"); - for (i = a - 12; i <= a + 12; i += 4) { - sword = get_sword_addr(i); - VG_(printf)(" %x -- tid: %u, state: %u\n", i, sword->other, sword->state); - } -} - -#if DEBUG_ACCESSES - #define DEBUG_STATE(args...) \ - VG_(printf)("(%u) ", size), \ - VG_(printf)(args) -#else - #define DEBUG_STATE(args...) -#endif - -static void eraser_mem_read_word(Addr a, ThreadId tid) -{ - shadow_word* sword /* egcs-2.91.66 complains uninit */ = NULL; - shadow_word prevstate; - ThreadLifeSeg *tls; - const LockSet *ls; - Bool statechange = False; - - static const void *const states[4] = { - [Vge_Virgin] &&st_virgin, - [Vge_Excl] &&st_excl, - [Vge_Shar] &&st_shar, - [Vge_SharMod] &&st_sharmod, - }; - - tls = thread_seg[tid]; - sk_assert(tls != NULL && tls->tid == tid); - - sword = get_sword_addr(a); - if (sword == SEC_MAP_ACCESS) { - VG_(printf)("read distinguished 2ndary map! 0x%x\n", a); - return; - } - - prevstate = *sword; - - goto *states[sword->state]; - - /* This looks like reading of unitialised memory, may be legit. Eg. - * calloc() zeroes its values, so untouched memory may actually be - * initialised. Leave that stuff to Valgrind. */ - st_virgin: - if (TID_INDICATING_NONVIRGIN == sword->other) { - DEBUG_STATE("Read VIRGIN --> EXCL: %8x, %u\n", a, tid); - if (DEBUG_VIRGIN_READS) - dump_around_a(a); - } else { - DEBUG_STATE("Read SPECIAL --> EXCL: %8x, %u\n", a, tid); - } - statechange = True; - *sword = SW(Vge_Excl, packTLS(tls)); /* remember exclusive owner */ - tls->refcount++; - goto done; - - st_excl: { - ThreadLifeSeg *sw_tls = unpackTLS(sword->other); - - if (tls == sw_tls) { - DEBUG_STATE("Read EXCL: %8x, %u\n", a, tid); - } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) { - DEBUG_STATE("Read EXCL/ERR: %8x, %u\n", a, tid); - } else if (tlsIsDisjoint(tls, sw_tls)) { - DEBUG_STATE("Read EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid); - statechange = True; - sword->other = packTLS(tls); - sw_tls->refcount--; - tls->refcount++; - } else { - DEBUG_STATE("Read EXCL(%u) --> SHAR: %8x, %u\n", sw_tls->tid, a, tid); - sw_tls->refcount--; - statechange = True; - *sword = SW(Vge_Shar, packLockSet(thread_locks[tid])); - - if (DEBUG_MEM_LOCKSET_CHANGES) - print_LockSet("excl read locks", unpackLockSet(sword->other)); - } - goto done; - } - - st_shar: - DEBUG_STATE("Read SHAR: %8x, %u\n", a, tid); - sword->other = packLockSet(intersect(unpackLockSet(sword->other), - thread_locks[tid])); - statechange = sword->other != prevstate.other; - goto done; - - st_sharmod: - DEBUG_STATE("Read SHAR_MOD: %8x, %u\n", a, tid); - ls = intersect(unpackLockSet(sword->other), - thread_locks[tid]); - sword->other = packLockSet(ls); - - statechange = sword->other != prevstate.other; - - if (isempty(ls)) { - record_eraser_error(tid, a, False /* !is_write */, prevstate); - } - goto done; - - done: - if (clo_execontext != EC_None && statechange) { - EC_EIP eceip; - - if (clo_execontext == EC_Some) - eceip = EIP(VG_(get_EIP)(tid), prevstate, tls); - else - eceip = EC(VG_(get_ExeContext)(tid), prevstate, tls); - setExeContext(a, eceip); - } -} - -static void eraser_mem_read(Addr a, UInt size, ThreadId tid) -{ - Addr end; - - end = ROUNDUP(a+size, 4); - a = ROUNDDN(a, 4); - - for ( ; a < end; a += 4) - eraser_mem_read_word(a, tid); -} - -static void eraser_mem_write_word(Addr a, ThreadId tid) -{ - ThreadLifeSeg *tls; - shadow_word* sword /* egcs-2.91.66 complains uninit */ = NULL; - shadow_word prevstate; - Bool statechange = False; - static const void *const states[4] = { - [Vge_Virgin] &&st_virgin, - [Vge_Excl] &&st_excl, - [Vge_Shar] &&st_shar, - [Vge_SharMod] &&st_sharmod, - }; - - tls = thread_seg[tid]; - sk_assert(tls != NULL && tls->tid == tid); - - sword = get_sword_addr(a); - if (sword == SEC_MAP_ACCESS) { - VG_(printf)("read distinguished 2ndary map! 0x%x\n", a); - return; - } - - prevstate = *sword; - - goto *states[sword->state]; - - st_virgin: - if (TID_INDICATING_NONVIRGIN == sword->other) - DEBUG_STATE("Write VIRGIN --> EXCL: %8x, %u\n", a, tid); - else - DEBUG_STATE("Write SPECIAL --> EXCL: %8x, %u\n", a, tid); - statechange = True; - *sword = SW(Vge_Excl, packTLS(tls));/* remember exclusive owner */ - tls->refcount++; - goto done; - - st_excl: { - ThreadLifeSeg *sw_tls = unpackTLS(sword->other); - - if (tls == sw_tls) { - DEBUG_STATE("Write EXCL: %8x, %u\n", a, tid); - goto done; - } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) { - DEBUG_STATE("Write EXCL/ERR: %8x, %u\n", a, tid); - goto done; - } else if (tlsIsDisjoint(tls, sw_tls)) { - DEBUG_STATE("Write EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid); - sword->other = packTLS(tls); - sw_tls->refcount--; - tls->refcount++; - goto done; - } else { - DEBUG_STATE("Write EXCL(%u) --> SHAR_MOD: %8x, %u\n", sw_tls->tid, a, tid); - statechange = True; - sw_tls->refcount--; - *sword = SW(Vge_SharMod, packLockSet(thread_locks[tid])); - if(DEBUG_MEM_LOCKSET_CHANGES) - print_LockSet("excl write locks", unpackLockSet(sword->other)); - goto SHARED_MODIFIED; - } - } - - st_shar: - DEBUG_STATE("Write SHAR --> SHAR_MOD: %8x, %u\n", a, tid); - sword->state = Vge_SharMod; - sword->other = packLockSet(intersect(unpackLockSet(sword->other), - thread_locks[tid])); - statechange = True; - goto SHARED_MODIFIED; - - st_sharmod: - DEBUG_STATE("Write SHAR_MOD: %8x, %u\n", a, tid); - sword->other = packLockSet(intersect(unpackLockSet(sword->other), - thread_locks[tid])); - statechange = sword->other != prevstate.other; - - SHARED_MODIFIED: - if (isempty(unpackLockSet(sword->other))) { - record_eraser_error(tid, a, True /* is_write */, prevstate); - } - goto done; - - done: - if (clo_execontext != EC_None && statechange) { - EC_EIP eceip; - - if (clo_execontext == EC_Some) - eceip = EIP(VG_(get_EIP)(tid), prevstate, tls); - else - eceip = EC(VG_(get_ExeContext)(tid), prevstate, tls); - setExeContext(a, eceip); - } -} - -static void eraser_mem_write(Addr a, UInt size, ThreadId tid) -{ - Addr end; - - end = ROUNDUP(a+size, 4); - a = ROUNDDN(a, 4); - - for ( ; a < end; a += 4) - eraser_mem_write_word(a, tid); -} - -#undef DEBUG_STATE - -REGPARM(1) static void eraser_mem_help_read_1(Addr a) -{ - eraser_mem_read(a, 1, VG_(get_current_tid)()); -} - -REGPARM(1) static void eraser_mem_help_read_2(Addr a) -{ - eraser_mem_read(a, 2, VG_(get_current_tid)()); -} - -REGPARM(1) static void eraser_mem_help_read_4(Addr a) -{ - eraser_mem_read(a, 4, VG_(get_current_tid)()); -} - -REGPARM(2) static void eraser_mem_help_read_N(Addr a, UInt size) -{ - eraser_mem_read(a, size, VG_(get_current_tid)()); -} - -REGPARM(2) static void eraser_mem_help_write_1(Addr a, UInt val) -{ - if (*(UChar *)a != val) - eraser_mem_write(a, 1, VG_(get_current_tid)()); -} -REGPARM(2) static void eraser_mem_help_write_2(Addr a, UInt val) -{ - if (*(UShort *)a != val) - eraser_mem_write(a, 2, VG_(get_current_tid)()); -} -REGPARM(2) static void eraser_mem_help_write_4(Addr a, UInt val) -{ - if (*(UInt *)a != val) - eraser_mem_write(a, 4, VG_(get_current_tid)()); -} -REGPARM(2) static void eraser_mem_help_write_N(Addr a, UInt size) -{ - eraser_mem_write(a, size, VG_(get_current_tid)()); -} - -static void hg_thread_create(ThreadId parent, ThreadId child) -{ - if (0) - VG_(printf)("CREATE: %u creating %u\n", parent, child); - - newTLS(child); - addPriorTLS(child, parent); - - newTLS(parent); -} - -static void hg_thread_join(ThreadId joiner, ThreadId joinee) -{ - if (0) - VG_(printf)("JOIN: %u joining on %u\n", joiner, joinee); - - newTLS(joiner); - addPriorTLS(joiner, joinee); - - clearTLS(joinee); -} - -static Int __BUS_HARDWARE_LOCK__; - -static void bus_lock(void) -{ - ThreadId tid = VG_(get_current_tid)(); - eraser_pre_mutex_lock(tid, &__BUS_HARDWARE_LOCK__); - eraser_post_mutex_lock(tid, &__BUS_HARDWARE_LOCK__); -} - -static void bus_unlock(void) -{ - ThreadId tid = VG_(get_current_tid)(); - eraser_post_mutex_unlock(tid, &__BUS_HARDWARE_LOCK__); -} - -/*--------------------------------------------------------------------*/ -/*--- Client requests ---*/ -/*--------------------------------------------------------------------*/ - -Bool SK_(handle_client_request)(ThreadId tid, UInt *args, UInt *ret) -{ - if (!VG_IS_SKIN_USERREQ('H','G',args[0])) - return False; - - switch(args[0]) { - case VG_USERREQ__HG_CLEAN_MEMORY: - set_address_range_state(args[1], args[2], Vge_VirginInit); - *ret = 0; /* meaningless */ - break; - - case VG_USERREQ__HG_KNOWN_RACE: - set_address_range_state(args[1], args[2], Vge_Error); - *ret = 0; /* meaningless */ - break; - - default: - return False; - } - - return True; -} - - -/*--------------------------------------------------------------------*/ -/*--- Setup ---*/ -/*--------------------------------------------------------------------*/ - -void SK_(pre_clo_init)(void) -{ - Int i; - LockSet *empty; - - VG_(details_name) ("Helgrind"); - VG_(details_version) (NULL); - VG_(details_description) ("a data race detector"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 115 ); - - VG_(needs_core_errors)(); - VG_(needs_skin_errors)(); - VG_(needs_data_syms)(); - VG_(needs_client_requests)(); - VG_(needs_command_line_options)(); - VG_(needs_shadow_memory)(); - - VG_(init_new_mem_startup) (& eraser_new_mem_startup); - - /* stack ones not decided until VG_(post_clo_init)() */ - - VG_(init_new_mem_brk) (& make_writable); - VG_(init_new_mem_mmap) (& eraser_new_mem_startup); - - VG_(init_change_mem_mprotect) (& eraser_set_perms); - - VG_(init_ban_mem_stack) (NULL); - - VG_(init_die_mem_stack) (NULL); - VG_(init_die_mem_stack_signal) (NULL); - VG_(init_die_mem_brk) (NULL); - VG_(init_die_mem_munmap) (NULL); - - VG_(init_pre_mem_read) (& eraser_pre_mem_read); - VG_(init_pre_mem_read_asciiz) (& eraser_pre_mem_read_asciiz); - VG_(init_pre_mem_write) (& eraser_pre_mem_write); - VG_(init_post_mem_write) (NULL); - - VG_(init_post_thread_create) (& hg_thread_create); - VG_(init_post_thread_join) (& hg_thread_join); - - VG_(init_pre_mutex_lock) (& eraser_pre_mutex_lock); - VG_(init_post_mutex_lock) (& eraser_post_mutex_lock); - VG_(init_post_mutex_unlock) (& eraser_post_mutex_unlock); - - VG_(register_compact_helper)((Addr) & eraser_mem_help_read_1); - VG_(register_compact_helper)((Addr) & eraser_mem_help_read_2); - VG_(register_compact_helper)((Addr) & eraser_mem_help_read_4); - VG_(register_noncompact_helper)((Addr) & eraser_mem_help_read_N); - - VG_(register_compact_helper)((Addr) & eraser_mem_help_write_1); - VG_(register_compact_helper)((Addr) & eraser_mem_help_write_2); - VG_(register_compact_helper)((Addr) & eraser_mem_help_write_4); - VG_(register_noncompact_helper)((Addr) & eraser_mem_help_write_N); - - VG_(register_noncompact_helper)((Addr) & bus_lock); - VG_(register_noncompact_helper)((Addr) & bus_unlock); - - for(i = 0; i < LOCKSET_HASH_SZ; i++) - lockset_hash[i] = NULL; - - empty = alloc_LockSet(0); - insert_LockSet(empty); - emptyset = empty; - - /* Init lock table and thread segments */ - for (i = 0; i < VG_N_THREADS; i++) { - thread_locks[i] = empty; - - newTLS(i); - } - - init_shadow_memory(); - hg_malloc_list = VG_(HT_construct)(); -} - -Bool SK_(process_cmd_line_option)(Char* arg) -{ - if (VG_CLO_STREQ(arg, "--show-last-access=no")) - clo_execontext = EC_None; - else if (VG_CLO_STREQ(arg, "--show-last-access=some")) - clo_execontext = EC_Some; - else if (VG_CLO_STREQ(arg, "--show-last-access=all")) - clo_execontext = EC_All; - - else VG_BOOL_CLO("--private-stacks", clo_priv_stacks) - - else - return VG_(replacement_malloc_process_cmd_line_option)(arg); - - return True; -} - -void SK_(print_usage)(void) -{ - VG_(printf)( -" --private-stacks=yes|no assume thread stacks are used privately [no]\n" -" --show-last-access=no|some|all\n" -" show location of last word access on error [no]\n" - ); - VG_(replacement_malloc_print_usage)(); -} - -void SK_(print_debug_usage)(void) -{ - VG_(replacement_malloc_print_debug_usage)(); -} - -void SK_(post_clo_init)(void) -{ - void (*stack_tracker)(Addr a, UInt len); - - if (clo_execontext) { - execontext_map = VG_(malloc)(sizeof(ExeContextMap *) * 65536); - VG_(memset)(execontext_map, 0, sizeof(ExeContextMap *) * 65536); - } - - if (clo_priv_stacks) - stack_tracker = & eraser_new_mem_stack_private; - else - stack_tracker = & eraser_new_mem_stack; - - VG_(init_new_mem_stack) (stack_tracker); - VG_(init_new_mem_stack_signal) (stack_tracker); -} - - -void SK_(fini)(Int exitcode) -{ - if (DEBUG_LOCK_TABLE) { - pp_all_LockSets(); - pp_all_mutexes(); - } - - if (LOCKSET_SANITY) - sanity_check_locksets("SK_(fini)"); - - if (VG_(clo_verbosity) > 0) - VG_(message)(Vg_UserMsg, "%u possible data races found; %u lock order problems", - n_eraser_warnings, n_lockorder_warnings); - - if (0) - VG_(printf)("stk_ld:%u+stk_st:%u = %u nonstk_ld:%u+nonstk_st:%u = %u %u%%\n", - stk_ld, stk_st, stk_ld + stk_st, - nonstk_ld, nonstk_st, nonstk_ld + nonstk_st, - ((stk_ld+stk_st)*100) / (stk_ld + stk_st + nonstk_ld + nonstk_st)); -} - -/* Uses a 1:1 mapping */ -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 1.0) - -/*--------------------------------------------------------------------*/ -/*--- end hg_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/helgrind/tests/.cvsignore b/VEX/head20041019/helgrind/tests/.cvsignore deleted file mode 100644 index d43164e02..000000000 --- a/VEX/head20041019/helgrind/tests/.cvsignore +++ /dev/null @@ -1,12 +0,0 @@ -Makefile.in -Makefile -allok -deadlock -inherit -race -race2 -readshared -*.stdout.diff -*.stderr.diff -*.stdout.out -*.stderr.out diff --git a/VEX/head20041019/helgrind/tests/CVS/Entries b/VEX/head20041019/helgrind/tests/CVS/Entries deleted file mode 100644 index 30468eaf0..000000000 --- a/VEX/head20041019/helgrind/tests/CVS/Entries +++ /dev/null @@ -1,45 +0,0 @@ -/.cvsignore/1.4/Wed Oct 13 14:55:07 2004// -/Makefile.am/1.8/Sat Jul 10 14:56:26 2004// -/allok.c/1.1/Thu Oct 16 06:09:41 2003// -/allok.stderr.exp/1.1/Wed Oct 15 22:15:37 2003// -/allok.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/deadlock.c/1.2/Mon Sep 13 20:48:20 2004// -/deadlock.stderr.exp/1.5/Mon Dec 15 09:00:21 2003// -/deadlock.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/filter_stderr/1.4/Thu Nov 6 11:34:52 2003// -/inherit.c/1.2/Fri Apr 16 07:22:42 2004// -/inherit.stderr.exp/1.4/Fri Apr 16 07:22:42 2004// -/inherit.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/insn_basic.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_fpu.stderr.exp/1.1/Sat Mar 27 18:02:37 2004// -/insn_fpu.stdout.exp/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.vgtest/1.1/Sat Mar 27 18:02:37 2004// -/insn_mmx.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmxext.stderr.exp/1.2/Tue Mar 9 08:50:02 2004// -/insn_mmxext.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_mmxext.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse2.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/race.c/1.1/Thu Oct 16 06:09:41 2003// -/race.stderr.exp/1.4/Thu Nov 13 17:53:43 2003// -/race.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/race2.c/1.1/Thu Oct 16 06:09:41 2003// -/race2.stderr.exp/1.4/Thu Nov 13 17:53:43 2003// -/race2.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/readshared.c/1.1/Thu Oct 16 06:09:41 2003// -/readshared.stderr.exp/1.1/Wed Oct 15 22:15:37 2003// -/readshared.vgtest/1.1/Wed Oct 15 22:15:37 2003// -/toobig-allocs.stderr.exp/1.1/Sat Jul 10 14:56:26 2004// -/toobig-allocs.vgtest/1.1/Sat Jul 10 14:56:26 2004// -D diff --git a/VEX/head20041019/helgrind/tests/CVS/Repository b/VEX/head20041019/helgrind/tests/CVS/Repository deleted file mode 100644 index c11c4a19b..000000000 --- a/VEX/head20041019/helgrind/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/helgrind/tests diff --git a/VEX/head20041019/helgrind/tests/CVS/Root b/VEX/head20041019/helgrind/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/helgrind/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/helgrind/tests/CVS/Template b/VEX/head20041019/helgrind/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/Makefile.am b/VEX/head20041019/helgrind/tests/Makefile.am deleted file mode 100644 index 16775a00b..000000000 --- a/VEX/head20041019/helgrind/tests/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -noinst_SCRIPTS = filter_stderr - -INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2 - -EXTRA_DIST = $(noinst_SCRIPTS) \ - allok.stderr.exp allok.vgtest \ - deadlock.stderr.exp deadlock.vgtest \ - inherit.stderr.exp inherit.vgtest \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ - $(addsuffix .stdout.exp,$(INSN_TESTS)) \ - $(addsuffix .vgtest,$(INSN_TESTS)) \ - race.stderr.exp race.vgtest \ - race2.stderr.exp race2.vgtest \ - readshared.stderr.exp readshared.vgtest \ - toobig-allocs.stderr.exp toobig-allocs.vgtest - -check_PROGRAMS = \ - allok deadlock inherit race race2 readshared - -allok_SOURCES = allok.c -deadlock_SOURCES = deadlock.c -inherit_SOURCES = inherit.c -race_SOURCES = race.c -race2_SOURCES = race2.c -readshared_SOURCES = readshared.c - -# force -gstabs, because we don't print symaddr for DWARF yet -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -gstabs -LDADD = -lpthread diff --git a/VEX/head20041019/helgrind/tests/allok.c b/VEX/head20041019/helgrind/tests/allok.c deleted file mode 100644 index 144ce608d..000000000 --- a/VEX/head20041019/helgrind/tests/allok.c +++ /dev/null @@ -1,32 +0,0 @@ -/* All OK */ - -#include - -static pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; - -static int shared; - -static void *th(void *v) -{ - pthread_mutex_lock(&mx); - shared++; - pthread_mutex_unlock(&mx); - - return 0; -} - -int main() -{ - pthread_t a, b; - - pthread_mutex_lock(&mx); - pthread_mutex_unlock(&mx); - - pthread_create(&a, NULL, th, NULL); - pthread_create(&b, NULL, th, NULL); - - pthread_join(a, NULL); - pthread_join(b, NULL); - - return 0; -} diff --git a/VEX/head20041019/helgrind/tests/allok.stderr.exp b/VEX/head20041019/helgrind/tests/allok.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/helgrind/tests/allok.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/helgrind/tests/allok.vgtest b/VEX/head20041019/helgrind/tests/allok.vgtest deleted file mode 100644 index 6063069f7..000000000 --- a/VEX/head20041019/helgrind/tests/allok.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: allok -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/deadlock.c b/VEX/head20041019/helgrind/tests/deadlock.c deleted file mode 100644 index 1142f5cfe..000000000 --- a/VEX/head20041019/helgrind/tests/deadlock.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Simple possible deadlock */ -#include - -static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER; - -static void *t1(void *v) -{ - pthread_mutex_lock(&m1); - pthread_mutex_lock(&m2); - pthread_mutex_unlock(&m1); - pthread_mutex_unlock(&m2); - - return 0; -} - -static void *t2(void *v) -{ - pthread_mutex_lock(&m2); - pthread_mutex_lock(&m1); - pthread_mutex_unlock(&m1); - pthread_mutex_unlock(&m2); - - return 0; -} - -int main() -{ - pthread_t a, b; - - /* prevent spurious messages from the dynamic linker */ - pthread_mutex_lock(&m1); - pthread_mutex_unlock(&m1); - - pthread_create(&a, NULL, t1, NULL); - pthread_create(&b, NULL, t2, NULL); - - pthread_join(a, NULL); - pthread_join(b, NULL); - - return 0; -} - diff --git a/VEX/head20041019/helgrind/tests/deadlock.stderr.exp b/VEX/head20041019/helgrind/tests/deadlock.stderr.exp deleted file mode 100644 index 050d00878..000000000 --- a/VEX/head20041019/helgrind/tests/deadlock.stderr.exp +++ /dev/null @@ -1,15 +0,0 @@ - -Thread 3: -Mutex 0x........(m1) locked in inconsistent order - at 0x........: pthread_mutex_lock (vg_libpthread.c:...) - by 0x........: t2 (deadlock.c:20) - by 0x........: thread_wrapper (vg_libpthread.c:...) - by 0x........: do__quit (vg_scheduler.c:...) - while holding locks 0x........(m2) - 0x........(m2) last locked at - at 0x........: pthread_mutex_lock (vg_libpthread.c:...) - by 0x........: t2 (deadlock.c:19) - by 0x........: thread_wrapper (vg_libpthread.c:...) - by 0x........: do__quit (vg_scheduler.c:...) - while depending on locks 0x........(m1) - diff --git a/VEX/head20041019/helgrind/tests/deadlock.vgtest b/VEX/head20041019/helgrind/tests/deadlock.vgtest deleted file mode 100644 index 38418b486..000000000 --- a/VEX/head20041019/helgrind/tests/deadlock.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: deadlock -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/filter_stderr b/VEX/head20041019/helgrind/tests/filter_stderr deleted file mode 100755 index 92ce7c1b6..000000000 --- a/VEX/head20041019/helgrind/tests/filter_stderr +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh - -# Same as for MemCheck - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | -$dir/../../tests/filter_addresses | - -# Anonymise paths like "section of /foo/bar/helgrind/tests/baz)" -sed "s/section of \/.*helgrind\/tests.*$/section of \/...helgrind\/tests.../" | - -# Anonymise line numbers in vg_scheduler.c -sed "s/vg_scheduler.c:[0-9]\+/vg_scheduler.c:.../" | - -# Output looks like... -# -# ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -# [0] = { } -# ==27116== 0 possible data races found -sed "/ERROR SUMMARY:/ , /0 possible data races found/ d" - diff --git a/VEX/head20041019/helgrind/tests/inherit.c b/VEX/head20041019/helgrind/tests/inherit.c deleted file mode 100644 index 700ec4f5c..000000000 --- a/VEX/head20041019/helgrind/tests/inherit.c +++ /dev/null @@ -1,55 +0,0 @@ -/* test child thread inheriting data */ - -// *** -// -// Helgrind should detect an error on line 48 for this test, but it doesn't! -// -// *** - -#include -#include - -static volatile int shared[2]; - -static void *t1(void *v) -{ - volatile int *ip = (int *)v; - *ip += 44; - *ip *= 2; - sleep(1); - return 0; -} - -static void *t2(void *v) -{ - volatile int *ip = (int *)v; - *ip += 88; - *ip *= 3; - sleep(2); - return 0; -} - -int main() -{ - pthread_t a, b; - volatile int ret = 0; - - sleep(0); - - shared[0] = 22; - shared[1] = 77; - - pthread_create(&a, NULL, t1, (void *)&shared[0]); - pthread_create(&b, NULL, t2, (void *)&shared[1]); - - pthread_join(a, NULL); - - ret += shared[0]; /* no error - a is finished */ - ret += shared[1]; /* expect error - b has not finished, - so we can't touch shared[1] yet */ - - pthread_join(b, NULL); - - - return ret; -} diff --git a/VEX/head20041019/helgrind/tests/inherit.stderr.exp b/VEX/head20041019/helgrind/tests/inherit.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/helgrind/tests/inherit.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/helgrind/tests/inherit.vgtest b/VEX/head20041019/helgrind/tests/inherit.vgtest deleted file mode 100644 index 5db4a7448..000000000 --- a/VEX/head20041019/helgrind/tests/inherit.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: inherit -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/insn_basic.stderr.exp b/VEX/head20041019/helgrind/tests/insn_basic.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_basic.stdout.exp b/VEX/head20041019/helgrind/tests/insn_basic.stdout.exp deleted file mode 100644 index 40cabbcd0..000000000 --- a/VEX/head20041019/helgrind/tests/insn_basic.stdout.exp +++ /dev/null @@ -1,1083 +0,0 @@ -aaa_1 ... ok -aaa_2 ... ok -aaa_3 ... ok -aaa_4 ... ok -aaa_5 ... ok -aaa_6 ... ok -aaa_7 ... ok -aaa_8 ... ok -aad_1 ... ok -aad_2 ... ok -aam_1 ... ok -aam_2 ... ok -aas_1 ... ok -aas_2 ... ok -aas_3 ... ok -aas_4 ... ok -aas_5 ... ok -aas_6 ... ok -aas_7 ... ok -aas_8 ... ok -adcb_1 ... ok -adcb_2 ... ok -adcb_3 ... ok -adcb_4 ... ok -adcb_5 ... ok -adcb_6 ... ok -adcb_7 ... ok -adcb_8 ... ok -adcb_9 ... ok -adcb_10 ... ok -adcb_11 ... ok -adcb_12 ... ok -adcw_1 ... ok -adcw_2 ... ok -adcw_3 ... ok -adcw_4 ... ok -adcw_5 ... ok -adcw_6 ... ok -adcw_7 ... ok -adcw_8 ... ok -adcw_9 ... ok -adcw_10 ... ok -adcw_11 ... ok -adcw_12 ... ok -adcw_13 ... ok -adcw_14 ... ok -adcl_1 ... ok -adcl_2 ... ok -adcl_3 ... ok -adcl_4 ... ok -adcl_5 ... ok -adcl_6 ... ok -adcl_7 ... ok -adcl_8 ... ok -adcl_9 ... ok -adcl_10 ... ok -adcl_11 ... ok -adcl_12 ... ok -adcl_13 ... ok -adcl_14 ... ok -addb_1 ... ok -addb_2 ... ok -addb_3 ... ok -addb_4 ... ok -addb_5 ... ok -addb_6 ... ok -addw_1 ... ok -addw_2 ... ok -addw_3 ... ok -addw_4 ... ok -addw_5 ... ok -addw_6 ... ok -addw_7 ... ok -addl_1 ... ok -addl_2 ... ok -addl_3 ... ok -addl_4 ... ok -addl_5 ... ok -addl_6 ... ok -addl_7 ... ok -andb_1 ... ok -andb_2 ... ok -andb_3 ... ok -andb_4 ... ok -andb_5 ... ok -andb_6 ... ok -andw_1 ... ok -andw_2 ... ok -andw_3 ... ok -andw_4 ... ok -andw_5 ... ok -andw_6 ... ok -andw_7 ... ok -andl_1 ... ok -andl_2 ... ok -andl_3 ... ok -andl_4 ... ok -andl_5 ... ok -andl_6 ... ok -andl_7 ... ok -bsfw_1 ... ok -bsfw_2 ... ok -bsfl_1 ... ok -bsfl_2 ... ok -bsrw_1 ... ok -bsrw_2 ... ok -bsrl_1 ... ok -bsrl_2 ... ok -bswapl_1 ... ok -btw_1 ... ok -btw_2 ... ok -btw_3 ... ok -btw_4 ... ok -btw_5 ... ok -btw_6 ... ok -btw_7 ... ok -btw_8 ... ok -btl_1 ... ok -btl_2 ... ok -btl_3 ... ok -btl_4 ... ok -btl_5 ... ok -btl_6 ... ok -btl_7 ... ok -btl_8 ... ok -btcw_1 ... ok -btcw_2 ... ok -btcw_3 ... ok -btcw_4 ... ok -btcw_5 ... ok -btcw_6 ... ok -btcw_7 ... ok -btcw_8 ... ok -btcl_1 ... ok -btcl_2 ... ok -btcl_3 ... ok -btcl_4 ... ok -btcl_5 ... ok -btcl_6 ... ok -btcl_7 ... ok -btcl_8 ... ok -btrw_1 ... ok -btrw_2 ... ok -btrw_3 ... ok -btrw_4 ... ok -btrw_5 ... ok -btrw_6 ... ok -btrw_7 ... ok -btrw_8 ... ok -btrl_1 ... ok -btrl_2 ... ok -btrl_3 ... ok -btrl_4 ... ok -btrl_5 ... ok -btrl_6 ... ok -btrl_7 ... ok -btrl_8 ... ok -btsw_1 ... ok -btsw_2 ... ok -btsw_3 ... ok -btsw_4 ... ok -btsw_5 ... ok -btsw_6 ... ok -btsw_7 ... ok -btsw_8 ... ok -btsl_1 ... ok -btsl_2 ... ok -btsl_3 ... ok -btsl_4 ... ok -btsl_5 ... ok -btsl_6 ... ok -btsl_7 ... ok -btsl_8 ... ok -cbw_1 ... ok -cbw_2 ... ok -cdq_1 ... ok -cdq_2 ... ok -clc_1 ... ok -clc_2 ... ok -cld_1 ... ok -cld_2 ... ok -cmc_1 ... ok -cmc_2 ... ok -cmpb_1 ... ok -cmpb_2 ... ok -cmpb_3 ... ok -cmpb_4 ... ok -cmpb_5 ... ok -cmpb_6 ... ok -cmpb_7 ... ok -cmpb_8 ... ok -cmpb_9 ... ok -cmpb_10 ... ok -cmpb_11 ... ok -cmpb_12 ... ok -cmpb_13 ... ok -cmpb_14 ... ok -cmpb_15 ... ok -cmpb_16 ... ok -cmpb_17 ... ok -cmpb_18 ... ok -cmpb_19 ... ok -cmpb_20 ... ok -cmpb_21 ... ok -cmpb_22 ... ok -cmpb_23 ... ok -cmpb_24 ... ok -cmpb_25 ... ok -cmpb_26 ... ok -cmpb_27 ... ok -cmpb_28 ... ok -cmpb_29 ... ok -cmpb_30 ... ok -cmpb_31 ... ok -cmpb_32 ... ok -cmpb_33 ... ok -cmpb_34 ... ok -cmpb_35 ... ok -cmpb_36 ... ok -cmpb_37 ... ok -cmpb_38 ... ok -cmpb_39 ... ok -cmpb_40 ... ok -cmpb_41 ... ok -cmpb_42 ... ok -cmpb_43 ... ok -cmpb_44 ... ok -cmpb_45 ... ok -cmpb_46 ... ok -cmpb_47 ... ok -cmpb_48 ... ok -cmpb_49 ... ok -cmpb_50 ... ok -cmpb_51 ... ok -cmpb_52 ... ok -cmpb_53 ... ok -cmpb_54 ... ok -cmpb_55 ... ok -cmpb_56 ... ok -cmpb_57 ... ok -cmpb_58 ... ok -cmpb_59 ... ok -cmpb_60 ... ok -cmpw_1 ... ok -cmpw_2 ... ok -cmpw_3 ... ok -cmpw_4 ... ok -cmpw_5 ... ok -cmpw_6 ... ok -cmpw_7 ... ok -cmpw_8 ... ok -cmpw_9 ... ok -cmpw_10 ... ok -cmpw_11 ... ok -cmpw_12 ... ok -cmpw_13 ... ok -cmpw_14 ... ok -cmpw_15 ... ok -cmpw_16 ... ok -cmpw_17 ... ok -cmpw_18 ... ok -cmpw_19 ... ok -cmpw_20 ... ok -cmpw_21 ... ok -cmpw_22 ... ok -cmpw_23 ... ok -cmpw_24 ... ok -cmpw_25 ... ok -cmpw_26 ... ok -cmpw_27 ... ok -cmpw_28 ... ok -cmpw_29 ... ok -cmpw_30 ... ok -cmpw_31 ... ok -cmpw_32 ... ok -cmpw_33 ... ok -cmpw_34 ... ok -cmpw_35 ... ok -cmpw_36 ... ok -cmpw_37 ... ok -cmpw_38 ... ok -cmpw_39 ... ok -cmpw_40 ... ok -cmpw_41 ... ok -cmpw_42 ... ok -cmpw_43 ... ok -cmpw_44 ... ok -cmpw_45 ... ok -cmpw_46 ... ok -cmpw_47 ... ok -cmpw_48 ... ok -cmpw_49 ... ok -cmpw_50 ... ok -cmpw_51 ... ok -cmpw_52 ... ok -cmpw_53 ... ok -cmpw_54 ... ok -cmpw_55 ... ok -cmpw_56 ... ok -cmpw_57 ... ok -cmpw_58 ... ok -cmpw_59 ... ok -cmpw_60 ... ok -cmpw_61 ... ok -cmpw_62 ... ok -cmpw_63 ... ok -cmpw_64 ... ok -cmpw_65 ... ok -cmpw_66 ... ok -cmpw_67 ... ok -cmpw_68 ... ok -cmpw_69 ... ok -cmpw_70 ... ok -cmpw_71 ... ok -cmpw_72 ... ok -cmpw_73 ... ok -cmpw_74 ... ok -cmpw_75 ... ok -cmpw_76 ... ok -cmpw_77 ... ok -cmpw_78 ... ok -cmpw_79 ... ok -cmpw_80 ... ok -cmpl_1 ... ok -cmpl_2 ... ok -cmpl_3 ... ok -cmpl_4 ... ok -cmpl_5 ... ok -cmpl_6 ... ok -cmpl_7 ... ok -cmpl_8 ... ok -cmpl_9 ... ok -cmpl_10 ... ok -cmpl_11 ... ok -cmpl_12 ... ok -cmpl_13 ... ok -cmpl_14 ... ok -cmpl_15 ... ok -cmpl_16 ... ok -cmpl_17 ... ok -cmpl_18 ... ok -cmpl_19 ... ok -cmpl_20 ... ok -cmpl_21 ... ok -cmpl_22 ... ok -cmpl_23 ... ok -cmpl_24 ... ok -cmpl_25 ... ok -cmpl_26 ... ok -cmpl_27 ... ok -cmpl_28 ... ok -cmpl_29 ... ok -cmpl_30 ... ok -cmpl_31 ... ok -cmpl_32 ... ok -cmpl_33 ... ok -cmpl_34 ... ok -cmpl_35 ... ok -cmpl_36 ... ok -cmpl_37 ... ok -cmpl_38 ... ok -cmpl_39 ... ok -cmpl_40 ... ok -cmpl_41 ... ok -cmpl_42 ... ok -cmpl_43 ... ok -cmpl_44 ... ok -cmpl_45 ... ok -cmpl_46 ... ok -cmpl_47 ... ok -cmpl_48 ... ok -cmpl_49 ... ok -cmpl_50 ... ok -cmpl_51 ... ok -cmpl_52 ... ok -cmpl_53 ... ok -cmpl_54 ... ok -cmpl_55 ... ok -cmpl_56 ... ok -cmpl_57 ... ok -cmpl_58 ... ok -cmpl_59 ... ok -cmpl_60 ... ok -cmpl_61 ... ok -cmpl_62 ... ok -cmpl_63 ... ok -cmpl_64 ... ok -cmpl_65 ... ok -cmpl_66 ... ok -cmpl_67 ... ok -cmpl_68 ... ok -cmpl_69 ... ok -cmpl_70 ... ok -cmpl_71 ... ok -cmpl_72 ... ok -cmpl_73 ... ok -cmpl_74 ... ok -cmpl_75 ... ok -cmpl_76 ... ok -cmpl_77 ... ok -cmpl_78 ... ok -cmpl_79 ... ok -cmpl_80 ... ok -cmpxchgb_1 ... ok -cmpxchgb_2 ... ok -cmpxchgb_3 ... ok -cmpxchgb_4 ... ok -cmpxchgw_1 ... ok -cmpxchgw_2 ... ok -cmpxchgw_3 ... ok -cmpxchgw_4 ... ok -cmpxchgl_1 ... ok -cmpxchgl_2 ... ok -cmpxchgl_3 ... ok -cmpxchgl_4 ... ok -cwd_1 ... ok -cwd_2 ... ok -cwde_1 ... ok -cwde_2 ... ok -daa_1 ... ok -daa_2 ... ok -das_1 ... ok -decb_1 ... ok -decb_2 ... ok -decw_1 ... ok -decw_2 ... ok -decl_1 ... ok -decl_2 ... ok -divb_1 ... ok -divb_2 ... ok -divw_1 ... ok -divw_2 ... ok -divl_1 ... ok -divl_2 ... ok -idivb_1 ... ok -idivb_2 ... ok -idivw_1 ... ok -idivw_2 ... ok -idivl_1 ... ok -idivl_2 ... ok -imulb_1 ... ok -imulb_2 ... ok -imulw_1 ... ok -imulw_2 ... ok -imull_1 ... ok -imull_2 ... ok -imulw_3 ... ok -imulw_4 ... ok -imulw_5 ... ok -imulw_6 ... ok -imulw_7 ... ok -imulw_8 ... ok -imulw_9 ... ok -imulw_10 ... ok -imull_3 ... ok -imull_4 ... ok -imull_5 ... ok -imull_6 ... ok -imull_7 ... ok -imull_8 ... ok -imull_9 ... ok -imull_10 ... ok -incb_1 ... ok -incb_2 ... ok -incw_1 ... ok -incw_2 ... ok -incl_1 ... ok -incl_2 ... ok -lahf_1 ... ok -lahf_2 ... ok -movb_1 ... ok -movb_2 ... ok -movb_3 ... ok -movb_4 ... ok -movb_5 ... ok -movw_1 ... ok -movw_2 ... ok -movw_3 ... ok -movw_4 ... ok -movw_5 ... ok -movl_1 ... ok -movl_2 ... ok -movl_3 ... ok -movl_4 ... ok -movl_5 ... ok -movsbw_1 ... ok -movsbw_2 ... ok -movsbl_1 ... ok -movsbl_2 ... ok -movswl_1 ... ok -movswl_2 ... ok -movzbw_1 ... ok -movzbw_2 ... ok -movzbl_1 ... ok -movzbl_2 ... ok -movzwl_1 ... ok -movzwl_2 ... ok -mulb_1 ... ok -mulb_2 ... ok -mulw_1 ... ok -mulw_2 ... ok -mull_1 ... ok -mull_2 ... ok -negb_1 ... ok -negb_2 ... ok -negw_1 ... ok -negw_2 ... ok -negl_1 ... ok -negl_2 ... ok -notb_1 ... ok -notb_2 ... ok -notw_1 ... ok -notw_2 ... ok -notl_1 ... ok -notl_2 ... ok -orb_1 ... ok -orb_2 ... ok -orb_3 ... ok -orb_4 ... ok -orb_5 ... ok -orb_6 ... ok -orw_1 ... ok -orw_2 ... ok -orw_3 ... ok -orw_4 ... ok -orw_5 ... ok -orw_6 ... ok -orw_7 ... ok -orl_1 ... ok -orl_2 ... ok -orl_3 ... ok -orl_4 ... ok -orl_5 ... ok -orl_6 ... ok -orl_7 ... ok -rclb_1 ... ok -rclb_2 ... ok -rclb_3 ... ok -rclb_4 ... ok -rclb_5 ... ok -rclb_6 ... ok -rclw_1 ... ok -rclw_2 ... ok -rclw_3 ... ok -rclw_4 ... ok -rclw_5 ... ok -rclw_6 ... ok -rcll_1 ... ok -rcll_2 ... ok -rcll_3 ... ok -rcll_4 ... ok -rcll_5 ... ok -rcll_6 ... ok -rcrb_1 ... ok -rcrb_2 ... ok -rcrb_3 ... ok -rcrb_4 ... ok -rcrb_5 ... ok -rcrb_6 ... ok -rcrw_1 ... ok -rcrw_2 ... ok -rcrw_3 ... ok -rcrw_4 ... ok -rcrw_5 ... ok -rcrw_6 ... ok -rcrl_1 ... ok -rcrl_2 ... ok -rcrl_3 ... ok -rcrl_4 ... ok -rcrl_5 ... ok -rcrl_6 ... ok -rolb_1 ... ok -rolb_2 ... ok -rolb_3 ... ok -rolb_4 ... ok -rolb_5 ... ok -rolb_6 ... ok -rolw_1 ... ok -rolw_2 ... ok -rolw_3 ... ok -rolw_4 ... ok -rolw_5 ... ok -rolw_6 ... ok -roll_1 ... ok -roll_2 ... ok -roll_3 ... ok -roll_4 ... ok -roll_5 ... ok -roll_6 ... ok -rorb_1 ... ok -rorb_2 ... ok -rorb_3 ... ok -rorb_4 ... ok -rorb_5 ... ok -rorb_6 ... ok -rorw_1 ... ok -rorw_2 ... ok -rorw_3 ... ok -rorw_4 ... ok -rorw_5 ... ok -rorw_6 ... ok -rorl_1 ... ok -rorl_2 ... ok -rorl_3 ... ok -rorl_4 ... ok -rorl_5 ... ok -rorl_6 ... ok -sahf_1 ... ok -sahf_2 ... ok -salb_1 ... ok -salb_2 ... ok -salb_3 ... ok -salb_4 ... ok -salb_5 ... ok -salb_6 ... ok -salw_1 ... ok -salw_2 ... ok -salw_3 ... ok -salw_4 ... ok -salw_5 ... ok -salw_6 ... ok -sall_1 ... ok -sall_2 ... ok -sall_3 ... ok -sall_4 ... ok -sall_5 ... ok -sall_6 ... ok -sarb_1 ... ok -sarb_2 ... ok -sarb_3 ... ok -sarb_4 ... ok -sarb_5 ... ok -sarb_6 ... ok -sarw_1 ... ok -sarw_2 ... ok -sarw_3 ... ok -sarw_4 ... ok -sarw_5 ... ok -sarw_6 ... ok -sarl_1 ... ok -sarl_2 ... ok -sarl_3 ... ok -sarl_4 ... ok -sarl_5 ... ok -sarl_6 ... ok -sbbb_1 ... ok -sbbb_2 ... ok -sbbb_3 ... ok -sbbb_4 ... ok -sbbb_5 ... ok -sbbb_6 ... ok -sbbb_7 ... ok -sbbb_8 ... ok -sbbb_9 ... ok -sbbb_10 ... ok -sbbb_11 ... ok -sbbb_12 ... ok -sbbw_1 ... ok -sbbw_2 ... ok -sbbw_3 ... ok -sbbw_4 ... ok -sbbw_5 ... ok -sbbw_6 ... ok -sbbw_7 ... ok -sbbw_8 ... ok -sbbw_9 ... ok -sbbw_10 ... ok -sbbw_11 ... ok -sbbw_12 ... ok -sbbw_13 ... ok -sbbw_14 ... ok -sbbl_1 ... ok -sbbl_2 ... ok -sbbl_3 ... ok -sbbl_4 ... ok -sbbl_5 ... ok -sbbl_6 ... ok -sbbl_7 ... ok -sbbl_8 ... ok -sbbl_9 ... ok -sbbl_10 ... ok -sbbl_11 ... ok -sbbl_12 ... ok -sbbl_13 ... ok -sbbl_14 ... ok -seta_1 ... ok -seta_2 ... ok -seta_3 ... ok -seta_4 ... ok -seta_5 ... ok -seta_6 ... ok -seta_7 ... ok -seta_8 ... ok -setae_1 ... ok -setae_2 ... ok -setae_3 ... ok -setae_4 ... ok -setb_1 ... ok -setb_2 ... ok -setb_3 ... ok -setb_4 ... ok -setbe_1 ... ok -setbe_2 ... ok -setbe_3 ... ok -setbe_4 ... ok -setbe_5 ... ok -setbe_6 ... ok -setbe_7 ... ok -setbe_8 ... ok -setc_1 ... ok -setc_2 ... ok -setc_3 ... ok -setc_4 ... ok -sete_1 ... ok -sete_2 ... ok -sete_3 ... ok -sete_4 ... ok -setg_1 ... ok -setg_2 ... ok -setg_3 ... ok -setg_4 ... ok -setg_5 ... ok -setg_6 ... ok -setg_7 ... ok -setg_8 ... ok -setg_9 ... ok -setg_10 ... ok -setg_11 ... ok -setg_12 ... ok -setg_13 ... ok -setg_14 ... ok -setg_15 ... ok -setg_16 ... ok -setge_1 ... ok -setge_2 ... ok -setge_3 ... ok -setge_4 ... ok -setge_5 ... ok -setge_6 ... ok -setge_7 ... ok -setge_8 ... ok -setl_1 ... ok -setl_2 ... ok -setl_3 ... ok -setl_4 ... ok -setl_5 ... ok -setl_6 ... ok -setl_7 ... ok -setl_8 ... ok -setle_1 ... ok -setle_2 ... ok -setle_3 ... ok -setle_4 ... ok -setle_5 ... ok -setle_6 ... ok -setle_7 ... ok -setle_8 ... ok -setle_9 ... ok -setle_10 ... ok -setle_11 ... ok -setle_12 ... ok -setle_13 ... ok -setle_14 ... ok -setle_15 ... ok -setle_16 ... ok -setna_1 ... ok -setna_2 ... ok -setna_3 ... ok -setna_4 ... ok -setna_5 ... ok -setna_6 ... ok -setna_7 ... ok -setna_8 ... ok -setnae_1 ... ok -setnae_2 ... ok -setnae_3 ... ok -setnae_4 ... ok -setnb_1 ... ok -setnb_2 ... ok -setnb_3 ... ok -setnb_4 ... ok -setnbe_1 ... ok -setnbe_2 ... ok -setnbe_3 ... ok -setnbe_4 ... ok -setnbe_5 ... ok -setnbe_6 ... ok -setnbe_7 ... ok -setnbe_8 ... ok -setnc_1 ... ok -setnc_2 ... ok -setnc_3 ... ok -setnc_4 ... ok -setne_1 ... ok -setne_2 ... ok -setne_3 ... ok -setne_4 ... ok -setng_1 ... ok -setng_2 ... ok -setng_3 ... ok -setng_4 ... ok -setng_5 ... ok -setng_6 ... ok -setng_7 ... ok -setng_8 ... ok -setng_9 ... ok -setng_10 ... ok -setng_11 ... ok -setng_12 ... ok -setng_13 ... ok -setng_14 ... ok -setng_15 ... ok -setng_16 ... ok -setnge_1 ... ok -setnge_2 ... ok -setnge_3 ... ok -setnge_4 ... ok -setnge_5 ... ok -setnge_6 ... ok -setnge_7 ... ok -setnge_8 ... ok -setnl_1 ... ok -setnl_2 ... ok -setnl_3 ... ok -setnl_4 ... ok -setnl_5 ... ok -setnl_6 ... ok -setnl_7 ... ok -setnl_8 ... ok -setnle_1 ... ok -setnle_2 ... ok -setnle_3 ... ok -setnle_4 ... ok -setnle_5 ... ok -setnle_6 ... ok -setnle_7 ... ok -setnle_8 ... ok -setnle_9 ... ok -setnle_10 ... ok -setnle_11 ... ok -setnle_12 ... ok -setnle_13 ... ok -setnle_14 ... ok -setnle_15 ... ok -setnle_16 ... ok -setno_1 ... ok -setno_2 ... ok -setno_3 ... ok -setno_4 ... ok -setnp_1 ... ok -setnp_2 ... ok -setnp_3 ... ok -setnp_4 ... ok -setns_1 ... ok -setns_2 ... ok -setns_3 ... ok -setns_4 ... ok -setnz_1 ... ok -setnz_2 ... ok -setnz_3 ... ok -setnz_4 ... ok -seto_1 ... ok -seto_2 ... ok -seto_3 ... ok -seto_4 ... ok -setp_1 ... ok -setp_2 ... ok -setp_3 ... ok -setp_4 ... ok -sets_1 ... ok -sets_2 ... ok -sets_3 ... ok -sets_4 ... ok -setz_1 ... ok -setz_2 ... ok -setz_3 ... ok -setz_4 ... ok -shlb_1 ... ok -shlb_2 ... ok -shlb_3 ... ok -shlb_4 ... ok -shlb_5 ... ok -shlb_6 ... ok -shlw_1 ... ok -shlw_2 ... ok -shlw_3 ... ok -shlw_4 ... ok -shlw_5 ... ok -shlw_6 ... ok -shll_1 ... ok -shll_2 ... ok -shll_3 ... ok -shll_4 ... ok -shll_5 ... ok -shll_6 ... ok -shrb_1 ... ok -shrb_2 ... ok -shrb_3 ... ok -shrb_4 ... ok -shrb_5 ... ok -shrb_6 ... ok -shrw_1 ... ok -shrw_2 ... ok -shrw_3 ... ok -shrw_4 ... ok -shrw_5 ... ok -shrw_6 ... ok -shrl_1 ... ok -shrl_2 ... ok -shrl_3 ... ok -shrl_4 ... ok -shrl_5 ... ok -shrl_6 ... ok -shldw_1 ... ok -shldw_2 ... ok -shldw_3 ... ok -shldw_4 ... ok -shldw_5 ... ok -shldw_6 ... ok -shldw_7 ... ok -shldw_8 ... ok -shldl_1 ... ok -shldl_2 ... ok -shldl_3 ... ok -shldl_4 ... ok -shldl_5 ... ok -shldl_6 ... ok -shldl_7 ... ok -shldl_8 ... ok -shrdw_1 ... ok -shrdw_2 ... ok -shrdw_3 ... ok -shrdw_4 ... ok -shrdw_5 ... ok -shrdw_6 ... ok -shrdw_7 ... ok -shrdw_8 ... ok -shrdl_1 ... ok -shrdl_2 ... ok -shrdl_3 ... ok -shrdl_4 ... ok -shrdl_5 ... ok -shrdl_6 ... ok -shrdl_7 ... ok -shrdl_8 ... ok -stc_1 ... ok -stc_2 ... ok -std_1 ... ok -std_2 ... ok -subb_1 ... ok -subb_2 ... ok -subb_3 ... ok -subb_4 ... ok -subb_5 ... ok -subb_6 ... ok -subw_1 ... ok -subw_2 ... ok -subw_3 ... ok -subw_4 ... ok -subw_5 ... ok -subw_6 ... ok -subw_7 ... ok -subl_1 ... ok -subl_2 ... ok -subl_3 ... ok -subl_4 ... ok -subl_5 ... ok -subl_6 ... ok -subl_7 ... ok -testb_1 ... ok -testb_2 ... ok -testb_3 ... ok -testb_4 ... ok -testb_5 ... ok -testb_6 ... ok -testb_7 ... ok -testb_8 ... ok -testb_9 ... ok -testb_10 ... ok -testb_11 ... ok -testb_12 ... ok -testb_13 ... ok -testb_14 ... ok -testb_15 ... ok -testb_16 ... ok -testb_17 ... ok -testb_18 ... ok -testb_19 ... ok -testb_20 ... ok -testb_21 ... ok -testb_22 ... ok -testb_23 ... ok -testb_24 ... ok -testb_25 ... ok -testw_1 ... ok -testw_2 ... ok -testw_3 ... ok -testw_4 ... ok -testw_5 ... ok -testw_6 ... ok -testw_7 ... ok -testw_8 ... ok -testw_9 ... ok -testw_10 ... ok -testw_11 ... ok -testw_12 ... ok -testw_13 ... ok -testw_14 ... ok -testw_15 ... ok -testw_16 ... ok -testw_17 ... ok -testw_18 ... ok -testw_19 ... ok -testw_20 ... ok -testw_21 ... ok -testw_22 ... ok -testw_23 ... ok -testw_24 ... ok -testw_25 ... ok -testl_1 ... ok -testl_2 ... ok -testl_3 ... ok -testl_4 ... ok -testl_5 ... ok -testl_6 ... ok -testl_7 ... ok -testl_8 ... ok -testl_9 ... ok -testl_10 ... ok -testl_11 ... ok -testl_12 ... ok -testl_13 ... ok -testl_14 ... ok -testl_15 ... ok -testl_16 ... ok -testl_17 ... ok -testl_18 ... ok -testl_19 ... ok -testl_20 ... ok -testl_21 ... ok -testl_22 ... ok -testl_23 ... ok -testl_24 ... ok -testl_25 ... ok -xaddb_1 ... ok -xaddb_2 ... ok -xaddw_1 ... ok -xaddw_2 ... ok -xaddl_1 ... ok -xaddl_2 ... ok -xchgb_1 ... ok -xchgb_2 ... ok -xchgb_3 ... ok -xchgw_1 ... ok -xchgw_2 ... ok -xchgw_3 ... ok -xchgw_4 ... ok -xchgw_5 ... ok -xchgl_1 ... ok -xchgl_2 ... ok -xchgl_3 ... ok -xchgl_4 ... ok -xchgl_5 ... ok -xorb_1 ... ok -xorb_2 ... ok -xorb_3 ... ok -xorb_4 ... ok -xorb_5 ... ok -xorb_6 ... ok -xorw_1 ... ok -xorw_2 ... ok -xorw_3 ... ok -xorw_4 ... ok -xorw_5 ... ok -xorw_6 ... ok -xorw_7 ... ok -xorl_1 ... ok -xorl_2 ... ok -xorl_3 ... ok -xorl_4 ... ok -xorl_5 ... ok -xorl_6 ... ok -xorl_7 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_basic.vgtest b/VEX/head20041019/helgrind/tests/insn_basic.vgtest deleted file mode 100644 index f5329ea81..000000000 --- a/VEX/head20041019/helgrind/tests/insn_basic.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_basic diff --git a/VEX/head20041019/helgrind/tests/insn_cmov.stderr.exp b/VEX/head20041019/helgrind/tests/insn_cmov.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_cmov.stdout.exp b/VEX/head20041019/helgrind/tests/insn_cmov.stdout.exp deleted file mode 100644 index 31ac17204..000000000 --- a/VEX/head20041019/helgrind/tests/insn_cmov.stdout.exp +++ /dev/null @@ -1,384 +0,0 @@ -cmova_1 ... ok -cmova_2 ... ok -cmova_3 ... ok -cmova_4 ... ok -cmova_5 ... ok -cmova_6 ... ok -cmova_7 ... ok -cmova_8 ... ok -cmovae_1 ... ok -cmovae_2 ... ok -cmovae_3 ... ok -cmovae_4 ... ok -cmovb_1 ... ok -cmovb_2 ... ok -cmovb_3 ... ok -cmovb_4 ... ok -cmovbe_1 ... ok -cmovbe_2 ... ok -cmovbe_3 ... ok -cmovbe_4 ... ok -cmovbe_5 ... ok -cmovbe_6 ... ok -cmovbe_7 ... ok -cmovbe_8 ... ok -cmovc_1 ... ok -cmovc_2 ... ok -cmovc_3 ... ok -cmovc_4 ... ok -cmove_1 ... ok -cmove_2 ... ok -cmove_3 ... ok -cmove_4 ... ok -cmovg_1 ... ok -cmovg_2 ... ok -cmovg_3 ... ok -cmovg_4 ... ok -cmovg_5 ... ok -cmovg_6 ... ok -cmovg_7 ... ok -cmovg_8 ... ok -cmovg_9 ... ok -cmovg_10 ... ok -cmovg_11 ... ok -cmovg_12 ... ok -cmovg_13 ... ok -cmovg_14 ... ok -cmovg_15 ... ok -cmovg_16 ... ok -cmovge_1 ... ok -cmovge_2 ... ok -cmovge_3 ... ok -cmovge_4 ... ok -cmovge_5 ... ok -cmovge_6 ... ok -cmovge_7 ... ok -cmovge_8 ... ok -cmovl_1 ... ok -cmovl_2 ... ok -cmovl_3 ... ok -cmovl_4 ... ok -cmovl_5 ... ok -cmovl_6 ... ok -cmovl_7 ... ok -cmovl_8 ... ok -cmovle_1 ... ok -cmovle_2 ... ok -cmovle_3 ... ok -cmovle_4 ... ok -cmovle_5 ... ok -cmovle_6 ... ok -cmovle_7 ... ok -cmovle_8 ... ok -cmovle_9 ... ok -cmovle_10 ... ok -cmovle_11 ... ok -cmovle_12 ... ok -cmovle_13 ... ok -cmovle_14 ... ok -cmovle_15 ... ok -cmovle_16 ... ok -cmovna_1 ... ok -cmovna_2 ... ok -cmovna_3 ... ok -cmovna_4 ... ok -cmovna_5 ... ok -cmovna_6 ... ok -cmovna_7 ... ok -cmovna_8 ... ok -cmovnae_1 ... ok -cmovnae_2 ... ok -cmovnae_3 ... ok -cmovnae_4 ... ok -cmovnb_1 ... ok -cmovnb_2 ... ok -cmovnb_3 ... ok -cmovnb_4 ... ok -cmovnbe_1 ... ok -cmovnbe_2 ... ok -cmovnbe_3 ... ok -cmovnbe_4 ... ok -cmovnbe_5 ... ok -cmovnbe_6 ... ok -cmovnbe_7 ... ok -cmovnbe_8 ... ok -cmovnc_1 ... ok -cmovnc_2 ... ok -cmovnc_3 ... ok -cmovnc_4 ... ok -cmovne_1 ... ok -cmovne_2 ... ok -cmovne_3 ... ok -cmovne_4 ... ok -cmovng_1 ... ok -cmovng_2 ... ok -cmovng_3 ... ok -cmovng_4 ... ok -cmovng_5 ... ok -cmovng_6 ... ok -cmovng_7 ... ok -cmovng_8 ... ok -cmovng_9 ... ok -cmovng_10 ... ok -cmovng_11 ... ok -cmovng_12 ... ok -cmovng_13 ... ok -cmovng_14 ... ok -cmovng_15 ... ok -cmovng_16 ... ok -cmovnge_1 ... ok -cmovnge_2 ... ok -cmovnge_3 ... ok -cmovnge_4 ... ok -cmovnge_5 ... ok -cmovnge_6 ... ok -cmovnge_7 ... ok -cmovnge_8 ... ok -cmovnl_1 ... ok -cmovnl_2 ... ok -cmovnl_3 ... ok -cmovnl_4 ... ok -cmovnl_5 ... ok -cmovnl_6 ... ok -cmovnl_7 ... ok -cmovnl_8 ... ok -cmovnle_1 ... ok -cmovnle_2 ... ok -cmovnle_3 ... ok -cmovnle_4 ... ok -cmovnle_5 ... ok -cmovnle_6 ... ok -cmovnle_7 ... ok -cmovnle_8 ... ok -cmovnle_9 ... ok -cmovnle_10 ... ok -cmovnle_11 ... ok -cmovnle_12 ... ok -cmovnle_13 ... ok -cmovnle_14 ... ok -cmovnle_15 ... ok -cmovnle_16 ... ok -cmovno_1 ... ok -cmovno_2 ... ok -cmovno_3 ... ok -cmovno_4 ... ok -cmovnp_1 ... ok -cmovnp_2 ... ok -cmovnp_3 ... ok -cmovnp_4 ... ok -cmovns_1 ... ok -cmovns_2 ... ok -cmovns_3 ... ok -cmovns_4 ... ok -cmovnz_1 ... ok -cmovnz_2 ... ok -cmovnz_3 ... ok -cmovnz_4 ... ok -cmovo_1 ... ok -cmovo_2 ... ok -cmovo_3 ... ok -cmovo_4 ... ok -cmovp_1 ... ok -cmovp_2 ... ok -cmovp_3 ... ok -cmovp_4 ... ok -cmovs_1 ... ok -cmovs_2 ... ok -cmovs_3 ... ok -cmovs_4 ... ok -cmovz_1 ... ok -cmovz_2 ... ok -cmovz_3 ... ok -cmovz_4 ... ok -cmova_9 ... ok -cmova_10 ... ok -cmova_11 ... ok -cmova_12 ... ok -cmova_13 ... ok -cmova_14 ... ok -cmova_15 ... ok -cmova_16 ... ok -cmovae_5 ... ok -cmovae_6 ... ok -cmovae_7 ... ok -cmovae_8 ... ok -cmovb_5 ... ok -cmovb_6 ... ok -cmovb_7 ... ok -cmovb_8 ... ok -cmovbe_9 ... ok -cmovbe_10 ... ok -cmovbe_11 ... ok -cmovbe_12 ... ok -cmovbe_13 ... ok -cmovbe_14 ... ok -cmovbe_15 ... ok -cmovbe_16 ... ok -cmovc_5 ... ok -cmovc_6 ... ok -cmovc_7 ... ok -cmovc_8 ... ok -cmove_5 ... ok -cmove_6 ... ok -cmove_7 ... ok -cmove_8 ... ok -cmovg_17 ... ok -cmovg_18 ... ok -cmovg_19 ... ok -cmovg_20 ... ok -cmovg_21 ... ok -cmovg_22 ... ok -cmovg_23 ... ok -cmovg_24 ... ok -cmovg_25 ... ok -cmovg_26 ... ok -cmovg_27 ... ok -cmovg_28 ... ok -cmovg_29 ... ok -cmovg_30 ... ok -cmovg_31 ... ok -cmovg_32 ... ok -cmovge_9 ... ok -cmovge_10 ... ok -cmovge_11 ... ok -cmovge_12 ... ok -cmovge_13 ... ok -cmovge_14 ... ok -cmovge_15 ... ok -cmovge_16 ... ok -cmovl_9 ... ok -cmovl_10 ... ok -cmovl_11 ... ok -cmovl_12 ... ok -cmovl_13 ... ok -cmovl_14 ... ok -cmovl_15 ... ok -cmovl_16 ... ok -cmovle_17 ... ok -cmovle_18 ... ok -cmovle_19 ... ok -cmovle_20 ... ok -cmovle_21 ... ok -cmovle_22 ... ok -cmovle_23 ... ok -cmovle_24 ... ok -cmovle_25 ... ok -cmovle_26 ... ok -cmovle_27 ... ok -cmovle_28 ... ok -cmovle_29 ... ok -cmovle_30 ... ok -cmovle_31 ... ok -cmovle_32 ... ok -cmovna_9 ... ok -cmovna_10 ... ok -cmovna_11 ... ok -cmovna_12 ... ok -cmovna_13 ... ok -cmovna_14 ... ok -cmovna_15 ... ok -cmovna_16 ... ok -cmovnae_5 ... ok -cmovnae_6 ... ok -cmovnae_7 ... ok -cmovnae_8 ... ok -cmovnb_5 ... ok -cmovnb_6 ... ok -cmovnb_7 ... ok -cmovnb_8 ... ok -cmovnbe_9 ... ok -cmovnbe_10 ... ok -cmovnbe_11 ... ok -cmovnbe_12 ... ok -cmovnbe_13 ... ok -cmovnbe_14 ... ok -cmovnbe_15 ... ok -cmovnbe_16 ... ok -cmovnc_5 ... ok -cmovnc_6 ... ok -cmovnc_7 ... ok -cmovnc_8 ... ok -cmovne_5 ... ok -cmovne_6 ... ok -cmovne_7 ... ok -cmovne_8 ... ok -cmovng_17 ... ok -cmovng_18 ... ok -cmovng_19 ... ok -cmovng_20 ... ok -cmovng_21 ... ok -cmovng_22 ... ok -cmovng_23 ... ok -cmovng_24 ... ok -cmovng_25 ... ok -cmovng_26 ... ok -cmovng_27 ... ok -cmovng_28 ... ok -cmovng_29 ... ok -cmovng_30 ... ok -cmovng_31 ... ok -cmovng_32 ... ok -cmovnge_9 ... ok -cmovnge_10 ... ok -cmovnge_11 ... ok -cmovnge_12 ... ok -cmovnge_13 ... ok -cmovnge_14 ... ok -cmovnge_15 ... ok -cmovnge_16 ... ok -cmovnl_9 ... ok -cmovnl_10 ... ok -cmovnl_11 ... ok -cmovnl_12 ... ok -cmovnl_13 ... ok -cmovnl_14 ... ok -cmovnl_15 ... ok -cmovnl_16 ... ok -cmovnle_17 ... ok -cmovnle_18 ... ok -cmovnle_19 ... ok -cmovnle_20 ... ok -cmovnle_21 ... ok -cmovnle_22 ... ok -cmovnle_23 ... ok -cmovnle_24 ... ok -cmovnle_25 ... ok -cmovnle_26 ... ok -cmovnle_27 ... ok -cmovnle_28 ... ok -cmovnle_29 ... ok -cmovnle_30 ... ok -cmovnle_31 ... ok -cmovnle_32 ... ok -cmovno_5 ... ok -cmovno_6 ... ok -cmovno_7 ... ok -cmovno_8 ... ok -cmovnp_5 ... ok -cmovnp_6 ... ok -cmovnp_7 ... ok -cmovnp_8 ... ok -cmovns_5 ... ok -cmovns_6 ... ok -cmovns_7 ... ok -cmovns_8 ... ok -cmovnz_5 ... ok -cmovnz_6 ... ok -cmovnz_7 ... ok -cmovnz_8 ... ok -cmovo_5 ... ok -cmovo_6 ... ok -cmovo_7 ... ok -cmovo_8 ... ok -cmovp_5 ... ok -cmovp_6 ... ok -cmovp_7 ... ok -cmovp_8 ... ok -cmovs_5 ... ok -cmovs_6 ... ok -cmovs_7 ... ok -cmovs_8 ... ok -cmovz_5 ... ok -cmovz_6 ... ok -cmovz_7 ... ok -cmovz_8 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_cmov.vgtest b/VEX/head20041019/helgrind/tests/insn_cmov.vgtest deleted file mode 100644 index 0321a3ca8..000000000 --- a/VEX/head20041019/helgrind/tests/insn_cmov.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_cmov -cpu_test: cmov diff --git a/VEX/head20041019/helgrind/tests/insn_fpu.stderr.exp b/VEX/head20041019/helgrind/tests/insn_fpu.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_fpu.stdout.exp b/VEX/head20041019/helgrind/tests/insn_fpu.stdout.exp deleted file mode 100644 index 2dbaa07ce..000000000 --- a/VEX/head20041019/helgrind/tests/insn_fpu.stdout.exp +++ /dev/null @@ -1,452 +0,0 @@ -fabs_1 ... ok -fabs_2 ... ok -fabs_3 ... ok -fabs_4 ... ok -fadds_1 ... ok -fadds_2 ... ok -fadds_3 ... ok -fadds_4 ... ok -faddl_1 ... ok -faddl_2 ... ok -faddl_3 ... ok -faddl_4 ... ok -fadd_1 ... ok -fadd_2 ... ok -fadd_3 ... ok -fadd_4 ... ok -fadd_5 ... ok -fadd_6 ... ok -fadd_7 ... ok -fadd_8 ... ok -fadd_9 ... ok -fadd_10 ... ok -fadd_11 ... ok -fadd_12 ... ok -fadd_13 ... ok -fadd_14 ... ok -fadd_15 ... ok -fadd_16 ... ok -faddp_1 ... ok -faddp_2 ... ok -faddp_3 ... ok -faddp_4 ... ok -faddp_5 ... ok -faddp_6 ... ok -faddp_7 ... ok -faddp_8 ... ok -faddp_9 ... ok -faddp_10 ... ok -faddp_11 ... ok -faddp_12 ... ok -faddp_13 ... ok -faddp_14 ... ok -faddp_15 ... ok -faddp_16 ... ok -fiadds_1 ... ok -fiadds_2 ... ok -fiadds_3 ... ok -fiadds_4 ... ok -fiadds_5 ... ok -fiadds_6 ... ok -fiadds_7 ... ok -fiadds_8 ... ok -fiaddl_1 ... ok -fiaddl_2 ... ok -fiaddl_3 ... ok -fiaddl_4 ... ok -fiaddl_5 ... ok -fiaddl_6 ... ok -fiaddl_7 ... ok -fiaddl_8 ... ok -fcomi_1 ... ok -fcomi_2 ... ok -fcomi_3 ... ok -fcomi_4 ... ok -fcomi_5 ... ok -fcomi_6 ... ok -fcomip_1 ... ok -fcomip_2 ... ok -fcomip_3 ... ok -fcomip_4 ... ok -fcomip_5 ... ok -fcomip_6 ... ok -fucomi_1 ... ok -fucomi_2 ... ok -fucomi_3 ... ok -fucomi_4 ... ok -fucomi_5 ... ok -fucomi_6 ... ok -fucomip_1 ... ok -fucomip_2 ... ok -fucomip_3 ... ok -fucomip_4 ... ok -fucomip_5 ... ok -fucomip_6 ... ok -fchs_1 ... ok -fchs_2 ... ok -fchs_3 ... ok -fchs_4 ... ok -fdivs_1 ... ok -fdivs_2 ... ok -fdivs_3 ... ok -fdivs_4 ... ok -fdivl_1 ... ok -fdivl_2 ... ok -fdivl_3 ... ok -fdivl_4 ... ok -fdiv_1 ... ok -fdiv_2 ... ok -fdiv_3 ... ok -fdiv_4 ... ok -fdiv_5 ... ok -fdiv_6 ... ok -fdiv_7 ... ok -fdiv_8 ... ok -fdiv_9 ... ok -fdiv_10 ... ok -fdiv_11 ... ok -fdiv_12 ... ok -fdiv_13 ... ok -fdiv_14 ... ok -fdiv_15 ... ok -fdiv_16 ... ok -fdivp_1 ... ok -fdivp_2 ... ok -fdivp_3 ... ok -fdivp_4 ... ok -fdivp_5 ... ok -fdivp_6 ... ok -fdivp_7 ... ok -fdivp_8 ... ok -fdivp_9 ... ok -fdivp_10 ... ok -fdivp_11 ... ok -fdivp_12 ... ok -fdivp_13 ... ok -fdivp_14 ... ok -fdivp_15 ... ok -fdivp_16 ... ok -fidivs_1 ... ok -fidivs_2 ... ok -fidivs_3 ... ok -fidivs_4 ... ok -fidivs_5 ... ok -fidivs_6 ... ok -fidivs_7 ... ok -fidivs_8 ... ok -fidivl_1 ... ok -fidivl_2 ... ok -fidivl_3 ... ok -fidivl_4 ... ok -fidivl_5 ... ok -fidivl_6 ... ok -fidivl_7 ... ok -fidivl_8 ... ok -fdivrs_1 ... ok -fdivrs_2 ... ok -fdivrs_3 ... ok -fdivrs_4 ... ok -fdivrl_1 ... ok -fdivrl_2 ... ok -fdivrl_3 ... ok -fdivrl_4 ... ok -fdivr_1 ... ok -fdivr_2 ... ok -fdivr_3 ... ok -fdivr_4 ... ok -fdivr_5 ... ok -fdivr_6 ... ok -fdivr_7 ... ok -fdivr_8 ... ok -fdivr_9 ... ok -fdivr_10 ... ok -fdivr_11 ... ok -fdivr_12 ... ok -fdivr_13 ... ok -fdivr_14 ... ok -fdivr_15 ... ok -fdivr_16 ... ok -fdivrp_1 ... ok -fdivrp_2 ... ok -fdivrp_3 ... ok -fdivrp_4 ... ok -fdivrp_5 ... ok -fdivrp_6 ... ok -fdivrp_7 ... ok -fdivrp_8 ... ok -fdivrp_9 ... ok -fdivrp_10 ... ok -fdivrp_11 ... ok -fdivrp_12 ... ok -fdivrp_13 ... ok -fdivrp_14 ... ok -fdivrp_15 ... ok -fdivrp_16 ... ok -fidivrs_1 ... ok -fidivrs_2 ... ok -fidivrs_3 ... ok -fidivrs_4 ... ok -fidivrs_5 ... ok -fidivrs_6 ... ok -fidivrs_7 ... ok -fidivrs_8 ... ok -fidivrl_1 ... ok -fidivrl_2 ... ok -fidivrl_3 ... ok -fidivrl_4 ... ok -fidivrl_5 ... ok -fidivrl_6 ... ok -fidivrl_7 ... ok -fidivrl_8 ... ok -filds_1 ... ok -filds_2 ... ok -filds_3 ... ok -filds_4 ... ok -fildl_1 ... ok -fildl_2 ... ok -fildl_3 ... ok -fildl_4 ... ok -fildq_1 ... ok -fildq_2 ... ok -fildq_3 ... ok -fildq_4 ... ok -fists_1 ... ok -fists_2 ... ok -fists_3 ... ok -fists_4 ... ok -fists_5 ... ok -fists_6 ... ok -fists_7 ... ok -fists_8 ... ok -fistl_1 ... ok -fistl_2 ... ok -fistl_3 ... ok -fistl_4 ... ok -fistl_5 ... ok -fistl_6 ... ok -fistl_7 ... ok -fistl_8 ... ok -fistps_1 ... ok -fistps_2 ... ok -fistps_3 ... ok -fistps_4 ... ok -fistps_5 ... ok -fistps_6 ... ok -fistps_7 ... ok -fistps_8 ... ok -fistpl_1 ... ok -fistpl_2 ... ok -fistpl_3 ... ok -fistpl_4 ... ok -fistpl_5 ... ok -fistpl_6 ... ok -fistpl_7 ... ok -fistpl_8 ... ok -fistpq_1 ... ok -fistpq_2 ... ok -fistpq_3 ... ok -fistpq_4 ... ok -fistpq_5 ... ok -fistpq_6 ... ok -fistpq_7 ... ok -fistpq_8 ... ok -flds_1 ... ok -flds_2 ... ok -fldl_1 ... ok -fldl_2 ... ok -fld_1 ... ok -fld_2 ... ok -fld_3 ... ok -fld1_1 ... ok -fldl2t_1 ... ok -fldl2e_1 ... ok -fldpi_1 ... ok -fldlg2_1 ... ok -fldln2_1 ... ok -fldz_1 ... ok -fmuls_1 ... ok -fmuls_2 ... ok -fmuls_3 ... ok -fmuls_4 ... ok -fmull_1 ... ok -fmull_2 ... ok -fmull_3 ... ok -fmull_4 ... ok -fmul_1 ... ok -fmul_2 ... ok -fmul_3 ... ok -fmul_4 ... ok -fmul_5 ... ok -fmul_6 ... ok -fmul_7 ... ok -fmul_8 ... ok -fmul_9 ... ok -fmul_10 ... ok -fmul_11 ... ok -fmul_12 ... ok -fmul_13 ... ok -fmul_14 ... ok -fmul_15 ... ok -fmul_16 ... ok -fmulp_1 ... ok -fmulp_2 ... ok -fmulp_3 ... ok -fmulp_4 ... ok -fmulp_5 ... ok -fmulp_6 ... ok -fmulp_7 ... ok -fmulp_8 ... ok -fmulp_9 ... ok -fmulp_10 ... ok -fmulp_11 ... ok -fmulp_12 ... ok -fmulp_13 ... ok -fmulp_14 ... ok -fmulp_15 ... ok -fmulp_16 ... ok -fimuls_1 ... ok -fimuls_2 ... ok -fimuls_3 ... ok -fimuls_4 ... ok -fimuls_5 ... ok -fimuls_6 ... ok -fimuls_7 ... ok -fimuls_8 ... ok -fimull_1 ... ok -fimull_2 ... ok -fimull_3 ... ok -fimull_4 ... ok -fimull_5 ... ok -fimull_6 ... ok -fimull_7 ... ok -fimull_8 ... ok -frndint_1 ... ok -frndint_2 ... ok -frndint_3 ... ok -frndint_4 ... ok -frndint_5 ... ok -frndint_6 ... ok -frndint_7 ... ok -frndint_8 ... ok -frndint_9 ... ok -frndint_10 ... ok -frndint_11 ... ok -frndint_12 ... ok -frndint_13 ... ok -frndint_14 ... ok -frndint_15 ... ok -frndint_16 ... ok -fsubs_1 ... ok -fsubs_2 ... ok -fsubs_3 ... ok -fsubs_4 ... ok -fsubl_1 ... ok -fsubl_2 ... ok -fsubl_3 ... ok -fsubl_4 ... ok -fsub_1 ... ok -fsub_2 ... ok -fsub_3 ... ok -fsub_4 ... ok -fsub_5 ... ok -fsub_6 ... ok -fsub_7 ... ok -fsub_8 ... ok -fsub_9 ... ok -fsub_10 ... ok -fsub_11 ... ok -fsub_12 ... ok -fsub_13 ... ok -fsub_14 ... ok -fsub_15 ... ok -fsub_16 ... ok -fsubp_1 ... ok -fsubp_2 ... ok -fsubp_3 ... ok -fsubp_4 ... ok -fsubp_5 ... ok -fsubp_6 ... ok -fsubp_7 ... ok -fsubp_8 ... ok -fsubp_9 ... ok -fsubp_10 ... ok -fsubp_11 ... ok -fsubp_12 ... ok -fsubp_13 ... ok -fsubp_14 ... ok -fsubp_15 ... ok -fsubp_16 ... ok -fisubs_1 ... ok -fisubs_2 ... ok -fisubs_3 ... ok -fisubs_4 ... ok -fisubs_5 ... ok -fisubs_6 ... ok -fisubs_7 ... ok -fisubs_8 ... ok -fisubl_1 ... ok -fisubl_2 ... ok -fisubl_3 ... ok -fisubl_4 ... ok -fisubl_5 ... ok -fisubl_6 ... ok -fisubl_7 ... ok -fisubl_8 ... ok -fsubrs_1 ... ok -fsubrs_2 ... ok -fsubrs_3 ... ok -fsubrs_4 ... ok -fsubrl_1 ... ok -fsubrl_2 ... ok -fsubrl_3 ... ok -fsubrl_4 ... ok -fsubr_1 ... ok -fsubr_2 ... ok -fsubr_3 ... ok -fsubr_4 ... ok -fsubr_5 ... ok -fsubr_6 ... ok -fsubr_7 ... ok -fsubr_8 ... ok -fsubr_9 ... ok -fsubr_10 ... ok -fsubr_11 ... ok -fsubr_12 ... ok -fsubr_13 ... ok -fsubr_14 ... ok -fsubr_15 ... ok -fsubr_16 ... ok -fsubrp_1 ... ok -fsubrp_2 ... ok -fsubrp_3 ... ok -fsubrp_4 ... ok -fsubrp_5 ... ok -fsubrp_6 ... ok -fsubrp_7 ... ok -fsubrp_8 ... ok -fsubrp_9 ... ok -fsubrp_10 ... ok -fsubrp_11 ... ok -fsubrp_12 ... ok -fsubrp_13 ... ok -fsubrp_14 ... ok -fsubrp_15 ... ok -fsubrp_16 ... ok -fisubrs_1 ... ok -fisubrs_2 ... ok -fisubrs_3 ... ok -fisubrs_4 ... ok -fisubrs_5 ... ok -fisubrs_6 ... ok -fisubrs_7 ... ok -fisubrs_8 ... ok -fisubrl_1 ... ok -fisubrl_2 ... ok -fisubrl_3 ... ok -fisubrl_4 ... ok -fisubrl_5 ... ok -fisubrl_6 ... ok -fisubrl_7 ... ok -fisubrl_8 ... ok -fxch_1 ... ok -fxch_2 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_fpu.vgtest b/VEX/head20041019/helgrind/tests/insn_fpu.vgtest deleted file mode 100644 index 1b9546f54..000000000 --- a/VEX/head20041019/helgrind/tests/insn_fpu.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_fpu -cpu_test: fpu diff --git a/VEX/head20041019/helgrind/tests/insn_mmx.stderr.exp b/VEX/head20041019/helgrind/tests/insn_mmx.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_mmx.stdout.exp b/VEX/head20041019/helgrind/tests/insn_mmx.stdout.exp deleted file mode 100644 index 95cbae160..000000000 --- a/VEX/head20041019/helgrind/tests/insn_mmx.stdout.exp +++ /dev/null @@ -1,103 +0,0 @@ -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movq_1 ... ok -movq_2 ... ok -movq_3 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -por_1 ... ok -por_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_mmx.vgtest b/VEX/head20041019/helgrind/tests/insn_mmx.vgtest deleted file mode 100644 index ddbb97726..000000000 --- a/VEX/head20041019/helgrind/tests/insn_mmx.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmx -cpu_test: mmx diff --git a/VEX/head20041019/helgrind/tests/insn_mmxext.stderr.exp b/VEX/head20041019/helgrind/tests/insn_mmxext.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_mmxext.stdout.exp b/VEX/head20041019/helgrind/tests/insn_mmxext.stdout.exp deleted file mode 100644 index 23b2e55ab..000000000 --- a/VEX/head20041019/helgrind/tests/insn_mmxext.stdout.exp +++ /dev/null @@ -1,29 +0,0 @@ -movntq_1 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -sfence_1 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_mmxext.vgtest b/VEX/head20041019/helgrind/tests/insn_mmxext.vgtest deleted file mode 100644 index bb667097f..000000000 --- a/VEX/head20041019/helgrind/tests/insn_mmxext.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmxext -cpu_test: mmxext diff --git a/VEX/head20041019/helgrind/tests/insn_sse.stderr.exp b/VEX/head20041019/helgrind/tests/insn_sse.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_sse.stdout.exp b/VEX/head20041019/helgrind/tests/insn_sse.stdout.exp deleted file mode 100644 index f15bd81f0..000000000 --- a/VEX/head20041019/helgrind/tests/insn_sse.stdout.exp +++ /dev/null @@ -1,142 +0,0 @@ -addps_1 ... ok -addps_2 ... ok -addss_1 ... ok -addss_2 ... ok -andnps_1 ... ok -andnps_2 ... ok -andps_1 ... ok -andps_2 ... ok -cmpeqps_1 ... ok -cmpeqps_2 ... ok -cmpeqss_1 ... ok -cmpeqss_2 ... ok -cmpleps_1 ... ok -cmpleps_2 ... ok -cmpless_1 ... ok -cmpless_2 ... ok -cmpltps_1 ... ok -cmpltps_2 ... ok -cmpltss_1 ... ok -cmpltss_2 ... ok -cmpneqps_1 ... ok -cmpneqps_2 ... ok -cmpneqss_1 ... ok -cmpneqss_2 ... ok -cmpnleps_1 ... ok -cmpnleps_2 ... ok -cmpnless_1 ... ok -cmpnless_2 ... ok -cmpnltps_1 ... ok -cmpnltps_2 ... ok -cmpnltss_1 ... ok -cmpnltss_2 ... ok -comiss_1 ... ok -comiss_2 ... ok -comiss_3 ... ok -comiss_4 ... ok -comiss_5 ... ok -comiss_6 ... ok -cvtpi2ps_1 ... ok -cvtpi2ps_2 ... ok -cvtps2pi_1 ... ok -cvtps2pi_2 ... ok -cvtsi2ss_1 ... ok -cvtsi2ss_2 ... ok -cvtss2si_1 ... ok -cvtss2si_2 ... ok -cvttps2pi_1 ... ok -cvttps2pi_2 ... ok -cvttss2si_1 ... ok -cvttss2si_2 ... ok -divps_1 ... ok -divps_2 ... ok -divss_1 ... ok -divss_2 ... ok -maxps_1 ... ok -maxps_2 ... ok -maxss_1 ... ok -maxss_2 ... ok -minps_1 ... ok -minps_2 ... ok -minss_1 ... ok -minss_2 ... ok -movaps_1 ... ok -movaps_2 ... ok -movhlps_1 ... ok -movhps_1 ... ok -movhps_2 ... ok -movlhps_1 ... ok -movlps_1 ... ok -movlps_2 ... ok -movmskps_1 ... ok -movntps_1 ... ok -movntq_1 ... ok -movss_1 ... ok -movss_2 ... ok -movss_3 ... ok -movups_1 ... ok -movups_2 ... ok -mulps_1 ... ok -mulps_2 ... ok -mulss_1 ... ok -mulss_2 ... ok -orps_1 ... ok -orps_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -rcpps_1 ... ok -rcpps_2 ... ok -rcpss_1 ... ok -rcpss_2 ... ok -rsqrtps_1 ... ok -rsqrtps_2 ... ok -rsqrtss_1 ... ok -rsqrtss_2 ... ok -sfence_1 ... ok -shufps_1 ... ok -shufps_2 ... ok -sqrtps_1 ... ok -sqrtps_2 ... ok -sqrtss_1 ... ok -sqrtss_2 ... ok -subps_1 ... ok -subps_2 ... ok -subss_1 ... ok -subss_2 ... ok -ucomiss_1 ... ok -ucomiss_2 ... ok -ucomiss_3 ... ok -ucomiss_4 ... ok -ucomiss_5 ... ok -ucomiss_6 ... ok -unpckhps_1 ... ok -unpckhps_2 ... ok -unpcklps_1 ... ok -unpcklps_2 ... ok -xorps_1 ... ok -xorps_2 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_sse.vgtest b/VEX/head20041019/helgrind/tests/insn_sse.vgtest deleted file mode 100644 index 167c8e290..000000000 --- a/VEX/head20041019/helgrind/tests/insn_sse.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse -cpu_test: sse diff --git a/VEX/head20041019/helgrind/tests/insn_sse2.stderr.exp b/VEX/head20041019/helgrind/tests/insn_sse2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/helgrind/tests/insn_sse2.stdout.exp b/VEX/head20041019/helgrind/tests/insn_sse2.stdout.exp deleted file mode 100644 index 9c24f7262..000000000 --- a/VEX/head20041019/helgrind/tests/insn_sse2.stdout.exp +++ /dev/null @@ -1,294 +0,0 @@ -addpd_1 ... ok -addpd_2 ... ok -addsd_1 ... ok -addsd_2 ... ok -andpd_1 ... ok -andpd_2 ... ok -andnpd_1 ... ok -andnpd_2 ... ok -cmpeqpd_1 ... ok -cmpeqpd_2 ... ok -cmpltpd_1 ... ok -cmpltpd_2 ... ok -cmplepd_1 ... ok -cmplepd_2 ... ok -cmpneqpd_1 ... ok -cmpneqpd_2 ... ok -cmpnltpd_1 ... ok -cmpnltpd_2 ... ok -cmpnlepd_1 ... ok -cmpnlepd_2 ... ok -cmpeqsd_1 ... ok -cmpeqsd_2 ... ok -cmpltsd_1 ... ok -cmpltsd_2 ... ok -cmplesd_1 ... ok -cmplesd_2 ... ok -cmpneqsd_1 ... ok -cmpneqsd_2 ... ok -cmpnltsd_1 ... ok -cmpnltsd_2 ... ok -cmpnlesd_1 ... ok -cmpnlesd_2 ... ok -comisd_1 ... ok -comisd_2 ... ok -comisd_3 ... ok -comisd_4 ... ok -comisd_5 ... ok -comisd_6 ... ok -cvtdq2pd_1 ... ok -cvtdq2pd_2 ... ok -cvtdq2ps_1 ... ok -cvtdq2ps_2 ... ok -cvtpd2dq_1 ... ok -cvtpd2dq_2 ... ok -cvtpd2pi_1 ... ok -cvtpd2pi_2 ... ok -cvtpd2ps_1 ... ok -cvtpd2ps_2 ... ok -cvtpi2pd_1 ... ok -cvtpi2pd_2 ... ok -cvtps2dq_1 ... ok -cvtps2dq_2 ... ok -cvtps2pd_1 ... ok -cvtps2pd_2 ... ok -cvtsd2si_1 ... ok -cvtsd2si_2 ... ok -cvtsd2ss_1 ... ok -cvtsd2ss_2 ... ok -cvtsi2sd_1 ... ok -cvtsi2sd_2 ... ok -cvtss2sd_1 ... ok -cvtss2sd_2 ... ok -cvttpd2pi_1 ... ok -cvttpd2pi_2 ... ok -cvttpd2dq_1 ... ok -cvttpd2dq_2 ... ok -cvttps2dq_1 ... ok -cvttps2dq_2 ... ok -cvttsd2si_1 ... ok -cvttsd2si_2 ... ok -divpd_1 ... ok -divpd_2 ... ok -divsd_1 ... ok -divsd_2 ... ok -lfence_1 ... ok -maxpd_1 ... ok -maxpd_2 ... ok -maxsd_1 ... ok -maxsd_2 ... ok -mfence_1 ... ok -minpd_1 ... ok -minpd_2 ... ok -minsd_1 ... ok -minsd_2 ... ok -movapd_1 ... ok -movapd_2 ... ok -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movdqa_1 ... ok -movdqa_2 ... ok -movdqa_3 ... ok -movdqu_1 ... ok -movdqu_2 ... ok -movdqu_3 ... ok -movdq2q_1 ... ok -movhpd_1 ... ok -movhpd_2 ... ok -movlpd_1 ... ok -movlpd_2 ... ok -movmskpd_1 ... ok -movntdq_1 ... ok -movnti_1 ... ok -movntpd_1 ... ok -movq2dq_1 ... ok -movsd_1 ... ok -movsd_2 ... ok -movsd_3 ... ok -movupd_1 ... ok -movupd_2 ... ok -mulpd_1 ... ok -mulpd_2 ... ok -mulsd_1 ... ok -mulsd_2 ... ok -orpd_1 ... ok -orpd_2 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddq_1 ... ok -paddq_2 ... ok -paddq_3 ... ok -paddq_4 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pextrw_5 ... ok -pextrw_6 ... ok -pextrw_7 ... ok -pextrw_8 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pinsrw_5 ... ok -pinsrw_6 ... ok -pinsrw_7 ... ok -pinsrw_8 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -pmuludq_1 ... ok -pmuludq_2 ... ok -pmuludq_3 ... ok -pmuludq_4 ... ok -por_1 ... ok -por_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufd_1 ... ok -pshufd_2 ... ok -pshufhw_1 ... ok -pshufhw_2 ... ok -pshuflw_1 ... ok -pshuflw_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -pslldq_1 ... ok -pslldq_2 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrldq_1 ... ok -psrldq_2 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubq_1 ... ok -psubq_2 ... ok -psubq_3 ... ok -psubq_4 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhqdq_1 ... ok -punpckhqdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklqdq_1 ... ok -punpcklqdq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok -shufpd_1 ... ok -shufpd_2 ... ok -sqrtpd_1 ... ok -sqrtpd_2 ... ok -sqrtsd_1 ... ok -sqrtsd_2 ... ok -subpd_1 ... ok -subpd_2 ... ok -subsd_1 ... ok -subsd_2 ... ok -ucomisd_1 ... ok -ucomisd_2 ... ok -ucomisd_3 ... ok -ucomisd_4 ... ok -ucomisd_5 ... ok -ucomisd_6 ... ok -unpckhpd_1 ... ok -unpckhpd_2 ... ok -unpcklpd_1 ... ok -unpcklpd_2 ... ok -xorpd_1 ... ok -xorpd_2 ... ok diff --git a/VEX/head20041019/helgrind/tests/insn_sse2.vgtest b/VEX/head20041019/helgrind/tests/insn_sse2.vgtest deleted file mode 100644 index 42e82f38d..000000000 --- a/VEX/head20041019/helgrind/tests/insn_sse2.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse2 -cpu_test: sse2 diff --git a/VEX/head20041019/helgrind/tests/race.c b/VEX/head20041019/helgrind/tests/race.c deleted file mode 100644 index 111195bf9..000000000 --- a/VEX/head20041019/helgrind/tests/race.c +++ /dev/null @@ -1,27 +0,0 @@ -/* A simple race */ - -#include -#include - -static int shared; - -static void *th(void *v) -{ - shared++; - - return 0; -} - -int main() -{ - pthread_t a, b; - - pthread_create(&a, NULL, th, NULL); - sleep(1); /* force ordering */ - pthread_create(&b, NULL, th, NULL); - - pthread_join(a, NULL); - pthread_join(b, NULL); - - return 0; -} diff --git a/VEX/head20041019/helgrind/tests/race.stderr.exp b/VEX/head20041019/helgrind/tests/race.stderr.exp deleted file mode 100644 index 96832e62a..000000000 --- a/VEX/head20041019/helgrind/tests/race.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ - -Thread 3: -Possible data race writing variable at 0x........ (shared) - at 0x........: th (race.c:10) - by 0x........: thread_wrapper (vg_libpthread.c:...) - by 0x........: do__quit (vg_scheduler.c:...) - Address 0x........ is in BSS section of /...helgrind/tests... - Previous state: shared RO, no locks - diff --git a/VEX/head20041019/helgrind/tests/race.vgtest b/VEX/head20041019/helgrind/tests/race.vgtest deleted file mode 100644 index ca127cdac..000000000 --- a/VEX/head20041019/helgrind/tests/race.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: race -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/race2.c b/VEX/head20041019/helgrind/tests/race2.c deleted file mode 100644 index de01f2c49..000000000 --- a/VEX/head20041019/helgrind/tests/race2.c +++ /dev/null @@ -1,35 +0,0 @@ -/* A simple race - test symaddr */ - -#include -#include - -struct foo { - struct bar { - int plop[22]; - char biff; - } poot[11]; -}; - -static void *th(void *v) -{ - struct foo *f = (struct foo *)v; - - f->poot[5].plop[11]++; - - return 0; -} - -int main() -{ - struct foo foo; - pthread_t a, b; - - pthread_create(&a, NULL, th, &foo); - sleep(1); /* force ordering */ - pthread_create(&b, NULL, th, &foo); - - pthread_join(a, NULL); - pthread_join(b, NULL); - - return 0; -} diff --git a/VEX/head20041019/helgrind/tests/race2.stderr.exp b/VEX/head20041019/helgrind/tests/race2.stderr.exp deleted file mode 100644 index 9a7d7e642..000000000 --- a/VEX/head20041019/helgrind/tests/race2.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ - -Thread 3: -Possible data race writing variable at 0x........ - at 0x........: th (race2.c:17) - by 0x........: thread_wrapper (vg_libpthread.c:...) - by 0x........: do__quit (vg_scheduler.c:...) - Address 0x........ == &(f->poot[5].plop[11]) at race2.c:17 - Previous state: shared RO, no locks - diff --git a/VEX/head20041019/helgrind/tests/race2.vgtest b/VEX/head20041019/helgrind/tests/race2.vgtest deleted file mode 100644 index a67c27ae4..000000000 --- a/VEX/head20041019/helgrind/tests/race2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: race2 -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/readshared.c b/VEX/head20041019/helgrind/tests/readshared.c deleted file mode 100644 index 0541e7def..000000000 --- a/VEX/head20041019/helgrind/tests/readshared.c +++ /dev/null @@ -1,33 +0,0 @@ -/* All OK - test allowed read sharing */ - -#include -#include - -static int shared; - -static void *t1(void *v) -{ - return (void *)(shared + 44); -} - -static void *t2(void *v) -{ - return (void *)(shared + 55); -} - -int main() -{ - pthread_t a, b; - - shared = 22; - - pthread_create(&a, NULL, t1, NULL); - pthread_create(&b, NULL, t2, NULL); - - pthread_join(a, NULL); - pthread_join(b, NULL); - - assert(shared == 22); - - return 0; -} diff --git a/VEX/head20041019/helgrind/tests/readshared.stderr.exp b/VEX/head20041019/helgrind/tests/readshared.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/helgrind/tests/readshared.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/helgrind/tests/readshared.vgtest b/VEX/head20041019/helgrind/tests/readshared.vgtest deleted file mode 100644 index 2d91bee03..000000000 --- a/VEX/head20041019/helgrind/tests/readshared.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: readshared -vgopts: --optimise=no diff --git a/VEX/head20041019/helgrind/tests/toobig-allocs.stderr.exp b/VEX/head20041019/helgrind/tests/toobig-allocs.stderr.exp deleted file mode 100644 index 28c2b9ee0..000000000 --- a/VEX/head20041019/helgrind/tests/toobig-allocs.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ - -Attempting too-big malloc()... -Attempting too-big mmap()... - diff --git a/VEX/head20041019/helgrind/tests/toobig-allocs.vgtest b/VEX/head20041019/helgrind/tests/toobig-allocs.vgtest deleted file mode 100644 index 186cf5f90..000000000 --- a/VEX/head20041019/helgrind/tests/toobig-allocs.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: ../../tests/toobig-allocs diff --git a/VEX/head20041019/include/.cvsignore b/VEX/head20041019/include/.cvsignore deleted file mode 100644 index 3e26277d6..000000000 --- a/VEX/head20041019/include/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile.in -Makefile -tool.h diff --git a/VEX/head20041019/include/CVS/Entries b/VEX/head20041019/include/CVS/Entries deleted file mode 100644 index 4fb60480c..000000000 --- a/VEX/head20041019/include/CVS/Entries +++ /dev/null @@ -1,9 +0,0 @@ -/.cvsignore/1.3/Thu Sep 2 08:54:27 2004// -/Makefile.am/1.9/Mon Oct 18 18:07:49 2004// -/tool.h.base/1.7/Tue Sep 7 10:17:02 2004// -/tool_asm.h/1.2/Fri Sep 3 13:45:28 2004// -/valgrind.h.in/1.1/Mon Oct 18 18:07:49 2004// -/vg_kerneliface.h/1.25/Tue Sep 14 11:55:36 2004// -/vg_profile.c/1.12/Thu Sep 2 08:51:42 2004// -/vg_skin.h/1.104/Thu Sep 2 08:55:34 2004// -D/x86//// diff --git a/VEX/head20041019/include/CVS/Repository b/VEX/head20041019/include/CVS/Repository deleted file mode 100644 index 9ed88dbe9..000000000 --- a/VEX/head20041019/include/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/include diff --git a/VEX/head20041019/include/CVS/Root b/VEX/head20041019/include/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/include/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/include/CVS/Template b/VEX/head20041019/include/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/include/Makefile.am b/VEX/head20041019/include/Makefile.am deleted file mode 100644 index ad8370e54..000000000 --- a/VEX/head20041019/include/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ - -SUBDIRS = $(VG_ARCH) . - -EXTRA_DIST = \ - tool.h.base \ - valgrind.h.in \ - vg_profile.c - -incincdir = $(includedir)/valgrind - -incinc_HEADERS = \ - tool.h \ - tool_asm.h \ - valgrind.h \ - vg_kerneliface.h \ - vg_skin.h - -BUILT_SOURCES = tool.h valgrind.h -CLEANFILES = tool.h valgrind.h - -tool.h: $(srcdir)/tool.h.base \ - $(top_srcdir)/coregrind/gen_toolint.pl $(top_srcdir)/coregrind/toolfuncs.def - rm -f $@ - cat $(srcdir)/tool.h.base > $@ - $(PERL) $(top_srcdir)/coregrind/gen_toolint.pl toolproto < $(top_srcdir)/coregrind/toolfuncs.def >> $@ || rm -f $@ - $(PERL) $(top_srcdir)/coregrind/gen_toolint.pl initproto < $(top_srcdir)/coregrind/toolfuncs.def >> $@ || rm -f $@ diff --git a/VEX/head20041019/include/tool.h.base b/VEX/head20041019/include/tool.h.base deleted file mode 100644 index a1370a1ad..000000000 --- a/VEX/head20041019/include/tool.h.base +++ /dev/null @@ -1,1912 +0,0 @@ -/*-*- c -*- ----------------------------------------------------------*/ -/*--- The only header your tool will ever need to #include... ---*/ -/*--- tool.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __TOOL_H -#define __TOOL_H - -#include /* ANSI varargs stuff */ -#include /* for jmp_buf */ - -#include "tool_asm.h" // asm stuff - -#include "../../../pub/libvex_basictypes.h" -#include "../../../pub/libvex_ir.h" -#include "../../../pub/libvex.h" - - -/*====================================================================*/ -/*=== Basic types ===*/ -/*====================================================================*/ - -typedef HWord UWord; -typedef HWord Addr; - - -/* --------------------------------------------------------------------- - Now the basic types are set up, we can haul in the kernel-interface - definitions and tool_arch.h - ------------------------------------------------------------------ */ - -#include "tool_arch.h" // arch-specific tool stuff -#include "vg_kerneliface.h" - -/* --------------------------------------------------------------------- - Where to send bug reports to. - ------------------------------------------------------------------ */ - -#define VG_BUGS_TO "valgrind.kde.org" - - -/*====================================================================*/ -/*=== Build options and table sizes. ===*/ -/*====================================================================*/ - -/* You should be able to change these options or sizes, recompile, and - still have a working system. */ - -/* The maximum number of pthreads that we support. This is - deliberately not very high since our implementation of some of the - scheduler algorithms is surely O(N) in the number of threads, since - that's simple, at least. And (in practice) we hope that most - programs do not need many threads. */ -#define VG_N_THREADS 100 - -/* Maximum number of pthread keys available. Again, we start low until - the need for a higher number presents itself. */ -#define VG_N_THREAD_KEYS 50 - - -/*====================================================================*/ -/*=== Useful macros ===*/ -/*====================================================================*/ - -#define mycat_wrk(aaa,bbb) aaa##bbb -#define mycat(aaa,bbb) mycat_wrk(aaa,bbb) - -/* No, really. I _am_ that strange. */ -#define OINK(nnn) VG_(message)(Vg_DebugMsg, "OINK %d",nnn) - -/* Path to all our library/aux files */ -extern const Char *VG_(libdir); - - -/*====================================================================*/ -/*=== Core/tool interface version ===*/ -/*====================================================================*/ - -/* The major version number indicates binary-incompatible changes to the - interface; if the core and tool major versions don't match, Valgrind - will abort. The minor version indicates binary-compatible changes. -*/ -#define VG_CORE_INTERFACE_MAJOR_VERSION 6 -#define VG_CORE_INTERFACE_MINOR_VERSION 0 - -typedef struct _ToolInfo { - Int sizeof_ToolInfo; - Int interface_major_version; - Int interface_minor_version; - - /* Initialise tool. Must do the following: - - initialise the `details' struct, via the VG_(details_*)() functions - - register any helpers called by generated code - - May do the following: - - initialise the `needs' struct to indicate certain requirements, via - the VG_(needs_*)() functions - - initialize all the tool's entrypoints via the VG_(init_*)() functions - - register any tool-specific profiling events - - any other tool-specific initialisation - */ - void (*sk_pre_clo_init) ( void ); - - /* Specifies how big the shadow segment should be as a ratio to the - client address space. 0 for no shadow segment. */ - float shadow_ratio; -} ToolInfo; - -/* Every tool must include this macro somewhere, exactly once. */ -#define VG_DETERMINE_INTERFACE_VERSION(pre_clo_init, shadow) \ - const ToolInfo SK_(tool_info) = { \ - .sizeof_ToolInfo = sizeof(ToolInfo), \ - .interface_major_version = VG_CORE_INTERFACE_MAJOR_VERSION, \ - .interface_minor_version = VG_CORE_INTERFACE_MINOR_VERSION, \ - .sk_pre_clo_init = pre_clo_init, \ - .shadow_ratio = shadow, \ - }; - -/*====================================================================*/ -/*=== Command-line options ===*/ -/*====================================================================*/ - -/* Use this for normal null-termination-style string comparison */ -#define VG_STREQ(s1,s2) (s1 != NULL && s2 != NULL \ - && VG_(strcmp)((s1),(s2))==0) - -/* Use these for recognising tool command line options -- stops comparing - once whitespace is reached. */ -#define VG_CLO_STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2))) -#define VG_CLO_STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn))) - -// Higher-level command-line option recognisers; use in if/else chains - -#define VG_BOOL_CLO(qq_option, qq_var) \ - if (VG_CLO_STREQ(arg, qq_option"=yes")) { (qq_var) = True; } \ - else if (VG_CLO_STREQ(arg, qq_option"=no")) { (qq_var) = False; } - -#define VG_STR_CLO(qq_option, qq_var) \ - if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, arg, qq_option"=")) { \ - (qq_var) = &arg[ VG_(strlen)(qq_option)+1 ]; \ - } - -#define VG_NUM_CLO(qq_option, qq_var) \ - if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, arg, qq_option"=")) { \ - (qq_var) = (Int)VG_(atoll)( &arg[ VG_(strlen)(qq_option)+1 ] ); \ - } - -// Bounded integer arg -#define VG_BNUM_CLO(qq_option, qq_var, qq_lo, qq_hi) \ - if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, arg, qq_option"=")) { \ - (qq_var) = (Int)VG_(atoll)( &arg[ VG_(strlen)(qq_option)+1 ] ); \ - if ((qq_var) < (qq_lo)) (qq_var) = (qq_lo); \ - if ((qq_var) > (qq_hi)) (qq_var) = (qq_hi); \ - } - - -/* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */ -extern Int VG_(clo_verbosity); - -/* Profile? */ -extern Bool VG_(clo_profile); - -/* Call this if a recognised option was bad for some reason. - Note: don't use it just because an option was unrecognised -- return 'False' - from SKN_(process_cmd_line_option) to indicate that. */ -extern void VG_(bad_option) ( Char* opt ); - -/* Client args */ -extern Int VG_(client_argc); -extern Char** VG_(client_argv); - -/* Client environment. Can be inspected with VG_(getenv)() */ -extern Char** VG_(client_envp); - - -/*====================================================================*/ -/*=== Printing messages for the user ===*/ -/*====================================================================*/ - -/* Print a message prefixed by "???? "; '?' depends on the VgMsgKind. - Should be used for all user output. */ - -typedef - enum { Vg_UserMsg, /* '?' == '=' */ - Vg_DebugMsg, /* '?' == '-' */ - Vg_DebugExtraMsg, /* '?' == '+' */ - Vg_ClientMsg, /* '?' == '*' */ - } - VgMsgKind; - -/* Functions for building a message from multiple parts. */ -extern int VG_(start_msg) ( VgMsgKind kind ); -extern int VG_(add_to_msg) ( Char* format, ... ); -/* Ends and prints the message. Appends a newline. */ -extern int VG_(end_msg) ( void ); - -/* Send a single-part message. Appends a newline. */ -extern int VG_(message) ( VgMsgKind kind, Char* format, ... ); -extern int VG_(vmessage) ( VgMsgKind kind, Char* format, va_list vargs ); - - -/*====================================================================*/ -/*=== Profiling ===*/ -/*====================================================================*/ - -/* Nb: VGP_(register_profile_event)() relies on VgpUnc being the first one */ -#define VGP_CORE_LIST \ - /* These ones depend on the core */ \ - VGP_PAIR(VgpUnc, "unclassified"), \ - VGP_PAIR(VgpStartup, "startup"), \ - VGP_PAIR(VgpRun, "running"), \ - VGP_PAIR(VgpSched, "scheduler"), \ - VGP_PAIR(VgpMalloc, "low-lev malloc/free"), \ - VGP_PAIR(VgpCliMalloc, "client malloc/free"), \ - VGP_PAIR(VgpTranslate, "translate-main"), \ - VGP_PAIR(VgpToUCode, "to-ucode"), \ - VGP_PAIR(VgpFromUcode, "from-ucode"), \ - VGP_PAIR(VgpImprove, "improve"), \ - VGP_PAIR(VgpESPUpdate, "ESP-update"), \ - VGP_PAIR(VgpRegAlloc, "reg-alloc"), \ - VGP_PAIR(VgpLiveness, "liveness-analysis"), \ - VGP_PAIR(VgpDoLRU, "do-lru"), \ - VGP_PAIR(VgpSlowFindT, "slow-search-transtab"), \ - VGP_PAIR(VgpExeContext, "exe-context"), \ - VGP_PAIR(VgpReadSyms, "read-syms"), \ - VGP_PAIR(VgpSearchSyms, "search-syms"), \ - VGP_PAIR(VgpAddToT, "add-to-transtab"), \ - VGP_PAIR(VgpCoreSysWrap, "core-syscall-wrapper"), \ - VGP_PAIR(VgpDemangle, "demangle"), \ - VGP_PAIR(VgpCoreCheapSanity, "core-cheap-sanity"), \ - VGP_PAIR(VgpCoreExpensiveSanity, "core-expensive-sanity"), \ - /* These ones depend on the tool */ \ - VGP_PAIR(VgpPreCloInit, "pre-clo-init"), \ - VGP_PAIR(VgpPostCloInit, "post-clo-init"), \ - VGP_PAIR(VgpInstrument, "instrument"), \ - VGP_PAIR(VgpSkinSysWrap, "tool-syscall-wrapper"), \ - VGP_PAIR(VgpSkinCheapSanity, "tool-cheap-sanity"), \ - VGP_PAIR(VgpSkinExpensiveSanity, "tool-expensive-sanity"), \ - VGP_PAIR(VgpFini, "fini") - -#define VGP_PAIR(n,name) n -typedef enum { VGP_CORE_LIST } VgpCoreCC; -#undef VGP_PAIR - -/* When registering tool profiling events, ensure that the 'n' value is in - * the range (VgpFini+1..) */ -extern void VGP_(register_profile_event) ( Int n, Char* name ); - -extern void VGP_(pushcc) ( UInt cc ); -extern void VGP_(popcc) ( UInt cc ); - -/* Define them only if they haven't already been defined by vg_profile.c */ -#ifndef VGP_PUSHCC -# define VGP_PUSHCC(x) -#endif -#ifndef VGP_POPCC -# define VGP_POPCC(x) -#endif - - -/*====================================================================*/ -/*=== Useful stuff to call from generated code ===*/ -/*====================================================================*/ - -/* ------------------------------------------------------------------ */ -/* General stuff */ - -/* 64-bit counter for the number of basic blocks done. */ -extern ULong VG_(bbs_done); - -/* Get the simulated %esp */ -extern Addr VG_(get_stack_pointer) ( void ); - -/* Check if an address is 4-byte aligned */ -#define IS_ALIGNED4_ADDR(aaa_p) (0 == (((UInt)(aaa_p)) & 3)) -#define IS_ALIGNED8_ADDR(aaa_p) (0 == (((UInt)(aaa_p)) & 7)) - - -/* ------------------------------------------------------------------ */ -/* Thread-related stuff */ - -/* Special magic value for an invalid ThreadId. It corresponds to - LinuxThreads using zero as the initial value for - pthread_mutex_t.__m_owner and pthread_cond_t.__c_waiting. */ -#define VG_INVALID_THREADID ((ThreadId)(0)) - -/* ThreadIds are simply indices into the VG_(threads)[] array. */ -typedef - UInt - ThreadId; - -/* When looking for the current ThreadId, this is the safe option and - probably the one you want. - - Details: Use this one from non-generated code, eg. from functions called - on events like 'new_mem_heap'. In such a case, the "current" thread is - temporarily suspended as Valgrind's dispatcher is running. This function - is also suitable to be called from generated code (ie. from UCode, or a C - function called directly from UCode). - - If you use VG_(get_current_tid)() from non-generated code, it will return - 0 signifying the invalid thread, which is probably not what you want. */ -extern ThreadId VG_(get_current_or_recent_tid) ( void ); - -/* When looking for the current ThreadId, only use this one if you know what - you are doing. - - Details: Use this one from generated code, eg. from C functions called - from UCode. (VG_(get_current_or_recent_tid)() is also suitable in that - case.) If you use this function from non-generated code, it will return - 0 signifying the invalid thread, which is probably not what you want. */ -extern ThreadId VG_(get_current_tid) ( void ); - -/* Searches through all thread's stacks to see if any match. Returns - VG_INVALID_THREADID if none match. */ -extern ThreadId VG_(first_matching_thread_stack) - ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ), - void* d ); - - -/*====================================================================*/ -/*=== Valgrind's version of libc ===*/ -/*====================================================================*/ - -/* Valgrind doesn't use libc at all, for good reasons (trust us). So here - are its own versions of C library functions, but with VG_ prefixes. Note - that the types of some are slightly different to the real ones. Some - additional useful functions are provided too; descriptions of how they - work are given below. */ - -#if !defined(NULL) -# define NULL ((void*)0) -#endif - - -/* ------------------------------------------------------------------ */ -/* stdio.h - * - * Note that they all output to the file descriptor given by the - * --log-fd/--log-file/--log-socket argument, which defaults to 2 (stderr). - * Hence no need for VG_(fprintf)(). - */ -extern UInt VG_(printf) ( const char *format, ... ); -/* too noisy ... __attribute__ ((format (printf, 1, 2))) ; */ -extern UInt VG_(sprintf) ( Char* buf, Char *format, ... ); -extern UInt VG_(vprintf) ( void(*send)(Char), - const Char *format, va_list vargs ); - -extern Int VG_(rename) ( Char* old_name, Char* new_name ); - -/* ------------------------------------------------------------------ */ -/* stdlib.h */ - -extern void* VG_(malloc) ( Int nbytes ); -extern void VG_(free) ( void* p ); -extern void* VG_(calloc) ( Int n, Int nbytes ); -extern void* VG_(realloc) ( void* p, Int size ); -extern void* VG_(malloc_aligned) ( Int align_bytes, Int nbytes ); - -extern void VG_(print_malloc_stats) ( void ); - - -extern void VG_(exit)( Int status ) - __attribute__ ((__noreturn__)); -/* Prints a panic message (a constant string), appends newline and bug - reporting info, aborts. */ -__attribute__ ((__noreturn__)) -extern void VG_(skin_panic) ( Char* str ); - -/* Looks up VG_(client_envp) */ -extern Char* VG_(getenv) ( Char* name ); - -/* Get client resource limit*/ -extern Int VG_(getrlimit) ( Int resource, struct vki_rlimit *rlim ); - -/* Set client resource limit*/ -extern Int VG_(setrlimit) ( Int resource, struct vki_rlimit *rlim ); - -/* Crude stand-in for the glibc system() call. */ -extern Int VG_(system) ( Char* cmd ); - -extern Long VG_(atoll) ( Char* str ); - -/* Like atoll(), but converts a number of base 16 */ -extern Long VG_(atoll16) ( Char* str ); - -/* Like atoll(), but converts a number of base 2..36 */ -extern Long VG_(atoll36) ( UInt base, Char* str ); - -/* Like qsort(), but does shell-sort. The size==1/2/4 cases are specialised. */ -extern void VG_(ssort)( void* base, UInt nmemb, UInt size, - Int (*compar)(void*, void*) ); - - -/* ------------------------------------------------------------------ */ -/* ctype.h */ -extern Bool VG_(isspace) ( Char c ); -extern Bool VG_(isdigit) ( Char c ); -extern Char VG_(toupper) ( Char c ); - - -/* ------------------------------------------------------------------ */ -/* string.h */ -extern Int VG_(strlen) ( const Char* str ); -extern Char* VG_(strcat) ( Char* dest, const Char* src ); -extern Char* VG_(strncat) ( Char* dest, const Char* src, Int n ); -extern Char* VG_(strpbrk) ( const Char* s, const Char* accept ); -extern Char* VG_(strcpy) ( Char* dest, const Char* src ); -extern Char* VG_(strncpy) ( Char* dest, const Char* src, Int ndest ); -extern Int VG_(strcmp) ( const Char* s1, const Char* s2 ); -extern Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax ); -extern Char* VG_(strstr) ( const Char* haystack, Char* needle ); -extern Char* VG_(strchr) ( const Char* s, Char c ); -extern Char* VG_(strrchr) ( const Char* s, Char c ); -extern Char* VG_(strdup) ( const Char* s); -extern void* VG_(memcpy) ( void *d, const void *s, Int sz ); -extern void* VG_(memset) ( void *s, Int c, Int sz ); -extern Int VG_(memcmp) ( const void* s1, const void* s2, Int n ); - -/* Like strcmp() and strncmp(), but stop comparing at any whitespace. */ -extern Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 ); -extern Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax ); - -/* Like strncpy(), but if 'src' is longer than 'ndest' inserts a '\0' as the - last character. */ -extern void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest ); - -/* Mini-regexp function. Searches for 'pat' in 'str'. Supports - * meta-symbols '*' and '?'. '\' escapes meta-symbols. */ -extern Bool VG_(string_match) ( const Char* pat, const Char* str ); - - -/* ------------------------------------------------------------------ */ -/* math.h */ -/* Returns the base-2 logarithm of x. */ -extern Int VG_(log2) ( Int x ); - - -/* ------------------------------------------------------------------ */ -/* unistd.h, fcntl.h, sys/stat.h */ -extern Int VG_(getdents)( UInt fd, struct vki_dirent *dirp, UInt count ); -extern Int VG_(readlink)( Char* path, Char* buf, UInt bufsize ); -extern Int VG_(getpid) ( void ); -extern Int VG_(getppid) ( void ); -extern Int VG_(getpgrp) ( void ); -extern Int VG_(gettid) ( void ); -extern Int VG_(setpgid) ( Int pid, Int pgrp ); - -extern Int VG_(open) ( const Char* pathname, Int flags, Int mode ); -extern Int VG_(read) ( Int fd, void* buf, Int count); -extern Int VG_(write) ( Int fd, const void* buf, Int count); -extern Int VG_(lseek) ( Int fd, Long offset, Int whence); -extern void VG_(close) ( Int fd ); - -extern Int VG_(pipe) ( Int fd[2] ); - -/* Nb: VG_(rename)() declared in stdio.h section above */ -extern Int VG_(unlink) ( Char* file_name ); -extern Int VG_(stat) ( Char* file_name, struct vki_stat* buf ); -extern Int VG_(fstat) ( Int fd, struct vki_stat* buf ); -extern Int VG_(dup2) ( Int oldfd, Int newfd ); - -extern Char* VG_(getcwd) ( Char* buf, Int size ); - -/* Easier to use than VG_(getcwd)() -- does the buffer fiddling itself. - String put into 'cwd' is VG_(malloc)'d, and should be VG_(free)'d. - Returns False if it fails. Will fail if the pathname is > 65535 bytes. */ -extern Bool VG_(getcwd_alloc) ( Char** cwd ); - -/* ------------------------------------------------------------------ */ -/* assert.h */ -/* Asserts permanently enabled -- no turning off with NDEBUG. Hurrah! */ -#define VG__STRING(__str) #__str - -#define sk_assert(expr) \ - ((void) ((expr) ? 0 : \ - (VG_(skin_assert_fail) (VG__STRING(expr), \ - __FILE__, __LINE__, \ - __PRETTY_FUNCTION__), 0))) - -__attribute__ ((__noreturn__)) -extern void VG_(skin_assert_fail) ( const Char* expr, const Char* file, - Int line, const Char* fn ); - - -/* ------------------------------------------------------------------ */ -/* Get memory by anonymous mmap. */ -extern void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who ); - -extern Bool VG_(is_client_addr) (Addr a); -extern Addr VG_(get_client_base)(void); -extern Addr VG_(get_client_end) (void); -extern Addr VG_(get_client_size)(void); - -extern Bool VG_(is_shadow_addr) (Addr a); -extern Addr VG_(get_shadow_base)(void); -extern Addr VG_(get_shadow_end) (void); -extern Addr VG_(get_shadow_size)(void); - -extern void *VG_(shadow_alloc)(UInt size); - -extern Bool VG_(is_addressable)(Addr p, Int sz); - -extern Addr VG_(client_alloc)(Addr base, UInt len, UInt prot, UInt flags); -extern void VG_(client_free)(Addr addr); - -extern Bool VG_(is_valgrind_addr)(Addr a); - -/* initialize shadow pages in the range [p, p+sz) This calls - init_shadow_page for each one. It should be a lot more efficient - for bulk-initializing shadow pages than faulting on each one. -*/ -extern void VG_(init_shadow_range)(Addr p, UInt sz, Bool call_init); - -/* ------------------------------------------------------------------ */ -/* signal.h. - - Note that these use the vk_ (kernel) structure - definitions, which are different in places from those that glibc - defines -- hence the 'k' prefix. Since we're operating right at the - kernel interface, glibc's view of the world is entirely irrelevant. */ - -/* --- Signal set ops --- */ -extern Int VG_(ksigfillset) ( vki_ksigset_t* set ); -extern Int VG_(ksigemptyset) ( vki_ksigset_t* set ); - -extern Bool VG_(kisfullsigset) ( vki_ksigset_t* set ); -extern Bool VG_(kisemptysigset) ( vki_ksigset_t* set ); - -extern Int VG_(ksigaddset) ( vki_ksigset_t* set, Int signum ); -extern Int VG_(ksigdelset) ( vki_ksigset_t* set, Int signum ); -extern Int VG_(ksigismember) ( vki_ksigset_t* set, Int signum ); - -extern void VG_(ksigaddset_from_set) ( vki_ksigset_t* dst, vki_ksigset_t* src ); -extern void VG_(ksigdelset_from_set) ( vki_ksigset_t* dst, vki_ksigset_t* src ); - -/* --- Mess with the kernel's sig state --- */ -extern Int VG_(ksigprocmask) ( Int how, const vki_ksigset_t* set, - vki_ksigset_t* oldset ); -extern Int VG_(ksigaction) ( Int signum, - const vki_ksigaction* act, - vki_ksigaction* oldact ); - -extern Int VG_(ksigtimedwait)( const vki_ksigset_t *, vki_ksiginfo_t *, - const struct vki_timespec * ); - -extern Int VG_(ksignal) ( Int signum, void (*sighandler)(Int) ); -extern Int VG_(ksigaltstack) ( const vki_kstack_t* ss, vki_kstack_t* oss ); - -extern Int VG_(kkill) ( Int pid, Int signo ); -extern Int VG_(ktkill) ( Int pid, Int signo ); -extern Int VG_(ksigpending) ( vki_ksigset_t* set ); - -extern Int VG_(waitpid) ( Int pid, Int *status, Int options ); - -/* ------------------------------------------------------------------ */ -/* socket.h. */ - -extern Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen); -extern Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen); -extern Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval, - Int *optlen); - -/* ------------------------------------------------------------------ */ -/* other, randomly useful functions */ -extern UInt VG_(read_millisecond_timer) ( void ); - -extern void VG_(cpuid) ( UInt eax, - UInt *eax_ret, UInt *ebx_ret, - UInt *ecx_ret, UInt *edx_ret ); - -/*====================================================================*/ -/*=== UCode definition ===*/ -/*====================================================================*/ - -/* Tags which describe what operands are. Must fit into 4 bits, which - they clearly do. */ -typedef -enum { TempReg =0, /* virtual temp-reg */ - ArchReg =1, /* simulated integer reg */ - ArchRegS =2, /* simulated segment reg */ - RealReg =3, /* real machine's real reg */ - SpillNo =4, /* spill slot location */ - Literal =5, /* literal; .lit32 field has actual value */ - Lit16 =6, /* literal; .val[123] field has actual value */ - NoValue =7 /* operand not in use */ - } - Tag; - -/* Invalid register numbers (can't be negative) */ -#define INVALID_TEMPREG 999999999 -#define INVALID_REALREG 999999999 - -/* Microinstruction opcodes. */ -typedef - enum { - NOP, /* Null op */ - - LOCK, /* Indicate the existence of a LOCK prefix (functionally NOP) */ - - /* Moving values around */ - GET, PUT, /* simulated register <--> TempReg */ - GETF, PUTF, /* simulated %eflags <--> TempReg */ - LOAD, STORE, /* memory <--> TempReg */ - MOV, /* TempReg <--> TempReg */ - CMOV, /* Used for cmpxchg and cmov */ - - /* Arithmetic/logical ops */ - MUL, UMUL, /* Multiply */ - ADD, ADC, SUB, SBB, /* Add/subtract (w/wo carry) */ - AND, OR, XOR, NOT, /* Boolean ops */ - SHL, SHR, SAR, ROL, ROR, RCL, RCR, /* Shift/rotate (w/wo carry) */ - NEG, /* Negate */ - INC, DEC, /* Increment/decrement */ - BSWAP, /* Big-endian <--> little-endian */ - CC2VAL, /* Condition code --> 0 or 1 */ - WIDEN, /* Signed or unsigned widening */ - - /* Conditional or unconditional jump */ - JMP, - - /* FPU ops */ - FPU, /* Doesn't touch memory */ - FPU_R, FPU_W, /* Reads/writes memory */ - - /* ------------ MMX ops ------------ */ - /* In this and the SSE encoding, bytes at higher addresses are - held in bits [7:0] in these 16-bit words. I guess this means - it is a big-endian encoding. */ - - /* 1 byte, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[7:0]. */ - MMX1, - - /* 2 bytes, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[15:0]. */ - MMX2, - - /* 3 bytes, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[15:0] and val2[7:0]. */ - MMX3, - - /* 2 bytes, reads/writes mem. Insns of the form - bbbbbbbb:mod mmxreg r/m. - Held in val1[15:0], and mod and rm are to be replaced - at codegen time by a reference to the Temp/RealReg holding - the address. Arg2 holds this Temp/Real Reg. - Transfer is always at size 8. - */ - MMX2_MemRd, - MMX2_MemWr, - - /* 3 bytes, reads/writes mem. Insns of the form - bbbbbbbb:mod mmxreg r/m:bbbbbbbb - Held in val1[15:0] and val2[7:0], and mod and rm are to be - replaced at codegen time by a reference to the Temp/RealReg - holding the address. Arg2 holds this Temp/Real Reg. - Transfer is always at size 8. - */ - MMX2a1_MemRd, - - /* 2 bytes, reads/writes an integer ("E") register. Insns of the form - bbbbbbbb:11 mmxreg ireg. - Held in val1[15:0], and ireg is to be replaced - at codegen time by a reference to the relevant RealReg. - Transfer is always at size 4. Arg2 holds this Temp/Real Reg. - */ - MMX2_ERegRd, - MMX2_ERegWr, - - /* ------------ SSE/SSE2 ops ------------ */ - /* In the following: - - a digit N indicates the next N bytes are to be copied exactly - to the output. - - 'a' indicates a mod-xmmreg-rm byte, where the mod-rm part is - to be replaced at codegen time to a Temp/RealReg holding the - address. - - 'e' indicates a byte of the form '11 xmmreg ireg', where ireg - is read or written, and is to be replaced at codegen time by - a reference to the relevant RealReg. 'e' because it's the E - reg in Intel encoding parlance. - - 'g' indicates a byte of the form '11 ireg xmmreg', where ireg - is read or written, and is to be replaced at codegen time by - a reference to the relevant RealReg. 'g' because it's called - G in Intel parlance. */ - - /* 3 bytes, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[15:0] and val2[7:0]. */ - SSE3, - - /* 3 bytes, reads/writes mem. Insns of the form - bbbbbbbb:bbbbbbbb:mod mmxreg r/m. - Held in val1[15:0] and val2[7:0], and mod and rm are to be - replaced at codegen time by a reference to the Temp/RealReg - holding the address. Arg3 holds this Temp/Real Reg. - Transfer is usually, but not always, at size 16. */ - SSE2a_MemRd, - SSE2a_MemWr, - - /* 4 bytes, writes an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:11 ireg bbb. - Held in val1[15:0] and val2[7:0], and ireg is to be replaced - at codegen time by a reference to the relevant RealReg. - Transfer is always at size 4. Arg3 holds this Temp/Real Reg. - */ - SSE2g_RegWr, - - /* 5 bytes, writes an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:11 ireg bbb :bbbbbbbb. Held in - val1[15:0] and val2[7:0] and lit32[7:0], and ireg is to be - replaced at codegen time by a reference to the relevant - RealReg. Transfer is always at size 4. Arg3 holds this - Temp/Real Reg. - */ - SSE2g1_RegWr, - - /* 5 bytes, reads an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:11 bbb ireg :bbbbbbbb. Held in - val1[15:0] and val2[7:0] and lit32[7:0], and ireg is to be - replaced at codegen time by a reference to the relevant - RealReg. Transfer is always at size 4. Arg3 holds this - Temp/Real Reg. - */ - SSE2e1_RegRd, - - /* 4 bytes, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[15:0] and val2[15:0]. */ - SSE4, - - /* 4 bytes, reads/writes mem. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb:mod mmxreg r/m. - Held in val1[15:0] and val2[15:0], and mod and rm are to be - replaced at codegen time by a reference to the Temp/RealReg - holding the address. Arg3 holds this Temp/Real Reg. - Transfer is at stated size. */ - SSE3a_MemRd, - SSE3a_MemWr, - - /* 4 bytes, reads/writes mem. Insns of the form - bbbbbbbb:bbbbbbbb:mod mmxreg r/m:bbbbbbbb - Held in val1[15:0] and val2[15:0], and mod and rm are to be - replaced at codegen time by a reference to the Temp/RealReg - holding the address. Arg3 holds this Temp/Real Reg. - Transfer is at stated size. */ - SSE2a1_MemRd, - - /* 4 bytes, writes an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb:11 ireg bbb. - Held in val1[15:0] and val2[15:0], and ireg is to be replaced - at codegen time by a reference to the relevant RealReg. - Transfer is always at size 4. Arg3 holds this Temp/Real Reg. - */ - SSE3g_RegWr, - - /* 5 bytes, writes an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb: 11 ireg bbb :bbbbbbbb. Held in - val1[15:0] and val2[15:0] and lit32[7:0], and ireg is to be - replaced at codegen time by a reference to the relevant - RealReg. Transfer is always at size 4. Arg3 holds this - Temp/Real Reg. - */ - SSE3g1_RegWr, - - /* 4 bytes, reads an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb:11 bbb ireg. - Held in val1[15:0] and val2[15:0], and ireg is to be replaced - at codegen time by a reference to the relevant RealReg. - Transfer is always at size 4. Arg3 holds this Temp/Real Reg. - */ - SSE3e_RegRd, - SSE3e_RegWr, /* variant that writes Ereg, not reads it */ - - /* 5 bytes, reads an integer register. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb: 11 bbb ireg :bbbbbbbb. Held in - val1[15:0] and val2[15:0] and lit32[7:0], and ireg is to be - replaced at codegen time by a reference to the relevant - RealReg. Transfer is always at size 4. Arg3 holds this - Temp/Real Reg. - */ - SSE3e1_RegRd, - - /* 4 bytes, reads memory, writes an integer register, but is - nevertheless an SSE insn. The insn is of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb:mod ireg rm where mod indicates - memory (ie is not 11b) and ireg is the int reg written. The - first 4 bytes are held in lit32[31:0] since there is - insufficient space elsewhere. mod and rm are to be replaced - at codegen time by a reference to the Temp/RealReg holding - the address. Arg1 holds this Temp/RealReg. ireg is to be - replaced at codegen time by a reference to the relevant - RealReg in which the answer is to be written. Arg2 holds - this Temp/RealReg. Transfer to the destination reg is always - at size 4. However the memory read can be at sizes 4 or 8 - and so this is what the sz field holds. Note that the 4th - byte of the instruction (the modrm byte) is redundant, but we - store it anyway so as to be consistent with all other SSE - uinstrs. - */ - SSE3ag_MemRd_RegWr, - - /* 5 bytes, no memrefs, no iregdefs, copy exactly to the - output. Held in val1[15:0], val2[15:0] and val3[7:0]. */ - SSE5, - - /* 5 bytes, reads/writes mem. Insns of the form - bbbbbbbb:bbbbbbbb:bbbbbbbb:mod mmxreg r/m:bbbbbbbb - Held in val1[15:0], val2[15:0], lit32[7:0]. - mod and rm are to be replaced at codegen time by a reference - to the Temp/RealReg holding the address. Arg3 holds this - Temp/Real Reg. Transfer is always at size 16. */ - SSE3a1_MemRd, - - /* ------------------------ */ - - /* Not strictly needed, but improve address calculation translations. */ - LEA1, /* reg2 := const + reg1 */ - LEA2, /* reg3 := const + reg1 + reg2 * 1,2,4 or 8 */ - - /* Hack for x86 REP insns. Jump to literal if TempReg/RealReg - is zero. */ - JIFZ, - - /* Advance the simulated %eip by some small (< 128) number. */ - INCEIP, - - /* Dealing with segment registers */ - GETSEG, PUTSEG, /* simulated segment register <--> TempReg */ - USESEG, /* (LDT/GDT index, virtual addr) --> linear addr */ - - /* Not for translating x86 calls -- only to call helpers */ - CALLM_S, CALLM_E, /* Mark start/end of CALLM push/pop sequence */ - PUSH, POP, CLEAR, /* Add/remove/zap args for helpers */ - CALLM, /* Call assembly-code helper */ - - /* Not for translating x86 calls -- only to call C helper functions of - up to three arguments (or two if the functions has a return value). - Arguments and return value must be word-sized. More arguments can - be faked with global variables (eg. use VG_(lit_to_globvar)()). - - Seven possibilities: 'arg[123]' show where args go, 'ret' shows - where return value goes (if present). - - CCALL(-, -, - ) void f(void) - CCALL(arg1, -, - ) void f(UInt arg1) - CCALL(arg1, arg2, - ) void f(UInt arg1, UInt arg2) - CCALL(arg1, arg2, arg3) void f(UInt arg1, UInt arg2, UInt arg3) - CCALL(-, -, ret ) UInt f(UInt) - CCALL(arg1, -, ret ) UInt f(UInt arg1) - CCALL(arg1, arg2, ret ) UInt f(UInt arg1, UInt arg2) */ - CCALL, - - /* This opcode makes it easy for tools that extend UCode to do this to - avoid opcode overlap: - - enum { EU_OP1 = DUMMY_FINAL_UOPCODE + 1, ... } - - WARNING: Do not add new opcodes after this one! They can be added - before, though. */ - DUMMY_FINAL_UOPCODE - } - Opcode; - - -/* Condition codes, using the Intel encoding. CondAlways is an extra. */ -typedef - enum { - CondO = 0, /* overflow */ - CondNO = 1, /* no overflow */ - CondB = 2, /* below */ - CondNB = 3, /* not below */ - CondZ = 4, /* zero */ - CondNZ = 5, /* not zero */ - CondBE = 6, /* below or equal */ - CondNBE = 7, /* not below or equal */ - CondS = 8, /* negative */ - CondNS = 9, /* not negative */ - CondP = 10, /* parity even */ - CondNP = 11, /* not parity even */ - CondL = 12, /* jump less */ - CondNL = 13, /* not less */ - CondLE = 14, /* less or equal */ - CondNLE = 15, /* not less or equal */ - CondAlways = 16 /* Jump always */ - } - Condcode; - - -/* Descriptions of additional properties of *unconditional* jumps. */ -typedef - enum { - JmpBoring=0, /* boring unconditional jump */ - JmpCall=1, /* jump due to an x86 call insn */ - JmpRet=2, /* jump due to an x86 ret insn */ - JmpSyscall=3, /* do a system call, then jump */ - JmpClientReq=4,/* do a client request, then jump */ - JmpYield=5 /* do a yield, then jump */ - } - JmpKind; - - -/* Flags. User-level code can only read/write O(verflow), S(ign), - Z(ero), A(ux-carry), C(arry), P(arity), and may also write - D(irection). That's a total of 7 flags. A FlagSet is a bitset, - thusly: - 76543210 - DOSZACP - and bit 7 must always be zero since it is unused. - - Note: these Flag? values are **not** the positions in the actual - %eflags register. */ - -typedef UChar FlagSet; - -#define FlagD (1<<6) -#define FlagO (1<<5) -#define FlagS (1<<4) -#define FlagZ (1<<3) -#define FlagA (1<<2) -#define FlagC (1<<1) -#define FlagP (1<<0) - -#define FlagsOSZACP (FlagO | FlagS | FlagZ | FlagA | FlagC | FlagP) -#define FlagsOSZAP (FlagO | FlagS | FlagZ | FlagA | FlagP) -#define FlagsOSZCP (FlagO | FlagS | FlagZ | FlagC | FlagP) -#define FlagsOSACP (FlagO | FlagS | FlagA | FlagC | FlagP) -#define FlagsSZACP ( FlagS | FlagZ | FlagA | FlagC | FlagP) -#define FlagsSZAP ( FlagS | FlagZ | FlagA | FlagP) -#define FlagsSZP ( FlagS | FlagZ | FlagP) -#define FlagsZCP ( FlagZ | FlagC | FlagP) -#define FlagsOC (FlagO | FlagC ) -#define FlagsAC ( FlagA | FlagC ) - -#define FlagsALL (FlagsOSZACP | FlagD) -#define FlagsEmpty (FlagSet)0 - - -/* flag positions in eflags */ -#define EFlagC (1 << 0) /* carry */ -#define EFlagP (1 << 2) /* parity */ -#define EFlagA (1 << 4) /* aux carry */ -#define EFlagZ (1 << 6) /* zero */ -#define EFlagS (1 << 7) /* sign */ -#define EFlagD (1 << 10) /* direction */ -#define EFlagO (1 << 11) /* overflow */ -#define EFlagID (1 << 21) /* changable if CPUID exists */ - -/* Liveness of general purpose registers, useful for code generation. - Reg rank order 0..N-1 corresponds to bits 0..N-1, ie. first - reg's liveness in bit 0, last reg's in bit N-1. Note that - these rankings don't match the Intel register ordering. */ -typedef UInt RRegSet; - -#define ALL_RREGS_DEAD 0 /* 0000...00b */ -#define ALL_RREGS_LIVE ((1 << VG_MAX_REALREGS)-1) /* 0011...11b */ -#define UNIT_RREGSET(rank) (1 << (rank)) - -#define IS_RREG_LIVE(rank,rregs_live) (rregs_live & UNIT_RREGSET(rank)) -#define SET_RREG_LIVENESS(rank,rregs_live,b) \ - do { RRegSet unit = UNIT_RREGSET(rank); \ - if (b) rregs_live |= unit; \ - else rregs_live &= ~unit; \ - } while(0) - - -/* A Micro (u)-instruction. */ -typedef - struct { - /* word 1 */ - UInt lit32; /* 32-bit literal */ - - /* word 2 */ - UShort val1; /* first operand */ - UShort val2; /* second operand */ - - /* word 3 */ - UShort val3; /* third operand */ - UChar opcode; /* opcode */ - UShort size; /* data transfer size */ - - /* word 4 */ - FlagSet flags_r; /* :: FlagSet */ - FlagSet flags_w; /* :: FlagSet */ - UChar tag1:4; /* first operand tag */ - UChar tag2:4; /* second operand tag */ - UChar tag3:4; /* third operand tag */ - UChar extra4b:4; /* Spare field, used by WIDEN for src - -size, and by LEA2 for scale (1,2,4 or 8), - and by JMPs for original x86 instr size */ - - /* word 5 */ - UChar cond; /* condition, for jumps */ - Bool signed_widen:1; /* signed or unsigned WIDEN ? */ - JmpKind jmpkind:3; /* additional properties of unconditional JMP */ - - /* Additional properties for UInstrs that call C functions: - - CCALL - - PUT (when %ESP is the target) - - possibly tool-specific UInstrs - */ - UChar argc:2; /* Number of args, max 3 */ - UChar regparms_n:2; /* Number of args passed in registers */ - Bool has_ret_val:1; /* Function has return value? */ - - /* RealReg liveness; only sensical after reg alloc and liveness - analysis done. This info is a little bit arch-specific -- - VG_MAX_REALREGS can vary on different architectures. Note that - to use this information requires converting between register ranks - and the Intel register numbers, using VG_(realreg_to_rank)() - and/or VG_(rank_to_realreg)() */ - RRegSet regs_live_after:VG_MAX_REALREGS; - } - UInstr; - - -typedef - struct _UCodeBlock - UCodeBlock; - -extern Int VG_(get_num_instrs) (UCodeBlock* cb); -extern Int VG_(get_num_temps) (UCodeBlock* cb); - -extern UInstr* VG_(get_instr) (UCodeBlock* cb, Int i); -extern UInstr* VG_(get_last_instr) (UCodeBlock* cb); - - -/*====================================================================*/ -/*=== Instrumenting UCode ===*/ -/*====================================================================*/ - -/* Maximum number of registers read or written by a single UInstruction. */ -#define VG_MAX_REGS_USED 3 - -/* Find what this instruction does to its regs, useful for - analysis/optimisation passes. `tag' indicates whether we're considering - TempRegs (pre-reg-alloc) or RealRegs (post-reg-alloc). `regs' is filled - with the affected register numbers, `isWrites' parallels it and indicates - if the reg is read or written. If a reg is read and written, it will - appear twice in `regs'. `regs' and `isWrites' must be able to fit - VG_MAX_REGS_USED elements. */ -extern Int VG_(get_reg_usage) ( UInstr* u, Tag tag, Int* regs, Bool* isWrites ); - - -/* Used to register helper functions to be called from generated code. A - limited number of compact helpers can be registered; the code generated - to call them is slightly shorter -- so register the mostly frequently - called helpers as compact. */ -extern void VG_(register_compact_helper) ( Addr a ); -extern void VG_(register_noncompact_helper) ( Addr a ); - - -/* ------------------------------------------------------------------ */ -/* Virtual register allocation */ - -/* Get a new virtual register */ -extern Int VG_(get_new_temp) ( UCodeBlock* cb ); - -/* Get a new virtual shadow register */ -extern Int VG_(get_new_shadow) ( UCodeBlock* cb ); - -/* Get a virtual register's corresponding virtual shadow register */ -#define SHADOW(tempreg) ((tempreg)+1) - - -/* ------------------------------------------------------------------ */ -/* Low-level UInstr builders */ -extern void VG_(new_NOP) ( UInstr* u ); -extern void VG_(new_UInstr0) ( UCodeBlock* cb, Opcode opcode, Int sz ); -extern void VG_(new_UInstr1) ( UCodeBlock* cb, Opcode opcode, Int sz, - Tag tag1, UInt val1 ); -extern void VG_(new_UInstr2) ( UCodeBlock* cb, Opcode opcode, Int sz, - Tag tag1, UInt val1, - Tag tag2, UInt val2 ); -extern void VG_(new_UInstr3) ( UCodeBlock* cb, Opcode opcode, Int sz, - Tag tag1, UInt val1, - Tag tag2, UInt val2, - Tag tag3, UInt val3 ); - -/* Set read/write/undefined flags. Undefined flags are treaten as written, - but it's worth keeping them logically distinct. */ -extern void VG_(set_flag_fields) ( UCodeBlock* cb, FlagSet fr, FlagSet fw, - FlagSet fu); -extern void VG_(set_lit_field) ( UCodeBlock* cb, UInt lit32 ); -extern void VG_(set_ccall_fields) ( UCodeBlock* cb, Addr fn, UChar argc, - UChar regparms_n, Bool has_ret_val ); -extern void VG_(set_cond_field) ( UCodeBlock* cb, Condcode code ); -extern void VG_(set_widen_fields) ( UCodeBlock* cb, UInt szs, Bool is_signed ); - -extern void VG_(copy_UInstr) ( UCodeBlock* cb, UInstr* instr ); - -extern Bool VG_(any_flag_use)( UInstr* u ); - -/* Macro versions of the above; just shorter to type. */ -#define uInstr0 VG_(new_UInstr0) -#define uInstr1 VG_(new_UInstr1) -#define uInstr2 VG_(new_UInstr2) -#define uInstr3 VG_(new_UInstr3) -#define uLiteral VG_(set_lit_field) -#define uCCall VG_(set_ccall_fields) -#define uCond VG_(set_cond_field) -#define uWiden VG_(set_widen_fields) -#define uFlagsRWU VG_(set_flag_fields) -#define newTemp VG_(get_new_temp) -#define newShadow VG_(get_new_shadow) - -/* Refer to `the last instruction stuffed in' (can be lvalue). */ -#define LAST_UINSTR(cb) (cb)->instrs[(cb)->used-1] - - -/* ------------------------------------------------------------------ */ -/* Higher-level UInstr sequence builders */ - -extern void VG_(lit_to_reg) ( UCodeBlock* cb, UInt lit, UInt t ); -extern UInt VG_(lit_to_newreg) ( UCodeBlock* cb, UInt lit ); - -#define CB_F UCodeBlock* cb, Addr f -#define EV extern void -#define RPn UInt regparms_n - -/* Various CCALL builders, of the form "ccall__". 'R' - represents a TempReg, 'L' represents a literal, '0' represents nothing - (ie. no args, or no return value). */ - -EV VG_(ccall_0_0) ( CB_F ); - -EV VG_(ccall_R_0) ( CB_F, UInt R1, RPn ); -EV VG_(ccall_L_0) ( CB_F, UInt L1, RPn ); -EV VG_(ccall_R_R) ( CB_F, UInt R1, UInt R_ret, RPn ); -EV VG_(ccall_L_R) ( CB_F, UInt L1, UInt R_ret, RPn ); - -EV VG_(ccall_RR_0) ( CB_F, UInt R1, UInt R2, RPn ); -EV VG_(ccall_RL_0) ( CB_F, UInt R1, UInt RL, RPn ); -EV VG_(ccall_LR_0) ( CB_F, UInt L1, UInt R2, RPn ); -EV VG_(ccall_LL_0) ( CB_F, UInt L1, UInt L2, RPn ); -EV VG_(ccall_RR_R) ( CB_F, UInt R1, UInt R2, UInt R_ret, RPn ); -EV VG_(ccall_RL_R) ( CB_F, UInt R1, UInt L2, UInt R_ret, RPn ); -EV VG_(ccall_LR_R) ( CB_F, UInt L1, UInt R2, UInt R_ret, RPn ); -EV VG_(ccall_LL_R) ( CB_F, UInt L1, UInt L2, UInt R_ret, RPn ); - -EV VG_(ccall_RRR_0) ( CB_F, UInt R1, UInt R2, UInt R3, RPn ); -EV VG_(ccall_RLL_0) ( CB_F, UInt R1, UInt L2, UInt L3, RPn ); -EV VG_(ccall_LRR_0) ( CB_F, UInt L1, UInt R2, UInt R3, RPn ); -EV VG_(ccall_LLR_0) ( CB_F, UInt L1, UInt L2, UInt R3, RPn ); -EV VG_(ccall_LLL_0) ( CB_F, UInt L1, UInt L2, UInt L3, RPn ); - -#undef CB_F -#undef EV -#undef RPn - -/* One way around the 3-arg C function limit is to pass args via global - * variables... ugly, but it works. */ -void VG_(reg_to_globvar)(UCodeBlock* cb, UInt t, UInt* globvar_ptr); -void VG_(lit_to_globvar)(UCodeBlock* cb, UInt lit, UInt* globvar_ptr); - - -/* Old, deprecated versions of some of the helpers (DO NOT USE) */ -extern void VG_(call_helper_0_0) ( UCodeBlock* cb, Addr f); -extern void VG_(call_helper_1_0) ( UCodeBlock* cb, Addr f, UInt arg1, - UInt regparms_n); -extern void VG_(call_helper_2_0) ( UCodeBlock* cb, Addr f, UInt arg1, UInt arg2, - UInt regparms_n); -extern void VG_(set_global_var) ( UCodeBlock* cb, Addr globvar_ptr, UInt val); -extern void VG_(set_global_var_tempreg) ( UCodeBlock* cb, Addr globvar_ptr, - UInt t_val); - -/* ------------------------------------------------------------------ */ -/* Allocating/freeing basic blocks of UCode */ -extern UCodeBlock* VG_(setup_UCodeBlock) ( UCodeBlock* cb ); -extern void VG_(free_UCodeBlock) ( UCodeBlock* cb ); - -/* ------------------------------------------------------------------ */ -/* UCode pretty/ugly printing. Probably only useful to call from a tool - if VG_(needs).extended_UCode == True. */ - -/* When True, all generated code is/should be printed. */ -extern Bool VG_(print_codegen); - -/* Pretty/ugly printing functions */ -extern void VG_(pp_UCodeBlock) ( UCodeBlock* cb, Char* title ); -extern void VG_(pp_UInstr) ( Int instrNo, UInstr* u ); -extern void VG_(pp_UInstr_regs) ( Int instrNo, UInstr* u ); -extern void VG_(up_UInstr) ( Int instrNo, UInstr* u ); -extern Char* VG_(name_UOpcode) ( Bool upper, Opcode opc ); -extern Char* VG_(name_UCondcode) ( Condcode cond ); -extern void VG_(pp_UOperand) ( UInstr* u, Int operandNo, - Int sz, Bool parens ); - -/* ------------------------------------------------------------------ */ -/* Accessing archregs and their shadows */ -extern UInt VG_(get_archreg) ( UInt archreg ); -extern UInt VG_(get_thread_archreg) ( ThreadId tid, UInt archreg ); - -extern UInt VG_(get_shadow_archreg) ( UInt archreg ); -extern void VG_(set_shadow_archreg) ( UInt archreg, UInt val ); -extern void VG_(set_shadow_eflags) ( UInt val ); -extern Addr VG_(shadow_archreg_address) ( UInt archreg ); - -extern UInt VG_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg ); -extern void VG_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, - UInt val ); - -/*====================================================================*/ -/*=== Generating x86 code from UCode ===*/ -/*====================================================================*/ - -/* All this only necessary for tools with VG_(needs).extends_UCode == True. */ - -/* This is the Intel register encoding -- integer regs. */ -#define R_EAX 0 -#define R_ECX 1 -#define R_EDX 2 -#define R_EBX 3 -#define R_ESP 4 -#define R_EBP 5 -#define R_ESI 6 -#define R_EDI 7 - -#define R_AL (0+R_EAX) -#define R_CL (0+R_ECX) -#define R_DL (0+R_EDX) -#define R_BL (0+R_EBX) -#define R_AH (4+R_EAX) -#define R_CH (4+R_ECX) -#define R_DH (4+R_EDX) -#define R_BH (4+R_EBX) - -/* This is the Intel register encoding -- segment regs. */ -#define R_ES 0 -#define R_CS 1 -#define R_SS 2 -#define R_DS 3 -#define R_FS 4 -#define R_GS 5 - -/* For pretty printing x86 code */ -extern const Char* VG_(name_of_mmx_gran) ( UChar gran ); -extern const Char* VG_(name_of_mmx_reg) ( Int mmxreg ); -extern const Char* VG_(name_of_seg_reg) ( Int sreg ); -extern const Char* VG_(name_of_int_reg) ( Int size, Int reg ); -extern const Char VG_(name_of_int_size) ( Int size ); - -/* Shorter macros for convenience */ -#define nameIReg VG_(name_of_int_reg) -#define nameISize VG_(name_of_int_size) -#define nameSReg VG_(name_of_seg_reg) -#define nameMMXReg VG_(name_of_mmx_reg) -#define nameMMXGran VG_(name_of_mmx_gran) -#define nameXMMReg VG_(name_of_xmm_reg) - -/* Randomly useful things */ -extern UInt VG_(extend_s_8to32) ( UInt x ); - -/* Code emitters */ -extern void VG_(emitB) ( UInt b ); -extern void VG_(emitW) ( UInt w ); -extern void VG_(emitL) ( UInt l ); -extern void VG_(new_emit) ( Bool upd_cc, FlagSet uses_flags, FlagSet sets_flags ); - -/* Finding offsets */ -extern Int VG_(helper_offset) ( Addr a ); -extern Int VG_(shadow_reg_offset) ( Int arch ); -extern Int VG_(shadow_flags_offset) ( void ); - -/* Convert reg ranks <-> Intel register ordering, for using register - liveness information. */ -extern Int VG_(realreg_to_rank) ( Int realreg ); -extern Int VG_(rank_to_realreg) ( Int rank ); - -/* Call a subroutine. Does no argument passing, stack manipulations, etc. */ -extern void VG_(synth_call) ( Bool ensure_shortform, Int word_offset, - Bool upd_cc, FlagSet use_flags, FlagSet set_flags ); - -/* For calling C functions -- saves caller save regs, pushes args, calls, - clears the stack, restores caller save regs. `fn' must be registered in - the baseBlock first. Acceptable tags are RealReg and Literal. Optimises - things, eg. by not preserving non-live caller-save registers. - - WARNING: a UInstr should *not* be translated with synth_ccall() followed - by some other x86 assembly code; this will invalidate the results of - vg_realreg_liveness_analysis() and everything will fall over. */ -extern void VG_(synth_ccall) ( Addr fn, Int argc, Int regparms_n, UInt argv[], - Tag tagv[], Int ret_reg, - RRegSet regs_live_before, - RRegSet regs_live_after ); - -/* Addressing modes */ -extern void VG_(emit_amode_offregmem_reg)( Int off, Int regmem, Int reg ); -extern void VG_(emit_amode_ereg_greg) ( Int e_reg, Int g_reg ); - -/* v-size (4, or 2 with OSO) insn emitters */ -extern void VG_(emit_movv_offregmem_reg) ( Int sz, Int off, Int areg, Int reg ); -extern void VG_(emit_movv_reg_offregmem) ( Int sz, Int reg, Int off, Int areg ); -extern void VG_(emit_movv_reg_reg) ( Int sz, Int reg1, Int reg2 ); -extern void VG_(emit_nonshiftopv_lit_reg)( Bool upd_cc, Int sz, Opcode opc, UInt lit, - Int reg ); -extern void VG_(emit_shiftopv_lit_reg) ( Bool upd_cc, Int sz, Opcode opc, UInt lit, - Int reg ); -extern void VG_(emit_nonshiftopv_reg_reg)( Bool upd_cc, Int sz, Opcode opc, - Int reg1, Int reg2 ); -extern void VG_(emit_movv_lit_reg) ( Int sz, UInt lit, Int reg ); -extern void VG_(emit_unaryopv_reg) ( Bool upd_cc, Int sz, Opcode opc, Int reg ); -extern void VG_(emit_pushv_reg) ( Int sz, Int reg ); -extern void VG_(emit_popv_reg) ( Int sz, Int reg ); - -extern void VG_(emit_pushl_lit32) ( UInt int32 ); -extern void VG_(emit_pushl_lit8) ( Int lit8 ); -extern void VG_(emit_cmpl_zero_reg) ( Bool upd_cc, Int reg ); -extern void VG_(emit_swapl_reg_EAX) ( Int reg ); -extern void VG_(emit_movv_lit_offregmem) ( Int sz, UInt lit, Int off, - Int memreg ); - -/* b-size (1 byte) instruction emitters */ -extern void VG_(emit_movb_lit_offregmem) ( UInt lit, Int off, Int memreg ); -extern void VG_(emit_movb_reg_offregmem) ( Int reg, Int off, Int areg ); -extern void VG_(emit_unaryopb_reg) ( Bool upd_cc, Opcode opc, Int reg ); -extern void VG_(emit_testb_lit_reg) ( Bool upd_cc, UInt lit, Int reg ); - -/* zero-extended load emitters */ -extern void VG_(emit_movzbl_offregmem_reg) ( Bool bounds, Int off, Int regmem, Int reg ); -extern void VG_(emit_movzwl_offregmem_reg) ( Bool bounds, Int off, Int areg, Int reg ); -extern void VG_(emit_movzwl_regmem_reg) ( Bool bounds, Int reg1, Int reg2 ); - -/* misc instruction emitters */ -extern void VG_(emit_call_reg) ( Int reg ); -extern void VG_(emit_add_lit_to_esp) ( Int lit ); -extern void VG_(emit_pushal) ( void ); -extern void VG_(emit_popal) ( void ); -extern void VG_(emit_AMD_prefetch_reg) ( Int reg ); - -/* jump emitters */ -extern void VG_(init_target) ( Int *tgt ); - -extern void VG_(target_back) ( Int *tgt ); -extern void VG_(target_forward) ( Int *tgt ); -extern void VG_(emit_target_delta) ( Int *tgt ); - -typedef enum { - JP_NONE, /* no prediction */ - JP_TAKEN, /* predict taken */ - JP_NOT_TAKEN, /* predict not taken */ -} JumpPred; - -extern void VG_(emit_jcondshort_delta) ( Bool simd_cc, Condcode cond, Int delta, JumpPred ); -extern void VG_(emit_jcondshort_target)( Bool simd_cc, Condcode cond, Int *tgt, JumpPred ); - - -/*====================================================================*/ -/*=== Execution contexts ===*/ -/*====================================================================*/ - -/* Generic resolution type used in a few different ways, such as deciding - how closely to compare two errors for equality. */ -typedef - enum { Vg_LowRes, Vg_MedRes, Vg_HighRes } - VgRes; - -typedef - struct _ExeContext - ExeContext; - -/* Compare two ExeContexts. Number of callers considered depends on `res': - Vg_LowRes: 2 - Vg_MedRes: 4 - Vg_HighRes: all */ -extern Bool VG_(eq_ExeContext) ( VgRes res, - ExeContext* e1, ExeContext* e2 ); - -/* Print an ExeContext. */ -extern void VG_(pp_ExeContext) ( ExeContext* ); - -/* Take a snapshot of the client's stack. Search our collection of - ExeContexts to see if we already have it, and if not, allocate a - new one. Either way, return a pointer to the context. Context size - controlled by --num-callers option. - - If called from generated code, use VG_(get_current_tid)() to get the - current ThreadId. If called from non-generated code, the current - ThreadId should be passed in by the core. -*/ -extern ExeContext* VG_(get_ExeContext) ( ThreadId tid ); - -/* Get the nth IP from the ExeContext. 0 is the IP of the top function, 1 - is its caller, etc. Returns 0 if there isn't one, or if n is greater - than VG_(clo_backtrace_size), set by the --num-callers option. */ -extern Addr VG_(get_EIP_from_ExeContext) ( ExeContext* e, UInt n ); - -/* Just grab the client's IP, as a much smaller and cheaper - indication of where they are. Use is basically same as for - VG_(get_ExeContext)() above. -*/ -extern Addr VG_(get_EIP)( ThreadId tid ); - -/* For tools needing more control over stack traces: walks the stack to get - instruction pointers from the top stack frames for thread 'tid'. Maximum of - 'n_ips' addresses put into 'ips'; 0 is the top of the stack, 1 is its - caller, etc. */ -extern UInt VG_(stack_snapshot) ( ThreadId tid, Addr* ips, UInt n_ips ); - -/* Does the same thing as VG_(pp_ExeContext)(), just with slightly - different input. */ -extern void VG_(mini_stack_dump) ( Addr ips[], UInt n_ips ); - - -/*====================================================================*/ -/*=== Error reporting ===*/ -/*====================================================================*/ - -/* ------------------------------------------------------------------ */ -/* Suppressions describe errors which we want to suppress, ie, not - show the user, usually because it is caused by a problem in a library - which we can't fix, replace or work around. Suppressions are read from - a file at startup time. This gives flexibility so that new - suppressions can be added to the file as and when needed. -*/ - -typedef - Int /* Do not make this unsigned! */ - SuppKind; - -/* The tool-relevant parts of a suppression are: - kind: what kind of suppression; must be in the range (0..) - string: use is optional. NULL by default. - extra: use is optional. NULL by default. void* so it's extensible. -*/ -typedef - struct _Supp - Supp; - -/* Useful in SK_(error_matches_suppression)() */ -SuppKind VG_(get_supp_kind) ( Supp* su ); -Char* VG_(get_supp_string) ( Supp* su ); -void* VG_(get_supp_extra) ( Supp* su ); - -/* Must be used in VG_(recognised_suppression)() */ -void VG_(set_supp_kind) ( Supp* su, SuppKind suppkind ); -/* May be used in VG_(read_extra_suppression_info)() */ -void VG_(set_supp_string) ( Supp* su, Char* string ); -void VG_(set_supp_extra) ( Supp* su, void* extra ); - - -/* ------------------------------------------------------------------ */ -/* Error records contain enough info to generate an error report. The idea - is that (typically) the same few points in the program generate thousands - of errors, and we don't want to spew out a fresh error message for each - one. Instead, we use these structures to common up duplicates. -*/ - -typedef - Int /* Do not make this unsigned! */ - ErrorKind; - -/* The tool-relevant parts of an Error are: - kind: what kind of error; must be in the range (0..) - addr: use is optional. 0 by default. - string: use is optional. NULL by default. - extra: use is optional. NULL by default. void* so it's extensible. -*/ -typedef - struct _Error - Error; - -/* Useful in SK_(error_matches_suppression)(), SK_(pp_SkinError)(), etc */ -ExeContext* VG_(get_error_where) ( Error* err ); -SuppKind VG_(get_error_kind) ( Error* err ); -Addr VG_(get_error_address) ( Error* err ); -Char* VG_(get_error_string) ( Error* err ); -void* VG_(get_error_extra) ( Error* err ); - -/* Call this when an error occurs. It will be recorded if it hasn't been - seen before. If it has, the existing error record will have its count - incremented. - - 'tid' can be found as for VG_(get_ExeContext)(). The `extra' field can - be stack-allocated; it will be copied by the core if needed (but it - won't be copied if it's NULL). - - If no 'a', 's' or 'extra' of interest needs to be recorded, just use - NULL for them. */ -extern void VG_(maybe_record_error) ( ThreadId tid, ErrorKind ekind, - Addr a, Char* s, void* extra ); - -/* Similar to VG_(maybe_record_error)(), except this one doesn't record the - error -- useful for errors that can only happen once. The errors can be - suppressed, though. Return value is True if it was suppressed. - `print_error' dictates whether to print the error, which is a bit of a - hack that's useful sometimes if you just want to know if the error would - be suppressed without possibly printing it. `count_error' dictates - whether to add the error in the error total count (another mild hack). */ -extern Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, - Addr a, Char* s, void* extra, - ExeContext* where, Bool print_error, - Bool allow_GDB_attach, Bool count_error ); - -/* Gets a non-blank, non-comment line of at most nBuf chars from fd. - Skips leading spaces on the line. Returns True if EOF was hit instead. - Useful for reading in extra tool-specific suppression lines. */ -extern Bool VG_(get_line) ( Int fd, Char* buf, Int nBuf ); - - -/*====================================================================*/ -/*=== Obtaining debug information ===*/ -/*====================================================================*/ - -/* Get the file/function/line number of the instruction at address - 'a'. For these four, if debug info for the address is found, it - copies the info into the buffer/UInt and returns True. If not, it - returns False and nothing is copied. VG_(get_fnname) always - demangles C++ function names. VG_(get_fnname_w_offset) is the - same, except it appends "+N" to symbol names to indicate offsets. */ -extern Bool VG_(get_filename) ( Addr a, Char* filename, Int n_filename ); -extern Bool VG_(get_fnname) ( Addr a, Char* fnname, Int n_fnname ); -extern Bool VG_(get_linenum) ( Addr a, UInt* linenum ); -extern Bool VG_(get_fnname_w_offset) - ( Addr a, Char* fnname, Int n_fnname ); - -/* This one is more efficient if getting both filename and line number, - because the two lookups are done together. */ -extern Bool VG_(get_filename_linenum) - ( Addr a, Char* filename, Int n_filename, - UInt* linenum ); - -/* Succeeds only if we find from debug info that 'a' is the address of the - first instruction in a function -- as opposed to VG_(get_fnname) which - succeeds if we find from debug info that 'a' is the address of any - instruction in a function. Use this to instrument the start of - a particular function. Nb: if an executable/shared object is stripped - of its symbols, this function will not be able to recognise function - entry points within it. */ -extern Bool VG_(get_fnname_if_entry) ( Addr a, Char* fnname, Int n_fnname ); - -/* Succeeds if the address is within a shared object or the main executable. - It doesn't matter if debug info is present or not. */ -extern Bool VG_(get_objname) ( Addr a, Char* objname, Int n_objname ); - -/* Puts into 'buf' info about the code address %eip: the address, function - name (if known) and filename/line number (if known), like this: - - 0x4001BF05: realloc (vg_replace_malloc.c:339) - - 'n_buf' gives length of 'buf'. Returns 'buf'. -*/ -extern Char* VG_(describe_eip)(Addr eip, Char* buf, Int n_buf); - -/* Returns a string containing an expression for the given - address. String is malloced with VG_(malloc)() */ -Char *VG_(describe_addr)(ThreadId, Addr); - -/* A way to get information about what segments are mapped */ -typedef struct _SegInfo SegInfo; - -/* Returns NULL if the SegInfo isn't found. It doesn't matter if debug info - is present or not. */ -extern SegInfo* VG_(get_obj) ( Addr a ); - -extern const SegInfo* VG_(next_seginfo) ( const SegInfo *seg ); -extern Addr VG_(seg_start) ( const SegInfo *seg ); -extern UInt VG_(seg_size) ( const SegInfo *seg ); -extern const UChar* VG_(seg_filename) ( const SegInfo *seg ); -extern UInt VG_(seg_sym_offset)( const SegInfo *seg ); - -typedef - enum { - Vg_SectUnknown, - Vg_SectText, - Vg_SectData, - Vg_SectBSS, - Vg_SectGOT, - Vg_SectPLT, - } - VgSectKind; - -extern VgSectKind VG_(seg_sect_kind)(Addr); - - -/*====================================================================*/ -/*=== Generic hash table ===*/ -/*====================================================================*/ - -/* Generic type for a separately-chained hash table. Via a kind of dodgy - C-as-C++ style inheritance, tools can extend the VgHashNode type, so long - as the first two fields match the sizes of these two fields. Requires - a bit of casting by the tool. */ -typedef - struct _VgHashNode { - struct _VgHashNode * next; - UInt key; - } - VgHashNode; - -typedef - VgHashNode** - VgHashTable; - -/* Make a new table. */ -extern VgHashTable VG_(HT_construct) ( void ); - -/* Count the number of nodes in a table. */ -extern Int VG_(HT_count_nodes) ( VgHashTable table ); - -/* Add a node to the table. */ -extern void VG_(HT_add_node) ( VgHashTable t, VgHashNode* node ); - -/* Looks up a node in the hash table. Also returns the address of the - previous node's `next' pointer which allows it to be removed from the - list later without having to look it up again. */ -extern VgHashNode* VG_(HT_get_node) ( VgHashTable t, UInt key, - /*OUT*/VgHashNode*** next_ptr ); - -/* Allocates an array of pointers to all the shadow chunks of malloc'd - blocks. Must be freed with VG_(free)(). */ -extern VgHashNode** VG_(HT_to_array) ( VgHashTable t, /*OUT*/ UInt* n_shadows ); - -/* Returns first node that matches predicate `p', or NULL if none do. - Extra arguments can be implicitly passed to `p' using `d' which is an - opaque pointer passed to `p' each time it is called. */ -extern VgHashNode* VG_(HT_first_match) ( VgHashTable t, - Bool (*p)(VgHashNode*, void*), - void* d ); - -/* Applies a function f() once to each node. Again, `d' can be used - to pass extra information to the function. */ -extern void VG_(HT_apply_to_all_nodes)( VgHashTable t, - void (*f)(VgHashNode*, void*), - void* d ); - -/* Destroy a table. */ -extern void VG_(HT_destruct) ( VgHashTable t ); - - -/*====================================================================*/ -/*=== A generic skiplist ===*/ -/*====================================================================*/ - -/* - The idea here is that the skiplist puts its per-element data at the - end of the structure. When you initialize the skiplist, you tell - it what structure your list elements are going to be. Then you - should allocate them with VG_(SkipNode_Alloc), which will allocate - enough memory for the extra bits. - */ -#include /* for offsetof */ - -typedef struct _SkipList SkipList; -typedef struct _SkipNode SkipNode; - -typedef Int (*SkipCmp_t)(const void *key1, const void *key2); - -struct _SkipList { - const Short arena; /* allocation arena */ - const UShort size; /* structure size (not including SkipNode) */ - const UShort keyoff; /* key offset */ - const SkipCmp_t cmp; /* compare two keys */ - Char * (*strkey)(void *); /* stringify a key (for debugging) */ - SkipNode *head; /* list head */ -}; - -/* Use this macro to initialize your skiplist head. The arguments are pretty self explanitory: - _type is the type of your element structure - _key is the field within that type which you want to use as the key - _cmp is the comparison function for keys - it gets two typeof(_key) pointers as args - _strkey is a function which can return a string of your key - it's only used for debugging - _arena is the arena to use for allocation - -1 is the default - */ -#define SKIPLIST_INIT(_type, _key, _cmp, _strkey, _arena) \ - { \ - .arena = _arena, \ - .size = sizeof(_type), \ - .keyoff = offsetof(_type, _key), \ - .cmp = _cmp, \ - .strkey = _strkey, \ - .head = NULL, \ - } - -/* List operations: - SkipList_Find searchs a list. If it can't find an exact match, it either - returns NULL or a pointer to the element before where k would go - SkipList_Insert inserts a new element into the list. Duplicates are - forbidden. The element must have been created with SkipList_Alloc! - SkipList_Remove removes an element from the list and returns it. It - doesn't free the memory. -*/ -extern void *VG_(SkipList_Find) (const SkipList *l, void *key); -extern void VG_(SkipList_Insert)( SkipList *l, void *data); -extern void *VG_(SkipList_Remove)( SkipList *l, void *key); - -/* Node (element) operations: - SkipNode_Alloc: allocate memory for a new element on the list. Must be - used before an element can be inserted! Returns NULL if not enough - memory. - SkipNode_Free: free memory allocated above - SkipNode_First: return the first element on the list - SkipNode_Next: return the next element after "data" on the list - - NULL for none - - You can iterate through a SkipList like this: - - for(x = VG_(SkipNode_First)(&list); // or SkipList_Find - x != NULL; - x = VG_(SkipNode_Next)(&list, x)) { ... } -*/ -extern void *VG_(SkipNode_Alloc) (const SkipList *l); -extern void VG_(SkipNode_Free) (const SkipList *l, void *p); -extern void *VG_(SkipNode_First) (const SkipList *l); -extern void *VG_(SkipNode_Next) (const SkipList *l, void *data); - -/*====================================================================*/ -/*=== Functions for shadow registers ===*/ -/*====================================================================*/ - -/* Nb: make sure the shadow_regs 'need' is set before using these! */ - -/* This one lets you override the shadow of the return value register for a - syscall. Call it from SK_(post_syscall)() (not SK_(pre_syscall)()!) to - override the default shadow register value. */ -extern void VG_(set_return_from_syscall_shadow) ( ThreadId tid, - UInt ret_shadow ); - -/* This can be called from SK_(fini)() to find the shadow of the argument - to exit(), ie. the shadow of the program's return value. */ -extern UInt VG_(get_exit_status_shadow) ( void ); - - -/*====================================================================*/ -/*=== Specific stuff for replacing malloc() and friends ===*/ -/*====================================================================*/ - -/* If a tool replaces malloc() et al, the easiest way to do so is to - link with vg_replace_malloc.o into its vgpreload_*.so file, and - follow the following instructions. You can do it from scratch, - though, if you enjoy that sort of thing. */ - -/* Arena size for valgrind's own malloc(); default value is 0, but can - be overridden by tool -- but must be done so *statically*, eg: - - Int VG_(vg_malloc_redzone_szB) = 4; - - It can't be done from a function like SK_(pre_clo_init)(). So it can't, - for example, be controlled with a command line option, unfortunately. */ -extern UInt VG_(vg_malloc_redzone_szB); - -/* Can be called from SK_(malloc) et al to do the actual alloc/freeing. */ -extern void* VG_(cli_malloc) ( UInt align, Int nbytes ); -extern void VG_(cli_free) ( void* p ); - -/* Check if an address is within a range, allowing for redzones at edges */ -extern Bool VG_(addr_is_in_block)( Addr a, Addr start, UInt size ); - -/* ------------------------------------------------------------------ */ -/* Some options that can be used by a tool if malloc() et al are replaced. - The tool should call the functions in the appropriate places to give - control over these aspects of Valgrind's version of malloc(). */ - -/* Round malloc sizes upwards to integral number of words? default: NO */ -extern Bool VG_(clo_sloppy_malloc); -/* DEBUG: print malloc details? default: NO */ -extern Bool VG_(clo_trace_malloc); -/* Minimum alignment in functions that don't specify alignment explicitly. - default: 0, i.e. use default of the machine (== 4) */ -extern Int VG_(clo_alignment); - -extern Bool VG_(replacement_malloc_process_cmd_line_option) ( Char* arg ); -extern void VG_(replacement_malloc_print_usage) ( void ); -extern void VG_(replacement_malloc_print_debug_usage) ( void ); - - -/*====================================================================*/ -/*=== Tool-specific stuff ===*/ -/*====================================================================*/ - -/* ------------------------------------------------------------------ */ -/* Details */ - -/* Default value for avg_translations_sizeB (in bytes), indicating typical - code expansion of about 6:1. */ -#define VG_DEFAULT_TRANS_SIZEB 100 - -/* Information used in the startup message. `name' also determines the - string used for identifying suppressions in a suppression file as - belonging to this tool. `version' can be NULL, in which case (not - surprisingly) no version info is printed; this mechanism is designed for - tools distributed with Valgrind that share a version number with - Valgrind. Other tools not distributed as part of Valgrind should - probably have their own version number. */ -extern void VG_(details_name) ( Char* name ); -extern void VG_(details_version) ( Char* version ); -extern void VG_(details_description) ( Char* description ); -extern void VG_(details_copyright_author) ( Char* copyright_author ); - -/* Average size of a translation, in bytes, so that the translation - storage machinery can allocate memory appropriately. Not critical, - setting is optional. */ -extern void VG_(details_avg_translation_sizeB) ( UInt size ); - -/* String printed if an `sk_assert' assertion fails or VG_(skin_panic) - is called. Should probably be an email address. */ -extern void VG_(details_bug_reports_to) ( Char* bug_reports_to ); - -/* ------------------------------------------------------------------ */ -/* Needs */ - -/* Booleans that decide core behaviour, but don't require extra - operations to be defined if `True' */ - -/* Should __libc_freeres() be run? Bugs in it can crash the tool. */ -extern void VG_(needs_libc_freeres) ( void ); - -/* Want to have errors detected by Valgrind's core reported? Includes: - - pthread API errors (many; eg. unlocking a non-locked mutex) - - invalid file descriptors to blocking syscalls read() and write() - - bad signal numbers passed to sigaction() - - attempt to install signal handler for SIGKILL or SIGSTOP */ -extern void VG_(needs_core_errors) ( void ); - -/* Booleans that indicate extra operations are defined; if these are True, - the corresponding template functions (given below) must be defined. A - lot like being a member of a type class. */ - -/* Want to report errors from tool? This implies use of suppressions, too. */ -extern void VG_(needs_skin_errors) ( void ); - -/* Is information kept about specific individual basic blocks? (Eg. for - cachegrind there are cost-centres for every instruction, stored at a - basic block level.) If so, it sometimes has to be discarded, because - .so mmap/munmap-ping or self-modifying code (informed by the - DISCARD_TRANSLATIONS user request) can cause one instruction address - to be used for more than one instruction in one program run... */ -extern void VG_(needs_basic_block_discards) ( void ); - -/* Tool maintains information about each register? */ -extern void VG_(needs_shadow_regs) ( void ); - -/* Tool defines its own command line options? */ -extern void VG_(needs_command_line_options) ( void ); - -/* Tool defines its own client requests? */ -extern void VG_(needs_client_requests) ( void ); - -/* Tool defines its own UInstrs? */ -extern void VG_(needs_extended_UCode) ( void ); - -/* Tool does stuff before and/or after system calls? */ -extern void VG_(needs_syscall_wrapper) ( void ); - -/* Are tool-state sanity checks performed? */ -extern void VG_(needs_sanity_checks) ( void ); - -/* Do we need to see data symbols? */ -extern void VG_(needs_data_syms) ( void ); - -/* Does the tool need shadow memory allocated (if you set this, you must also statically initialize - float SK_(shadow_ratio) = n./m; - to define how many shadow bits you need per client address space bit. -*/ -extern void VG_(needs_shadow_memory)( void ); -extern float SK_(shadow_ratio); - -/* ------------------------------------------------------------------ */ -/* Core events to track */ - -/* Part of the core from which this call was made. Useful for determining - what kind of error message should be emitted. */ -typedef - enum { Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall, Vg_CoreTranslate } - CorePart; - -/* Useful to use in VG_(get_Xreg_usage)() */ -#define VG_UINSTR_READS_REG(ono,regs,isWrites) \ - { if (mycat(u->tag,ono) == tag) \ - { regs[n] = mycat(u->val,ono); \ - isWrites[n] = False; \ - n++; \ - } \ - } -#define VG_UINSTR_WRITES_REG(ono,regs,isWrites) \ - { if (mycat(u->tag,ono) == tag) \ - { regs[n] = mycat(u->val,ono); \ - isWrites[n] = True; \ - n++; \ - } \ - } - -#endif /* NDEF __TOOL_H */ - -/* gen_toolint.pl will put the VG_(init_*)() functions here: */ diff --git a/VEX/head20041019/include/tool_asm.h b/VEX/head20041019/include/tool_asm.h deleted file mode 100644 index 9e0ea2acb..000000000 --- a/VEX/head20041019/include/tool_asm.h +++ /dev/null @@ -1,61 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Tool-specific, asm-specific includes. tool_asm.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __TOOL_ASM_H -#define __TOOL_ASM_H - - -/* All symbols externally visible from valgrind.so are prefixed - as specified here. The prefix can be changed, so as to avoid - namespace conflict problems. -*/ -#define VGAPPEND(str1,str2) str1##str2 - -/* These macros should add different prefixes so the same base - name can safely be used across different macros. */ -#define VG_(str) VGAPPEND(vgPlain_,str) -#define VGP_(str) VGAPPEND(vgProf_,str) -#define VGOFF_(str) VGAPPEND(vgOff_,str) -#define VGA_(str) VGAPPEND(vgArch_,str) - -/* Tool-specific ones. Note that final name still starts with "vg". */ -#define SK_(str) VGAPPEND(vgSkin_,str) - -/* This is specifically for stringifying VG_(x) function names. We - need to do two macroexpansions to get the VG_ macro expanded before - stringifying */ -#define _STR(x) #x -#define STR(x) _STR(x) - -#endif /* ndef __TOOL_ASM_H */ - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/include/valgrind.h.in b/VEX/head20041019/include/valgrind.h.in deleted file mode 100644 index d7f57d76b..000000000 --- a/VEX/head20041019/include/valgrind.h.in +++ /dev/null @@ -1,379 +0,0 @@ - -/* - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (valgrind.h) only. The entire rest of Valgrind is licensed - under the terms of the GNU General Public License, version 2. See - the COPYING file in the source distribution for details. - - ---------------------------------------------------------------- - - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (valgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -#ifndef __VALGRIND_H -#define __VALGRIND_H - -#include - -#define __@VG_ARCH@__ // Architecture we're installed on - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query Valgrind's - execution inside your own programs. - - The resulting executables will still run without Valgrind, just a - little bit more slowly than they otherwise would, but otherwise - unchanged. When not running on valgrind, each client request - consumes very few (eg. < 10) instructions, so the resulting performance - loss is negligible unless you plan to execute client requests - millions of times per second. Nevertheless, if that is still a - problem, you can compile with the NVALGRIND symbol defined (gcc - -DNVALGRIND) so that client requests are not even compiled in. */ - -#ifndef NVALGRIND - -/* The following defines the magic code sequence which the JITter spots and - handles magically. Don't look too closely at this; it will rot - your brain. We must ensure that the default value gets put in the return - slot, so that everything works when this is executed not under Valgrind. - Args are passed in a memory block, and so there's no intrinsic limit to - the number that could be passed, but it's currently four. - - Nb: we put the assembly code sequences for all architectures in this one - file. This is because this file must be stand-alone, so we can't rely on - eg. x86/ subdirectories like we do within the rest of Valgrind. -*/ - -#ifdef __x86__ -/* This defines the magic code sequence which the JITter spots and - handles magically. Don't look too closely at this; it will rot - your brain. Valgrind dumps the result value in %EDX, so we first - copy the default value there, so that it is returned when not - running on Valgrind. Since %EAX points to a block of mem - containing the args, you can pass as many args as you want like - this. Currently this is set up to deal with 4 args since that's - the max that we appear to need (pthread_create). -*/ -#define VALGRIND_MAGIC_SEQUENCE( \ - _zzq_rlval, /* result lvalue */ \ - _zzq_default, /* result returned when running on real CPU */ \ - _zzq_request, /* request code */ \ - _zzq_arg1, /* request first param */ \ - _zzq_arg2, /* request second param */ \ - _zzq_arg3, /* request third param */ \ - _zzq_arg4 /* request fourth param */ ) \ - \ - { volatile unsigned int _zzq_args[5]; \ - _zzq_args[0] = (volatile unsigned int)(_zzq_request); \ - _zzq_args[1] = (volatile unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (volatile unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (volatile unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (volatile unsigned int)(_zzq_arg4); \ - asm volatile("movl %1, %%eax\n\t" \ - "movl %2, %%edx\n\t" \ - "roll $29, %%eax ; roll $3, %%eax\n\t" \ - "rorl $27, %%eax ; rorl $5, %%eax\n\t" \ - "roll $13, %%eax ; roll $19, %%eax\n\t" \ - "movl %%edx, %0\t" \ - : "=r" (_zzq_rlval) \ - : "r" (&_zzq_args[0]), "r" (_zzq_default) \ - : "eax", "edx", "cc", "memory" \ - ); \ - } -#endif // __x86__ - -// Insert assembly code for other architectures here... - -#else /* NVALGRIND */ -/* Define NVALGRIND to completely remove the Valgrind magic sequence - from the compiled code (analogous to NDEBUG's effects on - assert()) */ -#define VALGRIND_MAGIC_SEQUENCE( \ - _zzq_rlval, /* result lvalue */ \ - _zzq_default, /* result returned when running on real CPU */ \ - _zzq_request, /* request code */ \ - _zzq_arg1, /* request first param */ \ - _zzq_arg2, /* request second param */ \ - _zzq_arg3, /* request third param */ \ - _zzq_arg4 /* request fourth param */ ) \ - { \ - (_zzq_rlval) = (_zzq_default); \ - } -#endif /* NVALGRIND */ - -/* Some request codes. There are many more of these, but most are not - exposed to end-user view. These are the public ones, all of the - form 0x1000 + small_number. - - Core ones are in the range 0x00000000--0x0000ffff. The non-public ones - start at 0x2000. -*/ - -#define VG_USERREQ_SKIN_BASE(a,b) \ - ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) -#define VG_IS_SKIN_USERREQ(a, b, v) \ - (VG_USERREQ_SKIN_BASE(a,b) == ((v) & 0xffff0000)) - -typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, - - /* These allow any function of 0--3 args to be called from the - simulated CPU but run on the real CPU */ - VG_USERREQ__CLIENT_CALL0 = 0x1101, - VG_USERREQ__CLIENT_CALL1 = 0x1102, - VG_USERREQ__CLIENT_CALL2 = 0x1103, - VG_USERREQ__CLIENT_CALL3 = 0x1104, - - /* Can be useful in regression testing suites -- eg. can send - Valgrind's output to /dev/null and still count errors. */ - VG_USERREQ__COUNT_ERRORS = 0x1201, - - /* These are useful and can be interpreted by any tool that tracks - malloc() et al, by using vg_replace_malloc.c. */ - VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, - VG_USERREQ__FREELIKE_BLOCK = 0x1302, - /* Memory pool support. */ - VG_USERREQ__CREATE_MEMPOOL = 0x1303, - VG_USERREQ__DESTROY_MEMPOOL = 0x1304, - VG_USERREQ__MEMPOOL_ALLOC = 0x1305, - VG_USERREQ__MEMPOOL_FREE = 0x1306, - - /* Allow printfs to valgrind log. */ - VG_USERREQ__PRINTF = 0x1401, - VG_USERREQ__PRINTF_BACKTRACE = 0x1402 - } Vg_ClientRequest; - -#ifndef __GNUC__ -#define __extension__ -#endif - -/* Returns 1 if running on Valgrind, 0 if running on the real CPU. - Currently implemented but untested. */ -#define RUNNING_ON_VALGRIND __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* returned if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0); \ - _qzz_res; \ - }) - - -/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + - _qzz_len - 1]. Useful if you are debugging a JITter or some such, - since it provides a way to make sure valgrind will retranslate the - invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0); \ - } - -#ifndef NVALGRIND - -int VALGRIND_PRINTF(const char *format, ...) - __attribute__((format(__printf__, 1, 2))); -__attribute__((weak)) -int -VALGRIND_PRINTF(const char *format, ...) -{ - unsigned int _qzz_res; - va_list vargs; - va_start(vargs, format); - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF, - (unsigned int)format, (unsigned int)vargs, 0, 0); - va_end(vargs); - return _qzz_res; -} - -int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) - __attribute__((format(__printf__, 1, 2))); -__attribute__((weak)) -int -VALGRIND_PRINTF_BACKTRACE(const char *format, ...) -{ - unsigned int _qzz_res; - va_list vargs; - va_start(vargs, format); - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE, - (unsigned int)format, (unsigned int)vargs, 0, 0); - va_end(vargs); - return _qzz_res; -} - -#else /* NVALGRIND */ - -#define VALGRIND_PRINTF(...) -#define VALGRIND_PRINTF_BACKTRACE(...) - -#endif /* NVALGRIND */ - -/* These requests allow control to move from the simulated CPU to the - real CPU, calling an arbitary function */ -#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - ({unsigned int _qyy_res; \ - VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - ({unsigned int _qyy_res; \ - VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - ({unsigned int _qyy_res; \ - VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - ({unsigned int _qyy_res; \ - VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, _qyy_arg3); \ - _qyy_res; \ - }) - - -/* Counts the number of errors that have been recorded by a tool. Nb: - the tool must record the errors with VG_(maybe_record_error)() or - VG_(unique_error)() for them to be counted. */ -#define VALGRIND_COUNT_ERRORS \ - ({unsigned int _qyy_res; \ - VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \ - VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0); \ - _qyy_res; \ - }) - -/* Mark a block of memory as having been allocated by a malloc()-like - function. `addr' is the start of the usable block (ie. after any - redzone) `rzB' is redzone size if the allocator can apply redzones; - use '0' if not. Adding redzones makes it more likely Valgrind will spot - block overruns. `is_zeroed' indicates if the memory is zeroed, as it is - for calloc(). Put it immediately after the point where a block is - allocated. - - If you're allocating memory via superblocks, and then handing out small - chunks of each superblock, if you don't have redzones on your small - blocks, it's worth marking the superblock with VALGRIND_MAKE_NOACCESS - when it's created, so that block overruns are detected. But if you can - put redzones on, it's probably better to not do this, so that messages - for small overruns are described in terms of the small block rather than - the superblock (but if you have a big overrun that skips over a redzone, - you could miss an error this way). See memcheck/tests/custom_alloc.c - for an example. - - Nb: block must be freed via a free()-like function specified - with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed); \ - } - -/* Mark a block of memory as having been freed by a free()-like function. - `rzB' is redzone size; it must match that given to - VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak - checker. Put it immediately after the point where the block is freed. */ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0); \ - } - -/* Create a memory pool. */ -#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0); \ - } - -/* Destroy a memory pool. */ -#define VALGRIND_DESTROY_MEMPOOL(pool) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0); \ - } - -/* Associate a piece of memory with a memory pool. */ -#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0); \ - } - -/* Disassociate a piece of memory from a memory pool. */ -#define VALGRIND_MEMPOOL_FREE(pool, addr) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0); \ - } - -#endif /* __VALGRIND_H */ diff --git a/VEX/head20041019/include/vg_kerneliface.h b/VEX/head20041019/include/vg_kerneliface.h deleted file mode 100644 index 3d50b977e..000000000 --- a/VEX/head20041019/include/vg_kerneliface.h +++ /dev/null @@ -1,943 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A header file defining structures and constants which are ---*/ -/*--- important at the kernel boundary for this platform. ---*/ -/*--- vg_kerneliface.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __VG_KERNELIFACE_H -#define __VG_KERNELIFACE_H - -/* This file is ONLY to be included into core.h. Do not include - it directly into valgrind source .c files. This file defines types - and constants for the kernel interface, and to make that clear - everything is prefixed VKI. */ - -/*--- All the following stuff is correct for Linux kernels 2.2.X and - 2.4.X. ----*/ - -/* Should really get this from an include file somewhere. */ -#define VKI_BYTES_PER_PAGE_BITS 12 -#define VKI_BYTES_PER_PAGE (1 << VKI_BYTES_PER_PAGE_BITS) - -#define VKI_BYTES_PER_WORD 4 -#define VKI_WORDS_PER_PAGE (VKI_BYTES_PER_PAGE / VKI_BYTES_PER_WORD) - - -/* An implementation of signal sets. These are the same as the sigset - implementations in the relevant Linux kernels. Note carefully that - this has nothing to do with glibc's signal sets. We work entirely - at the kernel boundary, so the libc stuff is invisible and - irrelevant. */ - -/* The following is copied from - /usr/src/linux-2.4.9-13/include/asm-i386/signal.h */ -#define VKI_KNSIG 64 /* true for linux 2.2.X and 2.4.X */ -#define VKI_KNSIG_BPW 32 /* since we're using UInts */ -#define VKI_KNSIG_WORDS (VKI_KNSIG / VKI_KNSIG_BPW) - -typedef - struct { - UInt ws[VKI_KNSIG_WORDS]; - } - vki_ksigset_t; - - -typedef - struct { - void* ksa_handler; - unsigned long ksa_flags; - void (*ksa_restorer)(void); - vki_ksigset_t ksa_mask; - } - vki_ksigaction; - -typedef - struct { - void* ss_sp; - Int ss_flags; - UInt ss_size; - } - vki_kstack_t; - -#define SI_MAX_SIZE 128 -#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 3) - -union vki_sigval { - Int sival_int; - void *sival_ptr; -}; - -typedef - struct { - Int si_signo; - Int si_errno; - Int si_code; - - union { - Int _pad[SI_PAD_SIZE]; - - /* kill() */ - struct { - Int _pid; /* sender's pid */ - Short _uid; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - UInt _timer1; - UInt _timer2; - } _timer; - - /* POSIX.1b signals */ - struct { - Int _pid; /* sender's pid */ - UShort _uid; /* sender's uid */ - union vki_sigval _sigval; - } _rt; - - /* SIGCHLD */ - struct { - Int _pid; /* which child */ - UShort _uid; /* sender's uid */ - Int _status; /* exit code */ - Int _utime; - Int _stime; - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - struct { - void *_addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - Int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - Int _fd; - } _sigpoll; - } _sifields; - } vki_ksiginfo_t; - -/* linux-2.6/include/asm-generic/siginfo.h */ - -#define VKI_SI_USER 0 -#define VKI_SI_QUEUE -1 -#define VKI_SI_TKILL -6 - -struct vki_fpreg { - UShort significand[4]; - UShort exponent; -}; - -struct vki_fpxreg { - UShort significand[4]; - UShort exponent; - UShort padding[3]; -}; - -struct vki_xmmreg { - UInt element[4]; -}; - -struct vki_fpstate { - /* Regular FPU environment */ - unsigned long cw; - unsigned long sw; - unsigned long tag; - unsigned long ipoff; - unsigned long cssel; - unsigned long dataoff; - unsigned long datasel; - struct vki_fpreg _st[8]; - unsigned short status; - unsigned short magic; /* 0xffff = regular FPU data only */ - - /* FXSR FPU environment */ - unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ - unsigned long mxcsr; - unsigned long reserved; - struct vki_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ - struct vki_xmmreg _xmm[8]; - unsigned long padding[56]; -}; - -#define X86_FXSR_MAGIC 0x0000 - -struct vki_sigcontext { - UShort gs, __gsh; - UShort fs, __fsh; - UShort es, __esh; - UShort ds, __dsh; - UInt edi; - UInt esi; - UInt ebp; - UInt esp; - UInt ebx; - UInt edx; - UInt ecx; - UInt eax; - UInt trapno; - UInt err; - UInt eip; - UShort cs, __csh; - UInt eflags; - UInt esp_at_signal; - UShort ss, __ssh; - struct vki_fpstate * fpstate; - UInt oldmask; - UInt cr2; -}; - -struct vki_ucontext { - UInt uc_flags; - struct vki_ucontext *uc_link; - vki_kstack_t uc_stack; - struct vki_sigcontext uc_mcontext; - vki_ksigset_t uc_sigmask; /* mask last for extensibility */ -}; - - -/* sigaltstack controls */ -#define VKI_SS_ONSTACK 1 -#define VKI_SS_DISABLE 2 - -#define VKI_MINSIGSTKSZ 2048 -#define VKI_SIGSTKSZ 8192 - - - -#define VKI_SIG_BLOCK 0 /* for blocking signals */ -#define VKI_SIG_UNBLOCK 1 /* for unblocking signals */ -#define VKI_SIG_SETMASK 2 /* for setting the signal mask */ - -#define VKI_SIG_DFL ((void*)0) /* default signal handling */ -#define VKI_SIG_IGN ((void*)1) /* ignore signal */ -#define VKI_SIG_ERR ((void*)-1) /* error return from signal */ - -#define VKI_SA_ONSTACK 0x08000000 -#define VKI_SA_RESTART 0x10000000 -#define VKI_SA_NOCLDSTOP 0x00000001 -#define VKI_SA_SIGINFO 0x00000004 -#define VKI_SA_RESETHAND 0x80000000 -#define VKI_SA_ONESHOT VKI_SA_RESETHAND -#define VKI_SA_NODEFER 0x40000000 -#define VKI_SA_NOMASK VKI_SA_NODEFER -#define VKI_SA_NOCLDWAIT 0x00000002 -#define VKI_SA_RESTORER 0x04000000 -#if 0 -#define VKI_SA_INTERRUPT 0x20000000 /* dummy -- ignored */ -#endif - -/* extra wait flags */ -#define VKI_WNOHANG 1 /* Don't block waiting. */ -#define VKI_WUNTRACED 2 /* Report status of stopped children. */ -#define VKI__WALL 0x40000000 /* Wait for any child. */ -#define VKI__WCLONE 0x80000000 /* Wait for cloned process. */ - -#define VKI_SIGHUP 1 /* Hangup (POSIX). */ -#define VKI_SIGINT 2 /* Interrupt (ANSI). */ -#define VKI_SIGQUIT 3 /* Quit (POSIX). */ -#define VKI_SIGILL 4 /* Illegal instruction (ANSI). */ -#define VKI_SIGTRAP 5 /* Trace trap (POSIX). */ -#define VKI_SIGABRT 6 /* Abort (ANSI). */ -#define VKI_SIGIOT 6 /* IOT trap (4.2 BSD). */ -#define VKI_SIGBUS 7 /* BUS error (4.2 BSD). */ -#define VKI_SIGFPE 8 /* Floating-point exception (ANSI). */ -#define VKI_SIGKILL 9 /* Kill, unblockable (POSIX). */ -#define VKI_SIGUSR1 10 /* User-defined signal 1 (POSIX). */ -#define VKI_SIGSEGV 11 /* Segmentation violation (ANSI). */ -#define VKI_SIGUSR2 12 /* User-defined signal 2 (POSIX). */ -#define VKI_SIGPIPE 13 /* Broken pipe (POSIX). */ -#define VKI_SIGALRM 14 /* Alarm clock (POSIX). */ -#define VKI_SIGTERM 15 /* Termination (ANSI). */ -#define VKI_SIGSTKFLT 16 /* Stack fault. */ -#define VKI_SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ -#define VKI_SIGCHLD 17 /* Child status has changed (POSIX). */ -#define VKI_SIGCONT 18 /* Continue (POSIX). */ -#define VKI_SIGSTOP 19 /* Stop, unblockable (POSIX). */ -#define VKI_SIGTSTP 20 /* Keyboard stop (POSIX). */ -#define VKI_SIGTTIN 21 /* Background read from tty (POSIX). */ -#define VKI_SIGTTOU 22 /* Background write to tty (POSIX). */ -#define VKI_SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ -#define VKI_SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ -#define VKI_SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ -#define VKI_SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ -#define VKI_SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ -#define VKI_SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ -#define VKI_SIGPOLL SIGIO /* Pollable event occurred (System V). */ -#define VKI_SIGIO 29 /* I/O now possible (4.2 BSD). */ -#define VKI_SIGPWR 30 /* Power failure restart (System V). */ -#define VKI_SIGSYS 31 /* Bad system call. */ -#define VKI_SIGUNUSED 31 - -#define VKI_SIGRTMIN 32 -#define VKI_SIGRTMAX 63 - -#define VKI_SIGVGINT (VKI_SIGRTMIN+0) /* signal for internal use - interrupt */ -#define VKI_SIGVGKILL (VKI_SIGRTMIN+1) /* signal for internal use - kill */ -#define VKI_SIGRTUSERMIN (VKI_SIGRTMIN+2) /* first user-usable RT signal */ - -/* The following are copied from include/asm-i386/mman.h .*/ - -#define VKI_PROT_NONE 0x0 /* No page permissions */ -#define VKI_PROT_READ 0x1 /* Page can be read. */ -#define VKI_PROT_WRITE 0x2 /* Page can be written. */ -#define VKI_PROT_EXEC 0x4 /* Page can be executed. */ -#define VKI_MAP_ANONYMOUS 0x20 /* Don't use a file. */ -#define VKI_MAP_SHARED 0x01 /* Share changes. */ -#define VKI_MAP_PRIVATE 0x02 /* Changes are private. */ -#define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ -#define VKI_MAP_NOSYMS 0x40000000 /* internal pseudo-flag to disable symbol loading */ -#define VKI_MAP_CLIENT 0x80000000 /* internal pseudo-flag to distinguish client mappings */ - -/* linux/mman.h */ -#define VKI_MREMAP_MAYMOVE 1 -#define VKI_MREMAP_FIXED 2 - -/* Copied from linux-2.4.19/include/asm-i386/fcntl.h */ - -#define VKI_O_ACCMODE 0003 -#define VKI_O_RDONLY 00 -#define VKI_O_WRONLY 01 -#define VKI_O_RDWR 02 -#define VKI_O_CREAT 0100 /* not fcntl */ -#define VKI_O_EXCL 0200 /* not fcntl */ -#define VKI_O_TRUNC 01000 /* not fcntl */ -#define VKI_O_APPEND 02000 -#define VKI_O_NONBLOCK 04000 -#define VKI_O_SYNC 010000 -#define VKI_FASYNC 020000 /* fcntl, for BSD compatibility */ -#define VKI_O_DIRECT 040000 /* direct disk access hint */ -#define VKI_O_LARGEFILE 0100000 -#define VKI_O_DIRECTORY 0200000 /* must be a directory */ -#define VKI_O_NOFOLLOW 0400000 /* don't follow links */ - -#define VKI_SEEK_SET 0 -#define VKI_SEEK_CUR 1 -#define VKI_SEEK_END 2 - -/* Copied from linux-2.4.19/include/linux/stat.h */ - -#define VKI_S_IRWXU 00700 -#define VKI_S_IRUSR 00400 -#define VKI_S_IWUSR 00200 -#define VKI_S_IXUSR 00100 - -#define VKI_S_IRWXG 00070 -#define VKI_S_IRGRP 00040 -#define VKI_S_IWGRP 00020 -#define VKI_S_IXGRP 00010 - -#define VKI_S_IRWXO 00007 -#define VKI_S_IROTH 00004 -#define VKI_S_IWOTH 00002 -#define VKI_S_IXOTH 00001 - - -/* Copied from /usr/src/linux-2.4.9-13/include/asm/errno.h */ - -#define VKI_EPERM 1 /* Operation not permitted */ -#define VKI_ENOENT 2 /* No such file or directory */ -#define VKI_ESRCH 3 /* No such process */ -#define VKI_EINTR 4 /* Interrupted system call */ -#define VKI_EBADF 9 /* Bad file number */ -#define VKI_ENOMEM 12 /* Out of memory */ -#define VKI_EWOULDBLOCK VKI_EAGAIN /* Operation would block */ -#define VKI_EAGAIN 11 /* Try again */ -#define VKI_EACCES 13 /* Permission denied */ -#define VKI_EFAULT 14 /* Bad address */ -#define VKI_EEXIST 17 /* File exists */ -#define VKI_EINVAL 22 /* Invalid argument */ -#define VKI_ENFILE 23 /* File table overflow */ -#define VKI_EMFILE 24 /* Too many open files */ -#define VKI_ENOSYS 38 /* Function not implemented */ - -#define VKI_ERESTARTSYS 512 /* Restart the syscall */ - -/* Copied from linux/isdn.h */ - -#define VKI_IIOCGETCPS _IO( 'I',21 ) -#define VKI_IIOCNETGPN _IO( 'I',34 ) - -#define ISDN_MSNLEN 32 - -typedef struct { - char name[ 10 ]; - char phone[ ISDN_MSNLEN ]; - int outgoing; -} isdn_net_ioctl_phone; - - -/* Gawd ... hack ... */ - -typedef struct vki__user_cap_header_struct { - UInt version; - int pid; -} vki_cap_user_header_t; - -typedef struct vki__user_cap_data_struct { - UInt effective; - UInt permitted; - UInt inheritable; -} vki_cap_user_data_t; - - -/* "Byrial Jensen" says: - [various] ioctls take a pointer to a "struct - termios" but this is another and shorter "struct - termios" than the one defined in and used - by tcgetattr(3) and tcsetattr(3) and other library - functions. GNU libc translate between its library - termios and the kernel termios. -*/ - -#define VKI_SIZEOF_STRUCT_TERMIOS 36 - -/* Adam Gundy , 20 Mar 2002, says: */ -#define VKI_SIZEOF_STRUCT_TERMIO 17 - - -/* File descriptor sets, for doing select(). Copied from - /usr/src/linux-2.4.9-31/include/linux/posix_types.h -*/ -/* - * This allows for 1024 file descriptors: if NR_OPEN is ever grown - * beyond that you'll have to change this too. But 1024 fd's seem to be - * enough even for such "real" unices like OSF/1, so hopefully this is - * one limit that doesn't have to be changed [again]. - * - * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in - * (and thus ) - but this is a more logical - * place for them. Solved by having dummy defines in . - */ - -/* - * Those macros may have been defined in . But we always - * use the ones here. - */ -#undef VKI_NFDBITS -#define VKI_NFDBITS (8 * sizeof(unsigned long)) - -#undef VKI_FD_SETSIZE -#define VKI_FD_SETSIZE 1024 - -#undef VKI_FDSET_LONGS -#define VKI_FDSET_LONGS (VKI_FD_SETSIZE/VKI_NFDBITS) - -#undef VKI_FDELT -#define VKI_FDELT(d) ((d) / VKI_NFDBITS) - -#undef VKI_FDMASK -#define VKI_FDMASK(d) (1UL << ((d) % VKI_NFDBITS)) - -typedef struct { - unsigned long vki_fds_bits [VKI_FDSET_LONGS]; -} vki_fd_set; - - -struct vki_pollfd { - Int fd; - Short events; - Short revents; -}; - -/* asm/poll.h */ -#define VKI_POLLIN 0x0001 -#define VKI_POLLPRI 0x0002 -#define VKI_POLLOUT 0x0004 -#define VKI_POLLERR 0x0008 -#define VKI_POLLHUP 0x0010 -#define VKI_POLLNVAL 0x0020 - - -/* sys/epoll.h */ -typedef union vki_epoll_data { - void *ptr; - Int fd; - UInt u32; - ULong u64; -} vki_epoll_data_t; - -struct vki_epoll_event { - UInt events; /* Epoll events */ - vki_epoll_data_t data; /* User data variable */ -}; - - -/* -./include/asm-i386/posix_types.h:typedef long __kernel_suseconds_t; -./include/linux/types.h:typedef __kernel_suseconds_t suseconds_t; - -./include/asm-i386/posix_types.h:typedef long __kernel_time_t; -./include/linux/types.h:typedef __kernel_time_t time_t; -*/ - -struct vki_timeval { - /* time_t */ long tv_sec; /* seconds */ - /* suseconds_t */ long tv_usec; /* microseconds */ -}; - - - -/* For fcntl on fds .. - from ./include/asm-i386/fcntl.h */ -#define VKI_F_DUPFD 0 /* dup */ -#define VKI_F_GETFD 1 /* get close_on_exec */ -#define VKI_F_SETFD 2 /* set/clear close_on_exec */ -#define VKI_F_GETFL 3 /* get file->f_flags */ -#define VKI_F_SETFL 4 /* set file->f_flags */ -#define VKI_F_GETLK 5 -#define VKI_F_SETLK 6 -#define VKI_F_SETLKW 7 -#define VKI_F_GETLK64 12 /* using 'struct flock64' */ -#define VKI_F_SETLK64 13 -#define VKI_F_SETLKW64 14 - -/* for F_[GET|SET]FL */ -#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */ - -#define VKI_O_NONBLOCK 04000 - -/* For nanosleep ... - from ./include/linux/time.h */ -struct vki_timespec { - /* time_t */ long tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ -}; - -/* POSIX.1b structure for timer start values and intervals. */ -struct vki_itimerspec { - struct vki_timespec it_interval; - struct vki_timespec it_value; -}; - -/* STAT stuff - from /usr/src/linux-2.4.9-31/include/asm-i386/stat.h */ -struct vki_stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long __unused1; - unsigned long st_mtime; - unsigned long __unused2; - unsigned long st_ctime; - unsigned long __unused3; - unsigned long __unused4; - unsigned long __unused5; -}; - - -/* To do with the ELF frame constructed by the kernel on a process' - stack just before it transfers control to the program's interpreter - (to use the ELF parlance). - Constants from /usr/src/linux-2.4.9-31/include/linux/elf.h - Logic from /usr/src/linux-2.4.9-31/fs/binfmt_elf.c - and its counterpart in the 2.2.14 kernel sources - in Red Hat 6.2. */ -#define VKI_AT_NULL 0 -#define VKI_AT_SYSINFO 32 /* address of system info page */ -#define VKI_AT_CLKTCK 17 /* frequency at which times() increments */ -#define VKI_AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ -#define VKI_AT_BASE 7 /* base address of interpreter */ -#define VKI_AT_PAGESZ 6 /* system page size */ -#define VKI_AT_PHNUM 5 /* number of program headers */ -#define VKI_AT_PHENT 4 /* size of program header entry */ -#define VKI_AT_PHDR 3 /* program headers for program */ -#define VKI_AT_USER_AUX_SEGMENT 23 /* tell glibc what address segment - 0x3B points to. (Needed for - Red Hat Limbo, 7.3.92) */ - -/* Including leads to loads of hassle because then we - need sometimes (RedHat 7.3) and that is a - kernel-only header which deliberately #errors on gcc-3.1. Mucho - hassle considering that we only want to know sizeof(struct module). - Hence ... - - #include - #include - #include - - int main ( void ) - { - printf ("sizeof(struct module) = %d\n", sizeof(struct module) ); - return 0; - } -*/ - -#define VKI_SIZEOF_STRUCT_MODULE 96 - - -/* This is the structure passed to the modify_ldt syscall. Just so as - to confuse and annoy everyone, this is _not_ the same as an - VgLdtEntry and has to be translated into such. The logic for doing - so, in vg_ldt.c, is copied from the kernel sources. */ -/* - * ldt.h - * - * Definitions of structures used with the modify_ldt system call. - */ -typedef struct vki_modify_ldt_ldt_s { - unsigned int entry_number; - unsigned long base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int reserved:25; -} vki_modify_ldt_t; - -#define VKI_MODIFY_LDT_CONTENTS_DATA 0 -#define VKI_MODIFY_LDT_CONTENTS_STACK 1 -#define VKI_MODIFY_LDT_CONTENTS_CODE 2 - -#define VKI_GDT_TLS_ENTRIES 3 -#define VKI_GDT_TLS_MIN 6 -#define VKI_GDT_TLS_MAX (VKI_GDT_TLS_MIN + VKI_GDT_TLS_ENTRIES) - -/* Flags for clone() */ -/* linux/sched.h */ -#define VKI_CSIGNAL 0x000000ff /* signal mask to be sent at exit */ -#define VKI_CLONE_VM 0x00000100 /* set if VM shared between processes */ -#define VKI_CLONE_FS 0x00000200 /* set if fs info shared between processes */ -#define VKI_CLONE_FILES 0x00000400 /* set if open files shared between processes */ -#define VKI_CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ -#define VKI_CLONE_IDLETASK 0x00001000 /* set if new pid should be 0 (kernel only)*/ -#define VKI_CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ -#define VKI_CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ -#define VKI_CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ -#define VKI_CLONE_THREAD 0x00010000 /* Same thread group? */ -#define VKI_CLONE_NEWNS 0x00020000 /* New namespace group? */ -#define VKI_CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ -#define VKI_CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ -#define VKI_CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ -#define VKI_CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ -#define VKI_CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */ -#define VKI_CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force VKI_CLONE_PTRACE on this clone */ -#define VKI_CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ - -/* This is the structure passed to the getdents syscall. */ -/* - * linux/dirent.h - */ -typedef struct vki_dirent { - long d_ino; - long d_off; - unsigned short d_reclen; - char d_name[256]; -} vki_dirent; - - - -/* This is the structure passed to the getrlimit syscall. */ -/* - * bits/resource.h - */ -typedef struct vki_rlimit { - unsigned long rlim_cur; - unsigned long rlim_max; -} vki_rlimit; - -#define VKI_RLIMIT_CPU 0 /* CPU time in ms */ -#define VKI_RLIMIT_FSIZE 1 /* Maximum filesize */ -#define VKI_RLIMIT_DATA 2 /* max data size */ -#define VKI_RLIMIT_STACK 3 /* max stack size */ -#define VKI_RLIMIT_CORE 4 /* max core file size */ -#define VKI_RLIMIT_RSS 5 /* max resident set size */ -#define VKI_RLIMIT_NPROC 6 /* max number of processes */ -#define VKI_RLIMIT_NOFILE 7 /* max number of open files */ -#define VKI_RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ -#define VKI_RLIMIT_AS 9 /* address space limit */ -#define VKI_RLIMIT_LOCKS 10 /* maximum file locks held */ - -/* Socket stuff. */ -/* - * sys/socket.h - */ -typedef unsigned short vki_sa_family_t; -struct vki_sockaddr { - vki_sa_family_t sa_family; /* Address family. */ - char sa_data[14]; /* Address data. */ -}; - -/* statfs structs */ -/* - * bits/statfs.h - */ - -struct vki_statfs { - unsigned int f_type; - unsigned int f_bsize; - unsigned int f_blocks; - unsigned int f_bfree; - unsigned int f_bavail; - unsigned int f_files; - unsigned int f_ffree; - int f_fsid[ 2 ]; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_spare[5]; -}; - -struct vki_statfs64 { - unsigned int f_type; - unsigned int f_bsize; - unsigned long long f_blocks; - unsigned long long f_bfree; - unsigned long long f_bavail; - unsigned long long f_files; - unsigned long long f_ffree; - int f_fsid[ 2 ]; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_spare[5]; -}; - -/* - * linux/futex.h - */ - -#define VKI_FUTEX_WAIT 0 -#define VKI_FUTEX_WAKE 1 -#define VKI_FUTEX_FD 2 -#define VKI_FUTEX_REQUEUE 3 - -/* - * linux/ipc.h - */ - -#define VKI_IPC_CREAT 00001000 /* create if key is nonexistent */ -#define VKI_IPC_EXCL 00002000 /* fail if key exists */ -#define VKI_IPC_NOWAIT 00004000 /* return error on wait */ - -/* - * linux/elfcore.h - */ - -struct elf_siginfo -{ - int si_signo; /* signal number */ - int si_code; /* extra code */ - int si_errno; /* errno */ -}; - -/* - * This is the old layout of "struct pt_regs", and - * is still the layout used by user mode (the new - * pt_regs doesn't have all registers as the kernel - * doesn't use the extra segment registers) - */ -struct user_regs_struct { - long ebx, ecx, edx, esi, edi, ebp, eax; - unsigned short ds, __ds, es, __es; - unsigned short fs, __fs, gs, __gs; - long orig_eax, eip; - unsigned short cs, __cs; - long eflags, esp; - unsigned short ss, __ss; -}; - -struct user_i387_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ -}; - -struct user_fxsr_struct { - unsigned short cwd; - unsigned short swd; - unsigned short twd; - unsigned short fop; - long fip; - long fcs; - long foo; - long fos; - long mxcsr; - long reserved; - long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ - long padding[56]; -}; - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; -typedef struct user_fxsr_struct elf_fpxregset_t; - - -/* - * Definitions to generate Intel SVR4-like core files. - * These mostly have the same names as the SVR4 types with "elf_" - * tacked on the front to prevent clashes with linux definitions, - * and the typedef forms have been avoided. This is mostly like - * the SVR4 structure, but more Linuxy, with things that Linux does - * not support and which gdb doesn't really use excluded. - * Fields present but not used are marked with "XXX". - */ -struct elf_prstatus -{ -#if 0 - long pr_flags; /* XXX Process flags */ - short pr_why; /* XXX Reason for process halt */ - short pr_what; /* XXX More detailed reason */ -#endif - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - unsigned long pr_sigpend; /* Set of pending signals */ - unsigned long pr_sighold; /* Set of held signals */ -#if 0 - struct sigaltstack pr_altstack; /* Alternate stack info */ - struct sigaction pr_action; /* Signal action for current sig */ -#endif - Int pr_pid; - Int pr_ppid; - Int pr_pgrp; - Int pr_sid; - struct vki_timeval pr_utime; /* User time */ - struct vki_timeval pr_stime; /* System time */ - struct vki_timeval pr_cutime; /* Cumulative user time */ - struct vki_timeval pr_cstime; /* Cumulative system time */ -#if 0 - long pr_instr; /* Current instruction */ -#endif - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define ELF_PRARGSZ (80) /* Number of chars for args */ - -struct elf_prpsinfo -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - unsigned long pr_flag; /* flags */ - Int pr_uid; - Int pr_gid; - Int pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -/* - * linux/aio_abi.h - */ - -typedef struct { - unsigned id; /* kernel internal index number */ - unsigned nr; /* number of io_events */ - unsigned head; - unsigned tail; - - unsigned magic; - unsigned compat_features; - unsigned incompat_features; - unsigned header_length; /* size of aio_ring */ -} vki_aio_ring ; - -typedef vki_aio_ring *vki_aio_context_t; - -typedef struct { - ULong data; - ULong obj; - Long result; - Long result2; -} vki_io_event; - -typedef struct { - /* these are internal to the kernel/libc. */ - ULong aio_data; /* data to be returned in event's data */ - ULong aio_key; - /* the kernel sets aio_key to the req # */ - - /* common fields */ - UShort aio_lio_opcode; /* see IOCB_CMD_ above */ - UShort aio_reqprio; - UInt aio_fildes; - - ULong aio_buf; - ULong aio_nbytes; - Long aio_offset; - - /* extra parameters */ - ULong aio_reserved2; /* TODO: use this for a (struct sigevent *) */ - ULong aio_reserved3; -} vki_iocb; /* 64 bytes */ - -enum { - VKI_IOCB_CMD_PREAD = 0, - VKI_IOCB_CMD_PWRITE = 1, - VKI_IOCB_CMD_FSYNC = 2, - VKI_IOCB_CMD_FDSYNC = 3, - /* These two are experimental. - * IOCB_CMD_PREADX = 4, - * IOCB_CMD_POLL = 5, - */ - VKI_IOCB_CMD_NOOP = 6, -}; - -/* - * linux/mqueue.h - */ - -struct vki_mq_attr { - long mq_flags; /* message queue flags */ - long mq_maxmsg; /* maximum number of messages */ - long mq_msgsize; /* maximum message size */ - long mq_curmsgs; /* number of messages currently queued */ - long __reserved[4]; /* ignored for input, zeroed for output */ -}; - -#endif /* __VG_KERNELIFACE_H */ - -/*--------------------------------------------------------------------*/ -/*--- end vg_kerneliface.h ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/include/vg_profile.c b/VEX/head20041019/include/vg_profile.c deleted file mode 100644 index a5860ddc0..000000000 --- a/VEX/head20041019/include/vg_profile.c +++ /dev/null @@ -1,173 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Profiling machinery. #include this file into a tool to ---*/ -/*--- enable --profile=yes, but not for release versions of tools, ---*/ -/*--- because it uses glibc code. ---*/ -/*--- vg_profile.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __VG_PROFILE_C -#define __VG_PROFILE_C - -#include "tool.h" - -/* get rid of these, if possible */ -#include -#include - -/* Override the empty definitions from tool.h */ -#undef VGP_PUSHCC -#undef VGP_POPCC -#define VGP_PUSHCC(x) if (VG_(clo_profile)) VGP_(pushcc)(x) -#define VGP_POPCC(x) if (VG_(clo_profile)) VGP_(popcc)(x) - -#define VGP_M_STACK 20 -#define VGP_MAX_CCS 50 - - -/* All zeroed initially because they're static */ -static Int vgp_nticks; - -static Int vgp_counts [VGP_MAX_CCS]; -static Int vgp_entries[VGP_MAX_CCS]; -static Char* vgp_names [VGP_MAX_CCS]; - -static Int vgp_sp; -static UInt vgp_stack[VGP_M_STACK]; - -/* These definitions override the panicking ones in vg_profile.c */ - -void VGP_(register_profile_event) ( Int n, Char* name ) -{ - /* Adjust for negative values */ - n += VgpUnc; - if (n >= VGP_MAX_CCS) { - VG_(printf)("\nProfile event #%d higher than VGP_MAX_CCS of %d.\n" - "If you really need this many profile events, increase\n" - "VGP_MAX_CCS and recompile Valgrind.\n", - n, VGP_MAX_CCS); - VG_(skin_panic)("profile event too high"); - } - if (vgp_names[n] != NULL) { - VG_(printf)("\nProfile event #%d being registered as `%s'\n" - "already registered as `%s'.\n" - "Note that tool and core event numbers must not overlap.\n", - n, name, vgp_names[n]); - VG_(skin_panic)("profile event already registered"); - } - - vgp_names[n] = name; -} - -void VGP_(tick) ( int sigNo ) -{ - Int cc; - vgp_nticks++; - cc = vgp_stack[vgp_sp]; - sk_assert(cc >= 0 && cc < VGP_MAX_CCS); - vgp_counts[ cc ]++; -} - -void VGP_(init_profiling) ( void ) -{ - struct itimerval value; - Int ret; - - /* Register core events... tricky macro definition causes - VGP_(register_profile_event)() to be called once for each core event - in VGP_CORE_LIST. */ - sk_assert(VgpUnc == 0); -# define VGP_PAIR(n,name) VGP_(register_profile_event)(n,name) - VGP_CORE_LIST; -# undef VGP_PAIR - - vgp_sp = -1; - VGP_(pushcc) ( VgpUnc ); - - value.it_interval.tv_sec = 0; - value.it_interval.tv_usec = 10 * 1000; - value.it_value = value.it_interval; - - signal(SIGPROF, VGP_(tick) ); - ret = setitimer(ITIMER_PROF, &value, NULL); - if (ret != 0) VG_(skin_panic)("vgp_init_profiling"); -} - -void VGP_(done_profiling) ( void ) -{ - Int i; - VG_(printf)("\nProfiling done, %d ticks\n", vgp_nticks); - for (i = 0; i < VGP_MAX_CCS; i++) - if (NULL != vgp_names[i]) - VG_(printf)( - "%2d: %4d (%3d %%%%) ticks, %10d entries for %s\n", - i, vgp_counts[i], - (Int)(1000.0 * (double)vgp_counts[i] / (double)vgp_nticks), - vgp_entries[i], vgp_names[i] ); -} - -void VGP_(pushcc) ( UInt cc ) -{ - if (vgp_sp >= VGP_M_STACK-1) { - VG_(printf)( - "\nMaximum profile stack depth (%d) reached for event #%d (`%s').\n" - "This is probably due to a VGP_(pushcc)() without a matching\n" - "VGP_(popcc)(). Make sure they all match.\n" - "Or if you are nesting profiling events very deeply, increase\n" - "VGP_M_STACK and recompile Valgrind.\n", - VGP_M_STACK, cc, vgp_names[cc]); - VG_(skin_panic)("Profiling stack overflow"); - } - vgp_sp++; - vgp_stack[vgp_sp] = cc; - vgp_entries[ cc ] ++; -} - -void VGP_(popcc) ( UInt cc ) -{ - if (vgp_sp <= 0) { - VG_(printf)( - "\nProfile stack underflow. This is due to a VGP_(popcc)() without\n" - "a matching VGP_(pushcc)(). Make sure they all match.\n"); - VG_(skin_panic)("Profiling stack underflow"); - } - if (vgp_stack[vgp_sp] != cc) { - Int i; - VG_(printf)("popping %s, stack looks like:\n", vgp_names[cc]); - for (i = vgp_sp; i >= 0; i--) - VG_(printf)("%2d: %s\n", i, vgp_names[vgp_stack[i]]); - VG_(exit)(1); - } - vgp_sp--; -} - -#endif /* __VG_PROFILE_C */ - -/*--------------------------------------------------------------------*/ -/*--- end vg_profile.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/include/vg_skin.h b/VEX/head20041019/include/vg_skin.h deleted file mode 100644 index 0628888d9..000000000 --- a/VEX/head20041019/include/vg_skin.h +++ /dev/null @@ -1,3 +0,0 @@ -// "vg_skin.h" was renamed to "tool.h"; this is for backward compatibility -// with old external tools. -#include "tool.h" diff --git a/VEX/head20041019/include/x86/.cvsignore b/VEX/head20041019/include/x86/.cvsignore deleted file mode 100644 index 282522db0..000000000 --- a/VEX/head20041019/include/x86/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/VEX/head20041019/include/x86/CVS/Entries b/VEX/head20041019/include/x86/CVS/Entries deleted file mode 100644 index 5b45ed13c..000000000 --- a/VEX/head20041019/include/x86/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Fri Sep 3 13:45:29 2004// -/Makefile.am/1.1/Fri Sep 3 13:45:29 2004// -/tool_arch.h/1.4/Tue Sep 7 10:17:02 2004// -D diff --git a/VEX/head20041019/include/x86/CVS/Repository b/VEX/head20041019/include/x86/CVS/Repository deleted file mode 100644 index ca641eb5f..000000000 --- a/VEX/head20041019/include/x86/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/include/x86 diff --git a/VEX/head20041019/include/x86/CVS/Root b/VEX/head20041019/include/x86/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/include/x86/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/include/x86/CVS/Template b/VEX/head20041019/include/x86/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/include/x86/Makefile.am b/VEX/head20041019/include/x86/Makefile.am deleted file mode 100644 index 7d6172886..000000000 --- a/VEX/head20041019/include/x86/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -incincdir = $(includedir)/valgrind/x86 - -incinc_HEADERS = tool_arch.h - diff --git a/VEX/head20041019/include/x86/tool_arch.h b/VEX/head20041019/include/x86/tool_arch.h deleted file mode 100644 index b2457ceb3..000000000 --- a/VEX/head20041019/include/x86/tool_arch.h +++ /dev/null @@ -1,86 +0,0 @@ -/*--------------------------------------------------------------------*/ -/*--- x86/tool_arch.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __X86_TOOL_ARCH_H -#define __X86_TOOL_ARCH_H - -// XXX: eventually a lot of the stuff in this file can be made private to -// the x86/ subdir, and not visible to the core. But as long as the core -// still refers to them, they'll have to stay in here. - -/*====================================================================*/ -/*=== Registers, etc ===*/ -/*====================================================================*/ - -#define REGPARM(n) __attribute__((regparm(n))) - -#define FIRST_ARCH_REG R_EAX -#define LAST_ARCH_REG R_EDI - -#define N_ARCH_REGS 8 - -#define MIN_INSTR_SIZE 1 -#define MAX_INSTR_SIZE 16 - -/* Total number of integer registers available for allocation -- all of - them except %esp (points to Valgrind's stack) and %ebp (permanently - points at the baseBlock). - - If you increase this you'll have to also change at least these: - - VG_(rank_to_realreg)() - - VG_(realreg_to_rank)() - - ppRegsLiveness() - - the RegsLive type (maybe -- RegsLive type must have more than - VG_MAX_REALREGS bits) - - You can decrease it, and performance will drop because more spills will - occur. If you decrease it too much, everything will fall over. - - Do not change this unless you really know what you are doing! */ -#define VG_MAX_REALREGS 6 - - -/*====================================================================*/ -/*=== Instrumenting UCode ===*/ -/*====================================================================*/ - -/* ------------------------------------------------------------------ */ -/* Offsets of addresses of helper functions. A "helper" function is one - which is called from generated code via CALLM. */ - -// XXX: eventually these should be private to the x86 part, not visible to -// tools, and the IR should provide a better way than this to see what the -// original instruction was. - - -#endif // __X86_TOOL_ARCH_H - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/lackey/.cvsignore b/VEX/head20041019/lackey/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/lackey/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/lackey/CVS/Entries b/VEX/head20041019/lackey/CVS/Entries deleted file mode 100644 index 325e851de..000000000 --- a/VEX/head20041019/lackey/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:33 2002// -/Makefile.am/1.46/Wed Sep 1 23:20:48 2004// -/lk_main.c/1.24/Thu Sep 2 08:51:42 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/lackey/CVS/Repository b/VEX/head20041019/lackey/CVS/Repository deleted file mode 100644 index a3bb075cd..000000000 --- a/VEX/head20041019/lackey/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/lackey diff --git a/VEX/head20041019/lackey/CVS/Root b/VEX/head20041019/lackey/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/lackey/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/lackey/CVS/Template b/VEX/head20041019/lackey/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/lackey/Makefile.am b/VEX/head20041019/lackey/Makefile.am deleted file mode 100644 index a21574b9e..000000000 --- a/VEX/head20041019/lackey/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -val_PROGRAMS = vgskin_lackey.so - -vgskin_lackey_so_SOURCES = lk_main.c -vgskin_lackey_so_LDFLAGS = -shared - diff --git a/VEX/head20041019/lackey/docs/.cvsignore b/VEX/head20041019/lackey/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/lackey/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/lackey/docs/CVS/Entries b/VEX/head20041019/lackey/docs/CVS/Entries deleted file mode 100644 index 0455f9b22..000000000 --- a/VEX/head20041019/lackey/docs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Thu Oct 3 10:07:34 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:06 2004// -/lk_main.html/1.4/Sun Jan 4 16:43:22 2004// -D diff --git a/VEX/head20041019/lackey/docs/CVS/Repository b/VEX/head20041019/lackey/docs/CVS/Repository deleted file mode 100644 index d58e8e954..000000000 --- a/VEX/head20041019/lackey/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/lackey/docs diff --git a/VEX/head20041019/lackey/docs/CVS/Root b/VEX/head20041019/lackey/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/lackey/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/lackey/docs/CVS/Template b/VEX/head20041019/lackey/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/lackey/docs/Makefile.am b/VEX/head20041019/lackey/docs/Makefile.am deleted file mode 100644 index 4872f3344..000000000 --- a/VEX/head20041019/lackey/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = lk_main.html diff --git a/VEX/head20041019/lackey/docs/lk_main.html b/VEX/head20041019/lackey/docs/lk_main.html deleted file mode 100644 index a6f22a00c..000000000 --- a/VEX/head20041019/lackey/docs/lk_main.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - Cachegrind - - - - - -

Lackey

-
This manual was last updated on 2002-10-03
-

- -

-njn25@cam.ac.uk
-Copyright © 2002-2004 Nicholas Nethercote -

-Lackey is licensed under the GNU General Public License, -version 2
-Lackey is an example Valgrind tool that does some very basic program -measurement. -

- -

- -

1  Lackey

- -Lackey is a simple Valgrind tool that does some basic program measurement. -It adds quite a lot of simple instrumentation to the program's code. It is -primarily intended to be of use as an example tool. -

-It measures three things: - -

    -
  1. The number of calls to _dl_runtime_resolve(), the function - in glibc's dynamic linker that resolves function lookups into shared - objects.

    - -

  2. The number of UCode instructions (UCode is Valgrind's RISC-like - intermediate language), x86 instructions, and basic blocks executed by the - program, and some ratios between the three counts.

    - -

  3. The number of conditional branches encountered and the proportion of those - taken.

    -

- -
- - - diff --git a/VEX/head20041019/lackey/lk_main.c b/VEX/head20041019/lackey/lk_main.c deleted file mode 100644 index f577667f4..000000000 --- a/VEX/head20041019/lackey/lk_main.c +++ /dev/null @@ -1,291 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Simple tool for counting UInstrs, using a C helper. ---*/ -/*--- lk_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Lackey, an example Valgrind tool that does - some simple program measurement. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" -#include "../../../pub/libvex.h" - -/* Nb: use ULongs because the numbers can get very big */ -static ULong n_dlrr_calls = 0; -static ULong n_BBs = 0; -static ULong n_UInstrs = 0; -static ULong n_x86_instrs = 0; -static ULong n_Jccs = 0; -static ULong n_Jccs_untaken = 0; - -static void add_one_dlrr_call(void) -{ - n_dlrr_calls++; -} - -/* See comment above SK_(instrument) for reason why n_x86_instrs is - incremented here. */ -static void add_one_BB(void) -{ - n_BBs++; - n_x86_instrs++; -} - -static void add_one_UInstr(void) -{ - n_UInstrs++; -} - -static void add_one_x86_instr(void) -{ - n_x86_instrs++; -} - -static void add_one_Jcc(void) -{ - n_Jccs++; -} - -static void add_one_Jcc_untaken(void) -{ - n_Jccs_untaken++; -} - -void SK_(pre_clo_init)(void) -{ - VG_(details_name) ("Lackey"); - VG_(details_version) (NULL); - VG_(details_description) ("an example Valgrind tool"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 175 ); - -#if 0 - VG_(register_compact_helper)((Addr) & add_one_dlrr_call); - VG_(register_compact_helper)((Addr) & add_one_BB); - VG_(register_compact_helper)((Addr) & add_one_x86_instr); - VG_(register_compact_helper)((Addr) & add_one_UInstr); - VG_(register_compact_helper)((Addr) & add_one_Jcc); - VG_(register_compact_helper)((Addr) & add_one_Jcc_untaken); -#endif -} - -void SK_(post_clo_init)(void) -{ -} - - -/* Note: x86 instructions are marked by an INCEIP at the end of each one, - except for the final one in the basic block which ends in an - unconditional JMP. Sometimes the final unconditional JMP is preceded by - a conditional JMP (Jcc), and thus it isn't reached. Eg: - - - INCEIP ... - - - Jcc ... - JMP ... (will not be reached if Jcc succeeds) - - If we simplemindedly added calls to add_one_x86_instr() before INCEIPs - and unconditional JMPs, we'd sometimes miss the final call (when a - preceding conditional JMP succeeds), underestimating the x86 instruction - count. - - - call add_one_x86_instr() - INCEIP ... - - - Jcc ... - call add_one_x86_instr() - JMP ... - - Instead we add a call before each INCEIP, and also one at the start of the - block, but not one at the end, viz: - - call add_one_x86_instr() - - - call add_one_x86_instr() - INCEIP ... - - - Jcc ... - JMP ... - - Which gives us the right answer. And just to avoid two C calls, we fold - the basic-block-beginning call in with add_one_BB(). Phew. -*/ -IRBB* SK_(instrument)(IRBB* bb_in, VexGuestLayout* layout, IRType hWordTy ) -{ - IRDirty* di; - Int i; - - /* Set up BB */ - IRBB* bb = emptyIRBB(); - bb->tyenv = dopyIRTypeEnv(bb_in->tyenv); - bb->next = dopyIRExpr(bb_in->next); - bb->jumpkind = bb_in->jumpkind; - -#if 0 - /* We need to know the entry point for this bb to do this. In any - case it's pretty meaningless in the presence of bb chasing since - we may enter this function part way through an IRBB. */ - /* Count call to dlrr(), if this BB is dlrr()'s entry point */ - if (VG_(get_fnname_if_entry)(orig_addr, fnname, 100) && - 0 == VG_(strcmp)(fnname, "_dl_runtime_resolve")) - { - addStmtToIRBB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( "add_one_dlrr_call", mkIRExprVec_0() ) - )); - } -#endif - - /* Count this basic block */ - di = unsafeIRDirty_0_N( 0, "add_one_BB", &add_one_BB, mkIRExprVec_0() ); - addStmtToIRBB( bb, IRStmt_Dirty(di) ); - - for (i = 0; i < bb_in->stmts_used; i++) { - IRStmt* st = bb_in->stmts[i]; - if (!st) continue; - - switch (st->tag) { - case Ist_Exit: - /* Count Jcc */ - addStmtToIRBB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( 0, "add_one_Jcc", &add_one_Jcc, - mkIRExprVec_0() ) - )); - addStmtToIRBB( bb, dopyIRStmt(st) ); - /* Count non-taken Jcc */ - addStmtToIRBB( - bb, - IRStmt_Dirty( - unsafeIRDirty_0_N( 0, "add_one_Jcc_untaken", &add_one_Jcc_untaken, - mkIRExprVec_0() ) - )); - break; - - default: - addStmtToIRBB( bb, dopyIRStmt(st)); - } - } - - return bb; - - -#if 0 - UCodeBlock* cb; - Int i; - UInstr* u; - Char fnname[100]; - - cb = VG_(setup_UCodeBlock)(cb_in); - - /* Count basic block */ - VG_(call_helper_0_0)(cb, (Addr) & add_one_BB); - - for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) { - u = VG_(get_instr)(cb_in, i); - - switch (u->opcode) { - case NOP: case LOCK: case CALLM_S: case CALLM_E: - break; - - case INCEIP: - /* Count x86 instr */ - VG_(call_helper_0_0)(cb, (Addr) & add_one_x86_instr); - VG_(copy_UInstr)(cb, u); - break; - - case JMP: - if (u->cond != CondAlways) { - /* Count Jcc */ - VG_(call_helper_0_0)(cb, (Addr) & add_one_Jcc); - VG_(copy_UInstr)(cb, u); - /* Count non-taken Jcc */ - VG_(call_helper_0_0)(cb, (Addr) & add_one_Jcc_untaken); - } else { - VG_(copy_UInstr)(cb, u); - } - break; - - default: - /* Count UInstr */ - VG_(call_helper_0_0)(cb, (Addr) & add_one_UInstr); - VG_(copy_UInstr)(cb, u); - break; - } - } - - VG_(free_UCodeBlock)(cb_in); - return cb; -#endif -} - -void SK_(fini)(Int exitcode) -{ - VG_(message)(Vg_UserMsg, - "Counted %d calls to _dl_runtime_resolve()", n_dlrr_calls); - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "Executed:"); - VG_(message)(Vg_UserMsg, " BBs: %u", n_BBs); - VG_(message)(Vg_UserMsg, " x86 instrs: %u", n_x86_instrs); - VG_(message)(Vg_UserMsg, " UInstrs: %u", n_UInstrs); - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "Jccs:"); - VG_(message)(Vg_UserMsg, " total: %u", n_Jccs); - VG_(message)(Vg_UserMsg, " %% taken: %u%%", - (n_Jccs - n_Jccs_untaken)*100 / - (n_Jccs ? n_Jccs : 1)); - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "Ratios:"); - VG_(message)(Vg_UserMsg, " x86 instrs : BB = %3u : 10", - 10 * n_x86_instrs / n_BBs); - VG_(message)(Vg_UserMsg, " UInstrs : BB = %3u : 10", - 10 * n_UInstrs / n_BBs); - VG_(message)(Vg_UserMsg, " UInstrs : x86_instr = %3u : 10", - 10 * n_UInstrs / n_x86_instrs); - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "Exit code: %d", exitcode); -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 0) - - -/*--------------------------------------------------------------------*/ -/*--- end lk_main.c ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/lackey/tests/.cvsignore b/VEX/head20041019/lackey/tests/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/lackey/tests/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/lackey/tests/CVS/Entries b/VEX/head20041019/lackey/tests/CVS/Entries deleted file mode 100644 index 967349db7..000000000 --- a/VEX/head20041019/lackey/tests/CVS/Entries +++ /dev/null @@ -1,6 +0,0 @@ -/.cvsignore/1.1/Fri Oct 4 11:35:47 2002// -/Makefile.am/1.3/Thu Jun 12 14:12:58 2003// -/filter_stderr/1.2/Tue Apr 22 21:41:38 2003// -/true.stderr.exp/1.1/Fri Oct 4 11:35:47 2002// -/true.vgtest/1.1/Fri Oct 4 11:35:47 2002// -D diff --git a/VEX/head20041019/lackey/tests/CVS/Repository b/VEX/head20041019/lackey/tests/CVS/Repository deleted file mode 100644 index 4848b644f..000000000 --- a/VEX/head20041019/lackey/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/lackey/tests diff --git a/VEX/head20041019/lackey/tests/CVS/Root b/VEX/head20041019/lackey/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/lackey/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/lackey/tests/CVS/Template b/VEX/head20041019/lackey/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/lackey/tests/Makefile.am b/VEX/head20041019/lackey/tests/Makefile.am deleted file mode 100644 index e586af521..000000000 --- a/VEX/head20041019/lackey/tests/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_SCRIPTS = filter_stderr - -EXTRA_DIST = $(noinst_SCRIPTS) \ - true.stderr.exp true.vgtest diff --git a/VEX/head20041019/lackey/tests/filter_stderr b/VEX/head20041019/lackey/tests/filter_stderr deleted file mode 100755 index 1f415be4b..000000000 --- a/VEX/head20041019/lackey/tests/filter_stderr +++ /dev/null @@ -1,31 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | - -# Output looks like this... -# -# Counted 53 calls to _dl_runtime_resolve() -# -# Executed: -# BBs: 47131 -# x86 instrs: 193330 -# UInstrs: 523996 -# -# Jccs: -# total: 36368 -# % taken: 58% -# -# Ratios: -# x86 instrs : BB = 41 : 10 -# UInstrs : BB = 111 : 10 -# UInstrs : x86_instr = 27 : 10 -# -# Exit code: 0 -# -# ...so chop all lines between first and last (inclusive) -sed "/^Counted [0-9]\+ calls to _dl_runtime_resolve()$/ , \ - /UInstrs : x86_instrs = [0-9]\+ : [0-9]\+/ \ - d" - diff --git a/VEX/head20041019/lackey/tests/true.stderr.exp b/VEX/head20041019/lackey/tests/true.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/lackey/tests/true.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/lackey/tests/true.vgtest b/VEX/head20041019/lackey/tests/true.vgtest deleted file mode 100644 index 24fc0a48c..000000000 --- a/VEX/head20041019/lackey/tests/true.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: ../../tests/true diff --git a/VEX/head20041019/make-uninstall-docs b/VEX/head20041019/make-uninstall-docs deleted file mode 100755 index cc0db79bf..000000000 --- a/VEX/head20041019/make-uninstall-docs +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# small tool to help documentation writers. -# Copy docs out of an installation tree (`pwd`/Inst) back to the build tree -# since it is a lot easier to edit them in the installation tree. -# Use with care! - -cp Inst/share/doc/valgrind/coregrind_core.html coregrind/docs -cp Inst/share/doc/valgrind/coregrind_intro.html coregrind/docs -cp Inst/share/doc/valgrind/coregrind_tools.html coregrind/docs -cp Inst/share/doc/valgrind/manual.html docs -cp Inst/share/doc/valgrind/ac_main.html addrcheck/docs -cp Inst/share/doc/valgrind/mc_main.html memcheck/docs -cp Inst/share/doc/valgrind/mc_techdocs.html memcheck/docs -cp Inst/share/doc/valgrind/cg_main.html cachegrind/docs -cp Inst/share/doc/valgrind/cg_techdocs.html cachegrind/docs -cp Inst/share/doc/valgrind/cc_main.html corecheck/docs -cp Inst/share/doc/valgrind/hg_main.html helgrind/docs -cp Inst/share/doc/valgrind/lk_main.html lackey/docs -cp Inst/share/doc/valgrind/nl_main.html none/docs - diff --git a/VEX/head20041019/massif/.cvsignore b/VEX/head20041019/massif/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/massif/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/massif/CVS/Entries b/VEX/head20041019/massif/CVS/Entries deleted file mode 100644 index 7e5db8aac..000000000 --- a/VEX/head20041019/massif/CVS/Entries +++ /dev/null @@ -1,6 +0,0 @@ -/.cvsignore/1.1/Sun Feb 22 19:34:55 2004// -/Makefile.am/1.5/Wed Sep 1 23:20:48 2004// -/ms_main.c/1.16/Mon Sep 13 13:27:30 2004// -D/docs//// -D/hp2ps//// -D/tests//// diff --git a/VEX/head20041019/massif/CVS/Repository b/VEX/head20041019/massif/CVS/Repository deleted file mode 100644 index 0d85ece01..000000000 --- a/VEX/head20041019/massif/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/massif diff --git a/VEX/head20041019/massif/CVS/Root b/VEX/head20041019/massif/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/massif/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/massif/CVS/Template b/VEX/head20041019/massif/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/massif/Makefile.am b/VEX/head20041019/massif/Makefile.am deleted file mode 100644 index 620c4f1d8..000000000 --- a/VEX/head20041019/massif/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -SUBDIRS += hp2ps - -val_PROGRAMS = vgskin_massif.so vgpreload_massif.so - -vgskin_massif_so_SOURCES = ms_main.c -vgskin_massif_so_LDFLAGS = -shared - -vgpreload_massif_so_SOURCES = -vgpreload_massif_so_LDADD = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_massif_so_DEPENDENCIES = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_massif_so_LDFLAGS = -shared -Wl,-z,interpose,-z,initfirst - diff --git a/VEX/head20041019/massif/docs/.cvsignore b/VEX/head20041019/massif/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/massif/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/massif/docs/CVS/Entries b/VEX/head20041019/massif/docs/CVS/Entries deleted file mode 100644 index dd8835ecf..000000000 --- a/VEX/head20041019/massif/docs/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Sun Feb 22 19:34:55 2004// -/Makefile.am/1.2/Wed Aug 25 11:40:06 2004// -/date.gif/1.1/Sat Feb 14 16:40:01 2004/-kb/ -/ms_main.html/1.1/Sat Feb 14 16:40:01 2004// -D diff --git a/VEX/head20041019/massif/docs/CVS/Repository b/VEX/head20041019/massif/docs/CVS/Repository deleted file mode 100644 index 23a9639a1..000000000 --- a/VEX/head20041019/massif/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/massif/docs diff --git a/VEX/head20041019/massif/docs/CVS/Root b/VEX/head20041019/massif/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/massif/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/massif/docs/CVS/Template b/VEX/head20041019/massif/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/massif/docs/Makefile.am b/VEX/head20041019/massif/docs/Makefile.am deleted file mode 100644 index a53c35232..000000000 --- a/VEX/head20041019/massif/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = ms_main.html date.gif diff --git a/VEX/head20041019/massif/docs/date.gif b/VEX/head20041019/massif/docs/date.gif deleted file mode 100644 index eff527ace..000000000 Binary files a/VEX/head20041019/massif/docs/date.gif and /dev/null differ diff --git a/VEX/head20041019/massif/docs/ms_main.html b/VEX/head20041019/massif/docs/ms_main.html deleted file mode 100644 index 87d1abcf9..000000000 --- a/VEX/head20041019/massif/docs/ms_main.html +++ /dev/null @@ -1,331 +0,0 @@ - - - Massif: a heap profiler - - - - -

Massif: a heap profiler

- -To use this tool, you must specify --tool=massif -on the Valgrind command line. - - -

7.1  Heap profiling

-Massif is a heap profiler, i.e. it measures how much heap memory programs use. -In particular, it can give you information about: -
    -
  • Heap blocks; -
  • Heap administration blocks; -
  • Stack sizes. -
- -Heap profiling is useful to help you reduce the amount of memory your program -uses. On modern machines with virtual memory, this provides the following -benefits: -
    -
  • It can speed up your program -- a smaller program will interact better - with your machine's caches, avoid paging, and so on. - -
  • If your program uses lots of memory, it will reduce the chance that it - exhausts your machine's swap space. -
- -Also, there are certain space leaks that aren't detected by traditional -leak-checkers, such as Memcheck's. That's because the memory isn't ever -actually lost -- a pointer remains to it -- but it's not in use. Programs -that have leaks like this can unnecessarily increase the amount of memory -they are using over time. -

- - - -

7.2  Why Use a Heap Profiler?

- -Everybody knows how useful time profilers are for speeding up programs. They -are particularly useful because people are notoriously bad at predicting where -are the bottlenecks in their programs. -

-But the story is different for heap profilers. Some programming languages, -particularly lazy functional languages like Haskell, have quite sophisticated heap -profilers. But there are few tools as powerful for profiling C and C++ -programs. -

-Why is this? Maybe it's because C and C++ programmers must think that -they know where the memory is being allocated. After all, you can see all the -calls to malloc() and new and new[], -right? But, in a big program, do you really know which heap allocations are -being executed, how many times, and how large each allocation is? Can you give -even a vague estimate of the memory footprint for your program? Do you know -this for all the libraries your program uses? What about administration bytes -required by the heap allocator to track heap blocks -- have you thought about -them? What about the stack? If you are unsure about any of these things, -maybe you should think about heap profiling. -

-Massif can tell you these things. -

-Or maybe it's because it's relatively easy to add basic heap profiling -functionality into a program, to tell you how many bytes you have allocated for -certain objects, or similar. But this information might only be simple like -total counts for the whole program's execution. What about space usage at -different points in the program's execution, for example? And reimplementing -heap profiling code for each project is a pain. -

-Massif can save you this effort. -

- - - -

7.3  Overview

-First off, as for normal Valgrind use, you probably want to compile with -debugging info (the -g flag). But, as opposed to Memcheck, -you probably do want to turn optimisation on, since you should profile -your program as it will be normally run. -

-Then, run your program with valgrind --tool=massif in front of the -normal command line invocation. When the program finishes, Massif will print -summary space statistics. It also creates a graph representing the program's -heap usage in a file called massif.pid.ps, which can -be read by any PostScript viewer, such as Ghostview. -

-It also puts detailed information about heap consumption in a file file -massif.pid.txt (text format) or -massif.pid.html (HTML format), where -pid is the program's process id. -

- - - -

7.4  Basic Results of Profiling

- -To gather heap profiling information about the program prog, -type: -

-

-valgrind --tool=massif prog -
-

-The program will execute (slowly). Upon completion, summary statistics -that look like this will be printed: - -

-==27519== Total spacetime:   2,258,106 ms.B
-==27519== heap:              24.0%
-==27519== heap admin:         2.2%
-==27519== stack(s):          73.7%
-
- -All measurements are done in spacetime, i.e. space (in bytes) multiplied -by time (in milliseconds). Note that because Massif slows a program down a -lot, the actual spacetime figure is fairly meaningless; it's the relative -values that are interesting. -

-Which entries you see in the breakdown depends on the command line options -given. The above example measures all the possible parts of memory: -

    -
  • Heap: number of words allocated on the heap, via malloc(), - new and new[]. -

    -

  • Heap admin: each heap block allocated requires some administration data, - which lets the allocator track certain things about the block. It is easy - to forget about this, and if your program allocates lots of small blocks, - it can add up. This value is an estimate of the space required for this - administration data. -

    -

  • Stack(s): the spacetime used by the programs' stack(s). (Threaded programs - can have multiple stacks.) This includes signal handler stacks. -

    -

-

- - - -

7.5  Spacetime Graphs

-As well as printing summary information, Massif also creates a file -representing a spacetime graph, massif.pid.hp. -It will produce a file called massif.pid.ps, which can be -viewed in a PostScript viewer. -

-Massif uses a program called hp2ps to convert the raw data into -the PostScript graph. It's distributed with Massif, but came originally -from the Glasgow Haskell -Compiler. You shouldn't need to worry about this at all. However, if -the graph creation fails for any reason, Massif tell you, and will leave -behind a file named massif.pid.hp, containing the raw -heap profiling data. -

-Here's an example graph:
- spacetime graph -

-The graph is broken into several bands. Most bands represent a single line of -your program that does some heap allocation; each such band represents all -the allocations and deallocations done from that line. Up to twenty bands are -shown; less significant allocation sites are merged into "other" and/or "OTHER" -bands. The accompanying text/HTML file produced by Massif has more detail -about these heap allocation bands. Then there are single bands for the -stack(s) and heap admin bytes. -

-Note: it's the height of a band that's important. Don't let the ups and downs -caused by other bands confuse you. For example, the -read_alias_file band in the example has the same height all the -time it's in existence. -

-The triangles on the x-axis show each point at which a memory census was taken. -These aren't necessarily evenly spread; Massif only takes a census when -memory is allocated or deallocated. The time on the x-axis is wallclock -time, which is not ideal because you can get different graphs for different -executions of the same program, due to random OS delays. But it's not too -bad, and it becomes less of a problem the longer a program runs. -

-Massif takes censuses at an appropriate timescale; censuses take place less -frequently as the program runs for longer. There is no point having more -than 100-200 censuses on a single graph. -

-The graphs give a good overview of where your program's space use comes from, -and how that varies over time. The accompanying text/HTML file gives a lot -more information about heap use. - - -

7.6  Details of Heap Allocations

- -The text/HTML file contains information to help interpret the heap bands of the -graph. It also contains a lot of extra information about heap allocations that you don't see in the graph. -

-Here's part of the information that accompanies the above graph. - -


-== 0 ===========================
-Heap allocation functions accounted for 50.8% of measured spacetime
-

-Called from: -

    -
  • 22.1%: 0x401767D0: _nl_intern_locale_data (in /lib/i686/libc-2.3.2.so) -
  • 8.6%: 0x4017C393: read_alias_file (in /lib/i686/libc-2.3.2.so) - -
  • (several entries omitted) - -
  • and 6 other insignificant places
  • -
-
-The first part shows the total spacetime due to heap allocations, and the -places in the program where most memory was allocated (nb: if this program had -been compiled with -g, actual line numbers would be given). These -places are sorted, from most significant to least, and correspond to the bands -seen in the graph. Insignificant sites (accounting for less than 0.5% of total -spacetime) are omitted. -

-That alone can be useful, but often isn't enough. What if one of these -functions was called from several different places in the program? Which one -of these is responsible for most of the memory used? For -_nl_intern_locale_data(), this question is answered by clicking on -the 22.1% link, which takes us to the following part -of the file. - -


-

== 1 ===========================
-Context accounted for 22.1% of measured spacetime
-   0x401767D0: _nl_intern_locale_data (in /lib/i686/libc-2.3.2.so)
-

-Called from: -

    -
  • 22.1%: 0x40176F95: _nl_load_locale_from_archive (in /lib/i686/libc-2.3.2.so) -
-
- -At this level, we can see all the places from which -_nl_load_locale_from_archive() was called such that it allocated -memory at 0x401767D0. (We can click on the top 22.1% -link to go back to the parent entry.) At this level, we have moved beyond the -information presented in the graph. In this case, it is only called from one -place. We can again follow the link for more detail, moving to the following -part of the file. - -
-

== 2 ===========================
-Context accounted for 22.1% of measured spacetime
-   0x401767D0: _nl_intern_locale_data (in /lib/i686/libc-2.3.2.so)
-   0x40176F95: _nl_load_locale_from_archive (in /lib/i686/libc-2.3.2.so)
-

-Called from: -

    -
  • 22.1%: 0x40176184: _nl_find_locale (in /lib/i686/libc-2.3.2.so) -
-
- -In this way we can dig deeper into the call stack, to work out exactly what -sequence of calls led to some memory being allocated. At this point, with a -call depth of 3, the information runs out (thus the address of the child entry, -0x40176184, isn't a link). We could rerun the program with a greater ---depth value if we wanted more information. -

-Sometimes you will get a code location like this: -

    -
  • 30.8% : 0xFFFFFFFF: ??? -
-The code address isn't really 0xFFFFFFFF -- that's impossible. This is what -Massif does when it can't work out what the real code address is. -

-Massif produces this information in a plain text file by default, or HTML with -the --format=html option. The plain text version obviously -doesn't have the links, but a similar effect can be achieved by searching on -the code addresses. (In Vim, the '*' and '#' searches are ideal for this.) - - - -

7.7  Massif options

- -Massif-specific options are: - -
    -
  • --heap=no
    - --heap=yes [default]
    - When enabled, profile heap usage in detail. Without it, the - massif.pid.txt or - massif.pid.html will be very short. -

    -

  • --heap-admin=n [default: 8]
    - The number of admin bytes per block to use. This can only be an - estimate of the average, since it may vary. The allocator used by - glibc requires somewhere between 4--15 bytes per block, - depending on various factors. It also requires admin space for freed - blocks, although Massif does not count this. -

    -

  • --stacks=no
    - --stacks=yes [default]
    - When enabled, include stack(s) in the profile. Threaded programs can - have multiple stacks. -

    -

  • --depth=n [default: 3]
    - Depth of call chains to present in the detailed heap information. - Increasing it will give more information, but Massif will run the program - more slowly, using more memory, and produce a bigger - .txt/.hp file. -

    -

  • --alloc-fn=name
    - Specify a function that allocates memory. This is useful for functions - that are wrappers to malloc(), which can fill up the context - information uselessly (and give very uninformative bands on the graph). - Functions specified will be ignored in contexts, i.e. treated as though - they were malloc(). This option can be specified multiple - times on the command line, to name multiple functions. -

    -

  • --format=text [default]
    - --format=html
    - Produce the detailed heap information in text or HTML format. The file - suffix used will be either .txt or .html. -

    -

- - -

7.8  Accuracy

-The information should be pretty accurate. Some approximations made might -cause some allocation contexts to be attributed with less memory than they -actually allocated, but the amounts should be miniscule. -

-The heap admin spacetime figure is an approximation, as described above. If -anyone knows how to improve its accuracy, please let us know. - - - - diff --git a/VEX/head20041019/massif/hp2ps/.cvsignore b/VEX/head20041019/massif/hp2ps/.cvsignore deleted file mode 100644 index fa57f32c3..000000000 --- a/VEX/head20041019/massif/hp2ps/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile.in -Makefile -hp2ps diff --git a/VEX/head20041019/massif/hp2ps/AreaBelow.c b/VEX/head20041019/massif/hp2ps/AreaBelow.c deleted file mode 100644 index e14ed5ebe..000000000 --- a/VEX/head20041019/massif/hp2ps/AreaBelow.c +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "AreaBelow.h" - -/* - * Return the area enclosed by all of the curves. The algorithm - * used is the same as the trapizoidal rule for integration. - */ - -floatish -AreaBelow() -{ - intish i; - intish j; - intish bucket; - floatish value; - struct chunk *ch; - floatish area; - floatish trap; - floatish base; - floatish *maxima; - - maxima = (floatish *) xmalloc(nsamples * sizeof(floatish)); - for (i = 0; i < nsamples; i++) { - maxima[i] = 0.0; - } - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - bucket = ch->d[j].bucket; - value = ch->d[j].value; - if (bucket >= nsamples) - Disaster("bucket out of range"); - maxima[ bucket ] += value; - } - } - } - - area = 0.0; - - for (i = 1; i < nsamples; i++) { - base = samplemap[i] - samplemap[i-1]; - if (maxima[i] > maxima[i-1]) { - trap = base * maxima[i-1] + ((base * (maxima[i] - maxima[i-1]))/ 2.0); - } else { - trap = base * maxima[i] + ((base * (maxima[i-1] - maxima[i]))/ 2.0); - } - - area += trap; - } - - free(maxima); - return area; -} diff --git a/VEX/head20041019/massif/hp2ps/AreaBelow.h b/VEX/head20041019/massif/hp2ps/AreaBelow.h deleted file mode 100644 index a4c20d934..000000000 --- a/VEX/head20041019/massif/hp2ps/AreaBelow.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef AREA_BELOW_H -#define AREA_BELOW_H - -floatish AreaBelow PROTO((void)); - -#endif /* AREA_BELOW_H */ diff --git a/VEX/head20041019/massif/hp2ps/AuxFile.c b/VEX/head20041019/massif/hp2ps/AuxFile.c deleted file mode 100644 index dfc26cdb1..000000000 --- a/VEX/head20041019/massif/hp2ps/AuxFile.c +++ /dev/null @@ -1,172 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Shade.h" -#include "Error.h" -#include "HpFile.h" -#include "Reorder.h" - -/* own stuff */ -#include "AuxFile.h" - -static void GetAuxLine PROTO((FILE *)); /* forward */ -static void GetAuxTok PROTO((FILE *)); /* forward */ - -void -GetAuxFile(auxfp) - FILE* auxfp; -{ - g_ch = ' '; - endfile = 0; - linenum = 1; - - GetAuxTok(auxfp); - - while (endfile == 0) { - GetAuxLine(auxfp); - } - - fclose(auxfp); -} - - - -/* - * Read the next line from the aux file, check the syntax, and - * perform the appropriate action. - */ - -static void -GetAuxLine(auxfp) - FILE* auxfp; -{ - switch (thetok) { - case X_RANGE_TOK: - GetAuxTok(auxfp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d, floating point number must follow X_RANGE", - auxfile, linenum); - } - auxxrange = thefloatish; - GetAuxTok(auxfp); - break; - case Y_RANGE_TOK: - GetAuxTok(auxfp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d, floating point number must follow Y_RANGE", - auxfile, linenum); - } - auxyrange = thefloatish; - GetAuxTok(auxfp); - break; - case ORDER_TOK: - GetAuxTok(auxfp); - if (thetok != IDENTIFIER_TOK) { - Error("%s, line %d: identifier must follow ORDER", - auxfile, linenum); - } - GetAuxTok(auxfp); - if (thetok != INTEGER_TOK) { - Error("%s, line %d: identifier and integer must follow ORDER", - auxfile, linenum); - } - OrderFor(theident, theinteger); - GetAuxTok(auxfp); - break; - case SHADE_TOK: - GetAuxTok(auxfp); - if (thetok != IDENTIFIER_TOK) { - Error("%s, line %d: identifier must follow SHADE", - auxfile, linenum); - } - GetAuxTok(auxfp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d: identifier and floating point number must follow SHADE", - auxfile, linenum); - } - ShadeFor(theident, thefloatish); - GetAuxTok(auxfp); - break; - case EOF_TOK: - endfile = 1; - break; - default: - Error("%s, line %d: %s unexpected", auxfile, linenum, - TokenToString(thetok)); - break; - } -} - - - -/* - * Read the next token from the input and assign its value - * to the global variable "thetok". In the case of numbers, - * the corresponding value is also assigned to "thefloatish"; - * in the case of identifiers it is assigned to "theident". - */ - -static void GetAuxTok(auxfp) -FILE* auxfp; -{ - - while (isspace(g_ch)) { /* skip whitespace */ - if (g_ch == '\n') linenum++; - g_ch = getc(auxfp); - } - - if (g_ch == EOF) { - thetok = EOF_TOK; - return; - } - - if (isdigit(g_ch)) { - thetok = GetNumber(auxfp); - return; - } else if (IsIdChar(g_ch)) { /* g_ch can't be a digit here */ - GetIdent(auxfp); - if (!isupper(theident[0])) { - thetok = IDENTIFIER_TOK; - } else if (strcmp(theident, "X_RANGE") == 0) { - thetok = X_RANGE_TOK; - } else if (strcmp(theident, "Y_RANGE") == 0) { - thetok = Y_RANGE_TOK; - } else if (strcmp(theident, "ORDER") == 0) { - thetok = ORDER_TOK; - } else if (strcmp(theident, "SHADE") == 0) { - thetok = SHADE_TOK; - } else { - thetok = IDENTIFIER_TOK; - } - return; - } else { - Error("%s, line %d: strange character (%c)", auxfile, linenum, g_ch); - } -} - -void -PutAuxFile(auxfp) - FILE* auxfp; -{ - int i; - - fprintf(auxfp, "X_RANGE %.2f\n", xrange); - fprintf(auxfp, "Y_RANGE %.2f\n", yrange); - - for (i = 0; i < nidents; i++) { - fprintf(auxfp, "ORDER %s %d\n", identtable[i]->name, i+1); - } - - for (i = 0; i < nidents; i++) { - fprintf(auxfp, "SHADE %s %.2f\n", identtable[i]->name, - ShadeOf(identtable[i]->name)); - } - - fclose(auxfp); -} diff --git a/VEX/head20041019/massif/hp2ps/AuxFile.h b/VEX/head20041019/massif/hp2ps/AuxFile.h deleted file mode 100644 index be3fe1107..000000000 --- a/VEX/head20041019/massif/hp2ps/AuxFile.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef AUX_FILE_H -#define AUX_FILE_H - -void PutAuxFile PROTO((FILE *)); -void GetAuxFile PROTO((FILE *)); - -#endif /* AUX_FILE_H */ diff --git a/VEX/head20041019/massif/hp2ps/Axes.c b/VEX/head20041019/massif/hp2ps/Axes.c deleted file mode 100644 index b8036100e..000000000 --- a/VEX/head20041019/massif/hp2ps/Axes.c +++ /dev/null @@ -1,245 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Curves.h" -#include "Defines.h" -#include "Dimensions.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "Axes.h" - -typedef enum {MEGABYTE, KILOBYTE, BYTE} mkb; - -static void XAxis PROTO((void)); /* forward */ -static void YAxis PROTO((void)); /* forward */ - -static void XAxisMark PROTO((floatish, floatish)); /* forward */ -static void YAxisMark PROTO((floatish, floatish, mkb)); /* forward */ - -static floatish Round PROTO((floatish)); /* forward */ - -void -Axes() -{ - XAxis(); - YAxis(); -} - -static void -XAxisMark(x, num) - floatish x; floatish num; -{ - /* calibration mark */ - fprintf(psfp, "%f %f moveto\n", xpage(x), ypage(0.0)); - fprintf(psfp, "0 -4 rlineto\n"); - fprintf(psfp, "stroke\n"); - - /* number */ - fprintf(psfp, "HE%d setfont\n", NORMAL_FONT); - fprintf(psfp, "(%.1f)\n", num); - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "2 div\n"); - fprintf(psfp, "%f exch sub\n", xpage(x)); - fprintf(psfp, "%f moveto\n", borderspace); - fprintf(psfp, "show\n"); -} - - -#define N_X_MARKS 7 -#define XFUDGE 15 - -extern floatish xrange; -extern char *sampleunitstring; - -static void -XAxis() -{ - floatish increment, i; - floatish t, x; - floatish legendlen; - - /* draw the x axis line */ - fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(0.0)); - fprintf(psfp, "%f 0 rlineto\n", graphwidth); - fprintf(psfp, "%f setlinewidth\n", borderthick); - fprintf(psfp, "stroke\n"); - - /* draw x axis legend */ - fprintf(psfp, "HE%d setfont\n", NORMAL_FONT); - fprintf(psfp, "(%s)\n", sampleunitstring); - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "%f\n", xpage(0.0) + graphwidth); - fprintf(psfp, "exch sub\n"); - fprintf(psfp, "%f moveto\n", borderspace); - fprintf(psfp, "show\n"); - - - /* draw x axis scaling */ - - increment = Round(xrange / (floatish) N_X_MARKS); - - t = graphwidth / xrange; - legendlen = StringSize(sampleunitstring) + (floatish) XFUDGE; - - for (i = samplemap[0]; i < samplemap[nsamples - 1]; i += increment) { - x = (i - samplemap[0]) * t; - - if (x < (graphwidth - legendlen)) { - XAxisMark(x,i); - } - } -} - -static void -YAxisMark(y, num, unit) - floatish y; floatish num; mkb unit; -{ - /* calibration mark */ - fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(y)); - fprintf(psfp, "-4 0 rlineto\n"); - fprintf(psfp, "stroke\n"); - - /* number */ - fprintf(psfp, "HE%d setfont\n", NORMAL_FONT); - - switch (unit) { - case MEGABYTE : - fprintf(psfp, "("); - CommaPrint(psfp, (intish) (num / 1e6 + 0.5)); - fprintf(psfp, "M)\n"); - break; - case KILOBYTE : - fprintf(psfp, "("); - CommaPrint(psfp, (intish) (num / 1e3 + 0.5)); - fprintf(psfp, "k)\n"); - break; - case BYTE: - fprintf(psfp, "("); - CommaPrint(psfp, (intish) (num + 0.5)); - fprintf(psfp, ")\n"); - break; - } - - fprintf(psfp, "dup stringwidth\n"); - fprintf(psfp, "2 div\n"); - fprintf(psfp, "%f exch sub\n", ypage(y)); - - fprintf(psfp, "exch\n"); - fprintf(psfp, "%f exch sub\n", graphx0 - borderspace); - - fprintf(psfp, "exch\n"); - fprintf(psfp, "moveto\n"); - fprintf(psfp, "show\n"); -} - -#define N_Y_MARKS 7 -#define YFUDGE 15 - -extern floatish yrange; -extern char *valueunitstring; - -static void -YAxis() -{ - floatish increment, i; - floatish t, y; - floatish legendlen; - mkb unit; - - /* draw the y axis line */ - fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(0.0)); - fprintf(psfp, "0 %f rlineto\n", graphheight); - fprintf(psfp, "%f setlinewidth\n", borderthick); - fprintf(psfp, "stroke\n"); - - /* draw y axis legend */ - fprintf(psfp, "gsave\n"); - fprintf(psfp, "HE%d setfont\n", NORMAL_FONT); - fprintf(psfp, "(%s)\n", valueunitstring); - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "%f\n", ypage(0.0) + graphheight); - fprintf(psfp, "exch sub\n"); - fprintf(psfp, "%f exch\n", xpage(0.0) - borderspace); - fprintf(psfp, "translate\n"); - fprintf(psfp, "90 rotate\n"); - fprintf(psfp, "0 0 moveto\n"); - fprintf(psfp, "show\n"); - fprintf(psfp, "grestore\n"); - - /* draw y axis scaling */ - increment = max( yrange / (floatish) N_Y_MARKS, 1.0); - increment = Round(increment); - - if (increment >= 1e6) { - unit = MEGABYTE; - } else if (increment >= 1e3) { - unit = KILOBYTE; - } else { - unit = BYTE; - } - - t = graphheight / yrange; - legendlen = StringSize(valueunitstring) + (floatish) YFUDGE; - - for (i = 0.0; i <= yrange; i += increment) { - y = i * t; - - if (y < (graphheight - legendlen)) { - YAxisMark(y, i, unit); - } - } -} - - -/* - * Find a "nice round" value to use on the axis. - */ - -static floatish OneTwoFive PROTO((floatish)); /* forward */ - -static floatish -Round(y) - floatish y; -{ - int i; - - if (y > 10.0) { - for (i = 0; y > 10.0; y /= 10.0, i++) ; - y = OneTwoFive(y); - for ( ; i > 0; y = y * 10.0, i--) ; - - } else if (y < 1.0) { - for (i = 0; y < 1.0; y *= 10.0, i++) ; - y = OneTwoFive(y); - for ( ; i > 0; y = y / 10.0, i--) ; - - } else { - y = OneTwoFive(y); - } - - return (y); -} - - -/* - * OneTwoFive() -- Runciman's 1,2,5 scaling rule. Argument 1.0 <= y <= 10.0. - */ - -static floatish -OneTwoFive(y) - floatish y; -{ - if (y > 4.0) { - return (5.0); - } else if (y > 1.0) { - return (2.0); - } else { - return (1.0); - } -} diff --git a/VEX/head20041019/massif/hp2ps/Axes.h b/VEX/head20041019/massif/hp2ps/Axes.h deleted file mode 100644 index f9f252f6d..000000000 --- a/VEX/head20041019/massif/hp2ps/Axes.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef AXES_H -#define AXES_H - -void Axes PROTO((void)); - -#endif /* AXES_H */ diff --git a/VEX/head20041019/massif/hp2ps/CHANGES b/VEX/head20041019/massif/hp2ps/CHANGES deleted file mode 100644 index 60933d662..000000000 --- a/VEX/head20041019/massif/hp2ps/CHANGES +++ /dev/null @@ -1,39 +0,0 @@ -1. - -When generating PostScript to show strings, '(' and ')' may need to be escaped. -These characters are now escaped when the JOB string is shown. - -2. - -Manually deleting samples from a .hp file now does what you would expect. - -3. - -The -t flag for setting the threshold percentage has been scrapped. No one -ever used it. - -4. - -Long JOB strings cause hp2ps to use a big title box. Big and small boxes -can be forced with -b and -s flag. - -5. - -MARKS now print as small triangles which remain below the x axis. - -6. - -There is an updated manual page. - -7. - --m flag for setting maximum no of bands (default 20, cant be more than 20). --t flag for setting threshold (between 0% and 5%, default 1%). - -8. - -Axes scaling rounding errors removed. - -9. - -Fixed bug whereby x-axis was assumed to start at zero when placing MARKs. diff --git a/VEX/head20041019/massif/hp2ps/CVS/Entries b/VEX/head20041019/massif/hp2ps/CVS/Entries deleted file mode 100644 index f9a2e60c2..000000000 --- a/VEX/head20041019/massif/hp2ps/CVS/Entries +++ /dev/null @@ -1,46 +0,0 @@ -/.cvsignore/1.1/Sun Feb 22 19:34:55 2004// -/AreaBelow.c/1.3/Wed Jun 2 20:43:23 2004// -/AreaBelow.h/1.2/Sun Feb 15 15:38:08 2004// -/AuxFile.c/1.2/Sun Feb 15 15:38:08 2004// -/AuxFile.h/1.2/Sun Feb 15 15:38:08 2004// -/Axes.c/1.2/Sun Feb 15 15:38:08 2004// -/Axes.h/1.2/Sun Feb 15 15:38:08 2004// -/CHANGES/1.1/Sat Feb 14 16:40:02 2004// -/Curves.c/1.3/Wed Jun 2 20:43:23 2004// -/Curves.h/1.2/Sun Feb 15 15:38:08 2004// -/Defines.h/1.2/Sun Feb 15 15:38:08 2004// -/Deviation.c/1.3/Wed Jun 2 20:43:23 2004// -/Deviation.h/1.2/Sun Feb 15 15:38:08 2004// -/Dimensions.c/1.2/Sun Feb 15 15:38:08 2004// -/Dimensions.h/1.2/Sun Feb 15 15:38:08 2004// -/Error.c/1.3/Wed Jun 2 20:43:23 2004// -/Error.h/1.3/Wed Jun 2 20:43:23 2004// -/HpFile.c/1.2/Sun Feb 15 15:38:08 2004// -/HpFile.h/1.2/Sun Feb 15 15:38:08 2004// -/INSTALL/1.1/Sat Feb 14 16:40:02 2004// -/Key.c/1.2/Sun Feb 15 15:38:08 2004// -/Key.h/1.2/Sun Feb 15 15:38:08 2004// -/LICENSE/1.1/Sat Feb 14 16:40:02 2004// -/Main.c/1.2/Sun Feb 15 15:38:08 2004// -/Main.h/1.2/Sun Feb 15 15:38:08 2004// -/Makefile.am/1.5/Wed Sep 1 23:20:49 2004// -/Makefile.old/1.1/Tue Feb 24 23:38:17 2004// -/Marks.c/1.2/Sun Feb 15 15:38:08 2004// -/Marks.h/1.2/Sun Feb 15 15:38:08 2004// -/PsFile.c/1.2/Sun Feb 15 15:38:08 2004// -/PsFile.h/1.2/Sun Feb 15 15:38:08 2004// -/README/1.1/Sat Feb 14 16:40:02 2004// -/Reorder.c/1.2/Sun Feb 15 15:38:08 2004// -/Reorder.h/1.2/Sun Feb 15 15:38:08 2004// -/Scale.c/1.3/Wed Jun 2 20:43:23 2004// -/Scale.h/1.2/Sun Feb 15 15:38:08 2004// -/Shade.c/1.2/Sun Feb 15 15:38:08 2004// -/Shade.h/1.2/Sun Feb 15 15:38:08 2004// -/TopTwenty.c/1.3/Wed Jun 2 20:43:23 2004// -/TopTwenty.h/1.2/Sun Feb 15 15:38:08 2004// -/TraceElement.c/1.3/Wed Jun 2 20:43:24 2004// -/TraceElement.h/1.2/Sun Feb 15 15:38:08 2004// -/Utilities.c/1.4/Wed Jun 2 20:43:24 2004// -/Utilities.h/1.3/Wed Jun 2 20:43:24 2004// -/hp2ps.1/1.1/Sat Feb 14 16:40:02 2004// -D diff --git a/VEX/head20041019/massif/hp2ps/CVS/Repository b/VEX/head20041019/massif/hp2ps/CVS/Repository deleted file mode 100644 index 3db3dee42..000000000 --- a/VEX/head20041019/massif/hp2ps/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/massif/hp2ps diff --git a/VEX/head20041019/massif/hp2ps/CVS/Root b/VEX/head20041019/massif/hp2ps/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/massif/hp2ps/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/massif/hp2ps/CVS/Template b/VEX/head20041019/massif/hp2ps/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/massif/hp2ps/Curves.c b/VEX/head20041019/massif/hp2ps/Curves.c deleted file mode 100644 index 5176ecf8f..000000000 --- a/VEX/head20041019/massif/hp2ps/Curves.c +++ /dev/null @@ -1,169 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Dimensions.h" -#include "HpFile.h" -#include "Shade.h" -#include "Utilities.h" - -/* own stuff */ -#include "Curves.h" - -static floatish *g_x; /* x and y values */ -static floatish *g_y; - -static floatish *g_py; /* previous y values */ - -static void Curve PROTO((struct entry *)); /* forward */ -static void ShadeCurve - PROTO((floatish *x, floatish *y, floatish *py, floatish shade)); - -void -Curves() -{ - intish i; - - for (i = 0; i < nidents; i++) { - Curve(identtable[i]); - } -} - -/* - * Draw a curve, and fill the area that is below it and above - * the previous curve. - */ - -static void -Curve(e) - struct entry* e; -{ - struct chunk* ch; - int j; - - for (ch = e->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - g_y[ ch->d[j].bucket ] += ch->d[j].value; - } - } - - ShadeCurve(g_x, g_y, g_py, ShadeOf(e->name)); -} - - -static void PlotCurveLeftToRight PROTO((floatish *, floatish *)); /* forward */ -static void PlotCurveRightToLeft PROTO((floatish *, floatish *)); /* forward */ - -static void SaveCurve PROTO((floatish *, floatish *)); /* forward */ - -/* - * Map virtual x coord to physical x coord - */ - -floatish -xpage(x) - floatish x; -{ - return (x + graphx0); -} - - - -/* - * Map virtual y coord to physical y coord - */ - -floatish -ypage(y) - floatish y; -{ - return (y + graphy0); -} - - -/* - * Fill the region bounded by two splines, using the given - * shade. - */ - -static void -ShadeCurve(x, y, py, shade) - floatish *x; floatish *y; floatish *py; floatish shade; -{ - fprintf(psfp, "%f %f moveto\n", xpage(x[0]), ypage(py[0])); - PlotCurveLeftToRight(x, py); - - fprintf(psfp, "%f %f lineto\n", xpage(x[nsamples - 1]), - ypage(y[nsamples - 1])); - PlotCurveRightToLeft(x, y); - - fprintf(psfp, "closepath\n"); - - fprintf(psfp, "gsave\n"); - - SetPSColour(shade); - fprintf(psfp, "fill\n"); - - fprintf(psfp, "grestore\n"); - fprintf(psfp, "stroke\n"); - - SaveCurve(y, py); -} - -static void -PlotCurveLeftToRight(x,y) - floatish *x; floatish *y; -{ - intish i; - - for (i = 0; i < nsamples; i++) { - fprintf(psfp, "%f %f lineto\n", xpage(x[i]), ypage(y[i])); - } -} - -static void -PlotCurveRightToLeft(x,y) - floatish *x; floatish *y; -{ - intish i; - - for (i = nsamples - 1; i >= 0; i-- ) { - fprintf(psfp, "%f %f lineto\n", xpage(x[i]), ypage(y[i])); - } -} - -/* - * Save the curve coordinates stored in y[] in py[]. - */ - -static void -SaveCurve(y, py) - floatish *y; floatish* py; -{ - intish i; - - for (i = 0; i < nsamples; i++) { - py[i] = y[i]; - } -} - -extern floatish xrange; - -void -CurvesInit() -{ - intish i; - - g_x = (floatish*) xmalloc(nsamples * sizeof(floatish)); - g_y = (floatish*) xmalloc(nsamples * sizeof(floatish)); - g_py = (floatish*) xmalloc(nsamples * sizeof(floatish)); - - for (i = 0; i < nsamples; i++) { - g_x[i] = ((samplemap[i] - samplemap[0])/ xrange) * graphwidth; - g_y[i] = g_py[i] = 0.0; - } -} diff --git a/VEX/head20041019/massif/hp2ps/Curves.h b/VEX/head20041019/massif/hp2ps/Curves.h deleted file mode 100644 index 7ca720ee3..000000000 --- a/VEX/head20041019/massif/hp2ps/Curves.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef CURVES_H -#define CURVES_H - -void Curves PROTO((void)); -void CurvesInit PROTO((void)); - -floatish xpage PROTO((floatish)); -floatish ypage PROTO((floatish)); - -#endif /* CURVES_H */ diff --git a/VEX/head20041019/massif/hp2ps/Defines.h b/VEX/head20041019/massif/hp2ps/Defines.h deleted file mode 100644 index 4973555eb..000000000 --- a/VEX/head20041019/massif/hp2ps/Defines.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef DEFINES_H -#define DEFINES_H - -/* - * Things that can be altered. - */ - -#define THRESHOLD_PERCENT _thresh_ /* all values below 1% insignificant */ -#define DEFAULT_THRESHOLD 1.0 -extern floatish _thresh_; - -#define TWENTY _twenty_ /* show top 20 bands, grouping excess */ -#define DEFAULT_TWENTY 20 /* this is default and absolute maximum */ -extern int _twenty_; - -#define LARGE_FONT 12 /* Helvetica 12pt */ -#define NORMAL_FONT 10 /* Helvetica 10pt */ - -#define BORDER_HEIGHT 432.0 /* page border box 432pt (6 inches high) */ -#define BORDER_WIDTH 648.0 /* page border box 648pt (9 inches wide) */ -#define BORDER_SPACE 5.0 /* page border space */ -#define BORDER_THICK 0.5 /* page border line thickness 0.5pt */ - - -#define TITLE_HEIGHT 20.0 /* title box is 20pt high */ -#define TITLE_TEXT_FONT LARGE_FONT /* title in large font */ -#define TITLE_TEXT_SPACE 6.0 /* space between title text and box */ - - -#define AXIS_THICK 0.5 /* axis thickness 0.5pt */ -#define AXIS_TEXT_SPACE 6 /* space between axis legends and axis */ -#define AXIS_TEXT_FONT NORMAL_FONT /* axis legends in normal font */ -#define AXIS_Y_TEXT_SPACE 35 /* space for y axis text */ - -#define KEY_BOX_WIDTH 14 /* key boxes are 14pt high */ - -#define SMALL_JOB_STRING_WIDTH 35 /* small title for 35 characters or less */ -#define BIG_JOB_STRING_WIDTH 80 /* big title for everything else */ - -#define GRAPH_X0 (AXIS_Y_TEXT_SPACE + (2 * BORDER_SPACE)) -#define GRAPH_Y0 (AXIS_TEXT_FONT + (2 * BORDER_SPACE)) - - -/* - * Things that should be left well alone. - */ - - - -#define START_X 72 /* start 72pt (1 inch) from left (portrait) */ -#define START_Y 108 /* start 108pt (1.5 inch) from bottom (portrait) */ - -#define NUMBER_LENGTH 32 - -#define N_CHUNK 24 - -#define VERSION "0.25" /* as of 95/03/21 */ - -#define max(x,y) ((x) > (y) ? (x) : (y)) /* not everyone has this */ - -#endif /* DEFINES_H */ diff --git a/VEX/head20041019/massif/hp2ps/Deviation.c b/VEX/head20041019/massif/hp2ps/Deviation.c deleted file mode 100644 index 22a0e9ed4..000000000 --- a/VEX/head20041019/massif/hp2ps/Deviation.c +++ /dev/null @@ -1,143 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "Deviation.h" - -/* - * Reorder the identifiers in the identifier table so that the - * ones whose data points exhibit the mininal standard deviation - * come first. - */ - -void -Deviation() -{ - intish i; - intish j; - floatish dev; - struct chunk* ch; - int min; - floatish t; - struct entry* e; - floatish *averages; - floatish *deviations; - - averages = (floatish*) xmalloc(nidents * sizeof(floatish)); - deviations = (floatish*) xmalloc(nidents * sizeof(floatish)); - - /* find averages */ - - for (i = 0; i < nidents; i++) { - averages[i] = 0.0; - } - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - averages[i] += ch->d[j].value; - } - } - } - - for (i = 0; i < nidents; i++) { - averages[i] /= (floatish) nsamples; - } - - /* calculate standard deviation */ - - for (i = 0; i < nidents; i++) { - deviations[i] = 0.0; - } - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - dev = ch->d[j].value - averages[i]; - deviations[i] += dev * dev; - } - } - } - - for (i = 0; i < nidents; i++) { - deviations[i] = (floatish) sqrt ((doublish) (deviations[i] / - (floatish) (nsamples - 1))); - } - - - /* sort on basis of standard deviation */ - - for (i = 0; i < nidents-1; i++) { - min = i; - for (j = i+1; j < nidents; j++) { - if (deviations[ j ] < deviations[min]) { - min = j; - } - } - - t = deviations[min]; - deviations[min] = deviations[i]; - deviations[i] = t; - - e = identtable[min]; - identtable[min] = identtable[i]; - identtable[i] = e; - } - - free(averages); - free(deviations); -} - -void -Identorder(iflag) - int iflag; /* a funny three-way flag ? WDP 95/03 */ -{ - int i; - int j; - int min; - struct entry* e; - - /* sort on basis of ident string */ - if (iflag > 0) { - /* greatest at top i.e. smallest at start */ - - for (i = 0; i < nidents-1; i++) { - min = i; - for (j = i+1; j < nidents; j++) { - if (strcmp(identtable[j]->name, identtable[min]->name) < 0) { - min = j; - } - } - - e = identtable[min]; - identtable[min] = identtable[i]; - identtable[i] = e; - } - } else { - /* smallest at top i.e. greatest at start */ - - for (i = 0; i < nidents-1; i++) { - min = i; - for (j = i+1; j < nidents; j++) { - if (strcmp(identtable[j]->name, identtable[min]->name) > 0) { - min = j; - } - } - - e = identtable[min]; - identtable[min] = identtable[i]; - identtable[i] = e; - } - } -} diff --git a/VEX/head20041019/massif/hp2ps/Deviation.h b/VEX/head20041019/massif/hp2ps/Deviation.h deleted file mode 100644 index 1fe50adbc..000000000 --- a/VEX/head20041019/massif/hp2ps/Deviation.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef DEVIATION_H -#define DEVIATION_H - -void Deviation PROTO((void)); -void Identorder PROTO((int)); - -#endif /* DEVIATION_H */ diff --git a/VEX/head20041019/massif/hp2ps/Dimensions.c b/VEX/head20041019/massif/hp2ps/Dimensions.c deleted file mode 100644 index e3ebe00a7..000000000 --- a/VEX/head20041019/massif/hp2ps/Dimensions.c +++ /dev/null @@ -1,207 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "HpFile.h" -#include "Scale.h" - -/* own stuff */ -#include "Dimensions.h" - -/* - * Get page and other dimensions before printing. - */ - -floatish borderheight = BORDER_HEIGHT; -floatish borderwidth = BORDER_WIDTH; -floatish borderspace = BORDER_SPACE; -floatish borderthick = BORDER_THICK; - -floatish titlewidth = (BORDER_WIDTH - (2 * BORDER_SPACE)); -floatish titletextspace = TITLE_TEXT_SPACE; -floatish titleheight; - -floatish graphx0 = GRAPH_X0; -floatish graphy0 = GRAPH_Y0; - -floatish graphheight; -floatish graphwidth; - -static floatish KeyWidth PROTO((void)); /* forward */ - -void -Dimensions() -{ - xrange = samplemap[nsamples - 1] - samplemap[0]; - xrange = max(xrange, auxxrange); - if (xrange == 0.0) xrange = 1.0; /* avoid division by 0.0 */ - - yrange = MaxCombinedHeight(); - yrange = max(yrange, auxyrange); - if (yrange == 0.0) yrange = 1.0; /* avoid division by 0.0 */ - - if (!bflag && !sflag) { - bflag = strlen(jobstring) > SMALL_JOB_STRING_WIDTH; - } - - if (bflag) { - titleheight = 2 * TITLE_HEIGHT; - } else { - titleheight = TITLE_HEIGHT; - } - - graphwidth = titlewidth - graphx0 - (TWENTY ? KeyWidth() : 0); - graphheight = borderheight - titleheight - (2 * borderspace) - graphy0; -} - -/* - * Calculate the width of the key. - */ - -static floatish -KeyWidth() -{ - intish i; - floatish c; - - c = 0.0; - - for (i = 0; i < nidents; i++) { - c = max(c, StringSize(identtable[i]->name)); - } - - c += 3.0 * borderspace; - - c += (floatish) KEY_BOX_WIDTH; - - return c; -} - - -/* - * A desperately grim solution. - */ - - -floatish fonttab[] = { - /* 20 (' ') = */ 3.0, - /* 21 ('!') = */ 1.0, - /* 22 ('"') = */ 1.0, - /* 23 ('#') = */ 3.0, - /* 24 ('$') = */ 3.0, - /* 25 ('%') = */ 3.0, - /* 26 ('&') = */ 3.0, - /* 27 (''') = */ 1.0, - /* 28 ('(') = */ 3.0, - /* 29 (')') = */ 3.0, - /* 2a ('*') = */ 2.0, - /* 2b ('+') = */ 3.0, - /* 2c (',') = */ 1.0, - /* 2d ('-') = */ 3.0, - /* 2e ('.') = */ 1.0, - /* 2f ('/') = */ 3.0, - /* 30 ('0') = */ 4.0, - /* 31 ('1') = */ 4.0, - /* 32 ('2') = */ 4.0, - /* 33 ('3') = */ 4.0, - /* 34 ('4') = */ 4.0, - /* 35 ('5') = */ 4.0, - /* 36 ('6') = */ 4.0, - /* 37 ('7') = */ 4.0, - /* 38 ('8') = */ 4.0, - /* 39 ('9') = */ 4.0, - /* 3a (':') = */ 1.0, - /* 3b (';') = */ 1.0, - /* 3c ('<') = */ 3.0, - /* 3d ('=') = */ 3.0, - /* 3e ('>') = */ 3.0, - /* 3f ('?') = */ 2.0, - /* 40 ('@') = */ 3.0, - /* 41 ('A') = */ 5.0, - /* 42 ('B') = */ 5.0, - /* 43 ('C') = */ 5.0, - /* 44 ('D') = */ 5.0, - /* 45 ('E') = */ 5.0, - /* 46 ('F') = */ 5.0, - /* 47 ('G') = */ 5.0, - /* 48 ('H') = */ 5.0, - /* 49 ('I') = */ 1.0, - /* 4a ('J') = */ 5.0, - /* 4b ('K') = */ 5.0, - /* 4c ('L') = */ 5.0, - /* 4d ('M') = */ 5.0, - /* 4e ('N') = */ 5.0, - /* 4f ('O') = */ 5.0, - /* 50 ('P') = */ 5.0, - /* 51 ('Q') = */ 5.0, - /* 52 ('R') = */ 5.0, - /* 53 ('S') = */ 5.0, - /* 54 ('T') = */ 5.0, - /* 55 ('U') = */ 5.0, - /* 56 ('V') = */ 5.0, - /* 57 ('W') = */ 5.0, - /* 58 ('X') = */ 5.0, - /* 59 ('Y') = */ 5.0, - /* 5a ('Z') = */ 5.0, - /* 5b ('[') = */ 2.0, - /* 5c ('\') = */ 3.0, - /* 5d (']') = */ 2.0, - /* 5e ('^') = */ 1.0, - /* 5f ('_') = */ 3.0, - /* 60 ('`') = */ 1.0, - /* 61 ('a') = */ 3.0, - /* 62 ('b') = */ 3.0, - /* 63 ('c') = */ 3.0, - /* 64 ('d') = */ 3.0, - /* 65 ('e') = */ 3.0, - /* 66 ('f') = */ 3.0, - /* 67 ('g') = */ 3.0, - /* 68 ('h') = */ 3.0, - /* 69 ('i') = */ 1.0, - /* 6a ('j') = */ 2.0, - /* 6b ('k') = */ 3.0, - /* 6c ('l') = */ 1.0, - /* 6d ('m') = */ 5.0, - /* 6e ('n') = */ 3.0, - /* 6f ('o') = */ 3.0, - /* 70 ('p') = */ 3.0, - /* 71 ('q') = */ 3.0, - /* 72 ('r') = */ 2.0, - /* 73 ('s') = */ 3.0, - /* 74 ('t') = */ 2.0, - /* 75 ('u') = */ 3.0, - /* 76 ('v') = */ 3.0, - /* 77 ('w') = */ 3.0, - /* 78 ('x') = */ 3.0, - /* 79 ('y') = */ 3.0, - /* 7a ('z') = */ 3.0, - /* 7b ('{') = */ 2.0, - /* 7c ('|') = */ 1.0, - /* 7d ('}') = */ 2.0, - /* 7e ('~') = */ 2.0 -}; - - -/* - * What size is a string (in points)? - */ - -#define FUDGE (2.834646 * 0.6) - -floatish -StringSize(s) - char* s; -{ - floatish r; - - for (r = 0.0; *s; s++) { - r += fonttab[(*s) - 0x20]; - } - - return r * FUDGE; -} diff --git a/VEX/head20041019/massif/hp2ps/Dimensions.h b/VEX/head20041019/massif/hp2ps/Dimensions.h deleted file mode 100644 index 3ce5ab59e..000000000 --- a/VEX/head20041019/massif/hp2ps/Dimensions.h +++ /dev/null @@ -1,26 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef DIMENSIONS_H -#define DIMENSIONS_H - -extern floatish borderheight; -extern floatish borderwidth; -extern floatish borderspace; -extern floatish borderthick; - -extern floatish titleheight; -extern floatish titlewidth; -extern floatish titletextspace; - -extern floatish graphx0; -extern floatish graphy0; - -extern floatish graphheight; -extern floatish graphwidth; - -void Dimensions PROTO((void)); -floatish StringSize PROTO((char *)); - -#endif /* DIMENSIONS_H */ diff --git a/VEX/head20041019/massif/hp2ps/Error.c b/VEX/head20041019/massif/hp2ps/Error.c deleted file mode 100644 index 2ecba3da6..000000000 --- a/VEX/head20041019/massif/hp2ps/Error.c +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" - -/* own stuff */ -#include "Error.h" - -/*VARARGS0*/ -void -Error(const char *fmt, ...) -{ - va_list ap; - fflush(stdout); - fprintf(stderr, "%s: ", programname); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - exit(1); -} - -/*VARARGS0*/ -void -Disaster(const char *fmt, ...) -{ - va_list ap; - fflush(stdout); - fprintf(stderr, "%s: ", programname); - fprintf(stderr, " Disaster! ("); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, ")\n"); - exit(1); -} - -void -Usage(str) - const char *str; -{ - if (str) printf("error: %s\n", str); - printf("usage: %s -b -d -ef -g -i -p -mn -p -s -tf -y [file[.hp]]\n", programname); - printf("where -b use large title box\n"); - printf(" -d sort by standard deviation\n"); - printf(" -ef[in|mm|pt] produce Encapsulated PostScript f units wide (f > 2 inches)\n"); - printf(" -g produce output suitable for GHOSTSCRIPT previever\n"); - printf(" -i[+|-] sort by identifier string (-i+ gives greatest on top) \n"); - printf(" -mn print maximum of n bands (default & max 20)\n"); - printf(" -m0 removes the band limit altogether\n"); - printf(" -p use previous scaling, shading and ordering\n"); - printf(" -s use small title box\n"); - printf(" -tf ignore trace bands which sum below f%% (default 1%%, max 5%%)\n"); - printf(" -y traditional\n"); - printf(" -c colour ouput\n"); - exit(0); -} - diff --git a/VEX/head20041019/massif/hp2ps/Error.h b/VEX/head20041019/massif/hp2ps/Error.h deleted file mode 100644 index d38518d69..000000000 --- a/VEX/head20041019/massif/hp2ps/Error.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef ERROR_H -#define ERROR_H - -extern void Error PROTO((const char *, ...)); -extern void Disaster PROTO((const char *, ...)); -extern void Usage PROTO((const char *)); - -#endif /* ERROR_H */ diff --git a/VEX/head20041019/massif/hp2ps/HpFile.c b/VEX/head20041019/massif/hp2ps/HpFile.c deleted file mode 100644 index 26832af9e..000000000 --- a/VEX/head20041019/massif/hp2ps/HpFile.c +++ /dev/null @@ -1,591 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -#ifndef atof -double atof PROTO((const char *)); -#endif - -/* own stuff already included */ - -#define N_MARKS 50 /* start size of the mark table */ -#define N_SAMPLES 500 /* start size of the sample table */ - -char *theident; -char *thestring; -int theinteger; -floatish thefloatish; -int g_ch; /* last character read */ -token thetok; /* last token */ -int linenum; /* current line number */ -int endfile; /* true at end of file */ - -static boolish gotjob = 0; /* "JOB" read */ -static boolish gotdate = 0; /* "DATE" read */ -static boolish gotvalueunit = 0; /* "VALUE_UNIT" read */ -static boolish gotsampleunit = 0; /* "SAMPLE_UNIT" read */ -static boolish insample = 0; /* true when in sample */ - -static floatish lastsample; /* the last sample time */ - -static void GetHpLine PROTO((FILE *)); /* forward */ -static void GetHpTok PROTO((FILE *)); /* forward */ - -static struct entry *GetEntry PROTO((char *)); /* forward */ - -static void MakeIdentTable PROTO((void)); /* forward */ - -char *jobstring; -char *datestring; - -char *sampleunitstring; -char *valueunitstring; - -floatish *samplemap; /* sample intervals */ -floatish *markmap; /* sample marks */ - -/* - * An extremely simple parser. The input is organised into lines of - * the form - * - * JOB s -- job identifier string - * DATE s -- date string - * SAMPLE_UNIT s -- sample unit eg "seconds" - * VALUE_UNIT s -- value unit eg "bytes" - * MARK i -- sample mark - * BEGIN_SAMPLE i -- start of ith sample - * identifier i -- there are i identifiers in this sample - * END_SAMPLE i -- end of ith sample - * - */ - -void -GetHpFile(infp) - FILE *infp; -{ - nsamples = 0; - nmarks = 0; - nidents = 0; - - g_ch = ' '; - endfile = 0; - linenum = 1; - lastsample = 0.0; - - GetHpTok(infp); - - while (endfile == 0) { - GetHpLine(infp); - } - - if (!gotjob) { - Error("%s: JOB missing", hpfile); - } - - if (!gotdate) { - Error("%s: DATE missing", hpfile); - } - - if (!gotvalueunit) { - Error("%s: VALUE_UNIT missing", hpfile); - } - - if (!gotsampleunit) { - Error("%s: SAMPLE_UNIT missing", hpfile); - } - - if (nsamples == 0) { - Error("%s: contains no samples", hpfile); - } - - - MakeIdentTable(); - - fclose(hpfp); -} - - -/* - * Read the next line from the input, check the syntax, and perform - * the appropriate action. - */ - -static void -GetHpLine(infp) - FILE* infp; -{ - static intish nmarkmax = 0, nsamplemax = 0; - - switch (thetok) { - case JOB_TOK: - GetHpTok(infp); - if (thetok != STRING_TOK) { - Error("%s, line %d: string must follow JOB", hpfile, linenum); - } - jobstring = thestring; - gotjob = 1; - GetHpTok(infp); - break; - - case DATE_TOK: - GetHpTok(infp); - if (thetok != STRING_TOK) { - Error("%s, line %d: string must follow DATE", hpfile, linenum); - } - datestring = thestring; - gotdate = 1; - GetHpTok(infp); - break; - - case SAMPLE_UNIT_TOK: - GetHpTok(infp); - if (thetok != STRING_TOK) { - Error("%s, line %d: string must follow SAMPLE_UNIT", hpfile, - linenum); - } - sampleunitstring = thestring; - gotsampleunit = 1; - GetHpTok(infp); - break; - - case VALUE_UNIT_TOK: - GetHpTok(infp); - if (thetok != STRING_TOK) { - Error("%s, line %d: string must follow VALUE_UNIT", hpfile, - linenum); - } - valueunitstring = thestring; - gotvalueunit = 1; - GetHpTok(infp); - break; - - case MARK_TOK: - GetHpTok(infp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d, floating point number must follow MARK", - hpfile, linenum); - } - if (insample) { - Error("%s, line %d, MARK occurs within sample", hpfile, linenum); - } - if (nmarks >= nmarkmax) { - if (!markmap) { - nmarkmax = N_MARKS; - markmap = (floatish*) xmalloc(nmarkmax * sizeof(floatish)); - } else { - nmarkmax *= 2; - markmap = (floatish*) xrealloc(markmap, nmarkmax * sizeof(floatish)); - } - } - markmap[ nmarks++ ] = thefloatish; - GetHpTok(infp); - break; - - case BEGIN_SAMPLE_TOK: - insample = 1; - GetHpTok(infp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d, floating point number must follow BEGIN_SAMPLE", hpfile, linenum); - } - if (thefloatish < lastsample) { - Error("%s, line %d, samples out of sequence", hpfile, linenum); - } else { - lastsample = thefloatish; - } - if (nsamples >= nsamplemax) { - if (!samplemap) { - nsamplemax = N_SAMPLES; - samplemap = (floatish*) xmalloc(nsamplemax * sizeof(floatish)); - } else { - nsamplemax *= 2; - samplemap = (floatish*) xrealloc(samplemap, - nsamplemax * sizeof(floatish)); - } - } - samplemap[ nsamples ] = thefloatish; - GetHpTok(infp); - break; - - case END_SAMPLE_TOK: - insample = 0; - GetHpTok(infp); - if (thetok != FLOAT_TOK) { - Error("%s, line %d: floating point number must follow END_SAMPLE", - hpfile, linenum); - } - nsamples++; - GetHpTok(infp); - break; - - case IDENTIFIER_TOK: - GetHpTok(infp); - if (thetok != INTEGER_TOK) { - Error("%s, line %d: integer must follow identifier", hpfile, - linenum); - } - StoreSample(GetEntry(theident), nsamples, (floatish) theinteger); - GetHpTok(infp); - break; - - case EOF_TOK: - endfile = 1; - break; - - default: - Error("%s, line %d: %s unexpected", hpfile, linenum, - TokenToString(thetok)); - break; - } -} - - -char * -TokenToString(t) - token t; -{ - switch (t) { - case EOF_TOK: return "EOF"; - case INTEGER_TOK: return "integer"; - case FLOAT_TOK: return "floating point number"; - case IDENTIFIER_TOK: return "identifier"; - case STRING_TOK: return "string"; - case BEGIN_SAMPLE_TOK: return "BEGIN_SAMPLE"; - case END_SAMPLE_TOK: return "END_SAMPLE"; - case JOB_TOK: return "JOB"; - case DATE_TOK: return "DATE"; - case SAMPLE_UNIT_TOK: return "SAMPLE_UNIT"; - case VALUE_UNIT_TOK: return "VALUE_UNIT"; - case MARK_TOK: return "MARK"; - - case X_RANGE_TOK: return "X_RANGE"; - case Y_RANGE_TOK: return "Y_RANGE"; - case ORDER_TOK: return "ORDER"; - case SHADE_TOK: return "SHADE"; - default: return "(strange token)"; - } -} - -/* - * Read the next token from the input and assign its value - * to the global variable "thetok". In the case of numbers, - * the corresponding value is also assigned to "theinteger" - * or "thefloatish" as appropriate; in the case of identifiers - * it is assigned to "theident". - */ - -static void -GetHpTok(infp) - FILE* infp; -{ - - while (isspace(g_ch)) { /* skip whitespace */ - if (g_ch == '\n') linenum++; - g_ch = getc(infp); - } - - if (g_ch == EOF) { - thetok = EOF_TOK; - return; - } - - if (isdigit(g_ch)) { - thetok = GetNumber(infp); - return; - } else if (g_ch == '\"') { - GetString(infp); - thetok = STRING_TOK; - return; - } else if (IsIdChar(g_ch)) { - ASSERT(! (isdigit(g_ch))); /* g_ch can't be a digit here */ - GetIdent(infp); - if (!isupper(theident[0])) { - thetok = IDENTIFIER_TOK; - } else if (strcmp(theident, "BEGIN_SAMPLE") == 0) { - thetok = BEGIN_SAMPLE_TOK; - } else if (strcmp(theident, "END_SAMPLE") == 0) { - thetok = END_SAMPLE_TOK; - } else if (strcmp(theident, "JOB") == 0) { - thetok = JOB_TOK; - } else if (strcmp(theident, "DATE") == 0) { - thetok = DATE_TOK; - } else if (strcmp(theident, "SAMPLE_UNIT") == 0) { - thetok = SAMPLE_UNIT_TOK; - } else if (strcmp(theident, "VALUE_UNIT") == 0) { - thetok = VALUE_UNIT_TOK; - } else if (strcmp(theident, "MARK") == 0) { - thetok = MARK_TOK; - } else { - thetok = IDENTIFIER_TOK; - } - return; - } else { - Error("%s, line %d: strange character (%c)", hpfile, linenum, g_ch); - } -} - - -/* - * Read a sequence of digits and convert the result to an integer - * or floating point value (assigned to the "theinteger" or - * "thefloatish"). - */ - -static char numberstring[ NUMBER_LENGTH - 1 ]; - -token -GetNumber(infp) - FILE* infp; -{ - int i; - int containsdot; - - ASSERT(isdigit(ch)); /* we must have a digit to start with */ - - containsdot = 0; - - for (i = 0; i < NUMBER_LENGTH && (isdigit(g_ch) || g_ch == '.'); i++) { - numberstring[ i ] = g_ch; - containsdot |= (g_ch == '.'); - g_ch = getc(infp); - } - - ASSERT(i < NUMBER_LENGTH); /* did not overflow */ - - numberstring[ i ] = '\0'; - - if (containsdot) { - thefloatish = (floatish) atof(numberstring); - return FLOAT_TOK; - } else { - theinteger = atoi(numberstring); - return INTEGER_TOK; - } -} - -/* - * Read a sequence of identifier characters and assign the result - * to the string "theident". - */ - -void -GetIdent(infp) - FILE *infp; -{ - unsigned int i; - char idbuffer[5000]; - - for (i = 0; i < (sizeof idbuffer)-1 && IsIdChar(g_ch); i++) { - idbuffer[ i ] = g_ch; - g_ch = getc(infp); - } - - idbuffer[ i ] = '\0'; - - if (theident) - free(theident); - - theident = copystring(idbuffer); -} - - -/* - * Read a sequence of characters that make up a string and - * assign the result to "thestring". - */ - -void -GetString(infp) - FILE *infp; -{ - unsigned int i; - char stringbuffer[5000]; - - ASSERT(ch == '\"'); - - g_ch = getc(infp); /* skip the '\"' that begins the string */ - - for (i = 0; i < (sizeof stringbuffer)-1 && g_ch != '\"'; i++) { - stringbuffer[ i ] = g_ch; - g_ch = getc(infp); - } - - stringbuffer[i] = '\0'; - thestring = copystring(stringbuffer); - - ASSERT(g_ch == '\"'); - - g_ch = getc(infp); /* skip the '\"' that terminates the string */ -} - -boolish -IsIdChar(ch) - int ch; -{ - return (!isspace(ch)); -} - - -/* - * The information associated with each identifier is stored - * in a linked list of chunks. The table below allows the list - * of chunks to be retrieved given an identifier name. - */ - -#define N_HASH 513 - -static struct entry* hashtable[ N_HASH ]; - -static intish -Hash(s) - char *s; -{ - int r; - - for (r = 0; *s; s++) { - r = r + r + r + *s; - } - - if (r < 0) r = -r; - - return r % N_HASH; -} - -/* - * Get space for a new chunk. Initialise it, and return a pointer - * to the new chunk. - */ - -static struct chunk* -MakeChunk() -{ - struct chunk* ch; - struct datapoint* d; - - ch = (struct chunk*) xmalloc( sizeof(struct chunk) ); - - d = (struct datapoint*) xmalloc (sizeof(struct datapoint) * N_CHUNK); - - ch->nd = 0; - ch->d = d; - ch->next = 0; - return ch; -} - - -/* - * Get space for a new entry. Initialise it, and return a pointer - * to the new entry. - */ - -struct entry * -MakeEntry(name) - char *name; -{ - struct entry* e; - - e = (struct entry *) xmalloc(sizeof(struct entry)); - e->chk = MakeChunk(); - e->name = copystring(name); - return e; -} - -/* - * Get the entry associated with "name", creating a new entry if - * necessary. - */ - -static struct entry * -GetEntry(name) - char* name; -{ - intish h; - struct entry* e; - - h = Hash(name); - - for (e = hashtable[ h ]; e; e = e->next) { - if (strcmp(e->name, name) == 0) { - break; - } - } - - if (e) { - return (e); - } else { - nidents++; - e = MakeEntry(name); - e->next = hashtable[ h ]; - hashtable[ h ] = e; - return (e); - } -} - - -/* - * Store information from a sample. - */ - -void -StoreSample(en, bucket, value) - struct entry* en; intish bucket; floatish value; -{ - struct chunk* chk; - - for (chk = en->chk; chk->next != 0; chk = chk->next) - ; - - if (chk->nd < N_CHUNK) { - chk->d[ chk->nd ].bucket = bucket; - chk->d[ chk->nd ].value = value; - chk->nd += 1; - } else { - struct chunk* t; - t = chk->next = MakeChunk(); - t->d[ 0 ].bucket = bucket; - t->d[ 0 ].value = value; - t->nd += 1; - } -} - - -struct entry** identtable; - -/* - * The hash table is useful while reading the input, but it - * becomes a liability thereafter. The code below converts - * it to a more easily processed table. - */ - -static void -MakeIdentTable() -{ - intish i; - intish j; - struct entry* e; - - nidents = 0; - for (i = 0; i < N_HASH; i++) { - for (e = hashtable[ i ]; e; e = e->next) { - nidents++; - } - } - - identtable = (struct entry**) xmalloc(nidents * sizeof(struct entry*)); - j = 0; - - for (i = 0; i < N_HASH; i++) { - for (e = hashtable[ i ]; e; e = e->next, j++) { - identtable[ j ] = e; - } - } -} diff --git a/VEX/head20041019/massif/hp2ps/HpFile.h b/VEX/head20041019/massif/hp2ps/HpFile.h deleted file mode 100644 index 7a23dfeb4..000000000 --- a/VEX/head20041019/massif/hp2ps/HpFile.h +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef HP_FILE_H -#define HP_FILE_H - -typedef enum { - /* These tokens are found in ".hp" files */ - - EOF_TOK, - INTEGER_TOK, - FLOAT_TOK, - IDENTIFIER_TOK, - STRING_TOK, - BEGIN_SAMPLE_TOK, - END_SAMPLE_TOK, - JOB_TOK, - DATE_TOK, - SAMPLE_UNIT_TOK, - VALUE_UNIT_TOK, - MARK_TOK, - - /* These extra ones are found only in ".aux" files */ - - X_RANGE_TOK, - Y_RANGE_TOK, - ORDER_TOK, - SHADE_TOK -} token; - -struct datapoint { - int bucket; - floatish value; -}; - -struct chunk { - struct chunk *next; - short nd; /* 0 .. N_CHUNK - 1 */ - struct datapoint *d; -}; - - -struct entry { - struct entry *next; - struct chunk *chk; - char *name; -}; - -extern char *theident; -extern char *thestring; -extern int theinteger; -extern floatish thefloatish; -extern int g_ch; -extern token thetok; -extern int linenum; -extern int endfile; - -char *TokenToString PROTO((token)); - -extern struct entry** identtable; - -extern floatish *samplemap; -extern floatish *markmap; - -void GetHpFile PROTO((FILE *)); -void StoreSample PROTO((struct entry *, intish, floatish)); -struct entry *MakeEntry PROTO((char *)); - -token GetNumber PROTO((FILE *)); -void GetIdent PROTO((FILE *)); -void GetString PROTO((FILE *)); -boolish IsIdChar PROTO((int)); /* int is a "char" from getc */ - -extern char *jobstring; -extern char *datestring; - -extern char *sampleunitstring; -extern char *valueunitstring; - -#endif /* HP_FILE_H */ diff --git a/VEX/head20041019/massif/hp2ps/INSTALL b/VEX/head20041019/massif/hp2ps/INSTALL deleted file mode 100644 index 92fe7b77d..000000000 --- a/VEX/head20041019/massif/hp2ps/INSTALL +++ /dev/null @@ -1,17 +0,0 @@ -NOTE: these are instructions for installing hp2ps separately. If you only want -to use it with the Valgrind tool, Massif, it should be installed automatically. - -The original Makefile, for which the below instructions apply, is kept as -Makefile.old. - ------------------------------------------------------------------------------ -For binary distribution: - - - just copy "hp2ps" into an appropriate directory. - -For source distribution: - - - edit "Makefile" and set the $DSTBIN to the directory you wish to install - hp2ps in - - - do "make install" diff --git a/VEX/head20041019/massif/hp2ps/Key.c b/VEX/head20041019/massif/hp2ps/Key.c deleted file mode 100644 index d611552b8..000000000 --- a/VEX/head20041019/massif/hp2ps/Key.c +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Dimensions.h" -#include "HpFile.h" -#include "Shade.h" - -/* own stuff */ -#include "Key.h" - -static void KeyEntry PROTO((floatish, char *, floatish)); - -void Key() -{ - intish i; - floatish c; - floatish dc; - - for (i = 0; i < nidents; i++) /* count identifiers */ - ; - - c = graphy0; - dc = graphheight / (floatish) (i + 1); - - for (i = 0; i < nidents; i++) { - c += dc; - KeyEntry(c, identtable[i]->name, ShadeOf(identtable[i]->name)); - } -} - - - -static void -KeyEntry(centreline, name, colour) - floatish centreline; char* name; floatish colour; -{ - floatish namebase; - floatish keyboxbase; - floatish kstart; - - namebase = centreline - (floatish) (NORMAL_FONT / 2); - keyboxbase = centreline - ((floatish) KEY_BOX_WIDTH / 2.0); - - kstart = graphx0 + graphwidth; - - fprintf(psfp, "%f %f moveto\n", kstart + borderspace, keyboxbase); - fprintf(psfp, "0 %d rlineto\n", KEY_BOX_WIDTH); - fprintf(psfp, "%d 0 rlineto\n", KEY_BOX_WIDTH); - fprintf(psfp, "0 %d rlineto\n", -KEY_BOX_WIDTH); - fprintf(psfp, "closepath\n"); - - fprintf(psfp, "gsave\n"); - SetPSColour(colour); - fprintf(psfp, "fill\n"); - fprintf(psfp, "grestore\n"); - fprintf(psfp, "stroke\n"); - - fprintf(psfp, "HE%d setfont\n", NORMAL_FONT); - fprintf(psfp, "%f %f moveto\n", kstart + (floatish) KEY_BOX_WIDTH + 2 * borderspace, namebase); - - fprintf(psfp, "(%s) show\n", name); -} diff --git a/VEX/head20041019/massif/hp2ps/Key.h b/VEX/head20041019/massif/hp2ps/Key.h deleted file mode 100644 index b573ea081..000000000 --- a/VEX/head20041019/massif/hp2ps/Key.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef KEY_H -#define KEY_H - -void Key PROTO((void)); - -#endif /* KEY_H */ diff --git a/VEX/head20041019/massif/hp2ps/LICENSE b/VEX/head20041019/massif/hp2ps/LICENSE deleted file mode 100644 index b5059b71f..000000000 --- a/VEX/head20041019/massif/hp2ps/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -The Glasgow Haskell Compiler License - -Copyright 2002, The University Court of the University of Glasgow. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -- Neither name of the University nor the names of its contributors may be -used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF -GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. diff --git a/VEX/head20041019/massif/hp2ps/Main.c b/VEX/head20041019/massif/hp2ps/Main.c deleted file mode 100644 index 86621a92f..000000000 --- a/VEX/head20041019/massif/hp2ps/Main.c +++ /dev/null @@ -1,257 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "AuxFile.h" -#include "AreaBelow.h" -#include "Dimensions.h" -#include "HpFile.h" -#include "PsFile.h" -#include "Reorder.h" -#include "Scale.h" -#include "TopTwenty.h" -#include "TraceElement.h" -#include "Deviation.h" -#include "Error.h" -#include "Utilities.h" - -boolish pflag = 0; /* read auxiliary file */ -boolish eflag = 0; /* scaled EPSF */ -boolish dflag = 0; /* sort by standard deviation */ -int iflag = 0; /* sort by identifier (3-way flag) */ -boolish gflag = 0; /* output suitable for previewer */ -boolish yflag = 0; /* ignore marks */ -boolish bflag = 0; /* use a big title box */ -boolish sflag = 0; /* use a small title box */ -int mflag = 0; /* max no. of bands displayed (default 20) */ -boolish tflag = 0; /* ignored threshold specified */ -boolish cflag = 0; /* colour output */ - -boolish filter; /* true when running as a filter */ - -static floatish WidthInPoints PROTO((char *)); /* forward */ -static FILE *Fp PROTO((char *, char **, char *, char *)); /* forward */ - -char *hpfile; -char *psfile; -char *auxfile; - -char *programname; - -static char *pathName; -static char *baseName; /* "basename" is a std C library name (sigh) */ - -FILE* hpfp; -FILE* psfp; -FILE* auxfp; - -floatish xrange = 0.0; -floatish yrange = 0.0; - -floatish auxxrange = 0.0; -floatish auxyrange = 0.0; - -floatish epsfwidth; -floatish areabelow; - -intish nsamples; -intish nmarks; -intish nidents; - -floatish THRESHOLD_PERCENT = DEFAULT_THRESHOLD; -int TWENTY = DEFAULT_TWENTY; - -int main(argc, argv) -int argc; -char* argv[]; -{ - - programname = copystring(Basename(argv[0])); - - argc--, argv++; - while (argc && argv[0][0] == '-') { - while (*++*argv) - switch(**argv) { - case 'p': - pflag++; - break; - case 'e': - eflag++; - epsfwidth = WidthInPoints(*argv + 1); - goto nextarg; - case 'd': - dflag++; - goto nextarg; - case 'i': - switch( *(*argv + 1) ) { - case '-': - iflag = -1; - case '+': - default: - iflag = 1; - } - goto nextarg; - case 'g': - gflag++; - goto nextarg; - case 'y': - yflag++; - goto nextarg; - case 'b': - bflag++; - goto nextarg; - case 's': - sflag++; - goto nextarg; - case 'm': - mflag++; - TWENTY = atoi(*argv + 1); - if (TWENTY > DEFAULT_TWENTY) - Usage(*argv-1); - goto nextarg; - case 't': - tflag++; - THRESHOLD_PERCENT = (floatish) atof(*argv + 1); - if (THRESHOLD_PERCENT < 0 || THRESHOLD_PERCENT > 5) - Usage(*argv-1); - goto nextarg; - case 'c': - cflag++; - goto nextarg; - case '?': - default: - Usage(*argv-1); - } -nextarg: ; - argc--, argv++; - } - - hpfile = "stdin"; - psfile = "stdout"; - - hpfp = stdin; - psfp = stdout; - - filter = argc < 1; - - - - if (!filter) { - pathName = copystring(argv[0]); - DropSuffix(pathName, ".hp"); - baseName = copystring(Basename(pathName)); - - hpfp = Fp(pathName, &hpfile, ".hp", "r"); - psfp = Fp(baseName, &psfile, ".ps", "w"); - - if (pflag) auxfp = Fp(baseName, &auxfile, ".aux", "r"); - } - - GetHpFile(hpfp); - - if (!filter && pflag) GetAuxFile(auxfp); - - - TraceElement(); /* Orders on total, Removes trace elements (tflag) */ - - if (dflag) Deviation(); /* ReOrders on deviation */ - - if (iflag) Identorder(iflag); /* ReOrders on identifier */ - - if (pflag) Reorder(); /* ReOrders on aux file */ - - if (TWENTY) TopTwenty(); /* Selects top twenty (mflag) */ - - Dimensions(); - - areabelow = AreaBelow(); - - Scale(); - - PutPsFile(); - - if (!filter) { - auxfp = Fp(baseName, &auxfile, ".aux", "w"); - PutAuxFile(auxfp); - } - - return(0); -} - - - -typedef enum {POINTS, INCHES, MILLIMETRES} pim; - -static pim Units PROTO((char *)); /* forward */ - -static floatish -WidthInPoints(wstr) - char *wstr; -{ - floatish result; - - result = (floatish) atof(wstr); - - switch (Units(wstr)) { - case INCHES: - result *= 72.0; - break; - case MILLIMETRES: - result *= 2.834646; - break; - case POINTS: - default: ; - } - - if (result <= 144) /* Minimum of 2in wide ! */ - Usage(wstr); - - return result; -} - - -static pim -Units(wstr) - char* wstr; -{ -int i; - - i = strlen(wstr) - 2; - - if (wstr[i] == 'p' && wstr[i+1] == 't') { - return POINTS; - } else if (wstr[i] == 'i' && wstr[i+1] == 'n') { - return INCHES; - } else if (wstr[i] == 'm' && wstr[i+1] == 'm') { - return MILLIMETRES; - } else { - return POINTS; - } -} - -static FILE * -Fp(rootname, filename, suffix, mode) - char* rootname; char** filename; char* suffix; char* mode; -{ - *filename = copystring2(rootname, suffix); - - return(OpenFile(*filename, mode)); -} - -#ifdef DEBUG -void -_stgAssert (filename, linenum) - char *filename; - unsigned int linenum; -{ - fflush(stdout); - fprintf(stderr, "ASSERTION FAILED: file %s, line %u\n", filename, linenum); - fflush(stderr); - abort(); -} -#endif diff --git a/VEX/head20041019/massif/hp2ps/Main.h b/VEX/head20041019/massif/hp2ps/Main.h deleted file mode 100644 index 5fa954eb4..000000000 --- a/VEX/head20041019/massif/hp2ps/Main.h +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef MAIN_H -#define MAIN_H - -//#include "config.h" - -#ifdef __STDC__ -#define PROTO(x) x -#else -#define PROTO(x) () -#endif - -/* our own ASSERT macro (for C) */ -#ifndef DEBUG -#define ASSERT(predicate) /*nothing*/ - -#else -void _ghcAssert PROTO((char *, unsigned int)); - -#define ASSERT(predicate) \ - if (predicate) \ - /*null*/; \ - else \ - _ghcAssert(__FILE__, __LINE__) -#endif - -/* partain: some ubiquitous types: floatish & intish. - Dubious to use float/int, but that is what it used to be... - (WDP 95/03) -*/ -typedef double floatish; -typedef double doublish; /* higher precision, if anything; little used */ -typedef int boolish; - -/* Use "long long" if we have it: the numbers in profiles can easily - * overflow 32 bits after a few seconds execution. - */ -#define HAVE_LONG_LONG 1 // --added by njn, because config.h removed - -#ifdef HAVE_LONG_LONG -typedef long long int intish; -#else -typedef long int intish; -#endif - -extern intish nsamples; -extern intish nmarks; -extern intish nidents; - -extern floatish maxcombinedheight; -extern floatish areabelow; -extern floatish epsfwidth; - -extern floatish xrange; -extern floatish yrange; - -extern floatish auxxrange; -extern floatish auxyrange; - -extern boolish eflag; -extern boolish gflag; -extern boolish yflag; -extern boolish bflag; -extern boolish sflag; -extern int mflag; -extern boolish tflag; -extern boolish cflag; - -extern char *programname; - -extern char *hpfile; -extern char *psfile; -extern char *auxfile; - -extern FILE *hpfp; -extern FILE *psfp; -extern FILE *g_auxfp; - -#endif /* MAIN_H */ diff --git a/VEX/head20041019/massif/hp2ps/Makefile.am b/VEX/head20041019/massif/hp2ps/Makefile.am deleted file mode 100644 index 1f5100623..000000000 --- a/VEX/head20041019/massif/hp2ps/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -include $(top_srcdir)/Makefile.all.am - -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -g - -val_PROGRAMS = hp2ps - -EXTRA_DIST = \ - CHANGES \ - INSTALL \ - LICENSE \ - README \ - Makefile.old \ - hp2ps.1 - -hp2ps_SOURCES = \ - AuxFile.c \ - Axes.c \ - AreaBelow.c \ - Curves.c \ - Deviation.c \ - Dimensions.c \ - Error.c \ - HpFile.c \ - Key.c \ - Main.c \ - Marks.c \ - TopTwenty.c \ - TraceElement.c \ - PsFile.c \ - Reorder.c \ - Scale.c \ - Shade.c \ - Utilities.c -hp2ps_LDADD = -lm - -noinst_HEADERS = \ - AreaBelow.h \ - AuxFile.h \ - Axes.h \ - Curves.h \ - Defines.h \ - Deviation.h \ - Dimensions.h \ - Error.h \ - HpFile.h \ - Key.h \ - Main.h \ - Marks.h \ - PsFile.h \ - Reorder.h \ - Scale.h \ - Shade.h \ - TopTwenty.h \ - TraceElement.h \ - Utilities.h - -include $(top_srcdir)/Makefile.tool-inplace.am - diff --git a/VEX/head20041019/massif/hp2ps/Makefile.old b/VEX/head20041019/massif/hp2ps/Makefile.old deleted file mode 100644 index a62514955..000000000 --- a/VEX/head20041019/massif/hp2ps/Makefile.old +++ /dev/null @@ -1,42 +0,0 @@ -OBJS= \ - AuxFile.o \ - Axes.o \ - AreaBelow.o \ - Curves.o \ - Deviation.o \ - Dimensions.o \ - Error.o \ - HpFile.o \ - Key.o \ - Main.o \ - Marks.o \ - TopTwenty.o \ - TraceElement.o \ - PsFile.o \ - Reorder.o \ - Scale.o \ - Shade.o \ - Utilities.o - -# Please set MATHLIB and BIN appropriately. I don't need MATHLIB on my machine, -# but you may. - -MATHLIB = -lm - -DSTBIN = /n/Numbers/usr/lml/lml-0.997.4hp/sun3/bin - -CC= cc # gcc -Wall -CFLAGS= -g -LDFLAGS= ${STATICFLAG} - -TARGET=hp2ps - -${TARGET}: ${OBJS} - ${CC} -o ${TARGET} ${CCFLAGS} ${LDFLAGS} ${OBJS} ${MATHLIB} - -install: ${TARGET} - mv ${TARGET} ${DSTBIN}/${TARGET} - chmod 555 ${DSTBIN}/${TARGET} - -clean: - rm -f core *.o ${TARGET} diff --git a/VEX/head20041019/massif/hp2ps/Marks.c b/VEX/head20041019/massif/hp2ps/Marks.c deleted file mode 100644 index 80947df99..000000000 --- a/VEX/head20041019/massif/hp2ps/Marks.c +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include "Main.h" -#include "Curves.h" -#include "Dimensions.h" -#include "HpFile.h" - -/* own stuff */ -#include "Marks.h" - -static void Caret PROTO((floatish, floatish, floatish)); - -void -Marks() -{ - intish i; - floatish m; - - for (i = 0; i < nmarks; i++) { - m = ((markmap[i] - samplemap[0]) / xrange) * graphwidth; - Caret(xpage(m), ypage(0.0), 4.0); - } -} - - -/* - * Draw a small white caret at (x,y) with width 2 * d - */ - -static void -Caret(x,y,d) - floatish x; floatish y; floatish d; -{ - fprintf(psfp, "%f %f moveto\n", x - d, y); - fprintf(psfp, "%f %f rlineto\n", d, -d); - fprintf(psfp, "%f %f rlineto\n", d, d); - fprintf(psfp, "closepath\n"); - - fprintf(psfp, "gsave\n"); - fprintf(psfp, "1.0 setgray\n"); - fprintf(psfp, "fill\n"); - fprintf(psfp, "grestore\n"); - fprintf(psfp, "stroke\n"); -} diff --git a/VEX/head20041019/massif/hp2ps/Marks.h b/VEX/head20041019/massif/hp2ps/Marks.h deleted file mode 100644 index e71f1cdc7..000000000 --- a/VEX/head20041019/massif/hp2ps/Marks.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef MARKS_H -#define MARKS_H - -void Marks PROTO((void)); - -#endif /* MARKS_H */ diff --git a/VEX/head20041019/massif/hp2ps/PsFile.c b/VEX/head20041019/massif/hp2ps/PsFile.c deleted file mode 100644 index 2b203e476..000000000 --- a/VEX/head20041019/massif/hp2ps/PsFile.c +++ /dev/null @@ -1,284 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Dimensions.h" -#include "Curves.h" -#include "HpFile.h" -#include "Axes.h" -#include "Key.h" -#include "Marks.h" -#include "Utilities.h" - -/* own stuff */ -#include "PsFile.h" - -static void Prologue PROTO((void)); /* forward */ -static void Variables PROTO((void)); /* forward */ -static void BorderOutlineBox PROTO((void)); /* forward */ -static void BigTitleOutlineBox PROTO((void)); /* forward */ -static void TitleOutlineBox PROTO((void)); /* forward */ -static void BigTitleText PROTO((void)); /* forward */ -static void TitleText PROTO((void)); /* forward */ - -void -PutPsFile() -{ - Prologue(); - Variables(); - BorderOutlineBox(); - - if (bflag) { - BigTitleOutlineBox(); - BigTitleText(); - } else { - TitleOutlineBox(); - TitleText(); - } - - CurvesInit(); - - Axes(); - - if (TWENTY) Key(); - - Curves(); - - if (!yflag) Marks(); - - fprintf(psfp, "showpage\n"); -} - - -static void StandardSpecialComments PROTO((void)); /* forward */ -static void EPSFSpecialComments PROTO((floatish)); /* forward */ -static void Landscape PROTO((void)); /* forward */ -static void Portrait PROTO((void)); /* forward */ -static void Scaling PROTO((floatish)); /* forward */ - -static void -Prologue() -{ - if (eflag) { - floatish epsfscale = epsfwidth / (floatish) borderwidth; - EPSFSpecialComments(epsfscale); - Scaling(epsfscale); - } else { - StandardSpecialComments(); - if (gflag) Portrait(); else Landscape(); - } -} - -extern char *jobstring; -extern char *datestring; - -static void -StandardSpecialComments() -{ - fprintf(psfp, "%%!PS-Adobe-2.0\n"); - fprintf(psfp, "%%%%Title: %s\n", jobstring); - fprintf(psfp, "%%%%Creator: %s (version %s)\n", programname, VERSION); - fprintf(psfp, "%%%%CreationDate: %s\n", datestring); - fprintf(psfp, "%%%%EndComments\n"); -} - -static void -EPSFSpecialComments(epsfscale) - floatish epsfscale; -{ - fprintf(psfp, "%%!PS-Adobe-2.0\n"); - fprintf(psfp, "%%%%Title: %s\n", jobstring); - fprintf(psfp, "%%%%Creator: %s (version %s)\n", programname, VERSION); - fprintf(psfp, "%%%%CreationDate: %s\n", datestring); - fprintf(psfp, "%%%%BoundingBox: 0 0 %d %d\n", - (int) (borderwidth * epsfscale + 0.5), - (int) (borderheight * epsfscale + 0.5) ); - fprintf(psfp, "%%%%EndComments\n"); -} - - - -static void -Landscape() -{ - fprintf(psfp, "-90 rotate\n"); - fprintf(psfp, "%f %f translate\n", -(borderwidth + (floatish) START_Y), - (floatish) START_X); -} - -static void -Portrait() -{ - fprintf(psfp, "%f %f translate\n", (floatish) START_X, (floatish) START_Y); -} - -static void -Scaling(epsfscale) - floatish epsfscale; -{ - fprintf(psfp, "%f %f scale\n", epsfscale, epsfscale); -} - - -static void -Variables() -{ - fprintf(psfp, "/HE%d /Helvetica findfont %d scalefont def\n", - NORMAL_FONT, NORMAL_FONT); - - fprintf(psfp, "/HE%d /Helvetica findfont %d scalefont def\n", - LARGE_FONT, LARGE_FONT); -} - - -static void -BorderOutlineBox() -{ - fprintf(psfp, "newpath\n"); - fprintf(psfp, "0 0 moveto\n"); - fprintf(psfp, "0 %f rlineto\n", borderheight); - fprintf(psfp, "%f 0 rlineto\n", borderwidth); - fprintf(psfp, "0 %f rlineto\n", -borderheight); - fprintf(psfp, "closepath\n"); - fprintf(psfp, "%f setlinewidth\n", borderthick); - fprintf(psfp, "stroke\n"); -} - -static void -BigTitleOutlineBox() -{ - fprintf(psfp, "newpath\n"); - fprintf(psfp, "%f %f moveto\n", borderspace, - borderheight - titleheight - borderspace); - fprintf(psfp, "0 %f rlineto\n", titleheight); - fprintf(psfp, "%f 0 rlineto\n", titlewidth); - fprintf(psfp, "0 %f rlineto\n", -titleheight); - fprintf(psfp, "closepath\n"); - fprintf(psfp, "%f setlinewidth\n", borderthick); - fprintf(psfp, "stroke\n"); - - fprintf(psfp, "%f %f moveto\n", borderspace, - borderheight - titleheight / 2 - borderspace); - fprintf(psfp, "%f 0 rlineto\n", titlewidth); - fprintf(psfp, "stroke\n"); -} - - -static void -TitleOutlineBox() -{ - fprintf(psfp, "newpath\n"); - fprintf(psfp, "%f %f moveto\n", borderspace, - borderheight - titleheight - borderspace); - fprintf(psfp, "0 %f rlineto\n", titleheight); - fprintf(psfp, "%f 0 rlineto\n", titlewidth); - fprintf(psfp, "0 %f rlineto\n", -titleheight); - fprintf(psfp, "closepath\n"); - fprintf(psfp, "%f setlinewidth\n", borderthick); - fprintf(psfp, "stroke\n"); -} - -static void EscapePrint PROTO((char *, int)); /* forward */ - -static void -BigTitleText() -{ - floatish x, y; - - x = borderspace + titletextspace; - y = borderheight - titleheight / 2 - borderspace + titletextspace; - - /* job identifier goes on top at the far left */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fprintf(psfp, "%f %f moveto\n", x, y); - fputc('(', psfp); - EscapePrint(jobstring, BIG_JOB_STRING_WIDTH); - fprintf(psfp, ") show\n"); - - y = borderheight - titleheight - borderspace + titletextspace; - - /* area below curve gows at the botton, far left */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fprintf(psfp, "%f %f moveto\n", x, y); - fputc('(', psfp); - CommaPrint(psfp, (intish)areabelow); - fprintf(psfp, " %s x %s)\n", valueunitstring, sampleunitstring); - fprintf(psfp, "show\n"); - - /* date goes at far right */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fprintf(psfp, "(%s)\n", datestring); - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "%f\n", (titlewidth + borderspace) - titletextspace); - fprintf(psfp, "exch sub\n"); - fprintf(psfp, "%f moveto\n", y); - fprintf(psfp, "show\n"); -} - - -static void -TitleText() -{ - floatish x, y; - - x = borderspace + titletextspace; - y = borderheight - titleheight - borderspace + titletextspace; - - /* job identifier goes at far left */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fprintf(psfp, "%f %f moveto\n", x, y); - fputc('(', psfp); - EscapePrint(jobstring, SMALL_JOB_STRING_WIDTH); - fprintf(psfp, ") show\n"); - - /* area below curve is centered */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fputc('(', psfp); - CommaPrint(psfp, (intish) areabelow); - fprintf(psfp, " %s x %s)\n", valueunitstring, sampleunitstring); - - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "2 div\n"); - fprintf(psfp, "%f\n", titlewidth / 2); - fprintf(psfp, "exch sub\n"); - fprintf(psfp, "%f moveto\n", y); - fprintf(psfp, "show\n"); - - /* date goes at far right */ - - fprintf(psfp, "HE%d setfont\n", TITLE_TEXT_FONT); - fprintf(psfp, "(%s)\n", datestring); - fprintf(psfp, "dup stringwidth pop\n"); - fprintf(psfp, "%f\n", (titlewidth + borderspace) - titletextspace); - fprintf(psfp, "exch sub\n"); - fprintf(psfp, "%f moveto\n", y); - fprintf(psfp, "show\n"); -} - -/* - * Print a string s in width w, escaping characters where necessary. - */ - -static void -EscapePrint(s,w) - char* s; int w; -{ - for ( ; *s && w > 0; s++, w--) { - if (*s == '(') { /* escape required */ - fputc('\\', psfp); - } else if (*s == ')') { - fputc('\\', psfp); - } - - fputc(*s, psfp); - } -} diff --git a/VEX/head20041019/massif/hp2ps/PsFile.h b/VEX/head20041019/massif/hp2ps/PsFile.h deleted file mode 100644 index 01f8cc192..000000000 --- a/VEX/head20041019/massif/hp2ps/PsFile.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef PS_FILE_H -#define PS_FILE_H - -void PutPsFile PROTO((void)); - -#endif /* PS_FILE_H */ diff --git a/VEX/head20041019/massif/hp2ps/README b/VEX/head20041019/massif/hp2ps/README deleted file mode 100644 index f0f09ce35..000000000 --- a/VEX/head20041019/massif/hp2ps/README +++ /dev/null @@ -1 +0,0 @@ -This "hp2ps" program was written by Dave Wakeling at York. diff --git a/VEX/head20041019/massif/hp2ps/Reorder.c b/VEX/head20041019/massif/hp2ps/Reorder.c deleted file mode 100644 index fc6db6add..000000000 --- a/VEX/head20041019/massif/hp2ps/Reorder.c +++ /dev/null @@ -1,93 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "Reorder.h" - -static struct order { - char* ident; - int order; -} *ordermap = 0; - -static int ordermapmax = 0; -static int ordermapindex = 0; - - -void -OrderFor(ident, order) - char* ident; - int order; -{ - if (! ordermap) { - ordermapmax = (nidents > TWENTY ? nidents : TWENTY) * 2; - /* Assume nidents read is indication of the No of - idents in the .aux file (*2 for good luck !) */ - ordermap = xmalloc(ordermapmax * sizeof(struct order)); - } - - if (ordermapindex < ordermapmax) { - ordermap[ ordermapindex ].ident = copystring(ident); - ordermap[ ordermapindex ].order = order; - ordermapindex++; - } else { - Disaster("order map overflow"); - } -} - -/* - * Get the order of to be used for "ident" if there is one. - * Otherwise, return 0 which is the minimum ordering value. - */ - -int -OrderOf(ident) - char* ident; -{ - int i; - - for (i = 0; i < ordermapindex; i++) { - if (strcmp(ordermap[i].ident, ident) == 0) { /* got it */ - return(ordermap[i].order); - } - } - - return 0; -} - -/* - * Reorder on the basis of information from ".aux" file. - */ - -void -Reorder() -{ - intish i; - intish j; - int min; - struct entry* e; - int o1, o2; - - for (i = 0; i < nidents-1; i++) { - min = i; - for (j = i+1; j < nidents; j++) { - o1 = OrderOf(identtable[ j ]->name); - o2 = OrderOf(identtable[ min ]->name); - - if (o1 < o2 ) min = j; - } - - e = identtable[ min ]; - identtable[ min ] = identtable[ i ]; - identtable[ i ] = e; - } -} diff --git a/VEX/head20041019/massif/hp2ps/Reorder.h b/VEX/head20041019/massif/hp2ps/Reorder.h deleted file mode 100644 index 81c4ba340..000000000 --- a/VEX/head20041019/massif/hp2ps/Reorder.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef REORDER_H -#define REORDER_H - -void Reorder PROTO((void)); -int OrderOf PROTO((char *)); -void OrderFor PROTO((char *, int)); - -#endif /* REORDER_H */ diff --git a/VEX/head20041019/massif/hp2ps/Scale.c b/VEX/head20041019/massif/hp2ps/Scale.c deleted file mode 100644 index b6b5e3a9e..000000000 --- a/VEX/head20041019/massif/hp2ps/Scale.c +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Dimensions.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "Scale.h" - -/* - * Return the maximum combined height that all the sample - * curves will reach. This (absolute) figure can then be - * used to scale the samples automatically so that they - * fit on the page. - */ - -floatish -MaxCombinedHeight() -{ - intish i; - intish j; - floatish mx; - int bucket; - floatish value; - struct chunk* ch; - floatish *maxima; - - maxima = (floatish*) xmalloc(nsamples * sizeof(floatish)); - for (i = 0; i < nsamples; i++) { - maxima[ i ] = 0.0; - } - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - bucket = ch->d[j].bucket; - value = ch->d[j].value; - if (bucket >= nsamples) - Disaster("bucket out of range"); - maxima[ bucket ] += value; - } - } - } - - for (mx = maxima[ 0 ], i = 0; i < nsamples; i++) { - if (maxima[ i ] > mx) mx = maxima[ i ]; - } - - free(maxima); - return mx; -} - - - -/* - * Scale the values from the samples so that they will fit on - * the page. - */ - -extern floatish xrange; -extern floatish yrange; - -void -Scale() -{ - intish i; - intish j; - floatish sf; - struct chunk* ch; - - if (yrange == 0.0) /* no samples */ - return; - - sf = graphheight / yrange; - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - ch->d[j].value = ch->d[j].value * sf; - } - } - } -} diff --git a/VEX/head20041019/massif/hp2ps/Scale.h b/VEX/head20041019/massif/hp2ps/Scale.h deleted file mode 100644 index 2a3487ebb..000000000 --- a/VEX/head20041019/massif/hp2ps/Scale.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef SCALE_H -#define SCALE_H - -floatish MaxCombinedHeight PROTO((void)); -void Scale PROTO((void)); - -#endif /* SCALE_H */ diff --git a/VEX/head20041019/massif/hp2ps/Shade.c b/VEX/head20041019/massif/hp2ps/Shade.c deleted file mode 100644 index 0c1a3be09..000000000 --- a/VEX/head20041019/massif/hp2ps/Shade.c +++ /dev/null @@ -1,134 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "Utilities.h" - -/* own stuff */ -#include "Shade.h" - -static struct shade { - char* ident; - floatish shade; -} *shademap; - -static int shademapmax = 0; -static int shademapindex = 0; - -/* - * Set the shade to be used for "ident" to "shade". - */ - -void -ShadeFor(ident, shade) - char* ident; - floatish shade; -{ - if (! shademap) { - shademapmax = (nidents > TWENTY ? nidents : TWENTY) * 2; - /* Assume nidents read is indication of the No of - idents in the .aux file (*2 for good luck) */ - /* NB *2 is needed as .aux and .hp elements may differ */ - shademap = xmalloc(shademapmax * sizeof(struct shade)); - } - - if (shademapindex < shademapmax) { - shademap[ shademapindex ].ident = copystring(ident); - shademap[ shademapindex ].shade = shade; - shademapindex++; - } else { - Disaster("shade map overflow"); - } -} - -/* - * Get the shade to be used for "ident" if there is one. - * Otherwise, think of a new one. - */ - -static floatish ThinkOfAShade PROTO((void)); /* forward */ - -floatish -ShadeOf(ident) - char* ident; -{ - int i; - floatish shade; - - for (i = 0; i < shademapindex; i++) { - if (strcmp(shademap[i].ident, ident) == 0) { /* got it */ - return(shademap[i].shade); - } - } - - shade = ThinkOfAShade(); - - ShadeFor(ident, shade); - - return shade; -} - - - -#define N_MONO_SHADES 10 - -static floatish m_shades[ N_MONO_SHADES ] = { - 0.00000, 0.20000, 0.60000, 0.30000, 0.90000, - 0.40000, 1.00000, 0.70000, 0.50000, 0.80000 -}; - -#define N_COLOUR_SHADES 27 - -/* HACK: 0.100505 means 100% red, 50% green, 50% blue */ - -static floatish c_shades[ N_COLOUR_SHADES ] = { - 0.000000, 0.000010, 0.001000, 0.001010, 0.100000, - 0.100010, 0.101000, 0.101010, 0.000005, 0.000500, - 0.000510, 0.001005, 0.050000, 0.050010, 0.051000, - 0.051010, 0.100005, 0.100500, 0.100510, 0.101005, - 0.000505, 0.050005, 0.050500, 0.050510, 0.051005, - 0.100505, 0.050505 -}; - -static floatish -ThinkOfAShade() -{ - static int thisshade = -1; - - thisshade++; - return cflag ? - c_shades[ thisshade % N_COLOUR_SHADES ] : - m_shades[ thisshade % N_MONO_SHADES ] ; -} - -static floatish -extract_colour(shade,factor) - floatish shade; - intish factor; -{ - intish i,j; - - i = (int)(shade * factor); - j = i / 100; - return (i - j * 100) / 10.0; -} - -void -SetPSColour(shade) - floatish shade; -{ - if (cflag) { - fprintf(psfp, "%f %f %f setrgbcolor\n", - extract_colour(shade, (intish)100), - extract_colour(shade, (intish)10000), - extract_colour(shade, (intish)1000000)); - } else { - fprintf(psfp, "%f setgray\n", shade); - } -} diff --git a/VEX/head20041019/massif/hp2ps/Shade.h b/VEX/head20041019/massif/hp2ps/Shade.h deleted file mode 100644 index 66a803ea5..000000000 --- a/VEX/head20041019/massif/hp2ps/Shade.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef SHADE_H -#define SHADE_H - -floatish ShadeOf PROTO((char *)); -void ShadeFor PROTO((char *, floatish)); -void SetPSColour PROTO((floatish)); - -#endif /* SHADE_H */ diff --git a/VEX/head20041019/massif/hp2ps/TopTwenty.c b/VEX/head20041019/massif/hp2ps/TopTwenty.c deleted file mode 100644 index 3c6ccbde0..000000000 --- a/VEX/head20041019/massif/hp2ps/TopTwenty.c +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "Error.h" -#include "HpFile.h" -#include "Utilities.h" - -/* own stuff */ -#include "TopTwenty.h" - -/* - * We only have room in the key for a maximum of 20 identifiers. - * We therefore choose to keep the top 20 bands --- these will - * be the most important ones, since this pass is performed after - * the threshold and standard deviation passes. If there are more - * than 20 bands, the excess are gathered together as an "OTHER" ] - * band which appears as band 20. - */ - -void -TopTwenty() -{ - intish i; - intish j; - intish compact; - intish bucket; - floatish value; - struct entry* en; - struct chunk* ch; - floatish *other; - - i = nidents; - if (i <= TWENTY) return; /* nothing to do! */ - - other = (floatish*) xmalloc(nsamples * sizeof(floatish)); - /* build a list of samples for "OTHER" */ - - compact = (i - TWENTY) + 1; - - for (i = 0; i < nsamples; i++) { - other[ i ] = 0.0; - } - - for (i = 0; i < compact && i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - bucket = ch->d[j].bucket; - value = ch->d[j].value; - if (bucket >= nsamples) - Disaster("bucket out of range"); - other[ bucket ] += value; - } - } - } - - en = MakeEntry("OTHER"); - en->next = 0; - - for (i = 0; i < nsamples; i++) { - StoreSample(en, i, other[i]); - } - - /* slide samples down */ - for (i = compact; i < nidents; i++) { - identtable[i-compact+1] = identtable[i]; - } - - nidents = TWENTY; - identtable[0] = en; - free(other); -} diff --git a/VEX/head20041019/massif/hp2ps/TopTwenty.h b/VEX/head20041019/massif/hp2ps/TopTwenty.h deleted file mode 100644 index f724a4da7..000000000 --- a/VEX/head20041019/massif/hp2ps/TopTwenty.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef TOP_TWENTY_H -#define TOP_TWENTY_H - -void TopTwenty PROTO((void)); - -#endif /* TOP_TWENTY_H */ diff --git a/VEX/head20041019/massif/hp2ps/TraceElement.c b/VEX/head20041019/massif/hp2ps/TraceElement.c deleted file mode 100644 index 158eb938d..000000000 --- a/VEX/head20041019/massif/hp2ps/TraceElement.c +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Defines.h" -#include "HpFile.h" -#include "Error.h" -#include "Utilities.h" - -/* own stuff */ -#include "TraceElement.h" - -/* - * Compute the total volume for each identifier, and the grand - * total of these totals. The identifiers whose totals when - * added together amount to less that a threshold percentage - * (default 1%) of the grand total are considered to be ``trace - * elements'' and they are thrown away. - */ - -extern floatish thresholdpercent; - -void TraceElement() -{ - intish i; - intish j; - struct chunk* ch; - floatish grandtotal; - intish min; - floatish t; - floatish p; - struct entry* e; - intish *totals; - - totals = (intish *) xmalloc(nidents * sizeof(intish)); - - /* find totals */ - - for (i = 0; i < nidents; i++) { - totals[ i ] = 0; - } - - for (i = 0; i < nidents; i++) { - for (ch = identtable[i]->chk; ch; ch = ch->next) { - for (j = 0; j < ch->nd; j++) { - totals[ i ] += ch->d[j].value; - } - } - } - - /* sort on the basis of total */ - - for (i = 0; i < nidents-1; i++) { - min = i; - for (j = i+1; j < nidents; j++) { - if (totals[ j ] < totals[ min ]) { - min = j; - } - } - - t = totals[ min ]; - totals[ min ] = totals[ i ]; - totals[ i ] = t; - - e = identtable[ min ]; - identtable[ min ] = identtable[ i ]; - identtable[ i ] = e; - } - - - /* find the grand total (NB: can get *BIG*!) */ - - grandtotal = 0.0; - - for (i = 0; i < nidents; i++) { - grandtotal += (floatish) totals[ i ]; - } - - t = 0.0; /* cumulative percentage */ - - for (i = 0; i < nidents; i++) { - p = (100.0 * (floatish) totals[i]) / grandtotal; - t = t + p; - if (t >= THRESHOLD_PERCENT) { - break; - } - } - - /* identifiers from 0 to i-1 should be removed */ - for (j = 0; i < nidents; i++, j++) { - identtable[j] = identtable[i]; - } - - nidents = j; - - free(totals); -} diff --git a/VEX/head20041019/massif/hp2ps/TraceElement.h b/VEX/head20041019/massif/hp2ps/TraceElement.h deleted file mode 100644 index b5ee8b53d..000000000 --- a/VEX/head20041019/massif/hp2ps/TraceElement.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef TRACE_ELEMENT_H -#define TRACE_ELEMENT_H - -void TraceElement PROTO((void)); - -#endif /* TRACE_ELEMENT_H */ diff --git a/VEX/head20041019/massif/hp2ps/Utilities.c b/VEX/head20041019/massif/hp2ps/Utilities.c deleted file mode 100644 index 754cc8a01..000000000 --- a/VEX/head20041019/massif/hp2ps/Utilities.c +++ /dev/null @@ -1,136 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#include -#include -#include "Main.h" -#include "Error.h" - -extern void* malloc(); - -char* -Basename(name) - char* name; -{ - char* t; - - t = name; - - while (*name) { - if (*name == '/') { - t = name+1; - } - name++; - } - - return t; -} - -void -DropSuffix(name, suffix) - char* name; char* suffix; -{ - char* t; - - t = (char*) 0; - - while (*name) { - if (*name == '.') { - t = name; - } - name++; - } - - if (t != (char*) 0 && strcmp(t, suffix) == 0) { - *t = '\0'; - } -} - -FILE* -OpenFile(s, mode) - char* s; char* mode; -{ - FILE* r; - - if ((r = fopen(s, mode)) == NULL) { - /*NOTREACHED*/ - Error("cannot open %s", s); - } - - return r; -} - - -#define ONETHOUSAND 1000 - -/* - * Print a positive integer with commas - */ - -void -CommaPrint(fp,n) - FILE* fp; - intish n; -{ - if (n < ONETHOUSAND) { - fprintf(fp, "%d", (int)n); - } else { - CommaPrint(fp, n / ONETHOUSAND); - fprintf(fp, ",%03d", (int)(n % ONETHOUSAND)); - } -} - -void * -xmalloc(n) - size_t n; -{ - void *r; - - r = (void*) malloc(n); - if (!r) { - /*NOTREACHED*/ - Disaster("%s, sorry, out of memory", hpfile); - } - return r; -} - -void * -xrealloc(p, n) - void *p; - size_t n; -{ - void *r; - extern void *realloc(); - - r = realloc(p, n); - if (!r) { - /*NOTREACHED*/ - Disaster("%s, sorry, out of memory", hpfile); - } - return r; -} - -char * -copystring(s) - char *s; -{ - char *r; - - r = (char*) xmalloc(strlen(s)+1); - strcpy(r, s); - return r; -} - -char * -copystring2(s, t) - char *s, *t; -{ - char *r; - - r = (char*) xmalloc(strlen(s)+strlen(t)+1); - strcpy(r, s); - strcat(r, t); - return r; -} - diff --git a/VEX/head20041019/massif/hp2ps/Utilities.h b/VEX/head20041019/massif/hp2ps/Utilities.h deleted file mode 100644 index 674843a65..000000000 --- a/VEX/head20041019/massif/hp2ps/Utilities.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This file is part of hp2ps, a graph drawer for memory profiles. - Copyright (C) 2002 The University Court of the University of Glasgow. - This program is governed by the license contained in the file LICENSE. */ - -#ifndef UTILITIES_H -#define UTILITIES_H - -char* Basename PROTO((char *)); -void DropSuffix PROTO((char *, char *)); -FILE* OpenFile PROTO((char *, char *)); -void CommaPrint PROTO((FILE *, intish)); -char *copystring PROTO((char *)); -char *copystring2 PROTO((char *, char *)); -void *xmalloc PROTO((size_t)); -void *xrealloc PROTO((void *, size_t)); - -#endif /* UTILITIES_H */ diff --git a/VEX/head20041019/massif/hp2ps/hp2ps.1 b/VEX/head20041019/massif/hp2ps/hp2ps.1 deleted file mode 100644 index fd0bca023..000000000 --- a/VEX/head20041019/massif/hp2ps/hp2ps.1 +++ /dev/null @@ -1,145 +0,0 @@ -.\" man page for hp2ps -.ds PS P\s-2OST\s+2S\s-2CRIPT\s+2 -.\" typeset examples in fixed size font as indented paragraph -.de Ex -.sp -.RS -.nf -.ft C -.. -.de Xe -.RE -.sp -.fi -.. -.TH HP2PS 1 "18 April 1992" -.SH NAME -hp2ps \- convert a heap profile to a \*(PS graph -.SH SYNOPSIS -.B hp2ps -[flags] [file][.hp] -.SH DESCRIPTION -The program -.B hp2ps -converts a heap profile stored in -.IR file -into a \*(PS graph, sending the result to -.IR file.ps. -By convention, files to be processed by -.B hp2ps -have a -.I .hp -extension. However, for compatibility with older versions of -.B hp2ps, -this extension can be omitted. If -.IR file -is omitted entirely, then the program behaves as a filter. -.SH OPTIONS -The flags are: -.IP "\fB\-d\fP" -In order to make graphs more readable, -.B hp2ps -sorts the shaded bands for each identifier. The default sort ordering is for -the bands with the largest area to be stacked on top of the smaller ones. -The -.B \-d -option causes rougher bands (those reprsenting series of values with the -largest standard deviations) to be stacked on top of smoother ones. -.IP "\fB\-b\fP" -Normally, -.B hp2ps -puts the title of the graph in a small box at the top of the page. However, -if the JOB string is too long to fit in a small box (more than 35 characters), -then -.B hp2ps -will choose to use a big box instead. The -.B \-b -option forces -.B hp2ps -to use a big box. -.IP "\fB\-e\fP \fIfloat\fP[in|mm|pt]" -Generate encapsulated \*(PS suitable for inclusion in LaTeX documents. -Usually, the \*(PS graph is drawn in landscape mode in an area -9 inches wide by 6 inches high, and -.B hp2ps -arranges for this area to be approximately centered on a sheet of a4 -paper. This format is convenient of studying the graph in detail, but -it is unsuitable for inclusion in LaTeX documents. The -.B \-e -option causes the graph to be drawn in portrait mode, with -.I float -specifying the width in inches, millimetres or points (the default). -The resulting \*(PS file conforms to the -.I "Encapsulated Post Script" -(EPS) convention, and it can be included in a LaTeX document using Rokicki's -dvi-to-\*(PS converter -.B dvips. -.B hp2ps -requires the width to exceed 2 inches. -.IP "\fB\-g\fP" -Create output suitable for the -.B gs -\*(PS previewer (or similar). In this case the graph is printed in portrait -mode without scaling. The output is unsuitable for a laser printer. -.IP "\fB\-p\fP" -Use previous parameters. By default, the \*(PS graph is automatically -scaled both horizontally and vertically so that it fills the page. -However, when preparing a seires of graphs for use in a presentation, -it is often useful to draw a new graph using the same scale, shading and -ordering as a previous one. The -.B \-p -flag causes the graph to be drawn using the parameters determined by -a previous run of -.B hp2ps -on -.IR file. -.IP "\fB\-s\fP" -Use a small box for the title. -.IP "\fB\-y\fP" -Draw the graph in the traditional York style, ignoring marks. -.IP "\fB\-?\fP" -Print out usage information. -.SH "INPUT FORMAT" -The format of a heap profile is best described by example: -.Ex -JOB "a.out -p" -DATE "Fri Apr 17 11:43:45 1992" -SAMPLE_UNIT "seconds" -VALUE_UNIT "bytes" -BEGIN_SAMPLE 0.00 - SYSTEM 24 -END_SAMPLE 0.00 -BEGIN_SAMPLE 1.00 - elim 180 - insert 24 - intersect 12 - disin 60 - main 12 - reduce 20 - SYSTEM 12 -END_SAMPLE 1.00 -MARK 1.50 -MARK 1.75 -MARK 1.80 -BEGIN_SAMPLE 2.00 - elim 192 - insert 24 - intersect 12 - disin 84 - main 12 - SYSTEM 24 -END_SAMPLE 2.00 -BEGIN_SAMPLE 2.82 -END_SAMPLE 2.82 - -.Xe -.SH "SEE ALSO" -dvips(1), latex(1), hbchp (1), lmlchp(1) -.br -C. Runciman and D. Wakeling, -.I -Heap Profiling for Lazy Functional Languages, YCS-172, University of York, 1992 -.SH NOTES -\*(PS is a registered trademark of Adobe Systems Incorporated. -.SH AUTHOR -David Wakeling of the University of York. diff --git a/VEX/head20041019/massif/ms_main.c b/VEX/head20041019/massif/ms_main.c deleted file mode 100644 index baa6fa70a..000000000 --- a/VEX/head20041019/massif/ms_main.c +++ /dev/null @@ -1,1818 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Massif: a heap profiling tool. ms_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Massif, a Valgrind tool for profiling memory - usage of programs. - - Copyright (C) 2003-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -// Memory profiler. Produces a graph, gives lots of information about -// allocation contexts, in terms of space.time values (ie. area under the -// graph). Allocation context information is hierarchical, and can thus -// be inspected step-wise to an appropriate depth. See comments on data -// structures below for more info on how things work. - -#include "tool.h" -//#include "vg_profile.c" - -#include "valgrind.h" // For {MALLOC,FREE}LIKE_BLOCK - -/*------------------------------------------------------------*/ -/*--- Overview of operation ---*/ -/*------------------------------------------------------------*/ - -// Heap blocks are tracked, and the amount of space allocated by various -// contexts (ie. lines of code, more or less) is also tracked. -// Periodically, a census is taken, and the amount of space used, at that -// point, by the most significant (highly allocating) contexts is recorded. -// Census start off frequently, but are scaled back as the program goes on, -// so that there are always a good number of them. At the end, overall -// spacetimes for different contexts (of differing levels of precision) is -// calculated, the graph is printed, and the text giving spacetimes for the -// increasingly precise contexts is given. -// -// Measures the following: -// - heap blocks -// - heap admin bytes -// - stack(s) -// - code (code segments loaded at startup, and loaded with mmap) -// - data (data segments loaded at startup, and loaded/created with mmap, -// and brk()d segments) - -/*------------------------------------------------------------*/ -/*--- Main types ---*/ -/*------------------------------------------------------------*/ - -// An XPt represents an "execution point", ie. a code address. Each XPt is -// part of a tree of XPts (an "execution tree", or "XTree"). Each -// top-to-bottom path through an XTree gives an execution context ("XCon"), -// and is equivalent to a traditional Valgrind ExeContext. -// -// The XPt at the top of an XTree (but below "alloc_xpt") is called a -// "top-XPt". The XPts are the bottom of an XTree (leaf nodes) are -// "bottom-XPTs". The number of XCons in an XTree is equal to the number of -// bottom-XPTs in that XTree. -// -// All XCons have the same top-XPt, "alloc_xpt", which represents all -// allocation functions like malloc(). It's a bit of a fake XPt, though, -// and is only used because it makes some of the code simpler. -// -// XTrees are bi-directional. -// -// > parent < Example: if child1() calls parent() and child2() -// / | \ also calls parent(), and parent() calls malloc(), -// | / \ | the XTree will look like this. -// | v v | -// child1 child2 - -typedef struct _XPt XPt; - -struct _XPt { - Addr eip; // code address - - // Bottom-XPts: space for the precise context. - // Other XPts: space of all the descendent bottom-XPts. - // Nb: this value goes up and down as the program executes. - UInt curr_space; - - // An approximate space.time calculation used along the way for selecting - // which contexts to include at each census point. - // !!! top-XPTs only !!! - ULong approx_ST; - - // exact_ST_dbld is an exact space.time calculation done at the end, and - // used in the results. - // Note that it is *doubled*, to avoid rounding errors. - // !!! not used for 'alloc_xpt' !!! - ULong exact_ST_dbld; - - // n_children and max_children are integers; a very big program might - // have more than 65536 allocation points (Konqueror startup has 1800). - XPt* parent; // pointer to parent XPt - UInt n_children; // number of children - UInt max_children; // capacity of children array - XPt** children; // pointers to children XPts -}; - -// Each census snapshots the most significant XTrees, each XTree having a -// top-XPt as its root. The 'curr_space' element for each XPt is recorded -// in the snapshot. The snapshot contains all the XTree's XPts, not in a -// tree structure, but flattened into an array. This flat snapshot is used -// at the end for computing exact_ST_dbld for each XPt. -// -// Graph resolution, x-axis: no point having more than about 200 census -// x-points; you can't see them on the graph. Therefore: -// -// - do a census every 1 ms for first 200 --> 200, all (200 ms) -// - halve (drop half of them) --> 100, every 2nd (200 ms) -// - do a census every 2 ms for next 200 --> 200, every 2nd (400 ms) -// - halve --> 100, every 4th (400 ms) -// - do a census every 4 ms for next 400 --> 200, every 4th (800 ms) -// - etc. -// -// This isn't exactly right, because we actually drop (N/2)-1 when halving, -// but it shows the basic idea. - -#define MAX_N_CENSI 200 // Keep it even, for simplicity - -// Graph resolution, y-axis: hp2ps only draws the 19 biggest (in space-time) -// bands, rest get lumped into OTHERS. I only print the top N -// (cumulative-so-far space-time) at each point. N should be a bit bigger -// than 19 in case the cumulative space-time doesn't fit with the eventual -// space-time computed by hp2ps (but it should be close if the samples are -// evenly spread, since hp2ps does an approximate per-band space-time -// calculation that just sums the totals; ie. it assumes all samples are -// the same distance apart). - -#define MAX_SNAPSHOTS 32 - -typedef - struct { - XPt* xpt; - UInt space; - } - XPtSnapshot; - -// An XTree snapshot is stored as an array of of XPt snapshots. -typedef XPtSnapshot* XTreeSnapshot; - -typedef - struct { - Int ms_time; // Int: must allow -1 - XTreeSnapshot xtree_snapshots[MAX_SNAPSHOTS+1]; // +1 for zero-termination - UInt others_space; - UInt heap_admin_space; - UInt stacks_space; - } - Census; - -// Metadata for heap blocks. Each one contains a pointer to a bottom-XPt, -// which is a foothold into the XCon at which it was allocated. From -// HP_Chunks, XPt 'space' fields are incremented (at allocation) and -// decremented (at deallocation). -// -// Nb: first two fields must match core's VgHashNode. -typedef - struct _HP_Chunk { - struct _HP_Chunk* next; - Addr data; // Ptr to actual block - UInt size; // Size requested - XPt* where; // Where allocated; bottom-XPt - } - HP_Chunk; - -/*------------------------------------------------------------*/ -/*--- Profiling events ---*/ -/*------------------------------------------------------------*/ - -typedef - enum { - VgpGetXPt = VgpFini+1, - VgpGetXPtSearch, - VgpCensus, - VgpCensusHeap, - VgpCensusSnapshot, - VgpCensusTreeSize, - VgpUpdateXCon, - VgpCalcSpacetime2, - VgpPrintHp, - VgpPrintXPts, - } - VgpSkinCC; - -/*------------------------------------------------------------*/ -/*--- Statistics ---*/ -/*------------------------------------------------------------*/ - -// Konqueror startup, to give an idea of the numbers involved with a biggish -// program, with default depth: -// -// depth=3 depth=40 -// - 310,000 allocations -// - 300,000 frees -// - 15,000 XPts 800,000 XPts -// - 1,800 top-XPts - -static UInt n_xpts = 0; -static UInt n_bot_xpts = 0; -static UInt n_allocs = 0; -static UInt n_zero_allocs = 0; -static UInt n_frees = 0; -static UInt n_children_reallocs = 0; -static UInt n_snapshot_frees = 0; - -static UInt n_halvings = 0; -static UInt n_real_censi = 0; -static UInt n_fake_censi = 0; -static UInt n_attempted_censi = 0; - -/*------------------------------------------------------------*/ -/*--- Globals ---*/ -/*------------------------------------------------------------*/ - -#define FILENAME_LEN 256 - -#define SPRINTF(zz_buf, fmt, args...) \ - do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \ - VG_(write)(fd, (void*)zz_buf, len); \ - } while (0) - -#define BUF_LEN 1024 // general purpose -static Char buf [BUF_LEN]; -static Char buf2[BUF_LEN]; -static Char buf3[BUF_LEN]; - -static UInt sigstacks_space = 0; // Current signal stacks space sum - -static VgHashTable malloc_list = NULL; // HP_Chunks - -static UInt n_heap_blocks = 0; - - -#define MAX_ALLOC_FNS 32 // includes the builtin ones - -// First few filled in, rest should be zeroed. Zero-terminated vector. -static UInt n_alloc_fns = 11; -static Char* alloc_fns[MAX_ALLOC_FNS] = { - "malloc", - "operator new(unsigned)", - "operator new[](unsigned)", - "operator new(unsigned, std::nothrow_t const&)", - "operator new[](unsigned, std::nothrow_t const&)", - "__builtin_new", - "__builtin_vec_new", - "calloc", - "realloc", - "my_malloc", // from vg_libpthread.c - "memalign", -}; - - -/*------------------------------------------------------------*/ -/*--- Command line args ---*/ -/*------------------------------------------------------------*/ - -#define MAX_DEPTH 50 - -typedef - enum { - XText, XHTML, - } - XFormat; - -static Bool clo_heap = True; -static UInt clo_heap_admin = 8; -static Bool clo_stacks = True; -static Bool clo_depth = 3; -static XFormat clo_format = XText; - -Bool SK_(process_cmd_line_option)(Char* arg) -{ - VG_BOOL_CLO("--heap", clo_heap) - else VG_BOOL_CLO("--stacks", clo_stacks) - - else VG_NUM_CLO ("--heap-admin", clo_heap_admin) - else VG_BNUM_CLO("--depth", clo_depth, 1, MAX_DEPTH) - - else if (VG_CLO_STREQN(11, arg, "--alloc-fn=")) { - alloc_fns[n_alloc_fns] = & arg[11]; - n_alloc_fns++; - if (n_alloc_fns >= MAX_ALLOC_FNS) { - VG_(printf)("Too many alloc functions specified, sorry"); - VG_(bad_option)(arg); - } - } - - else if (VG_CLO_STREQ(arg, "--format=text")) - clo_format = XText; - else if (VG_CLO_STREQ(arg, "--format=html")) - clo_format = XHTML; - - else - return VG_(replacement_malloc_process_cmd_line_option)(arg); - - return True; -} - -void SK_(print_usage)(void) -{ - VG_(printf)( -" --heap=no|yes profile heap blocks [yes]\n" -" --heap-admin= average admin bytes per heap block [8]\n" -" --stacks=no|yes profile stack(s) [yes]\n" -" --depth= depth of contexts [3]\n" -" --alloc-fn= specify as an alloc function [empty]\n" -" --format=text|html format of textual output [text]\n" - ); - VG_(replacement_malloc_print_usage)(); -} - -void SK_(print_debug_usage)(void) -{ - VG_(replacement_malloc_print_debug_usage)(); -} - -/*------------------------------------------------------------*/ -/*--- Execution contexts ---*/ -/*------------------------------------------------------------*/ - -// Fake XPt representing all allocation functions like malloc(). Acts as -// parent node to all top-XPts. -static XPt* alloc_xpt; - -// Cheap allocation for blocks that never need to be freed. Saves about 10% -// for Konqueror startup with --depth=40. -static void* perm_malloc(UInt n_bytes) -{ - static Addr hp = 0; // current heap pointer - static Addr hp_lim = 0; // maximum usable byte in current block - - #define SUPERBLOCK_SIZE (1 << 20) // 1 MB - - if (hp + n_bytes > hp_lim) { - hp = (Addr)VG_(get_memory_from_mmap)(SUPERBLOCK_SIZE, "perm_malloc"); - hp_lim = hp + SUPERBLOCK_SIZE - 1; - } - - hp += n_bytes; - - return (void*)(hp - n_bytes); -} - - - -static XPt* new_XPt(Addr eip, XPt* parent, Bool is_bottom) -{ - XPt* xpt = perm_malloc(sizeof(XPt)); - xpt->eip = eip; - - xpt->curr_space = 0; - xpt->approx_ST = 0; - xpt->exact_ST_dbld = 0; - - xpt->parent = parent; - - // Check parent is not a bottom-XPt - sk_assert(parent == NULL || 0 != parent->max_children); - - xpt->n_children = 0; - - // If a bottom-XPt, don't allocate space for children. This can be 50% - // or more, although it tends to drop as --depth increases (eg. 10% for - // konqueror with --depth=20). - if ( is_bottom ) { - xpt->max_children = 0; - xpt->children = NULL; - n_bot_xpts++; - } else { - xpt->max_children = 4; - xpt->children = VG_(malloc)( xpt->max_children * sizeof(XPt*) ); - } - - // Update statistics - n_xpts++; - - return xpt; -} - -static Bool is_alloc_fn(Addr eip) -{ - Int i; - - if ( VG_(get_fnname)(eip, buf, BUF_LEN) ) { - for (i = 0; i < n_alloc_fns; i++) { - if (VG_STREQ(buf, alloc_fns[i])) - return True; - } - } - return False; -} - -// Returns an XCon, from the bottom-XPt. Nb: the XPt returned must be a -// bottom-XPt now and must always remain a bottom-XPt. We go to some effort -// to ensure this in certain cases. See comments below. -static XPt* get_XCon( ThreadId tid, Bool custom_malloc ) -{ - // Static to minimise stack size. +1 for added 0xffffffff %eip. - static Addr eips[MAX_DEPTH + MAX_ALLOC_FNS + 1]; - - XPt* xpt = alloc_xpt; - UInt n_eips, L, A, B, nC; - UInt overestimate; - Bool reached_bottom; - - VGP_PUSHCC(VgpGetXPt); - - // Want at least clo_depth non-alloc-fn entries in the snapshot. - // However, because we have 1 or more (an unknown number, at this point) - // alloc-fns ignored, we overestimate the size needed for the stack - // snapshot. Then, if necessary, we repeatedly increase the size until - // it is enough. - overestimate = 2; - while (True) { - n_eips = VG_(stack_snapshot)( tid, eips, clo_depth + overestimate ); - - // Now we add a dummy "unknown" %eip at the end. This is only used if we - // run out of %eips before hitting clo_depth. It's done to ensure the - // XPt we return is (now and forever) a bottom-XPt. If the returned XPt - // wasn't a bottom-XPt (now or later) it would cause problems later (eg. - // the parent's approx_ST wouldn't be equal [or almost equal] to the - // total of the childrens' approx_STs). - eips[ n_eips++ ] = 0xffffffff; - - // Skip over alloc functions in eips[]. - for (L = 0; is_alloc_fn(eips[L]) && L < n_eips; L++) { } - - // Must be at least one alloc function, unless client used - // MALLOCLIKE_BLOCK - if (!custom_malloc) sk_assert(L > 0); - - // Should be at least one non-alloc function. If not, try again. - if (L == n_eips) { - overestimate += 2; - if (overestimate > MAX_ALLOC_FNS) - VG_(skin_panic)("No stk snapshot big enough to find non-alloc fns"); - } else { - break; - } - } - A = L; - B = n_eips - 1; - reached_bottom = False; - - // By this point, the eips we care about are in eips[A]..eips[B] - - // Now do the search/insertion of the XCon. 'L' is the loop counter, - // being the index into eips[]. - while (True) { - // Look for %eip in xpt's children. - // XXX: linear search, ugh -- about 10% of time for konqueror startup - // XXX: tried cacheing last result, only hit about 4% for konqueror - // Nb: this search hits about 98% of the time for konqueror - VGP_PUSHCC(VgpGetXPtSearch); - - // If we've searched/added deep enough, or run out of EIPs, this is - // the bottom XPt. - if (L - A + 1 == clo_depth || L == B) - reached_bottom = True; - - nC = 0; - while (True) { - if (nC == xpt->n_children) { - // not found, insert new XPt - sk_assert(xpt->max_children != 0); - sk_assert(xpt->n_children <= xpt->max_children); - // Expand 'children' if necessary - if (xpt->n_children == xpt->max_children) { - xpt->max_children *= 2; - xpt->children = VG_(realloc)( xpt->children, - xpt->max_children * sizeof(XPt*) ); - n_children_reallocs++; - } - // Make new XPt for %eip, insert in list - xpt->children[ xpt->n_children++ ] = - new_XPt(eips[L], xpt, reached_bottom); - break; - } - if (eips[L] == xpt->children[nC]->eip) break; // found the %eip - nC++; // keep looking - } - VGP_POPCC(VgpGetXPtSearch); - - // Return found/built bottom-XPt. - if (reached_bottom) { - sk_assert(0 == xpt->children[nC]->n_children); // Must be bottom-XPt - VGP_POPCC(VgpGetXPt); - return xpt->children[nC]; - } - - // Descend to next level in XTree, the newly found/built non-bottom-XPt - xpt = xpt->children[nC]; - L++; - } -} - -// Update 'curr_space' of every XPt in the XCon, by percolating upwards. -static void update_XCon(XPt* xpt, Int space_delta) -{ - VGP_PUSHCC(VgpUpdateXCon); - - sk_assert(True == clo_heap); - sk_assert(0 != space_delta); - sk_assert(NULL != xpt); - sk_assert(0 == xpt->n_children); // must be bottom-XPt - - while (xpt != alloc_xpt) { - if (space_delta < 0) sk_assert(xpt->curr_space >= -space_delta); - xpt->curr_space += space_delta; - xpt = xpt->parent; - } - if (space_delta < 0) sk_assert(alloc_xpt->curr_space >= -space_delta); - alloc_xpt->curr_space += space_delta; - - VGP_POPCC(VgpUpdateXCon); -} - -// Actually want a reverse sort, biggest to smallest -static Int XPt_cmp_approx_ST(void* n1, void* n2) -{ - XPt* xpt1 = *(XPt**)n1; - XPt* xpt2 = *(XPt**)n2; - return (xpt1->approx_ST < xpt2->approx_ST ? 1 : -1); -} - -static Int XPt_cmp_exact_ST_dbld(void* n1, void* n2) -{ - XPt* xpt1 = *(XPt**)n1; - XPt* xpt2 = *(XPt**)n2; - return (xpt1->exact_ST_dbld < xpt2->exact_ST_dbld ? 1 : -1); -} - - -/*------------------------------------------------------------*/ -/*--- A generic Queue ---*/ -/*------------------------------------------------------------*/ - -typedef - struct { - UInt head; // Index of first entry - UInt tail; // Index of final+1 entry, ie. next free slot - UInt max_elems; - void** elems; - } - Queue; - -static Queue* construct_queue(UInt size) -{ - UInt i; - Queue* q = VG_(malloc)(sizeof(Queue)); - q->head = 0; - q->tail = 0; - q->max_elems = size; - q->elems = VG_(malloc)(size * sizeof(void*)); - for (i = 0; i < size; i++) - q->elems[i] = NULL; - - return q; -} - -static void destruct_queue(Queue* q) -{ - VG_(free)(q->elems); - VG_(free)(q); -} - -static void shuffle(Queue* dest_q, void** old_elems) -{ - UInt i, j; - for (i = 0, j = dest_q->head; j < dest_q->tail; i++, j++) - dest_q->elems[i] = old_elems[j]; - dest_q->head = 0; - dest_q->tail = i; - for ( ; i < dest_q->max_elems; i++) - dest_q->elems[i] = NULL; // paranoia -} - -// Shuffles elements down. If not enough slots free, increase size. (We -// don't wait until we've completely run out of space, because there could -// be lots of shuffling just before that point which would be slow.) -static void adjust(Queue* q) -{ - void** old_elems; - - sk_assert(q->tail == q->max_elems); - if (q->head < 10) { - old_elems = q->elems; - q->max_elems *= 2; - q->elems = VG_(malloc)(q->max_elems * sizeof(void*)); - shuffle(q, old_elems); - VG_(free)(old_elems); - } else { - shuffle(q, q->elems); - } -} - -static void enqueue(Queue* q, void* elem) -{ - if (q->tail == q->max_elems) - adjust(q); - q->elems[q->tail++] = elem; -} - -static Bool is_empty_queue(Queue* q) -{ - return (q->head == q->tail); -} - -static void* dequeue(Queue* q) -{ - if (is_empty_queue(q)) - return NULL; // Queue empty - else - return q->elems[q->head++]; -} - -/*------------------------------------------------------------*/ -/*--- malloc() et al replacement wrappers ---*/ -/*------------------------------------------------------------*/ - -static __inline__ -void add_HP_Chunk(HP_Chunk* hc) -{ - n_heap_blocks++; - VG_(HT_add_node) ( malloc_list, (VgHashNode*)hc ); -} - -static __inline__ -HP_Chunk* get_HP_Chunk(void* p, HP_Chunk*** prev_chunks_next_ptr) -{ - return (HP_Chunk*)VG_(HT_get_node) ( malloc_list, (UInt)p, - (VgHashNode***)prev_chunks_next_ptr ); -} - -static __inline__ -void remove_HP_Chunk(HP_Chunk* hc, HP_Chunk** prev_chunks_next_ptr) -{ - sk_assert(n_heap_blocks > 0); - n_heap_blocks--; - *prev_chunks_next_ptr = hc->next; -} - -// Forward declaration -static void hp_census(void); - -static -void* new_block ( void* p, Int size, UInt align, Bool is_zeroed ) -{ - HP_Chunk* hc; - Bool custom_alloc = (NULL == p); - if (size < 0) return NULL; - - VGP_PUSHCC(VgpCliMalloc); - - // Update statistics - n_allocs++; - if (0 == size) n_zero_allocs++; - - // Allocate and zero if necessary - if (!p) { - p = VG_(cli_malloc)( align, size ); - if (!p) { - VGP_POPCC(VgpCliMalloc); - return NULL; - } - if (is_zeroed) VG_(memset)(p, 0, size); - } - - // Make new HP_Chunk node, add to malloclist - hc = VG_(malloc)(sizeof(HP_Chunk)); - hc->size = size; - hc->data = (Addr)p; - hc->where = NULL; // paranoia - if (clo_heap) { - hc->where = get_XCon( VG_(get_current_or_recent_tid)(), custom_alloc ); - if (0 != size) - update_XCon(hc->where, size); - } - add_HP_Chunk( hc ); - - // do a census! - hp_census(); - - VGP_POPCC(VgpCliMalloc); - return p; -} - -static __inline__ -void die_block ( void* p, Bool custom_free ) -{ - HP_Chunk *hc, **remove_handle; - - VGP_PUSHCC(VgpCliMalloc); - - // Update statistics - n_frees++; - - // Remove HP_Chunk from malloclist - hc = get_HP_Chunk( p, &remove_handle ); - if (hc == NULL) - return; // must have been a bogus free(), or p==NULL - sk_assert(hc->data == (Addr)p); - remove_HP_Chunk(hc, remove_handle); - - if (clo_heap && hc->size != 0) - update_XCon(hc->where, -hc->size); - - VG_(free)( hc ); - - // Actually free the heap block, if necessary - if (!custom_free) - VG_(cli_free)( p ); - - // do a census! - hp_census(); - - VGP_POPCC(VgpCliMalloc); -} - - -void* SK_(malloc) ( Int n ) -{ - return new_block( NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(__builtin_new) ( Int n ) -{ - return new_block( NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(__builtin_vec_new) ( Int n ) -{ - return new_block( NULL, n, VG_(clo_alignment), /*is_zeroed*/False ); -} - -void* SK_(calloc) ( Int m, Int size ) -{ - return new_block( NULL, m*size, VG_(clo_alignment), /*is_zeroed*/True ); -} - -void *SK_(memalign)( Int align, Int n ) -{ - return new_block( NULL, n, align, False ); -} - -void SK_(free) ( void* p ) -{ - die_block( p, /*custom_free*/False ); -} - -void SK_(__builtin_delete) ( void* p ) -{ - die_block( p, /*custom_free*/False); -} - -void SK_(__builtin_vec_delete) ( void* p ) -{ - die_block( p, /*custom_free*/False ); -} - -void* SK_(realloc) ( void* p_old, Int new_size ) -{ - HP_Chunk* hc; - HP_Chunk** remove_handle; - Int i; - void* p_new; - UInt old_size; - XPt *old_where, *new_where; - - VGP_PUSHCC(VgpCliMalloc); - - // First try and find the block. - hc = get_HP_Chunk ( p_old, &remove_handle ); - if (hc == NULL) { - VGP_POPCC(VgpCliMalloc); - return NULL; // must have been a bogus free() - } - - sk_assert(hc->data == (Addr)p_old); - old_size = hc->size; - - if (new_size <= old_size) { - // new size is smaller or same; block not moved - p_new = p_old; - - } else { - // new size is bigger; make new block, copy shared contents, free old - p_new = VG_(cli_malloc)(VG_(clo_alignment), new_size); - - for (i = 0; i < old_size; i++) - ((UChar*)p_new)[i] = ((UChar*)p_old)[i]; - - VG_(cli_free)(p_old); - } - - old_where = hc->where; - new_where = get_XCon( VG_(get_current_or_recent_tid)(), - /*custom_malloc*/False); - - // Update HP_Chunk - hc->data = (Addr)p_new; - hc->size = new_size; - hc->where = new_where; - - // Update XPt curr_space fields - if (clo_heap) { - if (0 != old_size) update_XCon(old_where, -old_size); - if (0 != new_size) update_XCon(new_where, new_size); - } - - // If block has moved, have to remove and reinsert in the malloclist - // (since the updated 'data' field is the hash lookup key). - if (p_new != p_old) { - remove_HP_Chunk(hc, remove_handle); - add_HP_Chunk(hc); - } - - VGP_POPCC(VgpCliMalloc); - return p_new; -} - - -/*------------------------------------------------------------*/ -/*--- Taking a census ---*/ -/*------------------------------------------------------------*/ - -static Census censi[MAX_N_CENSI]; -static UInt curr_census = 0; - -// Must return False so that all stacks are traversed -static Bool count_stack_size( Addr stack_min, Addr stack_max, void *cp ) -{ - *(UInt *)cp += (stack_max - stack_min); - return False; -} - -static UInt get_xtree_size(XPt* xpt, UInt ix) -{ - UInt i; - - // If no memory allocated at all, nothing interesting to record. - if (alloc_xpt->curr_space == 0) return 0; - - // Ignore sub-XTrees that account for a miniscule fraction of current - // allocated space. - if (xpt->curr_space / (double)alloc_xpt->curr_space > 0.002) { - ix++; - - // Count all (non-zero) descendent XPts - for (i = 0; i < xpt->n_children; i++) - ix = get_xtree_size(xpt->children[i], ix); - } - return ix; -} - -static -UInt do_space_snapshot(XPt xpt[], XTreeSnapshot xtree_snapshot, UInt ix) -{ - UInt i; - - // Structure of this function mirrors that of get_xtree_size(). - - if (alloc_xpt->curr_space == 0) return 0; - - if (xpt->curr_space / (double)alloc_xpt->curr_space > 0.002) { - xtree_snapshot[ix].xpt = xpt; - xtree_snapshot[ix].space = xpt->curr_space; - ix++; - - for (i = 0; i < xpt->n_children; i++) - ix = do_space_snapshot(xpt->children[i], xtree_snapshot, ix); - } - return ix; -} - -static UInt ms_interval; -static UInt do_every_nth_census = 30; - -// Weed out half the censi; we choose those that represent the smallest -// time-spans, because that loses the least information. -// -// Algorithm for N censi: We find the census representing the smallest -// timeframe, and remove it. We repeat this until (N/2)-1 censi are gone. -// (It's (N/2)-1 because we never remove the first and last censi.) -// We have to do this one census at a time, rather than finding the (N/2)-1 -// smallest censi in one hit, because when a census is removed, it's -// neighbours immediately cover greater timespans. So it's N^2, but N only -// equals 200, and this is only done every 100 censi, which is not too often. -static void halve_censi(void) -{ - Int i, jp, j, jn, k; - Census* min_census; - - n_halvings++; - if (VG_(clo_verbosity) > 1) - VG_(message)(Vg_UserMsg, "Halving censi..."); - - // Sets j to the index of the first not-yet-removed census at or after i - #define FIND_CENSUS(i, j) \ - for (j = i; -1 == censi[j].ms_time; j++) { } - - for (i = 2; i < MAX_N_CENSI; i += 2) { - // Find the censi representing the smallest timespan. The timespan - // for census n = d(N-1,N)+d(N,N+1), where d(A,B) is the time between - // censi A and B. We don't consider the first and last censi for - // removal. - Int min_span = 0x7fffffff; - Int min_j = 0; - - // Initial triple: (prev, curr, next) == (jp, j, jn) - jp = 0; - FIND_CENSUS(1, j); - FIND_CENSUS(j+1, jn); - while (jn < MAX_N_CENSI) { - Int timespan = censi[jn].ms_time - censi[jp].ms_time; - sk_assert(timespan >= 0); - if (timespan < min_span) { - min_span = timespan; - min_j = j; - } - // Move on to next triple - jp = j; - j = jn; - FIND_CENSUS(jn+1, jn); - } - // We've found the least important census, now remove it - min_census = & censi[ min_j ]; - for (k = 0; NULL != min_census->xtree_snapshots[k]; k++) { - n_snapshot_frees++; - VG_(free)(min_census->xtree_snapshots[k]); - min_census->xtree_snapshots[k] = NULL; - } - min_census->ms_time = -1; - } - - // Slide down the remaining censi over the removed ones. The '<=' is - // because we are removing on (N/2)-1, rather than N/2. - for (i = 0, j = 0; i <= MAX_N_CENSI / 2; i++, j++) { - FIND_CENSUS(j, j); - if (i != j) { - censi[i] = censi[j]; - } - } - curr_census = i; - - // Double intervals - ms_interval *= 2; - do_every_nth_census *= 2; - - if (VG_(clo_verbosity) > 1) - VG_(message)(Vg_UserMsg, "...done"); -} - -// Take a census. Census time seems to be insignificant (usually <= 0 ms, -// almost always <= 1ms) so don't have to worry about subtracting it from -// running time in any way. -// -// XXX: NOT TRUE! with bigger depths, konqueror censuses can easily take -// 50ms! -static void hp_census(void) -{ - static UInt ms_prev_census = 0; - static UInt ms_next_census = 0; // zero allows startup census - - Int ms_time, ms_time_since_prev; - Int i, K; - Census* census; - - VGP_PUSHCC(VgpCensus); - - // Only do a census if it's time - ms_time = VG_(read_millisecond_timer)(); - ms_time_since_prev = ms_time - ms_prev_census; - if (ms_time < ms_next_census) { - n_fake_censi++; - VGP_POPCC(VgpCensus); - return; - } - n_real_censi++; - - census = & censi[curr_census]; - - census->ms_time = ms_time; - - // Heap: snapshot the K most significant XTrees ------------------- - if (clo_heap) { - K = ( alloc_xpt->n_children < MAX_SNAPSHOTS - ? alloc_xpt->n_children - : MAX_SNAPSHOTS); // max out - - // Update .approx_ST field (approximatively) for all top-XPts. - // We *do not* do it for any non-top-XPTs. - for (i = 0; i < alloc_xpt->n_children; i++) { - XPt* top_XPt = alloc_xpt->children[i]; - top_XPt->approx_ST += top_XPt->curr_space * ms_time_since_prev; - } - // Sort top-XPts by approx_ST field. - VG_(ssort)(alloc_xpt->children, alloc_xpt->n_children, sizeof(XPt*), - XPt_cmp_approx_ST); - - VGP_PUSHCC(VgpCensusHeap); - - // For each significant top-level XPt, record space info about its - // entire XTree, in a single census entry. - // Nb: the xtree_size count/snapshot buffer allocation, and the actual - // snapshot, take similar amounts of time (measured with the - // millisecond counter). - for (i = 0; i < K; i++) { - UInt xtree_size, xtree_size2; -// VG_(printf)("%7u ", alloc_xpt->children[i]->approx_ST); - // Count how many XPts are in the XTree - VGP_PUSHCC(VgpCensusTreeSize); - xtree_size = get_xtree_size( alloc_xpt->children[i], 0 ); - VGP_POPCC(VgpCensusTreeSize); - - // If no XPts counted (ie. alloc_xpt.curr_space==0 or XTree - // insignificant) then don't take any more snapshots. - if (0 == xtree_size) break; - - // Make array of the appropriate size (+1 for zero termination, - // which calloc() does for us). - census->xtree_snapshots[i] = - VG_(calloc)(xtree_size+1, sizeof(XPtSnapshot)); - if (0 && VG_(clo_verbosity) > 1) - VG_(printf)("calloc: %d (%d B)\n", xtree_size+1, - (xtree_size+1) * sizeof(XPtSnapshot)); - - // Take space-snapshot: copy 'curr_space' for every XPt in the - // XTree into the snapshot array, along with pointers to the XPts. - // (Except for ones with curr_space==0, which wouldn't contribute - // to the final exact_ST_dbld calculation anyway; excluding them - // saves a lot of memory and up to 40% time with big --depth valus. - VGP_PUSHCC(VgpCensusSnapshot); - xtree_size2 = do_space_snapshot(alloc_xpt->children[i], - census->xtree_snapshots[i], 0); - sk_assert(xtree_size == xtree_size2); - VGP_POPCC(VgpCensusSnapshot); - } -// VG_(printf)("\n\n"); - // Zero-terminate 'xtree_snapshot' array - census->xtree_snapshots[i] = NULL; - - VGP_POPCC(VgpCensusHeap); - - //VG_(printf)("printed %d censi\n", K); - - // Lump the rest into a single "others" entry. - census->others_space = 0; - for (i = K; i < alloc_xpt->n_children; i++) { - census->others_space += alloc_xpt->children[i]->curr_space; - } - } - - // Heap admin ------------------------------------------------------- - if (clo_heap_admin > 0) - census->heap_admin_space = clo_heap_admin * n_heap_blocks; - - // Stack(s) --------------------------------------------------------- - if (clo_stacks) { - census->stacks_space = sigstacks_space; - // slightly abusing this function - VG_(first_matching_thread_stack)( count_stack_size, &census->stacks_space ); - i++; - } - - // Finish, update interval if necessary ----------------------------- - curr_census++; - census = NULL; // don't use again now that curr_census changed - - // Halve the entries, if our census table is full - if (MAX_N_CENSI == curr_census) { - halve_censi(); - } - - // Take time for next census from now, rather than when this census - // should have happened. Because, if there's a big gap due to a kernel - // operation, there's no point doing catch-up censi every BB for a while - // -- that would just give N censi at almost the same time. - if (VG_(clo_verbosity) > 1) { - VG_(message)(Vg_UserMsg, "census: %d ms (took %d ms)", ms_time, - VG_(read_millisecond_timer)() - ms_time ); - } - ms_prev_census = ms_time; - ms_next_census = ms_time + ms_interval; - //ms_next_census += ms_interval; - - //VG_(printf)("Next: %d ms\n", ms_next_census); - - VGP_POPCC(VgpCensus); -} - -/*------------------------------------------------------------*/ -/*--- Tracked events ---*/ -/*------------------------------------------------------------*/ - -static void new_mem_stack_signal(Addr a, UInt len) -{ - sigstacks_space += len; -} - -static void die_mem_stack_signal(Addr a, UInt len) -{ - sk_assert(sigstacks_space >= len); - sigstacks_space -= len; -} - -/*------------------------------------------------------------*/ -/*--- Client Requests ---*/ -/*------------------------------------------------------------*/ - -Bool SK_(handle_client_request) ( ThreadId tid, UInt* argv, UInt* ret ) -{ - switch (argv[0]) { - case VG_USERREQ__MALLOCLIKE_BLOCK: { - void* res; - void* p = (void*)argv[1]; - UInt sizeB = argv[2]; - *ret = 0; - res = new_block( p, sizeB, /*align -- ignored*/0, /*is_zeroed*/False ); - sk_assert(res == p); - return True; - } - case VG_USERREQ__FREELIKE_BLOCK: { - void* p = (void*)argv[1]; - *ret = 0; - die_block( p, /*custom_free*/True ); - return True; - } - default: - *ret = 0; - return False; - } -} - -/*------------------------------------------------------------*/ -/*--- Initialisation ---*/ -/*------------------------------------------------------------*/ - -// Current directory at startup. -static Char* base_dir; - -UInt VG_(vg_malloc_redzone_szB) = 0; - -void SK_(pre_clo_init)() -{ - VG_(details_name) ("Massif"); - VG_(details_version) (NULL); - VG_(details_description) ("a space profiler"); - VG_(details_copyright_author)("Copyright (C) 2003, Nicholas Nethercote"); - VG_(details_bug_reports_to) (VG_BUGS_TO); - - // Needs - VG_(needs_libc_freeres)(); - VG_(needs_command_line_options)(); - VG_(needs_client_requests) (); - - // Events to track - VG_(init_new_mem_stack_signal) ( new_mem_stack_signal ); - VG_(init_die_mem_stack_signal) ( die_mem_stack_signal ); - - // Profiling events - VGP_(register_profile_event)(VgpGetXPt, "get-XPt"); - VGP_(register_profile_event)(VgpGetXPtSearch, "get-XPt-search"); - VGP_(register_profile_event)(VgpCensus, "census"); - VGP_(register_profile_event)(VgpCensusHeap, "census-heap"); - VGP_(register_profile_event)(VgpCensusSnapshot, "census-snapshot"); - VGP_(register_profile_event)(VgpCensusTreeSize, "census-treesize"); - VGP_(register_profile_event)(VgpUpdateXCon, "update-XCon"); - VGP_(register_profile_event)(VgpCalcSpacetime2, "calc-exact_ST_dbld"); - VGP_(register_profile_event)(VgpPrintHp, "print-hp"); - VGP_(register_profile_event)(VgpPrintXPts, "print-XPts"); - - // HP_Chunks - malloc_list = VG_(HT_construct)(); - - // Dummy node at top of the context structure. - alloc_xpt = new_XPt(0, NULL, /*is_bottom*/False); - - sk_assert( VG_(getcwd_alloc)(&base_dir) ); -} - -void SK_(post_clo_init)(void) -{ - ms_interval = 1; - - // Do an initial sample for t = 0 - hp_census(); -} - -/*------------------------------------------------------------*/ -/*--- Instrumentation ---*/ -/*------------------------------------------------------------*/ - -UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr) -{ - return cb_in; -} - -/*------------------------------------------------------------*/ -/*--- Spacetime recomputation ---*/ -/*------------------------------------------------------------*/ - -// Although we've been calculating space-time along the way, because the -// earlier calculations were done at a finer timescale, the .approx_ST field -// might not agree with what hp2ps sees, because we've thrown away some of -// the information. So recompute it at the scale that hp2ps sees, so we can -// confidently determine which contexts hp2ps will choose for displaying as -// distinct bands. This recomputation only happens to the significant ones -// that get printed in the .hp file, so it's cheap. -// -// The approx_ST calculation: -// ( a[0]*d(0,1) + a[1]*(d(0,1) + d(1,2)) + ... + a[N-1]*d(N-2,N-1) ) / 2 -// where -// a[N] is the space at census N -// d(A,B) is the time interval between censi A and B -// and -// d(A,B) + d(B,C) == d(A,C) -// -// Key point: we can calculate the area for a census without knowing the -// previous or subsequent censi's space; because any over/underestimates -// for this census will be reversed in the next, balancing out. This is -// important, as getting the previous/next census entry for a particular -// AP is a pain with this data structure, but getting the prev/next -// census time is easy. -// -// Each heap calculation gets added to its context's exact_ST_dbld field. -// The ULong* values are all running totals, hence the use of "+=" everywhere. - -// This does the calculations for a single census. -static void calc_exact_ST_dbld2(Census* census, UInt d_t1_t2, - ULong* twice_heap_ST, - ULong* twice_heap_admin_ST, - ULong* twice_stack_ST) -{ - UInt i, j; - XPtSnapshot* xpt_snapshot; - - // Heap -------------------------------------------------------- - if (clo_heap) { - for (i = 0; NULL != census->xtree_snapshots[i]; i++) { - // Compute total heap exact_ST_dbld for the entire XTree using only - // the top-XPt (the first XPt in xtree_snapshot). - *twice_heap_ST += d_t1_t2 * census->xtree_snapshots[i][0].space; - - // Increment exact_ST_dbld for every XPt in xtree_snapshot (inc. - // top one) - for (j = 0; NULL != census->xtree_snapshots[i][j].xpt; j++) { - xpt_snapshot = & census->xtree_snapshots[i][j]; - xpt_snapshot->xpt->exact_ST_dbld += d_t1_t2 * xpt_snapshot->space; - } - } - *twice_heap_ST += d_t1_t2 * census->others_space; - } - - // Heap admin -------------------------------------------------- - if (clo_heap_admin > 0) - *twice_heap_admin_ST += d_t1_t2 * census->heap_admin_space; - - // Stack(s) ---------------------------------------------------- - if (clo_stacks) - *twice_stack_ST += d_t1_t2 * census->stacks_space; -} - -// This does the calculations for all censi. -static void calc_exact_ST_dbld(ULong* heap2, ULong* heap_admin2, ULong* stack2) -{ - UInt i, N = curr_census; - - VGP_PUSHCC(VgpCalcSpacetime2); - - *heap2 = 0; - *heap_admin2 = 0; - *stack2 = 0; - - if (N <= 1) - return; - - calc_exact_ST_dbld2( &censi[0], censi[1].ms_time - censi[0].ms_time, - heap2, heap_admin2, stack2 ); - - for (i = 1; i <= N-2; i++) { - calc_exact_ST_dbld2( & censi[i], censi[i+1].ms_time - censi[i-1].ms_time, - heap2, heap_admin2, stack2 ); - } - - calc_exact_ST_dbld2( & censi[N-1], censi[N-1].ms_time - censi[N-2].ms_time, - heap2, heap_admin2, stack2 ); - // Now get rid of the halves. May lose a 0.5 on each, doesn't matter. - *heap2 /= 2; - *heap_admin2 /= 2; - *stack2 /= 2; - - VGP_POPCC(VgpCalcSpacetime2); -} - -/*------------------------------------------------------------*/ -/*--- Writing the graph file ---*/ -/*------------------------------------------------------------*/ - -static Char* make_filename(Char* dir, Char* suffix) -{ - Char* filename; - - /* Block is big enough for dir name + massif.. */ - filename = VG_(malloc)((VG_(strlen)(dir) + 32)*sizeof(Char)); - VG_(sprintf)(filename, "%s/massif.%d%s", dir, VG_(getpid)(), suffix); - - return filename; -} - -// Make string acceptable to hp2ps (sigh): remove spaces, escape parentheses. -static Char* clean_fnname(Char *d, Char* s) -{ - Char* dorig = d; - while (*s) { - if (' ' == *s) { *d = '%'; } - else if ('(' == *s) { *d++ = '\\'; *d = '('; } - else if (')' == *s) { *d++ = '\\'; *d = ')'; } - else { *d = *s; }; - s++; - d++; - } - *d = '\0'; - return dorig; -} - -static void file_err ( Char* file ) -{ - VG_(message)(Vg_UserMsg, "error: can't open output file `%s'", file ); - VG_(message)(Vg_UserMsg, " ... so profile results will be missing."); -} - -/* Format, by example: - - JOB "a.out -p" - DATE "Fri Apr 17 11:43:45 1992" - SAMPLE_UNIT "seconds" - VALUE_UNIT "bytes" - BEGIN_SAMPLE 0.00 - SYSTEM 24 - END_SAMPLE 0.00 - BEGIN_SAMPLE 1.00 - elim 180 - insert 24 - intersect 12 - disin 60 - main 12 - reduce 20 - SYSTEM 12 - END_SAMPLE 1.00 - MARK 1.50 - MARK 1.75 - MARK 1.80 - BEGIN_SAMPLE 2.00 - elim 192 - insert 24 - intersect 12 - disin 84 - main 12 - SYSTEM 24 - END_SAMPLE 2.00 - BEGIN_SAMPLE 2.82 - END_SAMPLE 2.82 - */ -static void write_hp_file(void) -{ - Int i, j; - Int fd, res; - Char *hp_file, *ps_file, *aux_file; - Char* cmdfmt; - Char* cmdbuf; - Int cmdlen; - - VGP_PUSHCC(VgpPrintHp); - - // Open file - hp_file = make_filename( base_dir, ".hp" ); - ps_file = make_filename( base_dir, ".ps" ); - aux_file = make_filename( base_dir, ".aux" ); - fd = VG_(open)(hp_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY, - VKI_S_IRUSR|VKI_S_IWUSR); - if (fd < 0) { - file_err( hp_file ); - VGP_POPCC(VgpPrintHp); - return; - } - - // File header, including command line - SPRINTF(buf, "JOB \""); - for (i = 0; i < VG_(client_argc); i++) - SPRINTF(buf, "%s ", VG_(client_argv)[i]); - SPRINTF(buf, /*" (%d ms/sample)\"\n"*/ "\"\n" - "DATE \"\"\n" - "SAMPLE_UNIT \"ms\"\n" - "VALUE_UNIT \"bytes\"\n", ms_interval); - - // Censi - for (i = 0; i < curr_census; i++) { - Census* census = & censi[i]; - - // Census start - SPRINTF(buf, "MARK %d.0\n" - "BEGIN_SAMPLE %d.0\n", - census->ms_time, census->ms_time); - - // Heap ----------------------------------------------------------- - if (clo_heap) { - // Print all the significant XPts from that census - for (j = 0; NULL != census->xtree_snapshots[j]; j++) { - // Grab the jth top-XPt - XTreeSnapshot xtree_snapshot = & census->xtree_snapshots[j][0]; - if ( ! VG_(get_fnname)(xtree_snapshot->xpt->eip, buf2, 16)) { - VG_(sprintf)(buf2, "???"); - } - SPRINTF(buf, "x%x:%s %d\n", xtree_snapshot->xpt->eip, - clean_fnname(buf3, buf2), xtree_snapshot->space); - } - - // Remaining heap block alloc points, combined - if (census->others_space > 0) - SPRINTF(buf, "other %d\n", census->others_space); - } - - // Heap admin ----------------------------------------------------- - if (clo_heap_admin > 0 && census->heap_admin_space) - SPRINTF(buf, "heap-admin %d\n", census->heap_admin_space); - - // Stack(s) ------------------------------------------------------- - if (clo_stacks) - SPRINTF(buf, "stack(s) %d\n", census->stacks_space); - - // Census end - SPRINTF(buf, "END_SAMPLE %d.0\n", census->ms_time); - } - - // Close file - sk_assert(fd >= 0); - VG_(close)(fd); - - // Attempt to convert file using hp2ps - cmdfmt = "%s/hp2ps -c -t1 %s"; - cmdlen = VG_(strlen)(VG_(libdir)) + VG_(strlen)(hp_file) - + VG_(strlen)(cmdfmt); - cmdbuf = VG_(malloc)( sizeof(Char) * cmdlen ); - VG_(sprintf)(cmdbuf, cmdfmt, VG_(libdir), hp_file); - res = VG_(system)(cmdbuf); - VG_(free)(cmdbuf); - if (res != 0) { - VG_(message)(Vg_UserMsg, - "Conversion to PostScript failed. Try converting manually."); - } else { - // remove the .hp and .aux file - VG_(unlink)(hp_file); - VG_(unlink)(aux_file); - } - - VG_(free)(hp_file); - VG_(free)(ps_file); - VG_(free)(aux_file); - - VGP_POPCC(VgpPrintHp); -} - -/*------------------------------------------------------------*/ -/*--- Writing the XPt text/HTML file ---*/ -/*------------------------------------------------------------*/ - -static void percentify(Int n, Int pow, Int field_width, char xbuf[]) -{ - int i, len, space; - - VG_(sprintf)(xbuf, "%d.%d%%", n / pow, n % pow); - len = VG_(strlen)(xbuf); - space = field_width - len; - if (space < 0) space = 0; /* Allow for v. small field_width */ - i = len; - - /* Right justify in field */ - for ( ; i >= 0; i--) xbuf[i + space] = xbuf[i]; - for (i = 0; i < space; i++) xbuf[i] = ' '; -} - -// Nb: uses a static buffer, each call trashes the last string returned. -static Char* make_perc(ULong spacetime, ULong total_spacetime) -{ - static Char mbuf[32]; - - UInt p = 10; - sk_assert(0 != total_spacetime); - percentify(spacetime * 100 * p / total_spacetime, p, 5, mbuf); - return mbuf; -} - -// Nb: passed in XPt is a lower-level XPt; %eips are grabbed from -// bottom-to-top of XCon, and then printed in the reverse order. -static UInt pp_XCon(Int fd, XPt* xpt) -{ - Addr rev_eips[clo_depth+1]; - Int i = 0; - Int n = 0; - Bool is_HTML = ( XHTML == clo_format ); - Char* maybe_br = ( is_HTML ? "
" : "" ); - Char* maybe_indent = ( is_HTML ? "  " : "" ); - - sk_assert(NULL != xpt); - - while (True) { - rev_eips[i] = xpt->eip; - n++; - if (alloc_xpt == xpt->parent) break; - i++; - xpt = xpt->parent; - } - - for (i = n-1; i >= 0; i--) { - // -1 means point to calling line - VG_(describe_eip)(rev_eips[i]-1, buf2, BUF_LEN); - SPRINTF(buf, " %s%s%s\n", maybe_indent, buf2, maybe_br); - } - - return n; -} - -// Important point: for HTML, each XPt must be identified uniquely for the -// HTML links to all match up correctly. Using xpt->eip is not -// sufficient, because function pointers mean that you can call more than -// one other function from a single code location. So instead we use the -// address of the xpt struct itself, which is guaranteed to be unique. - -static void pp_all_XPts2(Int fd, Queue* q, ULong heap_spacetime, - ULong total_spacetime) -{ - UInt i; - XPt *xpt, *child; - UInt L = 0; - UInt c1 = 1; - UInt c2 = 0; - ULong sum = 0; - UInt n; - Char *eip_desc, *perc; - Bool is_HTML = ( XHTML == clo_format ); - Char* maybe_br = ( is_HTML ? "
" : "" ); - Char* maybe_p = ( is_HTML ? "

" : "" ); - Char* maybe_ul = ( is_HTML ? "

    " : "" ); - Char* maybe_li = ( is_HTML ? "
  • " : "" ); - Char* maybe_fli = ( is_HTML ? "
  • " : "" ); - Char* maybe_ful = ( is_HTML ? "
" : "" ); - Char* end_hr = ( is_HTML ? "
" : - "=================================" ); - Char* depth = ( is_HTML ? "--depth" : "--depth" ); - - if (total_spacetime == 0) { - SPRINTF(buf, "(No heap memory allocated)\n"); - return; - } - - - SPRINTF(buf, "== %d ===========================%s\n", L, maybe_br); - - while (NULL != (xpt = (XPt*)dequeue(q))) { - // Check that non-top-level XPts have a zero .approx_ST field. - if (xpt->parent != alloc_xpt) sk_assert( 0 == xpt->approx_ST ); - - // Check that the sum of all children .exact_ST_dbld fields equals - // parent's (unless alloc_xpt, when it should == 0). - if (alloc_xpt == xpt) { - sk_assert(0 == xpt->exact_ST_dbld); - } else { - sum = 0; - for (i = 0; i < xpt->n_children; i++) { - sum += xpt->children[i]->exact_ST_dbld; - } - //sk_assert(sum == xpt->exact_ST_dbld); - // It's possible that not all the children were included in the - // exact_ST_dbld calculations. Hopefully almost all of them were, and - // all the important ones. -// sk_assert(sum <= xpt->exact_ST_dbld); -// sk_assert(sum * 1.05 > xpt->exact_ST_dbld ); -// if (sum != xpt->exact_ST_dbld) { -// VG_(printf)("%ld, %ld\n", sum, xpt->exact_ST_dbld); -// } - } - - if (xpt == alloc_xpt) { - SPRINTF(buf, "Heap allocation functions accounted for " - "%s of measured spacetime%s\n", - make_perc(heap_spacetime, total_spacetime), maybe_br); - } else { - // Remember: exact_ST_dbld is space.time *doubled* - perc = make_perc(xpt->exact_ST_dbld / 2, total_spacetime); - if (is_HTML) { - SPRINTF(buf, "" - "Context accounted for " - "%s of measured spacetime
\n", - xpt, xpt, perc); - } else { - SPRINTF(buf, "Context accounted for %s of measured spacetime\n", - perc); - } - n = pp_XCon(fd, xpt); - sk_assert(n == L); - } - - // Sort children by exact_ST_dbld - VG_(ssort)(xpt->children, xpt->n_children, sizeof(XPt*), - XPt_cmp_exact_ST_dbld); - - SPRINTF(buf, "%s\nCalled from:%s\n", maybe_p, maybe_ul); - for (i = 0; i < xpt->n_children; i++) { - child = xpt->children[i]; - - // Stop when <1% of total spacetime - if (child->exact_ST_dbld * 1000 / (total_spacetime * 2) < 5) { - UInt n_insig = xpt->n_children - i; - Char* s = ( n_insig == 1 ? "" : "s" ); - Char* and = ( 0 == i ? "" : "and " ); - Char* other = ( 0 == i ? "" : "other " ); - SPRINTF(buf, " %s%s%d %sinsignificant place%s%s\n\n", - maybe_li, and, n_insig, other, s, maybe_fli); - break; - } - - // Remember: exact_ST_dbld is space.time *doubled* - perc = make_perc(child->exact_ST_dbld / 2, total_spacetime); - eip_desc = VG_(describe_eip)(child->eip-1, buf2, BUF_LEN); - if (is_HTML) { - SPRINTF(buf, "
  • ", child ); - - if (child->n_children > 0) { - SPRINTF(buf, "%s", child, perc); - } else { - SPRINTF(buf, "%s", perc); - } - SPRINTF(buf, ": %s\n", eip_desc); - } else { - SPRINTF(buf, " %6s: %s\n\n", perc, eip_desc); - } - - if (child->n_children > 0) { - enqueue(q, (void*)child); - c2++; - } - } - SPRINTF(buf, "%s%s", maybe_ful, maybe_p); - c1--; - - // Putting markers between levels of the structure: - // c1 tracks how many to go on this level, c2 tracks how many we've - // queued up for the next level while finishing off this level. - // When c1 gets to zero, we've changed levels, so print a marker, - // move c2 into c1, and zero c2. - if (0 == c1) { - L++; - c1 = c2; - c2 = 0; - if (! is_empty_queue(q) ) { // avoid empty one at end - SPRINTF(buf, "== %d ===========================%s\n", L, maybe_br); - } - } else { - SPRINTF(buf, "---------------------------------%s\n", maybe_br); - } - } - SPRINTF(buf, "%s\n\nEnd of information. Rerun with a bigger " - "%s value for more.\n", end_hr, depth); -} - -static void pp_all_XPts(Int fd, XPt* xpt, ULong heap_spacetime, - ULong total_spacetime) -{ - Queue* q = construct_queue(100); - - enqueue(q, xpt); - pp_all_XPts2(fd, q, heap_spacetime, total_spacetime); - destruct_queue(q); -} - -static void -write_text_file(ULong total_ST, ULong heap_ST) -{ - Int fd, i; - Char* text_file; - Char* maybe_p = ( XHTML == clo_format ? "

    " : "" ); - - VGP_PUSHCC(VgpPrintXPts); - - // Open file - text_file = make_filename( base_dir, - ( XText == clo_format ? ".txt" : ".html" ) ); - - fd = VG_(open)(text_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY, - VKI_S_IRUSR|VKI_S_IWUSR); - if (fd < 0) { - file_err( text_file ); - VGP_POPCC(VgpPrintXPts); - return; - } - - // Header - if (XHTML == clo_format) { - SPRINTF(buf, "\n" - "\n" - "%s\n" - "\n" - "\n", - text_file); - } - - // Command line - SPRINTF(buf, "Command: "); - for (i = 0; i < VG_(client_argc); i++) - SPRINTF(buf, "%s ", VG_(client_argv)[i]); - SPRINTF(buf, "\n%s\n", maybe_p); - - if (clo_heap) - pp_all_XPts(fd, alloc_xpt, heap_ST, total_ST); - - sk_assert(fd >= 0); - VG_(close)(fd); - - VGP_POPCC(VgpPrintXPts); -} - -/*------------------------------------------------------------*/ -/*--- Finalisation ---*/ -/*------------------------------------------------------------*/ - -static void -print_summary(ULong total_ST, ULong heap_ST, ULong heap_admin_ST, - ULong stack_ST) -{ - VG_(message)(Vg_UserMsg, "Total spacetime: %,ld ms.B", total_ST); - - // Heap -------------------------------------------------------------- - if (clo_heap) - VG_(message)(Vg_UserMsg, "heap: %s", - ( 0 == total_ST ? (Char*)"(n/a)" - : make_perc(heap_ST, total_ST) ) ); - - // Heap admin -------------------------------------------------------- - if (clo_heap_admin) - VG_(message)(Vg_UserMsg, "heap admin: %s", - ( 0 == total_ST ? (Char*)"(n/a)" - : make_perc(heap_admin_ST, total_ST) ) ); - - sk_assert( VG_(HT_count_nodes)(malloc_list) == n_heap_blocks ); - - // Stack(s) ---------------------------------------------------------- - if (clo_stacks) { - sk_assert(0 != total_ST); - VG_(message)(Vg_UserMsg, "stack(s): %s", - make_perc(stack_ST, total_ST) ); - } - - if (VG_(clo_verbosity) > 1) { - sk_assert(n_xpts > 0); // always have alloc_xpt - VG_(message)(Vg_DebugMsg, " allocs: %u", n_allocs); - VG_(message)(Vg_DebugMsg, "zeroallocs: %u (%d%%)", n_zero_allocs, - n_zero_allocs * 100 / n_allocs ); - VG_(message)(Vg_DebugMsg, " frees: %u", n_frees); - VG_(message)(Vg_DebugMsg, " XPts: %u (%d B)", n_xpts, - n_xpts*sizeof(XPt)); - VG_(message)(Vg_DebugMsg, " bot-XPts: %u (%d%%)", n_bot_xpts, - n_bot_xpts * 100 / n_xpts); - VG_(message)(Vg_DebugMsg, " top-XPts: %u (%d%%)", alloc_xpt->n_children, - alloc_xpt->n_children * 100 / n_xpts); - VG_(message)(Vg_DebugMsg, "c-reallocs: %u", n_children_reallocs); - VG_(message)(Vg_DebugMsg, "snap-frees: %u", n_snapshot_frees); - VG_(message)(Vg_DebugMsg, "atmp censi: %u", n_attempted_censi); - VG_(message)(Vg_DebugMsg, "fake censi: %u", n_fake_censi); - VG_(message)(Vg_DebugMsg, "real censi: %u", n_real_censi); - VG_(message)(Vg_DebugMsg, " halvings: %u", n_halvings); - } -} - -void SK_(fini)(Int exit_status) -{ - ULong total_ST = 0; - ULong heap_ST = 0; - ULong heap_admin_ST = 0; - ULong stack_ST = 0; - - // Do a final (empty) sample to show program's end - hp_census(); - - // Redo spacetimes of significant contexts to match the .hp file. - calc_exact_ST_dbld(&heap_ST, &heap_admin_ST, &stack_ST); - total_ST = heap_ST + heap_admin_ST + stack_ST; - write_hp_file ( ); - write_text_file( total_ST, heap_ST ); - print_summary ( total_ST, heap_ST, heap_admin_ST, stack_ST ); -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 0) - -/*--------------------------------------------------------------------*/ -/*--- end ms_main.c ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/massif/tests/.cvsignore b/VEX/head20041019/massif/tests/.cvsignore deleted file mode 100644 index 36e014a1f..000000000 --- a/VEX/head20041019/massif/tests/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -Makefile.in -Makefile -massif.*.hp -massif.*.aux -massif.*.ps -massif.*.txt -massif.*.html -*.stdout.diff -*.stderr.diff -*.stdout.out -*.stderr.out diff --git a/VEX/head20041019/massif/tests/CVS/Entries b/VEX/head20041019/massif/tests/CVS/Entries deleted file mode 100644 index 574b572b7..000000000 --- a/VEX/head20041019/massif/tests/CVS/Entries +++ /dev/null @@ -1,10 +0,0 @@ -/.cvsignore/1.1/Sun Feb 22 19:34:55 2004// -/Makefile.am/1.2/Sat Jul 10 14:56:27 2004// -/filter_stderr/1.1/Sat Feb 14 16:48:35 2004// -/toobig-allocs.stderr.exp/1.1/Sat Jul 10 14:56:27 2004// -/toobig-allocs.vgtest/1.1/Sat Jul 10 14:56:27 2004// -/true_html.stderr.exp/1.1/Sat Feb 14 16:40:02 2004// -/true_html.vgtest/1.2/Sat Apr 17 17:25:08 2004// -/true_text.stderr.exp/1.1/Sat Feb 14 16:40:02 2004// -/true_text.vgtest/1.2/Sat Apr 17 17:25:08 2004// -D diff --git a/VEX/head20041019/massif/tests/CVS/Repository b/VEX/head20041019/massif/tests/CVS/Repository deleted file mode 100644 index 1b8e77267..000000000 --- a/VEX/head20041019/massif/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/massif/tests diff --git a/VEX/head20041019/massif/tests/CVS/Root b/VEX/head20041019/massif/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/massif/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/massif/tests/CVS/Template b/VEX/head20041019/massif/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/massif/tests/Makefile.am b/VEX/head20041019/massif/tests/Makefile.am deleted file mode 100644 index 0616d7802..000000000 --- a/VEX/head20041019/massif/tests/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -noinst_SCRIPTS = filter_stderr - -EXTRA_DIST = $(noinst_SCRIPTS) \ - toobig-allocs.stderr.exp toobig-allocs.vgtest \ - true_html.stderr.exp true_html.vgtest \ - true_text.stderr.exp true_text.vgtest - diff --git a/VEX/head20041019/massif/tests/filter_stderr b/VEX/head20041019/massif/tests/filter_stderr deleted file mode 100755 index f285a2720..000000000 --- a/VEX/head20041019/massif/tests/filter_stderr +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | - -# Remove numbers from all lines -sed "s/\([a-zA-Z(): ]*\)[ 0-9\.,()+rdw]*\(%\|ms.B\)$/\1/" - diff --git a/VEX/head20041019/massif/tests/toobig-allocs.stderr.exp b/VEX/head20041019/massif/tests/toobig-allocs.stderr.exp deleted file mode 100644 index 550068674..000000000 --- a/VEX/head20041019/massif/tests/toobig-allocs.stderr.exp +++ /dev/null @@ -1,8 +0,0 @@ - -Attempting too-big malloc()... -Attempting too-big mmap()... - -Total spacetime: -heap: -heap admin: -stack(s): diff --git a/VEX/head20041019/massif/tests/toobig-allocs.vgtest b/VEX/head20041019/massif/tests/toobig-allocs.vgtest deleted file mode 100644 index 186cf5f90..000000000 --- a/VEX/head20041019/massif/tests/toobig-allocs.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: ../../tests/toobig-allocs diff --git a/VEX/head20041019/massif/tests/true_html.stderr.exp b/VEX/head20041019/massif/tests/true_html.stderr.exp deleted file mode 100644 index c18e180c9..000000000 --- a/VEX/head20041019/massif/tests/true_html.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ - - -Total spacetime: -heap: -heap admin: -stack(s): diff --git a/VEX/head20041019/massif/tests/true_html.vgtest b/VEX/head20041019/massif/tests/true_html.vgtest deleted file mode 100644 index 7dfc68d82..000000000 --- a/VEX/head20041019/massif/tests/true_html.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: ../../tests/true -vgopts: --format=html -delete: massif.*.* diff --git a/VEX/head20041019/massif/tests/true_text.stderr.exp b/VEX/head20041019/massif/tests/true_text.stderr.exp deleted file mode 100644 index c18e180c9..000000000 --- a/VEX/head20041019/massif/tests/true_text.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ - - -Total spacetime: -heap: -heap admin: -stack(s): diff --git a/VEX/head20041019/massif/tests/true_text.vgtest b/VEX/head20041019/massif/tests/true_text.vgtest deleted file mode 100644 index 79f9796c4..000000000 --- a/VEX/head20041019/massif/tests/true_text.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: ../../tests/true -vgopts: --format=text -delete: massif.*.* diff --git a/VEX/head20041019/memcheck/.cvsignore b/VEX/head20041019/memcheck/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/memcheck/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/memcheck/CVS/Entries b/VEX/head20041019/memcheck/CVS/Entries deleted file mode 100644 index ff0eed04b..000000000 --- a/VEX/head20041019/memcheck/CVS/Entries +++ /dev/null @@ -1,18 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:34 2002// -/Makefile.am/1.52/Thu Sep 2 15:37:39 2004// -/mac_leakcheck.c/1.14/Tue Aug 3 13:29:08 2004// -/mac_malloc_wrappers.c/1.13/Sat Jul 10 14:56:27 2004// -/mac_needs.c/1.29/Sat Jul 10 14:56:27 2004// -/mac_replace_strmem.c/1.14/Wed Aug 25 13:33:17 2004// -/mac_shared.h/1.23/Thu Sep 2 08:51:43 2004// -/mc_asm.h/1.1/Thu Sep 2 15:37:39 2004// -/mc_clientreqs.c/1.21/Sun Jun 27 17:37:21 2004// -/mc_errcontext.c/1.22/Sun Jan 4 16:43:22 2004// -/mc_from_ucode.c/1.15/Sun Jan 4 16:43:22 2004// -/mc_helpers.S/1.10/Thu Sep 2 15:37:39 2004// -/mc_include.h/1.21/Thu Sep 2 15:37:39 2004// -/mc_main.c/1.53/Fri Sep 3 13:45:29 2004// -/mc_translate.c/1.43/Tue Aug 3 23:14:00 2004// -/memcheck.h/1.20/Wed Oct 6 12:18:47 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/memcheck/CVS/Repository b/VEX/head20041019/memcheck/CVS/Repository deleted file mode 100644 index 027eadb3e..000000000 --- a/VEX/head20041019/memcheck/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/memcheck diff --git a/VEX/head20041019/memcheck/CVS/Root b/VEX/head20041019/memcheck/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/memcheck/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/memcheck/CVS/Template b/VEX/head20041019/memcheck/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/Makefile.am b/VEX/head20041019/memcheck/Makefile.am deleted file mode 100644 index 632cebdea..000000000 --- a/VEX/head20041019/memcheck/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -## Build Memcheck at a higher optimisation level -AM_CFLAGS += -O2 - -val_PROGRAMS = vgskin_memcheck.so vgpreload_memcheck.so - -vgpreload_memcheck_so_SOURCES = \ - mac_replace_strmem.c -vgpreload_memcheck_so_LDADD = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_memcheck_so_DEPENDENCIES = $(top_builddir)/coregrind/vg_replace_malloc.o -vgpreload_memcheck_so_LDFLAGS = -shared -Wl,-z,interpose,-z,initfirst - -vgskin_memcheck_so_SOURCES = \ - mac_leakcheck.c \ - mac_malloc_wrappers.c \ - mac_needs.c \ - mc_main.c \ - mc_clientreqs.c \ - mc_errcontext.c \ - mc_from_ucode.c \ - mc_translate.c \ - mc_helpers.S -vgskin_memcheck_so_LDFLAGS = -shared - -mcincludedir = $(includedir)/valgrind - -mcinclude_HEADERS = \ - memcheck.h - -noinst_HEADERS = \ - mac_shared.h \ - mc_asm.h \ - mc_include.h - -mac_replace_strmem.o: CFLAGS += -fno-omit-frame-pointer -mc_main.o: CFLAGS += -fomit-frame-pointer diff --git a/VEX/head20041019/memcheck/docs/.cvsignore b/VEX/head20041019/memcheck/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/memcheck/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/memcheck/docs/CVS/Entries b/VEX/head20041019/memcheck/docs/CVS/Entries deleted file mode 100644 index f1e95dd9a..000000000 --- a/VEX/head20041019/memcheck/docs/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:35 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:06 2004// -/mc_main.html/1.12/Wed Oct 6 12:25:49 2004// -/mc_techdocs.html/1.10/Thu Sep 2 15:50:29 2004// -D diff --git a/VEX/head20041019/memcheck/docs/CVS/Repository b/VEX/head20041019/memcheck/docs/CVS/Repository deleted file mode 100644 index 4005d5f7c..000000000 --- a/VEX/head20041019/memcheck/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/memcheck/docs diff --git a/VEX/head20041019/memcheck/docs/CVS/Root b/VEX/head20041019/memcheck/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/memcheck/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/memcheck/docs/CVS/Template b/VEX/head20041019/memcheck/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/docs/Makefile.am b/VEX/head20041019/memcheck/docs/Makefile.am deleted file mode 100644 index 8d9e7c80e..000000000 --- a/VEX/head20041019/memcheck/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = mc_main.html mc_techdocs.html diff --git a/VEX/head20041019/memcheck/docs/mc_main.html b/VEX/head20041019/memcheck/docs/mc_main.html deleted file mode 100644 index 32b618160..000000000 --- a/VEX/head20041019/memcheck/docs/mc_main.html +++ /dev/null @@ -1,832 +0,0 @@ - - - - Memcheck: a heavyweight memory checker - - - -

    Memcheck: a heavyweight memory checker

    - -To use this tool, you must specify --tool=memcheck on the -Valgrind command line. - -

    3.1  Kinds of bugs that memcheck can find

    - -Memcheck is Valgrind-1.0.X's checking mechanism bundled up into a tool. - All reads and writes of memory are checked, and calls to - malloc/new/free/delete are intercepted. As a result, memcheck can - detect the following problems: -
      -
    • Use of uninitialised memory
    • -
    • Reading/writing memory after it has been free'd
    • -
    • Reading/writing off the end of malloc'd blocks
    • -
    • Reading/writing inappropriate areas on the stack
    • -
    • Memory leaks -- where pointers to malloc'd blocks are lost - forever
    • -
    • Mismatched use of malloc/new/new [] vs free/delete/delete []
    • -
    • Overlapping src and dst pointers in - memcpy() and related functions
    • -
    • Some misuses of the POSIX pthreads API
    • -
    -

    - - -

    3.2  Command-line flags specific to memcheck

    - -
      -
    • --leak-check=no [default]
      - --leak-check=yes -

      When enabled, search for memory leaks when the client program - finishes. A memory leak means a malloc'd block, which has not - yet been free'd, but to which no pointer can be found. Such a - block can never be free'd by the program, since no pointer to it - exists. Leak checking is disabled by default because it tends - to generate dozens of error messages.


    • - -

    • --show-reachable=no [default]
      - --show-reachable=yes -

      When disabled, the memory leak detector only shows blocks for - which it cannot find a pointer to at all, or it can only find a - pointer to the middle of. These blocks are prime candidates for - memory leaks. When enabled, the leak detector also reports on - blocks which it could find a pointer to. Your program could, at - least in principle, have freed such blocks before exit. - Contrast this to blocks for which no pointer, or only an - interior pointer could be found: they are more likely to - indicate memory leaks, because you do not actually have a - pointer to the start of the block which you can hand to - free, even if you wanted to.


    • - -

    • --leak-resolution=low [default]
      - --leak-resolution=med
      - --leak-resolution=high -

      When doing leak checking, determines how willing Memcheck is - to consider different backtraces to be the same. When set to - low, the default, only the first two entries need - match. When med, four entries have to match. When - high, all entries need to match. -

      - For hardcore leak debugging, you probably want to use - --leak-resolution=high together with - --num-callers=40 or some such large number. Note - however that this can give an overwhelming amount of - information, which is why the defaults are 4 callers and - low-resolution matching. -

      - Note that the --leak-resolution= setting does not - affect Memcheck's ability to find leaks. It only changes how - the results are presented. -


    • - -

    • --freelist-vol=<number> [default: 1000000] -

      When the client program releases memory using free (in C) or - delete (C++), that memory is not immediately made available for - re-allocation. Instead it is marked inaccessible and placed in - a queue of freed blocks. The purpose is to delay the point at - which freed-up memory comes back into circulation. This - increases the chance that Memcheck will be able to detect - invalid accesses to blocks for some significant period of time - after they have been freed. -

      - This flag specifies the maximum total size, in bytes, of the - blocks in the queue. The default value is one million bytes. - Increasing this increases the total amount of memory used by - Memcheck but may detect invalid uses of freed blocks which would - otherwise go undetected.


    • - -

    • --workaround-gcc296-bugs=no [default]
      - --workaround-gcc296-bugs=yes

      When enabled, - assume that reads and writes some small distance below the stack - pointer %esp are due to bugs in gcc 2.96, and does - not report them. The "small distance" is 256 bytes by default. - Note that gcc 2.96 is the default compiler on some popular Linux - distributions (RedHat 7.X, Mandrake) and so you may well need to - use this flag. Do not use it if you do not have to, as it can - cause real errors to be overlooked. Another option is to use a - gcc/g++ which does not generate accesses below the stack - pointer. 2.95.3 seems to be a good choice in this respect. -

      - Unfortunately (27 Feb 02) it looks like g++ 3.0.4 has a similar - bug, so you may need to issue this flag if you use 3.0.4. A - while later (early Apr 02) this is confirmed as a scheduling bug - in g++-3.0.4. -


    • - -

    • --partial-loads-ok=yes [the default]
      - --partial-loads-ok=no -

      Controls how Memcheck handles word (4-byte) loads from - addresses for which some bytes are addressible and others - are not. When yes (the default), such loads - do not elicit an address error. Instead, the loaded V bytes - corresponding to the illegal addresses indicate undefined, and - those corresponding to legal addresses are loaded from shadow - memory, as usual. -

      - When no, loads from partially - invalid addresses are treated the same as loads from completely - invalid addresses: an illegal-address error is issued, - and the resulting V bytes indicate valid data. -


    • - -

    • --cleanup=no
      - --cleanup=yes [default] -

      This is a flag to help debug valgrind itself. It is of no - use to end-users. When enabled, various improvments are - applied to the post-instrumented intermediate code, aimed at - removing redundant value checks.


    • -

      -

    - - - -

    3.3  Explanation of error messages from Memcheck

    - -Despite considerable sophistication under the hood, Memcheck can only -really detect two kinds of errors, use of illegal addresses, and use -of undefined values. Nevertheless, this is enough to help you -discover all sorts of memory-management nasties in your code. This -section presents a quick summary of what error messages mean. The -precise behaviour of the error-checking machinery is described in -this section. - - -

    3.3.1  Illegal read / Illegal write errors

    -For example: -
    -  Invalid read of size 4
    -     at 0x40F6BBCC: (within /usr/lib/libpng.so.2.1.0.9)
    -     by 0x40F6B804: (within /usr/lib/libpng.so.2.1.0.9)
    -     by 0x40B07FF4: read_png_image__FP8QImageIO (kernel/qpngio.cpp:326)
    -     by 0x40AC751B: QImageIO::read() (kernel/qimage.cpp:3621)
    -     Address 0xBFFFF0E0 is not stack'd, malloc'd or free'd
    -
    - -

    This happens when your program reads or writes memory at a place -which Memcheck reckons it shouldn't. In this example, the program did -a 4-byte read at address 0xBFFFF0E0, somewhere within the -system-supplied library libpng.so.2.1.0.9, which was called from -somewhere else in the same library, called from line 326 of -qpngio.cpp, and so on. - -

    Memcheck tries to establish what the illegal address might relate -to, since that's often useful. So, if it points into a block of -memory which has already been freed, you'll be informed of this, and -also where the block was free'd at. Likewise, if it should turn out -to be just off the end of a malloc'd block, a common result of -off-by-one-errors in array subscripting, you'll be informed of this -fact, and also where the block was malloc'd. - -

    In this example, Memcheck can't identify the address. Actually the -address is on the stack, but, for some reason, this is not a valid -stack address -- it is below the stack pointer, %esp, and that isn't -allowed. In this particular case it's probably caused by gcc -generating invalid code, a known bug in various flavours of gcc. - -

    Note that Memcheck only tells you that your program is about to -access memory at an illegal address. It can't stop the access from -happening. So, if your program makes an access which normally would -result in a segmentation fault, you program will still suffer the same -fate -- but you will get a message from Memcheck immediately prior to -this. In this particular example, reading junk on the stack is -non-fatal, and the program stays alive. - - -

    3.3.2  Use of uninitialised values

    -For example: -
    -  Conditional jump or move depends on uninitialised value(s)
    -     at 0x402DFA94: _IO_vfprintf (_itoa.h:49)
    -     by 0x402E8476: _IO_printf (printf.c:36)
    -     by 0x8048472: main (tests/manuel1.c:8)
    -     by 0x402A6E5E: __libc_start_main (libc-start.c:129)
    -
    - -

    An uninitialised-value use error is reported when your program uses -a value which hasn't been initialised -- in other words, is undefined. -Here, the undefined value is used somewhere inside the printf() -machinery of the C library. This error was reported when running the -following small program: -

    -  int main()
    -  {
    -    int x;
    -    printf ("x = %d\n", x);
    -  }
    -
    - -

    It is important to understand that your program can copy around -junk (uninitialised) data to its heart's content. Memcheck observes -this and keeps track of the data, but does not complain. A complaint -is issued only when your program attempts to make use of uninitialised -data. In this example, x is uninitialised. Memcheck observes the -value being passed to _IO_printf and thence to _IO_vfprintf, but makes -no comment. However, _IO_vfprintf has to examine the value of x so it -can turn it into the corresponding ASCII string, and it is at this -point that Memcheck complains. - -

    Sources of uninitialised data tend to be: -

      -
    • Local variables in procedures which have not been initialised, - as in the example above.
    • - -

    • The contents of malloc'd blocks, before you write something - there. In C++, the new operator is a wrapper round malloc, so - if you create an object with new, its fields will be - uninitialised until you (or the constructor) fill them in, which - is only Right and Proper.
    • -
    - - - -

    3.3.3  Illegal frees

    -For example: -
    -  Invalid free()
    -     at 0x4004FFDF: free (vg_clientmalloc.c:577)
    -     by 0x80484C7: main (tests/doublefree.c:10)
    -     by 0x402A6E5E: __libc_start_main (libc-start.c:129)
    -     by 0x80483B1: (within tests/doublefree)
    -     Address 0x3807F7B4 is 0 bytes inside a block of size 177 free'd
    -     at 0x4004FFDF: free (vg_clientmalloc.c:577)
    -     by 0x80484C7: main (tests/doublefree.c:10)
    -     by 0x402A6E5E: __libc_start_main (libc-start.c:129)
    -     by 0x80483B1: (within tests/doublefree)
    -
    -

    Memcheck keeps track of the blocks allocated by your program with -malloc/new, so it can know exactly whether or not the argument to -free/delete is legitimate or not. Here, this test program has -freed the same block twice. As with the illegal read/write errors, -Memcheck attempts to make sense of the address free'd. If, as -here, the address is one which has previously been freed, you wil -be told that -- making duplicate frees of the same block easy to spot. - - -

    3.3.4  When a block is freed with an inappropriate -deallocation function

    -In the following example, a block allocated with new[] -has wrongly been deallocated with free: -
    -  Mismatched free() / delete / delete []
    -     at 0x40043249: free (vg_clientfuncs.c:171)
    -     by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149)
    -     by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60)
    -     by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44)
    -     Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd
    -     at 0x4004318C: __builtin_vec_new (vg_clientfuncs.c:152)
    -     by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314)
    -     by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416)
    -     by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272)
    -
    -The following was told to me be the KDE 3 developers. I didn't know -any of it myself. They also implemented the check itself. -

    -In C++ it's important to deallocate memory in a way compatible with -how it was allocated. The deal is: -

      -
    • If allocated with malloc, calloc, - realloc, valloc or - memalign, you must deallocate with free. -
    • If allocated with new[], you must deallocate with - delete[]. -
    • If allocated with new, you must deallocate with - delete. -
    -The worst thing is that on Linux apparently it doesn't matter if you -do muddle these up, and it all seems to work ok, but the same program -may then crash on a different platform, Solaris for example. So it's -best to fix it properly. According to the KDE folks "it's amazing how -many C++ programmers don't know this". -

    -Pascal Massimino adds the following clarification: -delete[] must be called associated with a -new[] because the compiler stores the size of the array -and the pointer-to-member to the destructor of the array's content -just before the pointer actually returned. This implies a -variable-sized overhead in what's returned by new or -new[]. It rather surprising how compilers [Ed: -runtime-support libraries?] are robust to mismatch in -new/delete -new[]/delete[]. - - -

    3.3.5  Passing system call parameters with inadequate -read/write permissions

    - -Memcheck checks all parameters to system calls. If a system call -needs to read from a buffer provided by your program, Memcheck checks -that the entire buffer is addressible and has valid data, ie, it is -readable. And if the system call needs to write to a user-supplied -buffer, Memcheck checks that the buffer is addressible. After the -system call, Memcheck updates its administrative information to -precisely reflect any changes in memory permissions caused by the -system call. - -

    Here's an example of a system call with an invalid parameter: -

    -  #include <stdlib.h>
    -  #include <unistd.h>
    -  int main( void )
    -  {
    -    char* arr = malloc(10);
    -    (void) write( 1 /* stdout */, arr, 10 );
    -    return 0;
    -  }
    -
    - -

    You get this complaint ... -

    -  Syscall param write(buf) contains uninitialised or unaddressable byte(s)
    -     at 0x4035E072: __libc_write
    -     by 0x402A6E5E: __libc_start_main (libc-start.c:129)
    -     by 0x80483B1: (within tests/badwrite)
    -     by <bogus frame pointer> ???
    -     Address 0x3807E6D0 is 0 bytes inside a block of size 10 alloc'd
    -     at 0x4004FEE6: malloc (ut_clientmalloc.c:539)
    -     by 0x80484A0: main (tests/badwrite.c:6)
    -     by 0x402A6E5E: __libc_start_main (libc-start.c:129)
    -     by 0x80483B1: (within tests/badwrite)
    -
    - -

    ... because the program has tried to write uninitialised junk from -the malloc'd block to the standard output. - -

    3.3.6  Overlapping source and destination blocks

    -The following C library functions copy some data from one memory block -to another (or something similar): memcpy(), -strcpy(), strncpy(), strcat(), -strncat(). The blocks pointed to by their src and -dst pointers aren't allowed to overlap. Memcheck checks -for this. -

    -For example: -

    -==27492== Source and destination overlap in memcpy(0xbffff294, 0xbffff280, 21)
    -==27492==    at 0x40026CDC: memcpy (mc_replace_strmem.c:71)
    -==27492==    by 0x804865A: main (overlap.c:40)
    -==27492==    by 0x40246335: __libc_start_main (../sysdeps/generic/libc-start.c:129)
    -==27492==    by 0x8048470: (within /auto/homes/njn25/grind/head6/memcheck/tests/overlap)
    -==27492== 
    -
    -

    -You don't want the two blocks to overlap because one of them could get -partially trashed by the copying. - - -

    3.4  Writing suppressions files

    - -The basic suppression format was described in this section. -

    -The suppression (2nd) line should have the form: -

    -Memcheck:suppression_type
    -
    -Or, since some of the suppressions are shared with Addrcheck: -
    -Memcheck,Addrcheck:suppression_type
    -
    - -

    -The Memcheck suppression types are as follows: -Value1, -Value2, -Value4, -Value8, -Value16, -meaning an uninitialised-value error when -using a value of 1, 2, 4, 8 or 16 bytes. -Or -Cond (or its old name, Value0), -meaning use of an uninitialised CPU condition code. Or: -Addr1, -Addr2, -Addr4, -Addr8, -Addr16, -meaning an invalid address during a -memory access of 1, 2, 4, 8 or 16 bytes respectively. Or -Param, -meaning an invalid system call parameter error. Or -Free, meaning an invalid or mismatching free. -Overlap, meaning a src/dst -overlap in memcpy() or a similar function. Last but not least, -you can suppress leak reports with Leak. Leak suppression was -added in valgrind-1.9.3, I believe. -

    - -The extra information line: for Param errors, is the name of the offending -system call parameter. -No other error kinds have this extra line. -

    -The first line of the calling context: for Value and Addr errors, it is either -the name of the function in which the error occurred, or, failing that, the -full path of the .so file or executable containing the error location. For -Free errors, is the name of the function doing the freeing (eg, -free, __builtin_vec_delete, etc). For Overlap -errors, is the name of the function with the overlapping arguments (eg. -memcpy(), strcpy(), etc). -

    -Lastly, there's the rest of the calling context. -

    - - -

    3.5  Details of Memcheck's checking machinery

    - -Read this section if you want to know, in detail, exactly what and how -Memcheck is checking. - - -

    3.5.1  Valid-value (V) bits

    - -It is simplest to think of Memcheck implementing a synthetic Intel x86 -CPU which is identical to a real CPU, except for one crucial detail. -Every bit (literally) of data processed, stored and handled by the -real CPU has, in the synthetic CPU, an associated "valid-value" bit, -which says whether or not the accompanying bit has a legitimate value. -In the discussions which follow, this bit is referred to as the V -(valid-value) bit. - -

    Each byte in the system therefore has a 8 V bits which follow -it wherever it goes. For example, when the CPU loads a word-size item -(4 bytes) from memory, it also loads the corresponding 32 V bits from -a bitmap which stores the V bits for the process' entire address -space. If the CPU should later write the whole or some part of that -value to memory at a different address, the relevant V bits will be -stored back in the V-bit bitmap. - -

    In short, each bit in the system has an associated V bit, which -follows it around everywhere, even inside the CPU. Yes, the CPU's -(integer and %eflags) registers have their own V bit -vectors. - -

    Copying values around does not cause Memcheck to check for, or -report on, errors. However, when a value is used in a way which might -conceivably affect the outcome of your program's computation, the -associated V bits are immediately checked. If any of these indicate -that the value is undefined, an error is reported. - -

    Here's an (admittedly nonsensical) example: -

    -  int i, j;
    -  int a[10], b[10];
    -  for (i = 0; i < 10; i++) {
    -    j = a[i];
    -    b[i] = j;
    -  }
    -
    - -

    Memcheck emits no complaints about this, since it merely copies -uninitialised values from a[] into b[], and -doesn't use them in any way. However, if the loop is changed to -

    -  for (i = 0; i < 10; i++) {
    -    j += a[i];
    -  }
    -  if (j == 77) 
    -     printf("hello there\n");
    -
    -then Valgrind will complain, at the if, that the -condition depends on uninitialised values. Note that it -doesn't complain at the j += a[i];, since -at that point the undefinedness is not "observable". It's only -when a decision has to be made as to whether or not to do the -printf -- an observable action of your program -- that -Memcheck complains. - -

    Most low level operations, such as adds, cause Memcheck to -use the V bits for the operands to calculate the V bits for the -result. Even if the result is partially or wholly undefined, -it does not complain. - -

    Checks on definedness only occur in two places: when a value is -used to generate a memory address, and where control flow decision -needs to be made. Also, when a system call is detected, valgrind -checks definedness of parameters as required. - -

    If a check should detect undefinedness, an error message is -issued. The resulting value is subsequently regarded as well-defined. -To do otherwise would give long chains of error messages. In effect, -we say that undefined values are non-infectious. - -

    This sounds overcomplicated. Why not just check all reads from -memory, and complain if an undefined value is loaded into a CPU register? -Well, that doesn't work well, because perfectly legitimate C programs routinely -copy uninitialised values around in memory, and we don't want endless complaints -about that. Here's the canonical example. Consider a struct -like this: -

    -  struct S { int x; char c; };
    -  struct S s1, s2;
    -  s1.x = 42;
    -  s1.c = 'z';
    -  s2 = s1;
    -
    - -

    The question to ask is: how large is struct S, in -bytes? An int is 4 bytes and a char one byte, so perhaps a struct S -occupies 5 bytes? Wrong. All (non-toy) compilers we know of will -round the size of struct S up to a whole number of words, -in this case 8 bytes. Not doing this forces compilers to generate -truly appalling code for subscripting arrays of struct -S's. - -

    So s1 occupies 8 bytes, yet only 5 of them will be initialised. -For the assignment s2 = s1, gcc generates code to copy -all 8 bytes wholesale into s2 without regard for their -meaning. If Memcheck simply checked values as they came out of -memory, it would yelp every time a structure assignment like this -happened. So the more complicated semantics described above is -necessary. This allows gcc to copy s1 into -s2 any way it likes, and a warning will only be emitted -if the uninitialised values are later used. - -

    One final twist to this story. The above scheme allows garbage to -pass through the CPU's integer registers without complaint. It does -this by giving the integer registers V tags, passing these around in -the expected way. This complicated and computationally expensive to -do, but is necessary. Memcheck is more simplistic about -floating-point loads and stores. In particular, V bits for data read -as a result of floating-point loads are checked at the load -instruction. So if your program uses the floating-point registers to -do memory-to-memory copies, you will get complaints about -uninitialised values. Fortunately, I have not yet encountered a -program which (ab)uses the floating-point registers in this way. - - -

    3.5.2  Valid-address (A) bits

    - -Notice that the previous subsection describes how the validity of values -is established and maintained without having to say whether the -program does or does not have the right to access any particular -memory location. We now consider the latter issue. - -

    As described above, every bit in memory or in the CPU has an -associated valid-value (V) bit. In addition, all bytes in memory, but -not in the CPU, have an associated valid-address (A) bit. This -indicates whether or not the program can legitimately read or write -that location. It does not give any indication of the validity or the -data at that location -- that's the job of the V bits -- only whether -or not the location may be accessed. - -

    Every time your program reads or writes memory, Memcheck checks the -A bits associated with the address. If any of them indicate an -invalid address, an error is emitted. Note that the reads and writes -themselves do not change the A bits, only consult them. - -

    So how do the A bits get set/cleared? Like this: - -

      -
    • When the program starts, all the global data areas are marked as - accessible.

    • -

      - -

    • When the program does malloc/new, the A bits for exactly the - area allocated, and not a byte more, are marked as accessible. - Upon freeing the area the A bits are changed to indicate - inaccessibility.

    • -

      - -

    • When the stack pointer register (%esp) moves up or down, A bits - are set. The rule is that the area from %esp up to the base of - the stack is marked as accessible, and below %esp is - inaccessible. (If that sounds illogical, bear in mind that the - stack grows down, not up, on almost all Unix systems, including - GNU/Linux.) Tracking %esp like this has the useful side-effect - that the section of stack used by a function for local variables - etc is automatically marked accessible on function entry and - inaccessible on exit.

    • -

      - -

    • When doing system calls, A bits are changed appropriately. For - example, mmap() magically makes files appear in the process's - address space, so the A bits must be updated if mmap() - succeeds.

    • -

      - -

    • Optionally, your program can tell Valgrind about such changes - explicitly, using the client request mechanism described above. -
    - - - -

    3.5.3  Putting it all together

    -Memcheck's checking machinery can be summarised as follows: - -
      -
    • Each byte in memory has 8 associated V (valid-value) bits, - saying whether or not the byte has a defined value, and a single - A (valid-address) bit, saying whether or not the program - currently has the right to read/write that address.

    • -

      - -

    • When memory is read or written, the relevant A bits are - consulted. If they indicate an invalid address, Valgrind emits - an Invalid read or Invalid write error.

    • -

      - -

    • When memory is read into the CPU's integer registers, the - relevant V bits are fetched from memory and stored in the - simulated CPU. They are not consulted.

    • -

      - -

    • When an integer register is written out to memory, the V bits - for that register are written back to memory too.

    • -

      - -

    • When memory is read into the CPU's floating point registers, the - relevant V bits are read from memory and they are immediately - checked. If any are invalid, an uninitialised value error is - emitted. This precludes using the floating-point registers to - copy possibly-uninitialised memory, but simplifies Valgrind in - that it does not have to track the validity status of the - floating-point registers.

    • -

      - -

    • As a result, when a floating-point register is written to - memory, the associated V bits are set to indicate a valid - value.

    • -

      - -

    • When values in integer CPU registers are used to generate a - memory address, or to determine the outcome of a conditional - branch, the V bits for those values are checked, and an error - emitted if any of them are undefined.

    • -

      - -

    • When values in integer CPU registers are used for any other - purpose, Valgrind computes the V bits for the result, but does - not check them.

    • -

      - -

    • One the V bits for a value in the CPU have been checked, they - are then set to indicate validity. This avoids long chains of - errors.

    • -

      - -

    • When values are loaded from memory, valgrind checks the A bits - for that location and issues an illegal-address warning if - needed. In that case, the V bits loaded are forced to indicate - Valid, despite the location being invalid. -

      - This apparently strange choice reduces the amount of confusing - information presented to the user. It avoids the - unpleasant phenomenon in which memory is read from a place which - is both unaddressible and contains invalid values, and, as a - result, you get not only an invalid-address (read/write) error, - but also a potentially large set of uninitialised-value errors, - one for every time the value is used. -

      - There is a hazy boundary case to do with multi-byte loads from - addresses which are partially valid and partially invalid. See - details of the flag --partial-loads-ok for details. -


    • -
    - -Memcheck intercepts calls to malloc, calloc, realloc, valloc, -memalign, free, new and delete. The behaviour you get is: - -
      - -
    • malloc/new: the returned memory is marked as addressible but not - having valid values. This means you have to write on it before - you can read it.

    • -

      - -

    • calloc: returned memory is marked both addressible and valid, - since calloc() clears the area to zero.

    • -

      - -

    • realloc: if the new size is larger than the old, the new section - is addressible but invalid, as with malloc.

    • -

      - -

    • If the new size is smaller, the dropped-off section is marked as - unaddressible. You may only pass to realloc a pointer - previously issued to you by malloc/calloc/realloc.

    • -

      - -

    • free/delete: you may only pass to free a pointer previously - issued to you by malloc/calloc/realloc, or the value - NULL. Otherwise, Valgrind complains. If the pointer is indeed - valid, Valgrind marks the entire area it points at as - unaddressible, and places the block in the freed-blocks-queue. - The aim is to defer as long as possible reallocation of this - block. Until that happens, all attempts to access it will - elicit an invalid-address error, as you would hope.

    • -
    - - - - - -

    3.6  Memory leak detection

    - -Memcheck keeps track of all memory blocks issued in response to calls -to malloc/calloc/realloc/new. So when the program exits, it knows -which blocks are still outstanding -- have not been returned, in other -words. Ideally, you want your program to have no blocks still in use -at exit. But many programs do. - -

    For each such block, Memcheck scans the entire address space of the -process, looking for pointers to the block. One of three situations -may result: - -

      -
    • A pointer to the start of the block is found. This usually - indicates programming sloppiness; since the block is still - pointed at, the programmer could, at least in principle, free'd - it before program exit.

    • -

      - -

    • A pointer to the interior of the block is found. The pointer - might originally have pointed to the start and have been moved - along, or it might be entirely unrelated. Memcheck deems such a - block as "dubious", that is, possibly leaked, - because it's unclear whether or - not a pointer to it still exists.

    • -

      - -

    • The worst outcome is that no pointer to the block can be found. - The block is classified as "leaked", because the - programmer could not possibly have free'd it at program exit, - since no pointer to it exists. This might be a symptom of - having lost the pointer at some earlier point in the - program.
    • -
    - -Memcheck reports summaries about leaked and dubious blocks. -For each such block, it will also tell you where the block was -allocated. This should help you figure out why the pointer to it has -been lost. In general, you should attempt to ensure your programs do -not have any leaked or dubious blocks at exit. - -

    The precise area of memory in which Memcheck searches for pointers -is: all naturally-aligned 4-byte words for which all A bits indicate -addressibility and all V bits indicated that the stored value is -actually valid. -

    - - - -

    3.7  Client Requests

    - -The following client requests are defined in memcheck.h. They -also work for Addrcheck. See memcheck.h for exact -details of their arguments. - -
      -
    • VALGRIND_MAKE_NOACCESS, - VALGRIND_MAKE_WRITABLE and - VALGRIND_MAKE_READABLE. These mark address - ranges as completely inaccessible, accessible but containing - undefined data, and accessible and containing defined data, - respectively. Subsequent errors may have their faulting - addresses described in terms of these blocks. Returns a - "block handle". Returns zero when not run on Valgrind. -

      -

    • VALGRIND_DISCARD: At some point you may want - Valgrind to stop reporting errors in terms of the blocks - defined by the previous three macros. To do this, the above - macros return a small-integer "block handle". You can pass - this block handle to VALGRIND_DISCARD. After - doing so, Valgrind will no longer be able to relate - addressing errors to the user-defined block associated with - the handle. The permissions settings associated with the - handle remain in place; this just affects how errors are - reported, not whether they are reported. Returns 1 for an - invalid handle and 0 for a valid handle (although passing - invalid handles is harmless). Always returns 0 when not run - on Valgrind. -

      -

    • VALGRIND_CHECK_WRITABLE and - VALGRIND_CHECK_READABLE: check immediately - whether or not the given address range has the relevant - property, and if not, print an error message. Also, for the - convenience of the client, returns zero if the relevant - property holds; otherwise, the returned value is the address - of the first byte for which the property is not true. - Always returns 0 when not run on Valgrind. -

      -

    • VALGRIND_CHECK_DEFINED: a quick and easy way - to find out whether Valgrind thinks a particular variable - (lvalue, to be precise) is addressible and defined. Prints - an error message if not. Returns no value. -

      -

    • VALGRIND_DO_LEAK_CHECK: run the memory leak detector - right now. Returns no value. I guess this could be used to - incrementally check for leaks between arbitrary places in the - program's execution. Warning: not properly tested! -

      -

    • VALGRIND_COUNT_LEAKS: fills in the four arguments with - the number of bytes of memory found by the previous leak check to - be leaked, dubious, reachable and suppressed. Again, useful in - test harness code, after calling VALGRIND_DO_LEAK_CHECK. -

      -

    • VALGRIND_GET_VBITS and - VALGRIND_SET_VBITS: allow you to get and set the V (validity) - bits for an address range. You should probably only set V bits that you - have got with VALGRIND_GET_VBITS. Only for those who really - know what they are doing. -

      -

    - diff --git a/VEX/head20041019/memcheck/docs/mc_techdocs.html b/VEX/head20041019/memcheck/docs/mc_techdocs.html deleted file mode 100644 index e33a0aa10..000000000 --- a/VEX/head20041019/memcheck/docs/mc_techdocs.html +++ /dev/null @@ -1,2108 +0,0 @@ - - - - The design and implementation of Valgrind - - - - -  -

    The design and implementation of Valgrind

    - -
    -Detailed technical notes for hackers, maintainers and the -overly-curious
    -These notes pertain to snapshot 20020306
    -

    -jseward@acm.org
    -http://valgrind.kde.org
    -Copyright © 2000-2004 Julian Seward -

    -Valgrind is licensed under the GNU General Public License, -version 2
    -An open-source tool for finding memory-management problems in -x86 GNU/Linux executables. -

    - -

    - - - - -


    - -

    Introduction

    - -This document contains a detailed, highly-technical description of the -internals of Valgrind. This is not the user manual; if you are an -end-user of Valgrind, you do not want to read this. Conversely, if -you really are a hacker-type and want to know how it works, I assume -that you have read the user manual thoroughly. -

    -You may need to read this document several times, and carefully. Some -important things, I only say once. - - -

    History

    - -Valgrind came into public view in late Feb 2002. However, it has been -under contemplation for a very long time, perhaps seriously for about -five years. Somewhat over two years ago, I started working on the x86 -code generator for the Glasgow Haskell Compiler -(http://www.haskell.org/ghc), gaining familiarity with x86 internals -on the way. I then did Cacheprof (http://www.cacheprof.org), gaining -further x86 experience. Some time around Feb 2000 I started -experimenting with a user-space x86 interpreter for x86-Linux. This -worked, but it was clear that a JIT-based scheme would be necessary to -give reasonable performance for Valgrind. Design work for the JITter -started in earnest in Oct 2000, and by early 2001 I had an x86-to-x86 -dynamic translator which could run quite large programs. This -translator was in a sense pointless, since it did not do any -instrumentation or checking. - -

    -Most of the rest of 2001 was taken up designing and implementing the -instrumentation scheme. The main difficulty, which consumed a lot -of effort, was to design a scheme which did not generate large numbers -of false uninitialised-value warnings. By late 2001 a satisfactory -scheme had been arrived at, and I started to test it on ever-larger -programs, with an eventual eye to making it work well enough so that -it was helpful to folks debugging the upcoming version 3 of KDE. I've -used KDE since before version 1.0, and wanted to Valgrind to be an -indirect contribution to the KDE 3 development effort. At the start of -Feb 02 the kde-core-devel crew started using it, and gave a huge -amount of helpful feedback and patches in the space of three weeks. -Snapshot 20020306 is the result. - -

    -In the best Unix tradition, or perhaps in the spirit of Fred Brooks' -depressing-but-completely-accurate epitaph "build one to throw away; -you will anyway", much of Valgrind is a second or third rendition of -the initial idea. The instrumentation machinery -(vg_translate.c, vg_memory.c) and core CPU -simulation (vg_to_ucode.c, vg_from_ucode.c) -have had three redesigns and rewrites; the register allocator, -low-level memory manager (vg_malloc2.c) and symbol table -reader (vg_symtab2.c) are on the second rewrite. In a -sense, this document serves to record some of the knowledge gained as -a result. - - -

    Design overview

    - -Valgrind is compiled into a Linux shared object, -valgrind.so, and also a dummy one, -valgrinq.so, of which more later. The -valgrind shell script adds valgrind.so to -the LD_PRELOAD list of extra libraries to be -loaded with any dynamically linked library. This is a standard trick, -one which I assume the LD_PRELOAD mechanism was developed -to support. - -

    -valgrind.so -is linked with the -z initfirst flag, which requests that -its initialisation code is run before that of any other object in the -executable image. When this happens, valgrind gains control. The -real CPU becomes "trapped" in valgrind.so and the -translations it generates. The synthetic CPU provided by Valgrind -does, however, return from this initialisation function. So the -normal startup actions, orchestrated by the dynamic linker -ld.so, continue as usual, except on the synthetic CPU, -not the real one. Eventually main is run and returns, -and then the finalisation code of the shared objects is run, -presumably in inverse order to which they were initialised. Remember, -this is still all happening on the simulated CPU. Eventually -valgrind.so's own finalisation code is called. It spots -this event, shuts down the simulated CPU, prints any error summaries -and/or does leak detection, and returns from the initialisation code -on the real CPU. At this point, in effect the real and synthetic CPUs -have merged back into one, Valgrind has lost control of the program, -and the program finally exit()s back to the kernel in the -usual way. - -

    -The normal course of activity, once Valgrind has started up, is as -follows. Valgrind never runs any part of your program (usually -referred to as the "client"), not a single byte of it, directly. -Instead it uses function VG_(translate) to translate -basic blocks (BBs, straight-line sequences of code) into instrumented -translations, and those are run instead. The translations are stored -in the translation cache (TC), vg_tc, with the -translation table (TT), vg_tt supplying the -original-to-translation code address mapping. Auxiliary array -VG_(tt_fast) is used as a direct-map cache for fast -lookups in TT; it usually achieves a hit rate of around 98% and -facilitates an orig-to-trans lookup in 4 x86 insns, which is not bad. - -

    -Function VG_(dispatch) in vg_dispatch.S is -the heart of the JIT dispatcher. Once a translated code address has -been found, it is executed simply by an x86 call -to the translation. At the end of the translation, the next -original code addr is loaded into %eax, and the -translation then does a ret, taking it back to the -dispatch loop, with, interestingly, zero branch mispredictions. -The address requested in %eax is looked up first in -VG_(tt_fast), and, if not found, by calling C helper -VG_(search_transtab). If there is still no translation -available, VG_(dispatch) exits back to the top-level -C dispatcher VG_(toploop), which arranges for -VG_(translate) to make a new translation. All fairly -unsurprising, really. There are various complexities described below. - -

    -The translator, orchestrated by VG_(translate), is -complicated but entirely self-contained. It is described in great -detail in subsequent sections. Translations are stored in TC, with TT -tracking administrative information. The translations are subject to -an approximate LRU-based management scheme. With the current -settings, the TC can hold at most about 15MB of translations, and LRU -passes prune it to about 13.5MB. Given that the -orig-to-translation expansion ratio is about 13:1 to 14:1, this means -TC holds translations for more or less a megabyte of original code, -which generally comes to about 70000 basic blocks for C++ compiled -with optimisation on. Generating new translations is expensive, so it -is worth having a large TC to minimise the (capacity) miss rate. - -

    -The dispatcher, VG_(dispatch), receives hints from -the translations which allow it to cheaply spot all control -transfers corresponding to x86 call and ret -instructions. It has to do this in order to spot some special events: -

      -
    • Calls to VG_(shutdown). This is Valgrind's cue to - exit. NOTE: actually this is done a different way; it should be - cleaned up. -

      -

    • Returns of system call handlers, to the return address - VG_(signalreturn_bogusRA). The signal simulator - needs to know when a signal handler is returning, so we spot - jumps (returns) to this address. -

      -

    • Calls to vg_trap_here. All malloc, - free, etc calls that the client program makes are - eventually routed to a call to vg_trap_here, - and Valgrind does its own special thing with these calls. - In effect this provides a trapdoor, by which Valgrind can - intercept certain calls on the simulated CPU, run the call as it - sees fit itself (on the real CPU), and return the result to - the simulated CPU, quite transparently to the client program. -
    -Valgrind intercepts the client's malloc, -free, etc, -calls, so that it can store additional information. Each block -malloc'd by the client gives rise to a shadow block -in which Valgrind stores the call stack at the time of the -malloc -call. When the client calls free, Valgrind tries to -find the shadow block corresponding to the address passed to -free, and emits an error message if none can be found. -If it is found, the block is placed on the freed blocks queue -vg_freed_list, it is marked as inaccessible, and -its shadow block now records the call stack at the time of the -free call. Keeping free'd blocks in -this queue allows Valgrind to spot all (presumably invalid) accesses -to them. However, once the volume of blocks in the free queue -exceeds VG_(clo_freelist_vol), blocks are finally -removed from the queue. - -

    -Keeping track of A and V bits (note: if you don't know what these are, -you haven't read the user guide carefully enough) for memory is done -in vg_memory.c. This implements a sparse array structure -which covers the entire 4G address space in a way which is reasonably -fast and reasonably space efficient. The 4G address space is divided -up into 64K sections, each covering 64Kb of address space. Given a -32-bit address, the top 16 bits are used to select one of the 65536 -entries in VG_(primary_map). The resulting "secondary" -(SecMap) holds A and V bits for the 64k of address space -chunk corresponding to the lower 16 bits of the address. - - -

    Design decisions

    - -Some design decisions were motivated by the need to make Valgrind -debuggable. Imagine you are writing a CPU simulator. It works fairly -well. However, you run some large program, like Netscape, and after -tens of millions of instructions, it crashes. How can you figure out -where in your simulator the bug is? - -

    -Valgrind's answer is: cheat. Valgrind is designed so that it is -possible to switch back to running the client program on the real -CPU at any point. Using the --stop-after= flag, you can -ask Valgrind to run just some number of basic blocks, and then -run the rest of the way on the real CPU. If you are searching for -a bug in the simulated CPU, you can use this to do a binary search, -which quickly leads you to the specific basic block which is -causing the problem. - -

    -This is all very handy. It does constrain the design in certain -unimportant ways. Firstly, the layout of memory, when viewed from the -client's point of view, must be identical regardless of whether it is -running on the real or simulated CPU. This means that Valgrind can't -do pointer swizzling -- well, no great loss -- and it can't run on -the same stack as the client -- again, no great loss. -Valgrind operates on its own stack, VG_(stack), which -it switches to at startup, temporarily switching back to the client's -stack when doing system calls for the client. - -

    -Valgrind also receives signals on its own stack, -VG_(sigstack), but for different gruesome reasons -discussed below. - -

    -This nice clean switch-back-to-the-real-CPU-whenever-you-like story -is muddied by signals. Problem is that signals arrive at arbitrary -times and tend to slightly perturb the basic block count, with the -result that you can get close to the basic block causing a problem but -can't home in on it exactly. My kludgey hack is to define -SIGNAL_SIMULATION to 1 towards the bottom of -vg_syscall_mem.c, so that signal handlers are run on the -real CPU and don't change the BB counts. - -

    -A second hole in the switch-back-to-real-CPU story is that Valgrind's -way of delivering signals to the client is different from that of the -kernel. Specifically, the layout of the signal delivery frame, and -the mechanism used to detect a sighandler returning, are different. -So you can't expect to make the transition inside a sighandler and -still have things working, but in practice that's not much of a -restriction. - -

    -Valgrind's implementation of malloc, free, -etc, (in vg_clientmalloc.c, not the low-level stuff in -vg_malloc2.c) is somewhat complicated by the need to -handle switching back at arbitrary points. It does work tho. - - - -

    Correctness

    - -There's only one of me, and I have a Real Life (tm) as well as hacking -Valgrind [allegedly :-]. That means I don't have time to waste -chasing endless bugs in Valgrind. My emphasis is therefore on doing -everything as simply as possible, with correctness, stability and -robustness being the number one priority, more important than -performance or functionality. As a result: -
      -
    • The code is absolutely loaded with assertions, and these are - permanently enabled. I have no plan to remove or disable - them later. Over the past couple of months, as valgrind has - become more widely used, they have shown their worth, pulling - up various bugs which would otherwise have appeared as - hard-to-find segmentation faults. -

      - I am of the view that it's acceptable to spend 5% of the total - running time of your valgrindified program doing assertion checks - and other internal sanity checks. -

      -

    • Aside from the assertions, valgrind contains various sets of - internal sanity checks, which get run at varying frequencies - during normal operation. VG_(do_sanity_checks) - runs every 1000 basic blocks, which means 500 to 2000 times/second - for typical machines at present. It checks that Valgrind hasn't - overrun its private stack, and does some simple checks on the - memory permissions maps. Once every 25 calls it does some more - extensive checks on those maps. Etc, etc. -

      - The following components also have sanity check code, which can - be enabled to aid debugging: -

        -
      • The low-level memory-manager - (VG_(mallocSanityCheckArena)). This does a - complete check of all blocks and chains in an arena, which - is very slow. Is not engaged by default. -

        -

      • The symbol table reader(s): various checks to ensure - uniqueness of mappings; see VG_(read_symbols) - for a start. Is permanently engaged. -

        -

      • The A and V bit tracking stuff in vg_memory.c. - This can be compiled with cpp symbol - VG_DEBUG_MEMORY defined, which removes all the - fast, optimised cases, and uses simple-but-slow fallbacks - instead. Not engaged by default. -

        -

      • Ditto VG_DEBUG_LEAKCHECK. -

        -

      • The JITter parses x86 basic blocks into sequences of - UCode instructions. It then sanity checks each one with - VG_(saneUInstr) and sanity checks the sequence - as a whole with VG_(saneUCodeBlock). This stuff - is engaged by default, and has caught some way-obscure bugs - in the simulated CPU machinery in its time. -

        -

      • The system call wrapper does - VG_(first_and_last_secondaries_look_plausible) after - every syscall; this is known to pick up bugs in the syscall - wrappers. Engaged by default. -

        -

      • The main dispatch loop, in VG_(dispatch), checks - that translations do not set %ebp to any value - different from VG_EBP_DISPATCH_CHECKED or - & VG_(baseBlock). In effect this test is free, - and is permanently engaged. -

        -

      • There are a couple of ifdefed-out consistency checks I - inserted whilst debugging the new register allocater, - vg_do_register_allocation. -
      -

      -

    • I try to avoid techniques, algorithms, mechanisms, etc, for which - I can supply neither a convincing argument that they are correct, - nor sanity-check code which might pick up bugs in my - implementation. I don't always succeed in this, but I try. - Basically the idea is: avoid techniques which are, in practice, - unverifiable, in some sense. When doing anything, always have in - mind: "how can I verify that this is correct?" -
    - -

    -Some more specific things are: - -

      -
    • Valgrind runs in the same namespace as the client, at least from - ld.so's point of view, and it therefore absolutely - had better not export any symbol with a name which could clash - with that of the client or any of its libraries. Therefore, all - globally visible symbols exported from valgrind.so - are defined using the VG_ CPP macro. As you'll see - from tool_asm.h, this appends some arbitrary - prefix to the symbol, in order that it be, we hope, globally - unique. Currently the prefix is vgPlain_. For - convenience there are also VGM_, VGP_ - and VGOFF_. All locally defined symbols are declared - static and do not appear in the final shared object. -

      - To check this, I periodically do - nm valgrind.so | grep " T ", - which shows you all the globally exported text symbols. - They should all have an approved prefix, except for those like - malloc, free, etc, which we deliberately - want to shadow and take precedence over the same names exported - from glibc.so, so that valgrind can intercept those - calls easily. Similarly, nm valgrind.so | grep " D " - allows you to find any rogue data-segment symbol names. -

      -

    • Valgrind tries, and almost succeeds, in being completely - independent of all other shared objects, in particular of - glibc.so. For example, we have our own low-level - memory manager in vg_malloc2.c, which is a fairly - standard malloc/free scheme augmented with arenas, and - vg_mylibc.c exports reimplementations of various bits - and pieces you'd normally get from the C library. -

      - Why all the hassle? Because imagine the potential chaos of both - the simulated and real CPUs executing in glibc.so. - It just seems simpler and cleaner to be completely self-contained, - so that only the simulated CPU visits glibc.so. In - practice it's not much hassle anyway. Also, valgrind starts up - before glibc has a chance to initialise itself, and who knows what - difficulties that could lead to. Finally, glibc has definitions - for some types, specifically sigset_t, which conflict - (are different from) the Linux kernel's idea of same. When - Valgrind wants to fiddle around with signal stuff, it wants to - use the kernel's definitions, not glibc's definitions. So it's - simplest just to keep glibc out of the picture entirely. -

      - To find out which glibc symbols are used by Valgrind, reinstate - the link flags -nostdlib -Wl,-no-undefined. This - causes linking to fail, but will tell you what you depend on. - I have mostly, but not entirely, got rid of the glibc - dependencies; what remains is, IMO, fairly harmless. AFAIK the - current dependencies are: memset, - memcmp, stat, system, - sbrk, setjmp and longjmp. - -

      -

    • Similarly, valgrind should not really import any headers other - than the Linux kernel headers, since it knows of no API other than - the kernel interface to talk to. At the moment this is really not - in a good state, and vg_syscall_mem imports, via - vg_unsafe.h, a significant number of C-library - headers so as to know the sizes of various structs passed across - the kernel boundary. This is of course completely bogus, since - there is no guarantee that the C library's definitions of these - structs matches those of the kernel. I have started to sort this - out using vg_kerneliface.h, into which I had intended - to copy all kernel definitions which valgrind could need, but this - has not gotten very far. At the moment it mostly contains - definitions for sigset_t and struct - sigaction, since the kernel's definition for these really - does clash with glibc's. I plan to use a vki_ prefix - on all these types and constants, to denote the fact that they - pertain to Valgrind's Kernel Interface. -

      - Another advantage of having a vg_kerneliface.h file - is that it makes it simpler to interface to a different kernel. - Once can, for example, easily imagine writing a new - vg_kerneliface.h for FreeBSD, or x86 NetBSD. - -

    - -

    Current limitations

    - -Support for weird (non-POSIX) signal stuff is patchy. Does anybody -care? -

    - - - - -


    - -

    The instrumenting JITter

    - -This really is the heart of the matter. We begin with various side -issues. - -

    Run-time storage, and the use of host registers

    - -Valgrind translates client (original) basic blocks into instrumented -basic blocks, which live in the translation cache TC, until either the -client finishes or the translations are ejected from TC to make room -for newer ones. -

    -Since it generates x86 code in memory, Valgrind has complete control -of the use of registers in the translations. Now pay attention. I -shall say this only once, and it is important you understand this. In -what follows I will refer to registers in the host (real) cpu using -their standard names, %eax, %edi, etc. I -refer to registers in the simulated CPU by capitalising them: -%EAX, %EDI, etc. These two sets of -registers usually bear no direct relationship to each other; there is -no fixed mapping between them. This naming scheme is used fairly -consistently in the comments in the sources. -

    -Host registers, once things are up and running, are used as follows: -

      -
    • %esp, the real stack pointer, points - somewhere in Valgrind's private stack area, - VG_(stack) or, transiently, into its signal delivery - stack, VG_(sigstack). -

      -

    • %edi is used as a temporary in code generation; it - is almost always dead, except when used for the Left - value-tag operations. -

      -

    • %eax, %ebx, %ecx, - %edx and %esi are available to - Valgrind's register allocator. They are dead (carry unimportant - values) in between translations, and are live only in - translations. The one exception to this is %eax, - which, as mentioned far above, has a special significance to the - dispatch loop VG_(dispatch): when a translation - returns to the dispatch loop, %eax is expected to - contain the original-code-address of the next translation to run. - The register allocator is so good at minimising spill code that - using five regs and not having to save/restore %edi - actually gives better code than allocating to %edi - as well, but then having to push/pop it around special uses. -

      -

    • %ebp points permanently at - VG_(baseBlock). Valgrind's translations are - position-independent, partly because this is convenient, but also - because translations get moved around in TC as part of the LRUing - activity. All static entities which need to be referred to - from generated code, whether data or helper functions, are stored - starting at VG_(baseBlock) and are therefore reached - by indexing from %ebp. There is but one exception, - which is that by placing the value - VG_EBP_DISPATCH_CHECKED - in %ebp just before a return to the dispatcher, - the dispatcher is informed that the next address to run, - in %eax, requires special treatment. -

      -

    • The real machine's FPU state is pretty much unimportant, for - reasons which will become obvious. Ditto its %eflags - register. -
    - -

    -The state of the simulated CPU is stored in memory, in -VG_(baseBlock), which is a block of 200 words IIRC. -Recall that %ebp points permanently at the start of this -block. Function vg_init_baseBlock decides what the -offsets of various entities in VG_(baseBlock) are to be, -and allocates word offsets for them. The code generator then emits -%ebp relative addresses to get at those things. The -sequence in which entities are allocated has been carefully chosen so -that the 32 most popular entities come first, because this means 8-bit -offsets can be used in the generated code. - -

    -If I was clever, I could make %ebp point 32 words along -VG_(baseBlock), so that I'd have another 32 words of -short-form offsets available, but that's just complicated, and it's -not important -- the first 32 words take 99% (or whatever) of the -traffic. - -

    -Currently, the sequence of stuff in VG_(baseBlock) is as -follows: -

      -
    • 9 words, holding the simulated integer registers, - %EAX .. %EDI, and the simulated flags, - %EFLAGS. -

      -

    • Another 9 words, holding the V bit "shadows" for the above 9 regs. -

      -

    • The addresses of various helper routines called from - generated code: - VG_(helper_value_check4_fail), - VG_(helper_value_check0_fail), - which register V-check failures, - VG_(helperc_STOREV4), - VG_(helperc_STOREV1), - VG_(helperc_LOADV4), - VG_(helperc_LOADV1), - which do stores and loads of V bits to/from the - sparse array which keeps track of V bits in memory, - and - VGM_(handle_esp_assignment), which messes with - memory addressibility resulting from changes in %ESP. -

      -

    • The simulated %EIP. -

      -

    • 24 spill words, for when the register allocator can't make it work - with 5 measly registers. -

      -

    • Addresses of helpers VG_(helperc_STOREV2), - VG_(helperc_LOADV2). These are here because 2-byte - loads and stores are relatively rare, so are placed above the - magic 32-word offset boundary. -

      -

    • For similar reasons, addresses of helper functions - VGM_(fpu_write_check) and - VGM_(fpu_read_check), which handle the A/V maps - testing and changes required by FPU writes/reads. -

      -

    • Some other boring helper addresses: - VG_(helper_value_check2_fail) and - VG_(helper_value_check1_fail). These are probably - never emitted now, and should be removed. -

      -

    • The entire state of the simulated FPU, which I believe to be - 108 bytes long. -

      -

    • Finally, the addresses of various other helper functions in - vg_helpers.S, which deal with rare situations which - are tedious or difficult to generate code in-line for. -
    - -

    -As a general rule, the simulated machine's state lives permanently in -memory at VG_(baseBlock). However, the JITter does some -optimisations which allow the simulated integer registers to be -cached in real registers over multiple simulated instructions within -the same basic block. These are always flushed back into memory at -the end of every basic block, so that the in-memory state is -up-to-date between basic blocks. (This flushing is implied by the -statement above that the real machine's allocatable registers are -dead in between simulated blocks). - - -

    Startup, shutdown, and system calls

    - -Getting into of Valgrind (VG_(startup), called from -valgrind.so's initialisation section), really means -copying the real CPU's state into VG_(baseBlock), and -then installing our own stack pointer, etc, into the real CPU, and -then starting up the JITter. Exiting valgrind involves copying the -simulated state back to the real state. - -

    -Unfortunately, there's a complication at startup time. Problem is -that at the point where we need to take a snapshot of the real CPU's -state, the offsets in VG_(baseBlock) are not set up yet, -because to do so would involve disrupting the real machine's state -significantly. The way round this is to dump the real machine's state -into a temporary, static block of memory, -VG_(m_state_static). We can then set up the -VG_(baseBlock) offsets at our leisure, and copy into it -from VG_(m_state_static) at some convenient later time. -This copying is done by -VG_(copy_m_state_static_to_baseBlock). - -

    -On exit, the inverse transformation is (rather unnecessarily) used: -stuff in VG_(baseBlock) is copied to -VG_(m_state_static), and the assembly stub then copies -from VG_(m_state_static) into the real machine registers. - -

    -Doing system calls on behalf of the client (vg_syscall.S) -is something of a half-way house. We have to make the world look -sufficiently like that which the client would normally have to make -the syscall actually work properly, but we can't afford to lose -control. So the trick is to copy all of the client's state, except -its program counter, into the real CPU, do the system call, and -copy the state back out. Note that the client's state includes its -stack pointer register, so one effect of this partial restoration is -to cause the system call to be run on the client's stack, as it should -be. - -

    -As ever there are complications. We have to save some of our own state -somewhere when restoring the client's state into the CPU, so that we -can keep going sensibly afterwards. In fact the only thing which is -important is our own stack pointer, but for paranoia reasons I save -and restore our own FPU state as well, even though that's probably -pointless. - -

    -The complication on the above complication is, that for horrible -reasons to do with signals, we may have to handle a second client -system call whilst the client is blocked inside some other system -call (unbelievable!). That means there's two sets of places to -dump Valgrind's stack pointer and FPU state across the syscall, -and we decide which to use by consulting -VG_(syscall_depth), which is in turn maintained by -VG_(wrap_syscall). - - - -

    Introduction to UCode

    - -UCode lies at the heart of the x86-to-x86 JITter. The basic premise -is that dealing the the x86 instruction set head-on is just too darn -complicated, so we do the traditional compiler-writer's trick and -translate it into a simpler, easier-to-deal-with form. - -

    -In normal operation, translation proceeds through six stages, -coordinated by VG_(translate): -

      -
    1. Parsing of an x86 basic block into a sequence of UCode - instructions (VG_(disBB)). -

      -

    2. UCode optimisation (vg_improve), with the aim of - caching simulated registers in real registers over multiple - simulated instructions, and removing redundant simulated - %EFLAGS saving/restoring. -

      -

    3. UCode instrumentation (vg_instrument), which adds - value and address checking code. -

      -

    4. Post-instrumentation cleanup (vg_cleanup), removing - redundant value-check computations. -

      -

    5. Register allocation (vg_do_register_allocation), - which, note, is done on UCode. -

      -

    6. Emission of final instrumented x86 code - (VG_(emit_code)). -
    - -

    -Notice how steps 2, 3, 4 and 5 are simple UCode-to-UCode -transformation passes, all on straight-line blocks of UCode (type -UCodeBlock). Steps 2 and 4 are optimisation passes and -can be disabled for debugging purposes, with ---optimise=no and --cleanup=no respectively. - -

    -Valgrind can also run in a no-instrumentation mode, given ---instrument=no. This is useful for debugging the JITter -quickly without having to deal with the complexity of the -instrumentation mechanism too. In this mode, steps 3 and 4 are -omitted. - -

    -These flags combine, so that --instrument=no together with ---optimise=no means only steps 1, 5 and 6 are used. ---single-step=yes causes each x86 instruction to be -treated as a single basic block. The translations are terrible but -this is sometimes instructive. - -

    -The --stop-after=N flag switches back to the real CPU -after N basic blocks. It also re-JITs the final basic -block executed and prints the debugging info resulting, so this -gives you a way to get a quick snapshot of how a basic block looks as -it passes through the six stages mentioned above. If you want to -see full information for every block translated (probably not, but -still ...) find, in VG_(translate), the lines -
    dis = True; -
    dis = debugging_translation; -
    -and comment out the second line. This will spew out debugging -junk faster than you can possibly imagine. - - - -

    UCode operand tags: type Tag

    - -UCode is, more or less, a simple two-address RISC-like code. In -keeping with the x86 AT&T assembly syntax, generally speaking the -first operand is the source operand, and the second is the destination -operand, which is modified when the uinstr is notionally executed. - -

    -UCode instructions have up to three operand fields, each of which has -a corresponding Tag describing it. Possible values for -the tag are: - -

      -
    • NoValue: indicates that the field is not in use. -

      -

    • Lit16: the field contains a 16-bit literal. -

      -

    • Literal: the field denotes a 32-bit literal, whose - value is stored in the lit32 field of the uinstr - itself. Since there is only one lit32 for the whole - uinstr, only one operand field may contain this tag. -

      -

    • SpillNo: the field contains a spill slot number, in - the range 0 to 23 inclusive, denoting one of the spill slots - contained inside VG_(baseBlock). Such tags only - exist after register allocation. -

      -

    • RealReg: the field contains a number in the range 0 - to 7 denoting an integer x86 ("real") register on the host. The - number is the Intel encoding for integer registers. Such tags - only exist after register allocation. -

      -

    • ArchReg: the field contains a number in the range 0 - to 7 denoting an integer x86 register on the simulated CPU. In - reality this means a reference to one of the first 8 words of - VG_(baseBlock). Such tags can exist at any point in - the translation process. -

      -

    • Last, but not least, TempReg. The field contains the - number of one of an infinite set of virtual (integer) - registers. TempRegs are used everywhere throughout - the translation process; you can have as many as you want. The - register allocator maps as many as it can into - RealRegs and turns the rest into - SpillNos, so TempRegs should not exist - after the register allocation phase. -

      - TempRegs are always 32 bits long, even if the data - they hold is logically shorter. In that case the upper unused - bits are required, and, I think, generally assumed, to be zero. - TempRegs holding V bits for quantities shorter than - 32 bits are expected to have ones in the unused places, since a - one denotes "undefined". -

    - - -

    UCode instructions: type UInstr

    - -

    -UCode was carefully designed to make it possible to do register -allocation on UCode and then translate the result into x86 code -without needing any extra registers ... well, that was the original -plan, anyway. Things have gotten a little more complicated since -then. In what follows, UCode instructions are referred to as uinstrs, -to distinguish them from x86 instructions. Uinstrs of course have -uopcodes which are (naturally) different from x86 opcodes. - -

    -A uinstr (type UInstr) contains -various fields, not all of which are used by any one uopcode: -

      -
    • Three 16-bit operand fields, val1, val2 - and val3. -

      -

    • Three tag fields, tag1, tag2 - and tag3. Each of these has a value of type - Tag, - and they describe what the val1, val2 - and val3 fields contain. -

      -

    • A 32-bit literal field. -

      -

    • Two FlagSets, specifying which x86 condition codes are - read and written by the uinstr. -

      -

    • An opcode byte, containing a value of type Opcode. -

      -

    • A size field, indicating the data transfer size (1/2/4/8/10) in - cases where this makes sense, or zero otherwise. -

      -

    • A condition-code field, which, for jumps, holds a - value of type Condcode, indicating the condition - which applies. The encoding is as it is in the x86 insn stream, - except we add a 17th value CondAlways to indicate - an unconditional transfer. -

      -

    • Various 1-bit flags, indicating whether this insn pertains to an - x86 CALL or RET instruction, whether a widening is signed or not, - etc. -
    - -

    -UOpcodes (type Opcode) are divided into two groups: those -necessary merely to express the functionality of the x86 code, and -extra uopcodes needed to express the instrumentation. The former -group contains: -

      -
    • GET and PUT, which move values from the - simulated CPU's integer registers (ArchRegs) into - TempRegs, and back. GETF and - PUTF do the corresponding thing for the simulated - %EFLAGS. There are no corresponding insns for the - FPU register stack, since we don't explicitly simulate its - registers. -

      -

    • LOAD and STORE, which, in RISC-like - fashion, are the only uinstrs able to interact with memory. -

      -

    • MOV and CMOV allow unconditional and - conditional moves of values between TempRegs. -

      -

    • ALU operations. Again in RISC-like fashion, these only operate on - TempRegs (before reg-alloc) or RealRegs - (after reg-alloc). These are: ADD, ADC, - AND, OR, XOR, - SUB, SBB, SHL, - SHR, SAR, ROL, - ROR, RCL, RCR, - NOT, NEG, INC, - DEC, BSWAP, CC2VAL and - WIDEN. WIDEN does signed or unsigned - value widening. CC2VAL is used to convert condition - codes into a value, zero or one. The rest are obvious. -

      - To allow for more efficient code generation, we bend slightly the - restriction at the start of the previous para: for - ADD, ADC, XOR, - SUB and SBB, we allow the first (source) - operand to also be an ArchReg, that is, one of the - simulated machine's registers. Also, many of these ALU ops allow - the source operand to be a literal. See - VG_(saneUInstr) for the final word on the allowable - forms of uinstrs. -

      -

    • LEA1 and LEA2 are not strictly - necessary, but allow faciliate better translations. They - record the fancy x86 addressing modes in a direct way, which - allows those amodes to be emitted back into the final - instruction stream more or less verbatim. -

      -

    • CALLM calls a machine-code helper, one of the methods - whose address is stored at some VG_(baseBlock) - offset. PUSH and POP move values - to/from TempReg to the real (Valgrind's) stack, and - CLEAR removes values from the stack. - CALLM_S and CALLM_E delimit the - boundaries of call setups and clearings, for the benefit of the - instrumentation passes. Getting this right is critical, and so - VG_(saneUCodeBlock) makes various checks on the use - of these uopcodes. -

      - It is important to understand that these uopcodes have nothing to - do with the x86 call, return, - push or pop instructions, and are not - used to implement them. Those guys turn into combinations of - GET, PUT, LOAD, - STORE, ADD, SUB, and - JMP. What these uopcodes support is calling of - helper functions such as VG_(helper_imul_32_64), - which do stuff which is too difficult or tedious to emit inline. -

      -

    • FPU, FPU_R and FPU_W. - Valgrind doesn't attempt to simulate the internal state of the - FPU at all. Consequently it only needs to be able to distinguish - FPU ops which read and write memory from those that don't, and - for those which do, it needs to know the effective address and - data transfer size. This is made easier because the x86 FP - instruction encoding is very regular, basically consisting of - 16 bits for a non-memory FPU insn and 11 (IIRC) bits + an address mode - for a memory FPU insn. So our FPU uinstr carries - the 16 bits in its val1 field. And - FPU_R and FPU_W carry 11 bits in that - field, together with the identity of a TempReg or - (later) RealReg which contains the address. -

      -

    • JIFZ is unique, in that it allows a control-flow - transfer which is not deemed to end a basic block. It causes a - jump to a literal (original) address if the specified argument - is zero. -

      -

    • Finally, INCEIP advances the simulated - %EIP by the specified literal amount. This supports - lazy %EIP updating, as described below. -
    - -

    -Stages 1 and 2 of the 6-stage translation process mentioned above -deal purely with these uopcodes, and no others. They are -sufficient to express pretty much all the x86 32-bit protected-mode -instruction set, at -least everything understood by a pre-MMX original Pentium (P54C). - -

    -Stages 3, 4, 5 and 6 also deal with the following extra -"instrumentation" uopcodes. They are used to express all the -definedness-tracking and -checking machinery which valgrind does. In -later sections we show how to create checking code for each of the -uopcodes above. Note that these instrumentation uopcodes, although -some appearing complicated, have been carefully chosen so that -efficient x86 code can be generated for them. GNU superopt v2.5 did a -great job helping out here. Anyways, the uopcodes are as follows: - -

      -
    • GETV and PUTV are analogues to - GET and PUT above. They are identical - except that they move the V bits for the specified values back and - forth to TempRegs, rather than moving the values - themselves. -

      -

    • Similarly, LOADV and STOREV read and - write V bits from the synthesised shadow memory that Valgrind - maintains. In fact they do more than that, since they also do - address-validity checks, and emit complaints if the read/written - addresses are unaddressible. -

      -

    • TESTV, whose parameters are a TempReg - and a size, tests the V bits in the TempReg, at the - specified operation size (0/1/2/4 byte) and emits an error if any - of them indicate undefinedness. This is the only uopcode capable - of doing such tests. -

      -

    • SETV, whose parameters are also TempReg - and a size, makes the V bits in the TempReg indicated - definedness, at the specified operation size. This is usually - used to generate the correct V bits for a literal value, which is - of course fully defined. -

      -

    • GETVF and PUTVF are analogues to - GETF and PUTF. They move the single V - bit used to model definedness of %EFLAGS between its - home in VG_(baseBlock) and the specified - TempReg. -

      -

    • TAG1 denotes one of a family of unary operations on - TempRegs containing V bits. Similarly, - TAG2 denotes one in a family of binary operations on - V bits. -
    - -

    -These 10 uopcodes are sufficient to express Valgrind's entire -definedness-checking semantics. In fact most of the interesting magic -is done by the TAG1 and TAG2 -suboperations. - -

    -First, however, I need to explain about V-vector operation sizes. -There are 4 sizes: 1, 2 and 4, which operate on groups of 8, 16 and 32 -V bits at a time, supporting the usual 1, 2 and 4 byte x86 operations. -However there is also the mysterious size 0, which really means a -single V bit. Single V bits are used in various circumstances; in -particular, the definedness of %EFLAGS is modelled with a -single V bit. Now might be a good time to also point out that for -V bits, 1 means "undefined" and 0 means "defined". Similarly, for A -bits, 1 means "invalid address" and 0 means "valid address". This -seems counterintuitive (and so it is), but testing against zero on -x86s saves instructions compared to testing against all 1s, because -many ALU operations set the Z flag for free, so to speak. - -

    -With that in mind, the tag ops are: - -

      -
    • (UNARY) Pessimising casts: VgT_PCast40, - VgT_PCast20, VgT_PCast10, - VgT_PCast01, VgT_PCast02 and - VgT_PCast04. A "pessimising cast" takes a V-bit - vector at one size, and creates a new one at another size, - pessimised in the sense that if any of the bits in the source - vector indicate undefinedness, then all the bits in the result - indicate undefinedness. In this case the casts are all to or from - a single V bit, so for example VgT_PCast40 is a - pessimising cast from 32 bits to 1, whereas - VgT_PCast04 simply copies the single source V bit - into all 32 bit positions in the result. Surprisingly, these ops - can all be implemented very efficiently. -

      - There are also the pessimising casts VgT_PCast14, - from 8 bits to 32, VgT_PCast12, from 8 bits to 16, - and VgT_PCast11, from 8 bits to 8. This last one - seems nonsensical, but in fact it isn't a no-op because, as - mentioned above, any undefined (1) bits in the source infect the - entire result. -

      -

    • (UNARY) Propagating undefinedness upwards in a word: - VgT_Left4, VgT_Left2 and - VgT_Left1. These are used to simulate the worst-case - effects of carry propagation in adds and subtracts. They return a - V vector identical to the original, except that if the original - contained any undefined bits, then it and all bits above it are - marked as undefined too. Hence the Left bit in the names. -

      -

    • (UNARY) Signed and unsigned value widening: - VgT_SWiden14, VgT_SWiden24, - VgT_SWiden12, VgT_ZWiden14, - VgT_ZWiden24 and VgT_ZWiden12. These - mimic the definedness effects of standard signed and unsigned - integer widening. Unsigned widening creates zero bits in the new - positions, so VgT_ZWiden* accordingly park mark - those parts of their argument as defined. Signed widening copies - the sign bit into the new positions, so VgT_SWiden* - copies the definedness of the sign bit into the new positions. - Because 1 means undefined and 0 means defined, these operations - can (fascinatingly) be done by the same operations which they - mimic. Go figure. -

      -

    • (BINARY) Undefined-if-either-Undefined, - Defined-if-either-Defined: VgT_UifU4, - VgT_UifU2, VgT_UifU1, - VgT_UifU0, VgT_DifD4, - VgT_DifD2, VgT_DifD1. These do simple - bitwise operations on pairs of V-bit vectors, with - UifU giving undefined if either arg bit is - undefined, and DifD giving defined if either arg bit - is defined. Abstract interpretation junkies, if any make it this - far, may like to think of them as meets and joins (or is it joins - and meets) in the definedness lattices. -

      -

    • (BINARY; one value, one V bits) Generate argument improvement - terms for AND and OR: VgT_ImproveAND4_TQ, - VgT_ImproveAND2_TQ, VgT_ImproveAND1_TQ, - VgT_ImproveOR4_TQ, VgT_ImproveOR2_TQ, - VgT_ImproveOR1_TQ. These help out with AND and OR - operations. AND and OR have the inconvenient property that the - definedness of the result depends on the actual values of the - arguments as well as their definedness. At the bit level: -
      1 AND undefined = undefined, but -
      0 AND undefined = 0, and similarly -
      0 OR undefined = undefined, but -
      1 OR undefined = 1. -
      -

      - It turns out that gcc (quite legitimately) generates code which - relies on this fact, so we have to model it properly in order to - avoid flooding users with spurious value errors. The ultimate - definedness result of AND and OR is calculated using - UifU on the definedness of the arguments, but we - also DifD in some "improvement" terms which - take into account the above phenomena. -

      - ImproveAND takes as its first argument the actual - value of an argument to AND (the T) and the definedness of that - argument (the Q), and returns a V-bit vector which is defined (0) - for bits which have value 0 and are defined; this, when - DifD into the final result causes those bits to be - defined even if the corresponding bit in the other argument is undefined. -

      - The ImproveOR ops do the dual thing for OR - arguments. Note that XOR does not have this property that one - argument can make the other irrelevant, so there is no need for - such complexity for XOR. -

    - -

    -That's all the tag ops. If you stare at this long enough, and then -run Valgrind and stare at the pre- and post-instrumented ucode, it -should be fairly obvious how the instrumentation machinery hangs -together. - -

    -One point, if you do this: in order to make it easy to differentiate -TempRegs carrying values from TempRegs -carrying V bit vectors, Valgrind prints the former as (for example) -t28 and the latter as q28; the fact that -they carry the same number serves to indicate their relationship. -This is purely for the convenience of the human reader; the register -allocator and code generator don't regard them as different. - - -

    Translation into UCode

    - -VG_(disBB) allocates a new UCodeBlock and -then uses disInstr to translate x86 instructions one at a -time into UCode, dumping the result in the UCodeBlock. -This goes on until a control-flow transfer instruction is encountered. - -

    -Despite the large size of vg_to_ucode.c, this translation -is really very simple. Each x86 instruction is translated entirely -independently of its neighbours, merrily allocating new -TempRegs as it goes. The idea is to have a simple -translator -- in reality, no more than a macro-expander -- and the -- -resulting bad UCode translation is cleaned up by the UCode -optimisation phase which follows. To give you an idea of some x86 -instructions and their translations (this is a complete basic block, -as Valgrind sees it): -

    -        0x40435A50:  incl %edx
    -
    -           0: GETL      %EDX, t0
    -           1: INCL      t0  (-wOSZAP)
    -           2: PUTL      t0, %EDX
    -
    -        0x40435A51:  movsbl (%edx),%eax
    -
    -           3: GETL      %EDX, t2
    -           4: LDB       (t2), t2
    -           5: WIDENL_Bs t2
    -           6: PUTL      t2, %EAX
    -
    -        0x40435A54:  testb $0x20, 1(%ecx,%eax,2)
    -
    -           7: GETL      %EAX, t6
    -           8: GETL      %ECX, t8
    -           9: LEA2L     1(t8,t6,2), t4
    -          10: LDB       (t4), t10
    -          11: MOVB      $0x20, t12
    -          12: ANDB      t12, t10  (-wOSZACP)
    -          13: INCEIPo   $9
    -
    -        0x40435A59:  jnz-8 0x40435A50
    -
    -          14: Jnzo      $0x40435A50  (-rOSZACP)
    -          15: JMPo      $0x40435A5B
    -
    - -

    -Notice how the block always ends with an unconditional jump to the -next block. This is a bit unnecessary, but makes many things simpler. - -

    -Most x86 instructions turn into sequences of GET, -PUT, LEA1, LEA2, -LOAD and STORE. Some complicated ones -however rely on calling helper bits of code in -vg_helpers.S. The ucode instructions PUSH, -POP, CALL, CALLM_S and -CALLM_E support this. The calling convention is somewhat -ad-hoc and is not the C calling convention. The helper routines must -save all integer registers, and the flags, that they use. Args are -passed on the stack underneath the return address, as usual, and if -result(s) are to be returned, it (they) are either placed in dummy arg -slots created by the ucode PUSH sequence, or just -overwrite the incoming args. - -

    -In order that the instrumentation mechanism can handle calls to these -helpers, VG_(saneUCodeBlock) enforces the following -restrictions on calls to helpers: - -

      -
    • Each CALL uinstr must be bracketed by a preceding - CALLM_S marker (dummy uinstr) and a trailing - CALLM_E marker. These markers are used by the - instrumentation mechanism later to establish the boundaries of the - PUSH, POP and CLEAR - sequences for the call. -

      -

    • PUSH, POP and CLEAR - may only appear inside sections bracketed by CALLM_S - and CALLM_E, and nowhere else. -

      -

    • In any such bracketed section, no two PUSH insns may - push the same TempReg. Dually, no two two - POPs may pop the same TempReg. -

      -

    • Finally, although this is not checked, args should be removed from - the stack with CLEAR, rather than POPs - into a TempReg which is not subsequently used. This - is because the instrumentation mechanism assumes that all values - POPped from the stack are actually used. -
    - -Some of the translations may appear to have redundant -TempReg-to-TempReg moves. This helps the -next phase, UCode optimisation, to generate better code. - - - -

    UCode optimisation

    - -UCode is then subjected to an improvement pass -(vg_improve()), which blurs the boundaries between the -translations of the original x86 instructions. It's pretty -straightforward. Three transformations are done: - -
      -
    • Redundant GET elimination. Actually, more general - than that -- eliminates redundant fetches of ArchRegs. In our - running example, uinstr 3 GETs %EDX into - t2 despite the fact that, by looking at the previous - uinstr, it is already in t0. The GET is - therefore removed, and t2 renamed to t0. - Assuming t0 is allocated to a host register, it means - the simulated %EDX will exist in a host CPU register - for more than one simulated x86 instruction, which seems to me to - be a highly desirable property. -

      - There is some mucking around to do with subregisters; - %AL vs %AH %AX vs - %EAX etc. I can't remember how it works, but in - general we are very conservative, and these tend to invalidate the - caching. -

      -

    • Redundant PUT elimination. This annuls - PUTs of values back to simulated CPU registers if a - later PUT would overwrite the earlier - PUT value, and there is no intervening reads of the - simulated register (ArchReg). -

      - As before, we are paranoid when faced with subregister references. - Also, PUTs of %ESP are never annulled, - because it is vital the instrumenter always has an up-to-date - %ESP value available, %ESP changes - affect addressibility of the memory around the simulated stack - pointer. -

      - The implication of the above paragraph is that the simulated - machine's registers are only lazily updated once the above two - optimisation phases have run, with the exception of - %ESP. TempRegs go dead at the end of - every basic block, from which is is inferrable that any - TempReg caching a simulated CPU reg is flushed (back - into the relevant VG_(baseBlock) slot) at the end of - every basic block. The further implication is that the simulated - registers are only up-to-date at in between basic blocks, and not - at arbitrary points inside basic blocks. And the consequence of - that is that we can only deliver signals to the client in between - basic blocks. None of this seems any problem in practice. -

      -

    • Finally there is a simple def-use thing for condition codes. If - an earlier uinstr writes the condition codes, and the next uinsn - along which actually cares about the condition codes writes the - same or larger set of them, but does not read any, the earlier - uinsn is marked as not writing any condition codes. This saves - a lot of redundant cond-code saving and restoring. -
    - -The effect of these transformations on our short block is rather -unexciting, and shown below. On longer basic blocks they can -dramatically improve code quality. - -
    -at 3: delete GET, rename t2 to t0 in (4 .. 6)
    -at 7: delete GET, rename t6 to t0 in (8 .. 9)
    -at 1: annul flag write OSZAP due to later OSZACP
    -
    -Improved code:
    -           0: GETL      %EDX, t0
    -           1: INCL      t0
    -           2: PUTL      t0, %EDX
    -           4: LDB       (t0), t0
    -           5: WIDENL_Bs t0
    -           6: PUTL      t0, %EAX
    -           8: GETL      %ECX, t8
    -           9: LEA2L     1(t8,t0,2), t4
    -          10: LDB       (t4), t10
    -          11: MOVB      $0x20, t12
    -          12: ANDB      t12, t10  (-wOSZACP)
    -          13: INCEIPo   $9
    -          14: Jnzo      $0x40435A50  (-rOSZACP)
    -          15: JMPo      $0x40435A5B
    -
    - -

    UCode instrumentation

    - -Once you understand the meaning of the instrumentation uinstrs, -discussed in detail above, the instrumentation scheme is fairly -straightforward. Each uinstr is instrumented in isolation, and the -instrumentation uinstrs are placed before the original uinstr. -Our running example continues below. I have placed a blank line -after every original ucode, to make it easier to see which -instrumentation uinstrs correspond to which originals. - -

    -As mentioned somewhere above, TempRegs carrying values -have names like t28, and each one has a shadow carrying -its V bits, with names like q28. This pairing aids in -reading instrumented ucode. - -

    -One decision about all this is where to have "observation points", -that is, where to check that V bits are valid. I use a minimalistic -scheme, only checking where a failure of validity could cause the -original program to (seg)fault. So the use of values as memory -addresses causes a check, as do conditional jumps (these cause a check -on the definedness of the condition codes). And arguments -PUSHed for helper calls are checked, hence the weird -restrictions on help call preambles described above. - -

    -Another decision is that once a value is tested, it is thereafter -regarded as defined, so that we do not emit multiple undefined-value -errors for the same undefined value. That means that -TESTV uinstrs are always followed by SETV -on the same (shadow) TempRegs. Most of these -SETVs are redundant and are removed by the -post-instrumentation cleanup phase. - -

    -The instrumentation for calling helper functions deserves further -comment. The definedness of results from a helper is modelled using -just one V bit. So, in short, we do pessimising casts of the -definedness of all the args, down to a single bit, and then -UifU these bits together. So this single V bit will say -"undefined" if any part of any arg is undefined. This V bit is then -pessimally cast back up to the result(s) sizes, as needed. If, by -seeing that all the args are got rid of with CLEAR and -none with POP, Valgrind sees that the result of the call -is not actually used, it immediately examines the result V bit with a -TESTV -- SETV pair. If it did not do this, -there would be no observation point to detect that the some of the -args to the helper were undefined. Of course, if the helper's results -are indeed used, we don't do this, since the result usage will -presumably cause the result definedness to be checked at some suitable -future point. - -

    -In general Valgrind tries to track definedness on a bit-for-bit basis, -but as the above para shows, for calls to helpers we throw in the -towel and approximate down to a single bit. This is because it's too -complex and difficult to track bit-level definedness through complex -ops such as integer multiply and divide, and in any case there is no -reasonable code fragments which attempt to (eg) multiply two -partially-defined values and end up with something meaningful, so -there seems little point in modelling multiplies, divides, etc, in -that level of detail. - -

    -Integer loads and stores are instrumented with firstly a test of the -definedness of the address, followed by a LOADV or -STOREV respectively. These turn into calls to -(for example) VG_(helperc_LOADV4). These helpers do two -things: they perform an address-valid check, and they load or store V -bits from/to the relevant address in the (simulated V-bit) memory. - -

    -FPU loads and stores are different. As above the definedness of the -address is first tested. However, the helper routine for FPU loads -(VGM_(fpu_read_check)) emits an error if either the -address is invalid or the referenced area contains undefined values. -It has to do this because we do not simulate the FPU at all, and so -cannot track definedness of values loaded into it from memory, so we -have to check them as soon as they are loaded into the FPU, ie, at -this point. We notionally assume that everything in the FPU is -defined. - -

    -It follows therefore that FPU writes first check the definedness of -the address, then the validity of the address, and finally mark the -written bytes as well-defined. - -

    -If anyone is inspired to extend Valgrind to MMX/SSE insns, I suggest -you use the same trick. It works provided that the FPU/MMX unit is -not used to merely as a conduit to copy partially undefined data from -one place in memory to another. Unfortunately the integer CPU is used -like that (when copying C structs with holes, for example) and this is -the cause of much of the elaborateness of the instrumentation here -described. - -

    -vg_instrument() in vg_translate.c actually -does the instrumentation. There are comments explaining how each -uinstr is handled, so we do not repeat that here. As explained -already, it is bit-accurate, except for calls to helper functions. -Unfortunately the x86 insns bt/bts/btc/btr are done by -helper fns, so bit-level accuracy is lost there. This should be fixed -by doing them inline; it will probably require adding a couple new -uinstrs. Also, left and right rotates through the carry flag (x86 -rcl and rcr) are approximated via a single -V bit; so far this has not caused anyone to complain. The -non-carry rotates, rol and ror, are much -more common and are done exactly. Re-visiting the instrumentation for -AND and OR, they seem rather verbose, and I wonder if it could be done -more concisely now. - -

    -The lowercase o on many of the uopcodes in the running -example indicates that the size field is zero, usually meaning a -single-bit operation. - -

    -Anyroads, the post-instrumented version of our running example looks -like this: - -

    -Instrumented code:
    -           0: GETVL     %EDX, q0
    -           1: GETL      %EDX, t0
    -
    -           2: TAG1o     q0 = Left4 ( q0 )
    -           3: INCL      t0
    -
    -           4: PUTVL     q0, %EDX
    -           5: PUTL      t0, %EDX
    -
    -           6: TESTVL    q0
    -           7: SETVL     q0
    -           8: LOADVB    (t0), q0
    -           9: LDB       (t0), t0
    -
    -          10: TAG1o     q0 = SWiden14 ( q0 )
    -          11: WIDENL_Bs t0
    -
    -          12: PUTVL     q0, %EAX
    -          13: PUTL      t0, %EAX
    -
    -          14: GETVL     %ECX, q8
    -          15: GETL      %ECX, t8
    -
    -          16: MOVL      q0, q4
    -          17: SHLL      $0x1, q4
    -          18: TAG2o     q4 = UifU4 ( q8, q4 )
    -          19: TAG1o     q4 = Left4 ( q4 )
    -          20: LEA2L     1(t8,t0,2), t4
    -
    -          21: TESTVL    q4
    -          22: SETVL     q4
    -          23: LOADVB    (t4), q10
    -          24: LDB       (t4), t10
    -
    -          25: SETVB     q12
    -          26: MOVB      $0x20, t12
    -
    -          27: MOVL      q10, q14
    -          28: TAG2o     q14 = ImproveAND1_TQ ( t10, q14 )
    -          29: TAG2o     q10 = UifU1 ( q12, q10 )
    -          30: TAG2o     q10 = DifD1 ( q14, q10 )
    -          31: MOVL      q12, q14
    -          32: TAG2o     q14 = ImproveAND1_TQ ( t12, q14 )
    -          33: TAG2o     q10 = DifD1 ( q14, q10 )
    -          34: MOVL      q10, q16
    -          35: TAG1o     q16 = PCast10 ( q16 )
    -          36: PUTVFo    q16
    -          37: ANDB      t12, t10  (-wOSZACP)
    -
    -          38: INCEIPo   $9
    -
    -          39: GETVFo    q18
    -          40: TESTVo    q18
    -          41: SETVo     q18
    -          42: Jnzo      $0x40435A50  (-rOSZACP)
    -
    -          43: JMPo      $0x40435A5B
    -
    - - -

    UCode post-instrumentation cleanup

    - -

    -This pass, coordinated by vg_cleanup(), removes redundant -definedness computation created by the simplistic instrumentation -pass. It consists of two passes, -vg_propagate_definedness() followed by -vg_delete_redundant_SETVs. - -

    -vg_propagate_definedness() is a simple -constant-propagation and constant-folding pass. It tries to determine -which TempRegs containing V bits will always indicate -"fully defined", and it propagates this information as far as it can, -and folds out as many operations as possible. For example, the -instrumentation for an ADD of a literal to a variable quantity will be -reduced down so that the definedness of the result is simply the -definedness of the variable quantity, since the literal is by -definition fully defined. - -

    -vg_delete_redundant_SETVs removes SETVs on -shadow TempRegs for which the next action is a write. -I don't think there's anything else worth saying about this; it is -simple. Read the sources for details. - -

    -So the cleaned-up running example looks like this. As above, I have -inserted line breaks after every original (non-instrumentation) uinstr -to aid readability. As with straightforward ucode optimisation, the -results in this block are undramatic because it is so short; longer -blocks benefit more because they have more redundancy which gets -eliminated. - - -

    -at 29: delete UifU1 due to defd arg1
    -at 32: change ImproveAND1_TQ to MOV due to defd arg2
    -at 41: delete SETV
    -at 31: delete MOV
    -at 25: delete SETV
    -at 22: delete SETV
    -at 7: delete SETV
    -
    -           0: GETVL     %EDX, q0
    -           1: GETL      %EDX, t0
    -
    -           2: TAG1o     q0 = Left4 ( q0 )
    -           3: INCL      t0
    -
    -           4: PUTVL     q0, %EDX
    -           5: PUTL      t0, %EDX
    -
    -           6: TESTVL    q0
    -           8: LOADVB    (t0), q0
    -           9: LDB       (t0), t0
    -
    -          10: TAG1o     q0 = SWiden14 ( q0 )
    -          11: WIDENL_Bs t0
    -
    -          12: PUTVL     q0, %EAX
    -          13: PUTL      t0, %EAX
    -
    -          14: GETVL     %ECX, q8
    -          15: GETL      %ECX, t8
    -
    -          16: MOVL      q0, q4
    -          17: SHLL      $0x1, q4
    -          18: TAG2o     q4 = UifU4 ( q8, q4 )
    -          19: TAG1o     q4 = Left4 ( q4 )
    -          20: LEA2L     1(t8,t0,2), t4
    -
    -          21: TESTVL    q4
    -          23: LOADVB    (t4), q10
    -          24: LDB       (t4), t10
    -
    -          26: MOVB      $0x20, t12
    -
    -          27: MOVL      q10, q14
    -          28: TAG2o     q14 = ImproveAND1_TQ ( t10, q14 )
    -          30: TAG2o     q10 = DifD1 ( q14, q10 )
    -          32: MOVL      t12, q14
    -          33: TAG2o     q10 = DifD1 ( q14, q10 )
    -          34: MOVL      q10, q16
    -          35: TAG1o     q16 = PCast10 ( q16 )
    -          36: PUTVFo    q16
    -          37: ANDB      t12, t10  (-wOSZACP)
    -
    -          38: INCEIPo   $9
    -          39: GETVFo    q18
    -          40: TESTVo    q18
    -          42: Jnzo      $0x40435A50  (-rOSZACP)
    -
    -          43: JMPo      $0x40435A5B
    -
    - - -

    Translation from UCode

    - -This is all very simple, even though vg_from_ucode.c -is a big file. Position-independent x86 code is generated into -a dynamically allocated array emitted_code; this is -doubled in size when it overflows. Eventually the array is handed -back to the caller of VG_(translate), who must copy -the result into TC and TT, and free the array. - -

    -This file is structured into four layers of abstraction, which, -thankfully, are glued back together with extensive -__inline__ directives. From the bottom upwards: - -

      -
    • Address-mode emitters, emit_amode_regmem_reg et al. -

      -

    • Emitters for specific x86 instructions. There are quite a lot of - these, with names such as emit_movv_offregmem_reg. - The v suffix is Intel parlance for a 16/32 bit insn; - there are also b suffixes for 8 bit insns. -

      -

    • The next level up are the synth_* functions, which - synthesise possibly a sequence of raw x86 instructions to do some - simple task. Some of these are quite complex because they have to - work around Intel's silly restrictions on subregister naming. See - synth_nonshiftop_reg_reg for example. -

      -

    • Finally, at the top of the heap, we have - emitUInstr(), - which emits code for a single uinstr. -
    - -

    -Some comments: -

      -
    • The hack for FPU instructions becomes apparent here. To do a - FPU ucode instruction, we load the simulated FPU's - state into from its VG_(baseBlock) into the real FPU - using an x86 frstor insn, do the ucode - FPU insn on the real CPU, and write the updated FPU - state back into VG_(baseBlock) using an - fnsave instruction. This is pretty brutal, but is - simple and it works, and even seems tolerably efficient. There is - no attempt to cache the simulated FPU state in the real FPU over - multiple back-to-back ucode FPU instructions. -

      - FPU_R and FPU_W are also done this way, - with the minor complication that we need to patch in some - addressing mode bits so the resulting insn knows the effective - address to use. This is easy because of the regularity of the x86 - FPU instruction encodings. -

      -

    • An analogous trick is done with ucode insns which claim, in their - flags_r and flags_w fields, that they - read or write the simulated %EFLAGS. For such cases - we first copy the simulated %EFLAGS into the real - %eflags, then do the insn, then, if the insn says it - writes the flags, copy back to %EFLAGS. This is a - bit expensive, which is why the ucode optimisation pass goes to - some effort to remove redundant flag-update annotations. -
    - -

    -And so ... that's the end of the documentation for the instrumentating -translator! It's really not that complex, because it's composed as a -sequence of simple(ish) self-contained transformations on -straight-line blocks of code. - - -

    Top-level dispatch loop

    - -Urk. In VG_(toploop). This is basically boring and -unsurprising, not to mention fiddly and fragile. It needs to be -cleaned up. - -

    -The only perhaps surprise is that the whole thing is run -on top of a setjmp-installed exception handler, because, -supposing a translation got a segfault, we have to bail out of the -Valgrind-supplied exception handler VG_(oursignalhandler) -and immediately start running the client's segfault handler, if it has -one. In particular we can't finish the current basic block and then -deliver the signal at some convenient future point, because signals -like SIGILL, SIGSEGV and SIGBUS mean that the faulting insn should not -simply be re-tried. (I'm sure there is a clearer way to explain this). - - -

    Exceptions, creating new translations

    -

    Self-modifying code

    - -

    Lazy updates of the simulated program counter

    - -Simulated %EIP is not updated after every simulated x86 -insn as this was regarded as too expensive. Instead ucode -INCEIP insns move it along as and when necessary. -Currently we don't allow it to fall more than 4 bytes behind reality -(see VG_(disBB) for the way this works). -

    -Note that %EIP is always brought up to date by the inner -dispatch loop in VG_(dispatch), so that if the client -takes a fault we know at least which basic block this happened in. - - -

    The translation cache and translation table

    - -

    Signals

    - -Horrible, horrible. vg_signals.c. -Basically, since we have to intercept all system -calls anyway, we can see when the client tries to install a signal -handler. If it does so, we make a note of what the client asked to -happen, and ask the kernel to route the signal to our own signal -handler, VG_(oursignalhandler). This simply notes the -delivery of signals, and returns. - -

    -Every 1000 basic blocks, we see if more signals have arrived. If so, -VG_(deliver_signals) builds signal delivery frames on the -client's stack, and allows their handlers to be run. Valgrind places -in these signal delivery frames a bogus return address, -VG_(signalreturn_bogusRA), and checks all jumps to see -if any jump to it. If so, this is a sign that a signal handler is -returning, and if so Valgrind removes the relevant signal frame from -the client's stack, restores the from the signal frame the simulated -state before the signal was delivered, and allows the client to run -onwards. We have to do it this way because some signal handlers never -return, they just longjmp(), which nukes the signal -delivery frame. - -

    -The Linux kernel has a different but equally horrible hack for -detecting signal handler returns. Discovering it is left as an -exercise for the reader. - - - -

    Errors, error contexts, error reporting, suppressions

    -

    Client malloc/free

    -

    Low-level memory management

    -

    A and V bitmaps

    -

    Symbol table management

    -

    Dealing with system calls

    -

    Namespace management

    -

    GDB attaching

    -

    Non-dependence on glibc or anything else

    -

    The leak detector

    -

    Performance problems

    -

    Continuous sanity checking

    -

    Tracing, or not tracing, child processes

    -

    Assembly glue for syscalls

    - - -
    - -

    Extensions

    - -Some comments about Stuff To Do. - -

    Bugs

    - -Stephan Kulow and Marc Mutz report problems with kmail in KDE 3 CVS -(RC2 ish) when run on Valgrind. Stephan has it deadlocking; Marc has -it looping at startup. I can't repro either behaviour. Needs -repro-ing and fixing. - - -

    Threads

    - -Doing a good job of thread support strikes me as almost a -research-level problem. The central issues are how to do fast cheap -locking of the VG_(primary_map) structure, whether or not -accesses to the individual secondary maps need locking, what -race-condition issues result, and whether the already-nasty mess that -is the signal simulator needs further hackery. - -

    -I realise that threads are the most-frequently-requested feature, and -I am thinking about it all. If you have guru-level understanding of -fast mutual exclusion mechanisms and race conditions, I would be -interested in hearing from you. - - -

    Verification suite

    - -Directory tests/ contains various ad-hoc tests for -Valgrind. However, there is no systematic verification or regression -suite, that, for example, exercises all the stuff in -vg_memory.c, to ensure that illegal memory accesses and -undefined value uses are detected as they should be. It would be good -to have such a suite. - - -

    Porting to other platforms

    - -It would be great if Valgrind was ported to FreeBSD and x86 NetBSD, -and to x86 OpenBSD, if it's possible (doesn't OpenBSD use a.out-style -executables, not ELF ?) - -

    -The main difficulties, for an x86-ELF platform, seem to be: - -

      -
    • You'd need to rewrite the /proc/self/maps parser - (vg_procselfmaps.c). - Easy. -

      -

    • You'd need to rewrite vg_syscall_mem.c, or, more - specifically, provide one for your OS. This is tedious, but you - can implement syscalls on demand, and the Linux kernel interface - is, for the most part, going to look very similar to the *BSD - interfaces, so it's really a copy-paste-and-modify-on-demand job. - As part of this, you'd need to supply a new - vg_kerneliface.h file. -

      -

    • You'd also need to change the syscall wrappers for Valgrind's - internal use, in vg_mylibc.c. -
    - -All in all, I think a port to x86-ELF *BSDs is not really very -difficult, and in some ways I would like to see it happen, because -that would force a more clear factoring of Valgrind into platform -dependent and independent pieces. Not to mention, *BSD folks also -deserve to use Valgrind just as much as the Linux crew do. - - -

    -


    - -

    Easy stuff which ought to be done

    - -

    MMX instructions

    - -MMX insns should be supported, using the same trick as for FPU insns. -If the MMX registers are not used to copy uninitialised junk from one -place to another in memory, this means we don't have to actually -simulate the internal MMX unit state, so the FPU hack applies. This -should be fairly easy. - - - -

    Fix stabs-info reader

    - -The machinery in vg_symtab2.c which reads "stabs" style -debugging info is pretty weak. It usually correctly translates -simulated program counter values into line numbers and procedure -names, but the file name is often completely wrong. I think the -logic used to parse "stabs" entries is weak. It should be fixed. -The simplest solution, IMO, is to copy either the logic or simply the -code out of GNU binutils which does this; since GDB can clearly get it -right, binutils (or GDB?) must have code to do this somewhere. - - - - - -

    BT/BTC/BTS/BTR

    - -These are x86 instructions which test, complement, set, or reset, a -single bit in a word. At the moment they are both incorrectly -implemented and incorrectly instrumented. - -

    -The incorrect instrumentation is due to use of helper functions. This -means we lose bit-level definedness tracking, which could wind up -giving spurious uninitialised-value use errors. The Right Thing to do -is to invent a couple of new UOpcodes, I think GET_BIT -and SET_BIT, which can be used to implement all 4 x86 -insns, get rid of the helpers, and give bit-accurate instrumentation -rules for the two new UOpcodes. - -

    -I realised the other day that they are mis-implemented too. The x86 -insns take a bit-index and a register or memory location to access. -For registers the bit index clearly can only be in the range zero to -register-width minus 1, and I assumed the same applied to memory -locations too. But evidently not; for memory locations the index can -be arbitrary, and the processor will index arbitrarily into memory as -a result. This too should be fixed. Sigh. Presumably indexing -outside the immediate word is not actually used by any programs yet -tested on Valgrind, for otherwise they (presumably) would simply not -work at all. If you plan to hack on this, first check the Intel docs -to make sure my understanding is really correct. - - - -

    Using PREFETCH instructions

    - -Here's a small but potentially interesting project for performance -junkies. Experiments with valgrind's code generator and optimiser(s) -suggest that reducing the number of instructions executed in the -translations and mem-check helpers gives disappointingly small -performance improvements. Perhaps this is because performance of -Valgrindified code is limited by cache misses. After all, each read -in the original program now gives rise to at least three reads, one -for the VG_(primary_map), one of the resulting -secondary, and the original. Not to mention, the instrumented -translations are 13 to 14 times larger than the originals. All in all -one would expect the memory system to be hammered to hell and then -some. - -

    -So here's an idea. An x86 insn involving a read from memory, after -instrumentation, will turn into ucode of the following form: -

    -    ... calculate effective addr, into ta and qa ...
    -    TESTVL qa             -- is the addr defined?
    -    LOADV (ta), qloaded   -- fetch V bits for the addr
    -    LOAD  (ta), tloaded   -- do the original load
    -
    -At the point where the LOADV is done, we know the actual -address (ta) from which the real LOAD will -be done. We also know that the LOADV will take around -20 x86 insns to do. So it seems plausible that doing a prefetch of -ta just before the LOADV might just avoid a -miss at the LOAD point, and that might be a significant -performance win. - -

    -Prefetch insns are notoriously tempermental, more often than not -making things worse rather than better, so this would require -considerable fiddling around. It's complicated because Intels and -AMDs have different prefetch insns with different semantics, so that -too needs to be taken into account. As a general rule, even placing -the prefetches before the LOADV insn is too near the -LOAD; the ideal distance is apparently circa 200 CPU -cycles. So it might be worth having another analysis/transformation -pass which pushes prefetches as far back as possible, hopefully -immediately after the effective address becomes available. - -

    -Doing too many prefetches is also bad because they soak up bus -bandwidth / cpu resources, so some cleverness in deciding which loads -to prefetch and which to not might be helpful. One can imagine not -prefetching client-stack-relative (%EBP or -%ESP) accesses, since the stack in general tends to show -good locality anyway. - -

    -There's quite a lot of experimentation to do here, but I think it -might make an interesting week's work for someone. - -

    -As of 15-ish March 2002, I've started to experiment with this, using -the AMD prefetch/prefetchw insns. - - - -

    User-defined permission ranges

    - -This is quite a large project -- perhaps a month's hacking for a -capable hacker to do a good job -- but it's potentially very -interesting. The outcome would be that Valgrind could detect a -whole class of bugs which it currently cannot. - -

    -The presentation falls into two pieces. - -

    -Part 1: user-defined address-range permission setting -

    - -Valgrind intercepts the client's malloc, -free, etc calls, watches system calls, and watches the -stack pointer move. This is currently the only way it knows about -which addresses are valid and which not. Sometimes the client program -knows extra information about its memory areas. For example, the -client could at some point know that all elements of an array are -out-of-date. We would like to be able to convey to Valgrind this -information that the array is now addressable-but-uninitialised, so -that Valgrind can then warn if elements are used before they get new -values. - -

    -What I would like are some macros like this: -

    -   VALGRIND_MAKE_NOACCESS(addr, len)
    -   VALGRIND_MAKE_WRITABLE(addr, len)
    -   VALGRIND_MAKE_READABLE(addr, len)
    -
    -and also, to check that memory is addressible/initialised, -
    -   VALGRIND_CHECK_ADDRESSIBLE(addr, len)
    -   VALGRIND_CHECK_INITIALISED(addr, len)
    -
    - -

    -I then include in my sources a header defining these macros, rebuild -my app, run under Valgrind, and get user-defined checks. - -

    -Now here's a neat trick. It's a nuisance to have to re-link the app -with some new library which implements the above macros. So the idea -is to define the macros so that the resulting executable is still -completely stand-alone, and can be run without Valgrind, in which case -the macros do nothing, but when run on Valgrind, the Right Thing -happens. How to do this? The idea is for these macros to turn into a -piece of inline assembly code, which (1) has no effect when run on the -real CPU, (2) is easily spotted by Valgrind's JITter, and (3) no sane -person would ever write, which is important for avoiding false matches -in (2). So here's a suggestion: -

    -   VALGRIND_MAKE_NOACCESS(addr, len)
    -
    -becomes (roughly speaking) -
    -   movl addr, %eax
    -   movl len,  %ebx
    -   movl $1,   %ecx   -- 1 describes the action; MAKE_WRITABLE might be
    -                     -- 2, etc
    -   rorl $13, %ecx
    -   rorl $19, %ecx
    -   rorl $11, %eax
    -   rorl $21, %eax
    -
    -The rotate sequences have no effect, and it's unlikely they would -appear for any other reason, but they define a unique byte-sequence -which the JITter can easily spot. Using the operand constraints -section at the end of a gcc inline-assembly statement, we can tell gcc -that the assembly fragment kills %eax, %ebx, -%ecx and the condition codes, so this fragment is made -harmless when not running on Valgrind, runs quickly when not on -Valgrind, and does not require any other library support. - - -

    -Part 2: using it to detect interference between stack variables -

    - -Currently Valgrind cannot detect errors of the following form: -

    -void fooble ( void )
    -{
    -   int a[10];
    -   int b[10];
    -   a[10] = 99;
    -}
    -
    -Now imagine rewriting this as -
    -void fooble ( void )
    -{
    -   int spacer0;
    -   int a[10];
    -   int spacer1;
    -   int b[10];
    -   int spacer2;
    -   VALGRIND_MAKE_NOACCESS(&spacer0, sizeof(int));
    -   VALGRIND_MAKE_NOACCESS(&spacer1, sizeof(int));
    -   VALGRIND_MAKE_NOACCESS(&spacer2, sizeof(int));
    -   a[10] = 99;
    -}
    -
    -Now the invalid write is certain to hit spacer0 or -spacer1, so Valgrind will spot the error. - -

    -There are two complications. - -

    -The first is that we don't want to annotate sources by hand, so the -Right Thing to do is to write a C/C++ parser, annotator, prettyprinter -which does this automatically, and run it on post-CPP'd C/C++ source. -See http://www.cacheprof.org for an example of a system which -transparently inserts another phase into the gcc/g++ compilation -route. The parser/prettyprinter is probably not as hard as it sounds; -I would write it in Haskell, a powerful functional language well -suited to doing symbolic computation, with which I am intimately -familar. There is already a C parser written in Haskell by someone in -the Haskell community, and that would probably be a good starting -point. - -

    -The second complication is how to get rid of these -NOACCESS records inside Valgrind when the instrumented -function exits; after all, these refer to stack addresses and will -make no sense whatever when some other function happens to re-use the -same stack address range, probably shortly afterwards. I think I -would be inclined to define a special stack-specific macro -

    -   VALGRIND_MAKE_NOACCESS_STACK(addr, len)
    -
    -which causes Valgrind to record the client's %ESP at the -time it is executed. Valgrind will then watch for changes in -%ESP and discard such records as soon as the protected -area is uncovered by an increase in %ESP. I hesitate -with this scheme only because it is potentially expensive, if there -are hundreds of such records, and considering that changes in -%ESP already require expensive messing with stack access -permissions. - -

    -This is probably easier and more robust than for the instrumenter -program to try and spot all exit points for the procedure and place -suitable deallocation annotations there. Plus C++ procedures can -bomb out at any point if they get an exception, so spotting return -points at the source level just won't work at all. - -

    -Although some work, it's all eminently doable, and it would make -Valgrind into an even-more-useful tool. - - -

    - - - diff --git a/VEX/head20041019/memcheck/mac_leakcheck.c b/VEX/head20041019/memcheck/mac_leakcheck.c deleted file mode 100644 index 23c9e4515..000000000 --- a/VEX/head20041019/memcheck/mac_leakcheck.c +++ /dev/null @@ -1,555 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- The leak checker, shared between Memcheck and Addrcheck. ---*/ -/*--- mac_leakcheck.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors, and AddrCheck, a lightweight Valgrind tool - for detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mac_shared.h" - -/* Define to debug the memory-leak-detector. */ -/* #define VG_DEBUG_LEAKCHECK */ - -/*------------------------------------------------------------*/ -/*--- Low-level address-space scanning, for the leak ---*/ -/*--- detector. ---*/ -/*------------------------------------------------------------*/ - -static -jmp_buf memscan_jmpbuf; - - -static -void vg_scan_all_valid_memory_sighandler ( Int sigNo ) -{ - __builtin_longjmp(memscan_jmpbuf, 1); -} - - -/* Safely (avoiding SIGSEGV / SIGBUS) scan the entire valid address - space and pass the addresses and values of all addressible, - defined, aligned words to notify_word. This is the basis for the - leak detector. Returns the number of calls made to notify_word. - - Addresses are validated 3 ways. First we enquire whether (addr >> - 16) denotes a 64k chunk in use, by asking is_valid_64k_chunk(). If - so, we decide for ourselves whether each x86-level (4 K) page in - the chunk is safe to inspect. If yes, we enquire with - is_valid_address() whether or not each of the 1024 word-locations - on the page is valid. Only if so are that address and its contents - passed to notify_word. - - This is all to avoid duplication of this machinery between - Memcheck and Addrcheck. -*/ -static -UInt vg_scan_all_valid_memory ( Bool is_valid_64k_chunk ( UInt ), - Bool is_valid_address ( Addr ), - void (*notify_word)( Addr, UInt ) ) -{ - /* All volatile, because some gccs seem paranoid about longjmp(). */ - volatile Bool anyValid; - volatile Addr pageBase, addr; - volatile UInt res, numPages, page, primaryMapNo; - volatile UInt page_first_word, nWordsNotified; - - vki_ksigaction sigbus_saved; - vki_ksigaction sigbus_new; - vki_ksigaction sigsegv_saved; - vki_ksigaction sigsegv_new; - vki_ksigset_t blockmask_saved; - vki_ksigset_t unblockmask_new; - - /* Temporarily install a new sigsegv and sigbus handler, and make - sure SIGBUS, SIGSEGV and SIGTERM are unblocked. (Perhaps the - first two can never be blocked anyway?) */ - - sigbus_new.ksa_handler = vg_scan_all_valid_memory_sighandler; - sigbus_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART; - sigbus_new.ksa_restorer = NULL; - res = VG_(ksigemptyset)( &sigbus_new.ksa_mask ); - sk_assert(res == 0); - - sigsegv_new.ksa_handler = vg_scan_all_valid_memory_sighandler; - sigsegv_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART; - sigsegv_new.ksa_restorer = NULL; - res = VG_(ksigemptyset)( &sigsegv_new.ksa_mask ); - sk_assert(res == 0+0); - - res = VG_(ksigemptyset)( &unblockmask_new ); - res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGBUS ); - res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGSEGV ); - res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGTERM ); - sk_assert(res == 0+0+0); - - res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_new, &sigbus_saved ); - sk_assert(res == 0+0+0+0); - - res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_new, &sigsegv_saved ); - sk_assert(res == 0+0+0+0+0); - - res = VG_(ksigprocmask)( VKI_SIG_UNBLOCK, &unblockmask_new, &blockmask_saved ); - sk_assert(res == 0+0+0+0+0+0); - - /* The signal handlers are installed. Actually do the memory scan. */ - numPages = 1 << (32-VKI_BYTES_PER_PAGE_BITS); - sk_assert(numPages == 1048576); - sk_assert(4096 == (1 << VKI_BYTES_PER_PAGE_BITS)); - - nWordsNotified = 0; - - for (page = 0; page < numPages; page++) { - - /* Base address of this 4k page. */ - pageBase = page << VKI_BYTES_PER_PAGE_BITS; - - /* Skip if this page is in an unused 64k chunk. */ - primaryMapNo = pageBase >> 16; - if (!is_valid_64k_chunk(primaryMapNo)) - continue; - - /* Next, establish whether or not we want to consider any - locations on this page. We need to do so before actually - prodding it, because prodding it when in fact it is not - needed can cause a page fault which under some rare - circumstances can cause the kernel to extend the stack - segment all the way down to here, which is seriously bad. - Hence: */ - anyValid = False; - for (addr = pageBase; addr < pageBase+VKI_BYTES_PER_PAGE; addr += 4) { - if (is_valid_address(addr)) { - anyValid = True; - break; - } - } - - if (!anyValid) - continue; /* nothing interesting here .. move to the next page */ - - /* Ok, we have to prod cautiously at the page and see if it - explodes or not. */ - if (__builtin_setjmp(memscan_jmpbuf) == 0) { - /* try this ... */ - page_first_word = * (volatile UInt*)pageBase; - /* we get here if we didn't get a fault */ - /* Scan the page */ - for (addr = pageBase; addr < pageBase+VKI_BYTES_PER_PAGE; addr += 4) { - if (is_valid_address(addr)) { - nWordsNotified++; - notify_word ( addr, *(UInt*)addr ); - } - } - } else { - /* We get here if reading the first word of the page caused a - fault, which in turn caused the signal handler to longjmp. - Ignore this page. */ - if (0) - VG_(printf)( - "vg_scan_all_valid_memory_sighandler: ignoring page at %p\n", - (void*)pageBase - ); - } - } - - /* Restore signal state to whatever it was before. */ - res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_saved, NULL ); - sk_assert(res == 0 +0); - - res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_saved, NULL ); - sk_assert(res == 0 +0 +0); - - res = VG_(ksigprocmask)( VKI_SIG_SETMASK, &blockmask_saved, NULL ); - sk_assert(res == 0 +0 +0 +0); - - return nWordsNotified; -} - -/*------------------------------------------------------------*/ -/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/ -/*------------------------------------------------------------*/ - -/* A block is either - -- Proper-ly reached; a pointer to its start has been found - -- Interior-ly reached; only an interior pointer to it has been found - -- Unreached; so far, no pointers to any part of it have been found. -*/ -typedef - enum { Unreached, Interior, Proper } - Reachedness; - -/* A block record, used for generating err msgs. */ -typedef - struct _LossRecord { - struct _LossRecord* next; - /* Where these lost blocks were allocated. */ - ExeContext* allocated_at; - /* Their reachability. */ - Reachedness loss_mode; - /* Number of blocks and total # bytes involved. */ - UInt total_bytes; - UInt num_blocks; - } - LossRecord; - - -/* Find the i such that ptr points at or inside the block described by - shadows[i]. Return -1 if none found. This assumes that shadows[] - has been sorted on the ->data field. */ - -#ifdef VG_DEBUG_LEAKCHECK -/* Used to sanity-check the fast binary-search mechanism. */ -static -Int find_shadow_for_OLD ( Addr ptr, - MAC_Chunk** shadows, - Int n_shadows ) - -{ - Int i; - Addr a_lo, a_hi; - PROF_EVENT(70); - for (i = 0; i < n_shadows; i++) { - PROF_EVENT(71); - a_lo = shadows[i]->data; - a_hi = ((Addr)shadows[i]->data) + shadows[i]->size - 1; - if (a_lo <= ptr && ptr <= a_hi) - return i; - } - return -1; -} -#endif - - -static -Int find_shadow_for ( Addr ptr, - MAC_Chunk** shadows, - Int n_shadows ) -{ - Addr a_mid_lo, a_mid_hi; - Int lo, mid, hi, retVal; - /* VG_(printf)("find shadow for %p = ", ptr); */ - retVal = -1; - lo = 0; - hi = n_shadows-1; - while (True) { - /* invariant: current unsearched space is from lo to hi, inclusive. */ - if (lo > hi) break; /* not found */ - - mid = (lo + hi) / 2; - a_mid_lo = shadows[mid]->data; - a_mid_hi = shadows[mid]->data + shadows[mid]->size - 1; - - if (ptr < a_mid_lo) { - hi = mid-1; - continue; - } - if (ptr > a_mid_hi) { - lo = mid+1; - continue; - } - sk_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); - retVal = mid; - break; - } - -# ifdef VG_DEBUG_LEAKCHECK - sk_assert(retVal == find_shadow_for_OLD ( ptr, shadows, n_shadows )); -# endif - /* VG_(printf)("%d\n", retVal); */ - return retVal; -} - -/* Globals, for the following callback used by VG_(detect_memory_leaks). */ -static MAC_Chunk** lc_shadows; -static Int lc_n_shadows; -static Reachedness* lc_reachedness; -static Addr lc_min_mallocd_addr; -static Addr lc_max_mallocd_addr; - -static -void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a ) -{ - Int sh_no; - Addr ptr; - - /* Rule out some known causes of bogus pointers. Mostly these do - not cause much trouble because only a few false pointers can - ever lurk in these places. This mainly stops it reporting that - blocks are still reachable in stupid test programs like this - - int main (void) { char* a = malloc(100); return 0; } - - which people seem inordinately fond of writing, for some reason. - - Note that this is a complete kludge. It would be better to - ignore any addresses corresponding to valgrind.so's .bss and - .data segments, but I cannot think of a reliable way to identify - where the .bss segment has been put. If you can, drop me a - line. - */ - if (!VG_(is_client_addr)(a)) return; - - /* OK, let's get on and do something Useful for a change. */ - - ptr = (Addr)word_at_a; - if (ptr >= lc_min_mallocd_addr && ptr <= lc_max_mallocd_addr) { - /* Might be legitimate; we'll have to investigate further. */ - sh_no = find_shadow_for ( ptr, lc_shadows, lc_n_shadows ); - if (sh_no != -1) { - /* Found a block at/into which ptr points. */ - sk_assert(sh_no >= 0 && sh_no < lc_n_shadows); - sk_assert(ptr < lc_shadows[sh_no]->data + lc_shadows[sh_no]->size); - /* Decide whether Proper-ly or Interior-ly reached. */ - if (ptr == lc_shadows[sh_no]->data) { - if (0) VG_(printf)("pointer at %p to %p\n", a, word_at_a ); - lc_reachedness[sh_no] = Proper; - } else { - if (lc_reachedness[sh_no] == Unreached) - lc_reachedness[sh_no] = Interior; - } - } - } -} - -/* Used for printing leak errors, avoids exposing the LossRecord type (which - comes in as void*, requiring a cast. */ -void MAC_(pp_LeakError)(void* vl, UInt n_this_record, UInt n_total_records) -{ - LossRecord* l = (LossRecord*)vl; - - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, - "%d bytes in %d blocks are %s in loss record %d of %d", - l->total_bytes, l->num_blocks, - l->loss_mode==Unreached ? "definitely lost" - : (l->loss_mode==Interior ? "possibly lost" - : "still reachable"), - n_this_record, n_total_records - ); - VG_(pp_ExeContext)(l->allocated_at); -} - -Int MAC_(bytes_leaked) = 0; -Int MAC_(bytes_dubious) = 0; -Int MAC_(bytes_reachable) = 0; -Int MAC_(bytes_suppressed) = 0; - -static Int lc_compar(void* n1, void* n2) -{ - MAC_Chunk* mc1 = *(MAC_Chunk**)n1; - MAC_Chunk* mc2 = *(MAC_Chunk**)n2; - return (mc1->data < mc2->data ? -1 : 1); -} - -/* Top level entry point to leak detector. Call here, passing in - suitable address-validating functions (see comment at top of - vg_scan_all_valid_memory above). All this is to avoid duplication - of the leak-detection code for Memcheck and Addrcheck. - Also pass in a tool-specific function to extract the .where field - for allocated blocks, an indication of the resolution wanted for - distinguishing different allocation points, and whether or not - reachable blocks should be shown. -*/ -void MAC_(do_detect_memory_leaks) ( - Bool is_valid_64k_chunk ( UInt ), - Bool is_valid_address ( Addr ) -) -{ - Int i; - Int blocks_leaked; - Int blocks_dubious; - Int blocks_reachable; - Int blocks_suppressed; - Int n_lossrecords; - UInt bytes_notified; - Bool is_suppressed; - - LossRecord* errlist; - LossRecord* p; - - /* VG_(HT_to_array) allocates storage for shadows */ - lc_shadows = (MAC_Chunk**)VG_(HT_to_array)( MAC_(malloc_list), - &lc_n_shadows ); - - /* Sort the array. */ - VG_(ssort)((void*)lc_shadows, lc_n_shadows, sizeof(VgHashNode*), lc_compar); - - /* Sanity check; assert that the blocks are now in order */ - for (i = 0; i < lc_n_shadows-1; i++) { - sk_assert( lc_shadows[i]->data <= lc_shadows[i+1]->data); - } - - /* Sanity check -- make sure they don't overlap */ - for (i = 0; i < lc_n_shadows-1; i++) { - sk_assert( lc_shadows[i]->data + lc_shadows[i]->size - < lc_shadows[i+1]->data ); - } - - if (lc_n_shadows == 0) { - sk_assert(lc_shadows == NULL); - if (VG_(clo_verbosity) >= 1) { - VG_(message)(Vg_UserMsg, - "No malloc'd blocks -- no leaks are possible."); - } - return; - } - - if (VG_(clo_verbosity) > 0) - VG_(message)(Vg_UserMsg, - "searching for pointers to %d not-freed blocks.", - lc_n_shadows ); - - lc_min_mallocd_addr = lc_shadows[0]->data; - lc_max_mallocd_addr = lc_shadows[lc_n_shadows-1]->data - + lc_shadows[lc_n_shadows-1]->size - 1; - - lc_reachedness = VG_(malloc)( lc_n_shadows * sizeof(Reachedness) ); - for (i = 0; i < lc_n_shadows; i++) - lc_reachedness[i] = Unreached; - - /* Do the scan of memory. */ - bytes_notified - = VKI_BYTES_PER_WORD - * vg_scan_all_valid_memory ( - is_valid_64k_chunk, - is_valid_address, - &vg_detect_memory_leaks_notify_addr - ); - - if (VG_(clo_verbosity) > 0) - VG_(message)(Vg_UserMsg, "checked %d bytes.", bytes_notified); - - /* Common up the lost blocks so we can print sensible error messages. */ - n_lossrecords = 0; - errlist = NULL; - for (i = 0; i < lc_n_shadows; i++) { - - ExeContext* where = lc_shadows[i]->where; - - for (p = errlist; p != NULL; p = p->next) { - if (p->loss_mode == lc_reachedness[i] - && VG_(eq_ExeContext) ( MAC_(clo_leak_resolution), - p->allocated_at, - where) ) { - break; - } - } - if (p != NULL) { - p->num_blocks ++; - p->total_bytes += lc_shadows[i]->size; - } else { - n_lossrecords ++; - p = VG_(malloc)(sizeof(LossRecord)); - p->loss_mode = lc_reachedness[i]; - p->allocated_at = where; - p->total_bytes = lc_shadows[i]->size; - p->num_blocks = 1; - p->next = errlist; - errlist = p; - } - } - - /* Print out the commoned-up blocks and collect summary stats. */ - blocks_leaked = MAC_(bytes_leaked) = 0; - blocks_dubious = MAC_(bytes_dubious) = 0; - blocks_reachable = MAC_(bytes_reachable) = 0; - blocks_suppressed = MAC_(bytes_suppressed) = 0; - - for (i = 0; i < n_lossrecords; i++) { - Bool print_record; - LossRecord* p_min = NULL; - UInt n_min = 0xFFFFFFFF; - for (p = errlist; p != NULL; p = p->next) { - if (p->num_blocks > 0 && p->total_bytes < n_min) { - n_min = p->total_bytes; - p_min = p; - } - } - sk_assert(p_min != NULL); - - /* Ok to have tst==NULL; it's only used if --gdb-attach=yes, and - we disallow that when --leak-check=yes. - - Prints the error if not suppressed, unless it's reachable (Proper) - and --show-reachable=no */ - - print_record = ( MAC_(clo_show_reachable) || Proper != p_min->loss_mode ); - is_suppressed = - VG_(unique_error) ( VG_(get_current_tid)(), LeakErr, (UInt)i+1, - (Char*)n_lossrecords, (void*) p_min, - p_min->allocated_at, print_record, - /*allow_GDB_attach*/False, /*count_error*/False ); - - if (is_suppressed) { - blocks_suppressed += p_min->num_blocks; - MAC_(bytes_suppressed) += p_min->total_bytes; - - } else if (Unreached == p_min->loss_mode) { - blocks_leaked += p_min->num_blocks; - MAC_(bytes_leaked) += p_min->total_bytes; - - } else if (Interior == p_min->loss_mode) { - blocks_dubious += p_min->num_blocks; - MAC_(bytes_dubious) += p_min->total_bytes; - - } else if (Proper == p_min->loss_mode) { - blocks_reachable += p_min->num_blocks; - MAC_(bytes_reachable) += p_min->total_bytes; - - } else { - VG_(skin_panic)("generic_detect_memory_leaks: unknown loss mode"); - } - p_min->num_blocks = 0; - } - - if (VG_(clo_verbosity) > 0) { - VG_(message)(Vg_UserMsg, ""); - VG_(message)(Vg_UserMsg, "LEAK SUMMARY:"); - VG_(message)(Vg_UserMsg, " definitely lost: %d bytes in %d blocks.", - MAC_(bytes_leaked), blocks_leaked ); - VG_(message)(Vg_UserMsg, " possibly lost: %d bytes in %d blocks.", - MAC_(bytes_dubious), blocks_dubious ); - VG_(message)(Vg_UserMsg, " still reachable: %d bytes in %d blocks.", - MAC_(bytes_reachable), blocks_reachable ); - VG_(message)(Vg_UserMsg, " suppressed: %d bytes in %d blocks.", - MAC_(bytes_suppressed), blocks_suppressed ); - if (!MAC_(clo_show_reachable)) { - VG_(message)(Vg_UserMsg, - "Reachable blocks (those to which a pointer was found) are not shown."); - VG_(message)(Vg_UserMsg, - "To see them, rerun with: --show-reachable=yes"); - } - } - - VG_(free) ( lc_shadows ); - VG_(free) ( lc_reachedness ); -} - -/*--------------------------------------------------------------------*/ -/*--- end mac_leakcheck.c ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/memcheck/mac_malloc_wrappers.c b/VEX/head20041019/memcheck/mac_malloc_wrappers.c deleted file mode 100644 index 8ac92ac9f..000000000 --- a/VEX/head20041019/memcheck/mac_malloc_wrappers.c +++ /dev/null @@ -1,557 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- malloc/free wrappers for detecting errors and updating bits. ---*/ -/*--- mac_malloc_wrappers.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors, and AddrCheck, a lightweight Valgrind tool - for detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mac_shared.h" - -/*------------------------------------------------------------*/ -/*--- Defns ---*/ -/*------------------------------------------------------------*/ - -/* Stats ... */ -static UInt cmalloc_n_mallocs = 0; -static UInt cmalloc_n_frees = 0; -static UInt cmalloc_bs_mallocd = 0; - -/* We want a 16B redzone on heap blocks for Addrcheck and Memcheck */ -UInt VG_(vg_malloc_redzone_szB) = 16; - -/* Function pointers for the two tools to track interesting events. */ -void (*MAC_(new_mem_heap)) ( Addr a, UInt len, Bool is_inited ) = NULL; -void (*MAC_(ban_mem_heap)) ( Addr a, UInt len ) = NULL; -void (*MAC_(die_mem_heap)) ( Addr a, UInt len ) = NULL; -void (*MAC_(copy_mem_heap))( Addr from, Addr to, UInt len ) = NULL; - -/* Function pointers for internal sanity checking. */ -Bool (*MAC_(check_noaccess))( Addr a, UInt len, Addr* bad_addr ) = NULL; - - -/*------------------------------------------------------------*/ -/*--- Tracking malloc'd and free'd blocks ---*/ -/*------------------------------------------------------------*/ - -/* Record malloc'd blocks. Nb: Addrcheck and Memcheck construct this - separately in their respective initialisation functions. */ -VgHashTable MAC_(malloc_list) = NULL; - -/* Memory pools. Nb: Addrcheck and Memcheck construct this separately - in their respective initialisation functions. */ -VgHashTable MAC_(mempool_list) = NULL; - -/* Records blocks after freeing. */ -static MAC_Chunk* freed_list_start = NULL; -static MAC_Chunk* freed_list_end = NULL; -static Int freed_list_volume = 0; - -/* Put a shadow chunk on the freed blocks queue, possibly freeing up - some of the oldest blocks in the queue at the same time. */ -static void add_to_freed_queue ( MAC_Chunk* mc ) -{ - MAC_Chunk* sc1; - - /* Put it at the end of the freed list */ - if (freed_list_end == NULL) { - sk_assert(freed_list_start == NULL); - freed_list_end = freed_list_start = mc; - freed_list_volume = mc->size; - } else { - sk_assert(freed_list_end->next == NULL); - freed_list_end->next = mc; - freed_list_end = mc; - freed_list_volume += mc->size; - } - mc->next = NULL; - - /* Release enough of the oldest blocks to bring the free queue - volume below vg_clo_freelist_vol. */ - - while (freed_list_volume > MAC_(clo_freelist_vol)) { - sk_assert(freed_list_start != NULL); - sk_assert(freed_list_end != NULL); - - sc1 = freed_list_start; - freed_list_volume -= sc1->size; - /* VG_(printf)("volume now %d\n", freed_list_volume); */ - sk_assert(freed_list_volume >= 0); - - if (freed_list_start == freed_list_end) { - freed_list_start = freed_list_end = NULL; - } else { - freed_list_start = sc1->next; - } - sc1->next = NULL; /* just paranoia */ - - /* free MAC_Chunk */ - VG_(cli_free) ( (void*)(sc1->data) ); - VG_(free) ( sc1 ); - } -} - -/* Return the first shadow chunk satisfying the predicate p. */ -MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk) ( Bool (*p)(MAC_Chunk*, void*), - void* d ) -{ - MAC_Chunk* mc; - - /* No point looking through freed blocks if we're not keeping - them around for a while... */ - for (mc = freed_list_start; mc != NULL; mc = mc->next) - if (p(mc, d)) - return mc; - - return NULL; -} - -/* Allocate its shadow chunk, put it on the appropriate list. */ -static -void add_MAC_Chunk ( Addr p, UInt size, MAC_AllocKind kind, VgHashTable table) -{ - MAC_Chunk* mc; - - mc = VG_(malloc)(sizeof(MAC_Chunk)); - mc->data = p; - mc->size = size; - mc->allockind = kind; - mc->where = VG_(get_ExeContext)(VG_(get_current_or_recent_tid)()); - - /* Paranoia ... ensure this area is off-limits to the client, so - the mc->data field isn't visible to the leak checker. If memory - management is working correctly, anything pointer returned by - VG_(malloc) should be noaccess as far as the client is - concerned. */ - if (!MAC_(check_noaccess)( (Addr)mc, sizeof(MAC_Chunk), NULL )) { - VG_(skin_panic)("add_MAC_chunk: shadow area is accessible"); - } - - VG_(HT_add_node)( table, (VgHashNode*)mc ); -} - -/*------------------------------------------------------------*/ -/*--- client_malloc(), etc ---*/ -/*------------------------------------------------------------*/ - -/* Allocate memory and note change in memory available */ -__inline__ -void* MAC_(new_block) ( Addr p, UInt size, UInt align, UInt rzB, - Bool is_zeroed, MAC_AllocKind kind, VgHashTable table) -{ - VGP_PUSHCC(VgpCliMalloc); - cmalloc_n_mallocs ++; - cmalloc_bs_mallocd += size; - - // Allocate and zero if necessary - if (p) { - sk_assert(MAC_AllocCustom == kind); - } else { - sk_assert(MAC_AllocCustom != kind); - p = (Addr)VG_(cli_malloc)( align, size ); - if (!p) { - VGP_POPCC(VgpCliMalloc); - return NULL; - } - if (is_zeroed) VG_(memset)((void*)p, 0, size); - } - - add_MAC_Chunk( p, size, kind, table ); - - MAC_(ban_mem_heap)( p-rzB, rzB ); - MAC_(new_mem_heap)( p, size, is_zeroed ); - MAC_(ban_mem_heap)( p+size, rzB ); - - VGP_POPCC(VgpCliMalloc); - - return (void*)p; -} - -void* SK_(malloc) ( Int n ) -{ - if (n < 0) { - VG_(message)(Vg_UserMsg, "Warning: silly arg (%d) to malloc()", n ); - return NULL; - } else { - return MAC_(new_block) ( 0, n, VG_(clo_alignment), - VG_(vg_malloc_redzone_szB), /*is_zeroed*/False, MAC_AllocMalloc, - MAC_(malloc_list)); - } -} - -void* SK_(__builtin_new) ( Int n ) -{ - if (n < 0) { - VG_(message)(Vg_UserMsg, "Warning: silly arg (%d) to __builtin_new()", n); - return NULL; - } else { - return MAC_(new_block) ( 0, n, VG_(clo_alignment), - VG_(vg_malloc_redzone_szB), /*is_zeroed*/False, MAC_AllocNew, - MAC_(malloc_list)); - } -} - -void* SK_(__builtin_vec_new) ( Int n ) -{ - if (n < 0) { - VG_(message)(Vg_UserMsg, - "Warning: silly arg (%d) to __builtin_vec_new()", n ); - return NULL; - } else { - return MAC_(new_block) ( 0, n, VG_(clo_alignment), - VG_(vg_malloc_redzone_szB), /*is_zeroed*/False, MAC_AllocNewVec, - MAC_(malloc_list)); - } -} - -void* SK_(memalign) ( Int align, Int n ) -{ - if (n < 0) { - VG_(message)(Vg_UserMsg, "Warning: silly arg (%d) to memalign()", n); - return NULL; - } else { - return MAC_(new_block) ( 0, n, align, - VG_(vg_malloc_redzone_szB), /*is_zeroed*/False, MAC_AllocMalloc, - MAC_(malloc_list)); - } -} - -void* SK_(calloc) ( Int nmemb, Int size1 ) -{ - if (nmemb < 0 || size1 < 0) { - VG_(message)(Vg_UserMsg, "Warning: silly args (%d,%d) to calloc()", - nmemb, size1 ); - return NULL; - } else { - return MAC_(new_block) ( 0, nmemb*size1, VG_(clo_alignment), - VG_(vg_malloc_redzone_szB), /*is_zeroed*/True, MAC_AllocMalloc, - MAC_(malloc_list)); - } -} - -static -void die_and_free_mem ( MAC_Chunk* mc, - MAC_Chunk** prev_chunks_next_ptr, UInt rzB ) -{ - /* Note: ban redzones again -- just in case user de-banned them - with a client request... */ - MAC_(ban_mem_heap)( mc->data-rzB, rzB ); - MAC_(die_mem_heap)( mc->data, mc->size ); - MAC_(ban_mem_heap)( mc->data+mc->size, rzB ); - - /* Remove mc from the malloclist using prev_chunks_next_ptr to - avoid repeating the hash table lookup. Can't remove until at least - after free and free_mismatch errors are done because they use - describe_addr() which looks for it in malloclist. */ - *prev_chunks_next_ptr = mc->next; - - /* Put it out of harm's way for a while, if not from a client request */ - if (MAC_AllocCustom != mc->allockind) { - /* Record where freed */ - mc->where = VG_(get_ExeContext) ( VG_(get_current_or_recent_tid)() ); - add_to_freed_queue ( mc ); - } else - VG_(free) ( mc ); -} - -__inline__ -void MAC_(handle_free) ( Addr p, UInt rzB, MAC_AllocKind kind ) -{ - MAC_Chunk* mc; - MAC_Chunk** prev_chunks_next_ptr; - ThreadId tid = VG_(get_current_or_recent_tid)(); - - VGP_PUSHCC(VgpCliMalloc); - - cmalloc_n_frees++; - - mc = (MAC_Chunk*)VG_(HT_get_node) ( MAC_(malloc_list), (UInt)p, - (VgHashNode***)&prev_chunks_next_ptr ); - if (mc == NULL) { - MAC_(record_free_error) ( tid, p ); - VGP_POPCC(VgpCliMalloc); - return; - } - - /* check if its a matching free() / delete / delete [] */ - if (kind != mc->allockind) { - MAC_(record_freemismatch_error) ( tid, p ); - } - - die_and_free_mem ( mc, prev_chunks_next_ptr, rzB ); - VGP_POPCC(VgpCliMalloc); -} - -void SK_(free) ( void* p ) -{ - MAC_(handle_free)((Addr)p, VG_(vg_malloc_redzone_szB), MAC_AllocMalloc); -} - -void SK_(__builtin_delete) ( void* p ) -{ - MAC_(handle_free)((Addr)p, VG_(vg_malloc_redzone_szB), MAC_AllocNew); -} - -void SK_(__builtin_vec_delete) ( void* p ) -{ - MAC_(handle_free)((Addr)p, VG_(vg_malloc_redzone_szB), MAC_AllocNewVec); -} - -void* SK_(realloc) ( void* p, Int new_size ) -{ - MAC_Chunk *mc; - MAC_Chunk **prev_chunks_next_ptr; - UInt i; - ThreadId tid = VG_(get_current_or_recent_tid)(); - - VGP_PUSHCC(VgpCliMalloc); - - cmalloc_n_frees ++; - cmalloc_n_mallocs ++; - cmalloc_bs_mallocd += new_size; - - if (new_size < 0) { - VG_(message)(Vg_UserMsg, - "Warning: silly arg (%d) to realloc()", new_size ); - return NULL; - } - - /* First try and find the block. */ - mc = (MAC_Chunk*)VG_(HT_get_node) ( MAC_(malloc_list), (UInt)p, - (VgHashNode***)&prev_chunks_next_ptr ); - - if (mc == NULL) { - MAC_(record_free_error) ( tid, (Addr)p ); - /* Perhaps we should return to the program regardless. */ - VGP_POPCC(VgpCliMalloc); - return NULL; - } - - /* check if its a matching free() / delete / delete [] */ - if (MAC_AllocMalloc != mc->allockind) { - /* can not realloc a range that was allocated with new or new [] */ - MAC_(record_freemismatch_error) ( tid, (Addr)p ); - /* but keep going anyway */ - } - - if (mc->size == new_size) { - /* size unchanged */ - mc->where = VG_(get_ExeContext)(tid); - VGP_POPCC(VgpCliMalloc); - return p; - - } else if (mc->size > new_size) { - /* new size is smaller */ - MAC_(die_mem_heap)( mc->data+new_size, mc->size-new_size ); - mc->size = new_size; - mc->where = VG_(get_ExeContext)(tid); - VGP_POPCC(VgpCliMalloc); - return p; - - } else { - /* new size is bigger */ - Addr p_new; - - /* Get new memory */ - p_new = (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size); - - /* First half kept and copied, second half new, - red zones as normal */ - MAC_(ban_mem_heap) ( p_new-VG_(vg_malloc_redzone_szB), - VG_(vg_malloc_redzone_szB) ); - MAC_(copy_mem_heap)( (Addr)p, p_new, mc->size ); - MAC_(new_mem_heap) ( p_new+mc->size, new_size-mc->size, /*inited*/False ); - MAC_(ban_mem_heap) ( p_new+new_size, VG_(vg_malloc_redzone_szB) ); - - /* Copy from old to new */ - for (i = 0; i < mc->size; i++) - ((UChar*)p_new)[i] = ((UChar*)p)[i]; - - /* Free old memory */ - die_and_free_mem ( mc, prev_chunks_next_ptr, - VG_(vg_malloc_redzone_szB) ); - - /* this has to be after die_and_free_mem, otherwise the - former succeeds in shorting out the new block, not the - old, in the case when both are on the same list. */ - add_MAC_Chunk ( p_new, new_size, MAC_AllocMalloc, MAC_(malloc_list) ); - - VGP_POPCC(VgpCliMalloc); - return (void*)p_new; - } -} - -/* Memory pool stuff. */ - -void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed) -{ - MAC_Mempool* mp; - - mp = VG_(malloc)(sizeof(MAC_Mempool)); - mp->pool = pool; - mp->rzB = rzB; - mp->is_zeroed = is_zeroed; - mp->chunks = VG_(HT_construct)(); - - /* Paranoia ... ensure this area is off-limits to the client, so - the mp->data field isn't visible to the leak checker. If memory - management is working correctly, anything pointer returned by - VG_(malloc) should be noaccess as far as the client is - concerned. */ - if (!MAC_(check_noaccess)( (Addr)mp, sizeof(MAC_Mempool), NULL )) { - VG_(skin_panic)("MAC_(create_mempool): shadow area is accessible"); - } - - VG_(HT_add_node)( MAC_(mempool_list), (VgHashNode*)mp ); - -} - -static void destroy_mempool_nuke_chunk(VgHashNode *node, void *d) -{ - MAC_Chunk *mc = (MAC_Chunk *)node; - MAC_Mempool *mp = (MAC_Mempool *)d; - - /* Note: ban redzones again -- just in case user de-banned them - with a client request... */ - MAC_(ban_mem_heap)(mc->data-mp->rzB, mp->rzB ); - MAC_(die_mem_heap)(mc->data, mc->size ); - MAC_(ban_mem_heap)(mc->data+mc->size, mp->rzB ); -} - -void MAC_(destroy_mempool)(Addr pool) -{ - MAC_Mempool* mp; - MAC_Mempool** prev_next; - - mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list), - (UInt)pool, - (VgHashNode***)&prev_next ); - - if (mp == NULL) { - ThreadId tid = VG_(get_current_or_recent_tid)(); - - MAC_(record_illegal_mempool_error) ( tid, pool ); - return; - } - - *prev_next = mp->next; - VG_(HT_apply_to_all_nodes)(mp->chunks, destroy_mempool_nuke_chunk, mp); - VG_(HT_destruct)(mp->chunks); - - VG_(free)(mp); -} - -void MAC_(mempool_alloc)(Addr pool, Addr addr, UInt size) -{ - MAC_Mempool* mp; - MAC_Mempool** prev_next; - - mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list), (UInt)pool, - (VgHashNode***)&prev_next ); - - if (mp == NULL) { - ThreadId tid = VG_(get_current_or_recent_tid)(); - - MAC_(record_illegal_mempool_error) ( tid, pool ); - return; - } - - MAC_(new_block)(addr, size, /*ignored*/0, mp->rzB, mp->is_zeroed, - MAC_AllocCustom, mp->chunks); -} - -void MAC_(mempool_free)(Addr pool, Addr addr) -{ - MAC_Mempool* mp; - MAC_Mempool** prev_pool; - MAC_Chunk* mc; - MAC_Chunk** prev_chunk; - ThreadId tid = VG_(get_current_or_recent_tid)(); - - - mp = (MAC_Mempool*)VG_(HT_get_node)(MAC_(mempool_list), (UInt)pool, - (VgHashNode***)&prev_pool); - - if (mp == NULL) { - MAC_(record_illegal_mempool_error)(tid, pool); - return; - } - - mc = (MAC_Chunk*)VG_(HT_get_node)(mp->chunks, (UInt)addr, - (VgHashNode***)&prev_chunk); - - if (mc == NULL) { - MAC_(record_free_error)(tid, (Addr)addr); - return; - } - - die_and_free_mem(mc, prev_chunk, mp->rzB); -} - -typedef - struct { - UInt nblocks; - UInt nbytes; - } - MallocStats; - -static void malloc_stats_count_chunk(VgHashNode* node, void* d) { - MAC_Chunk* mc = (MAC_Chunk*)node; - MallocStats *ms = (MallocStats *)d; - - ms->nblocks ++; - ms->nbytes += mc->size; -} - -void MAC_(print_malloc_stats) ( void ) -{ - MallocStats ms; - - ms.nblocks = 0; - ms.nbytes = 0; - - /* Mmm... more lexical scoping */ - if (VG_(clo_verbosity) == 0) - return; - - /* Count memory still in use. */ - VG_(HT_apply_to_all_nodes)(MAC_(malloc_list), malloc_stats_count_chunk, &ms); - - VG_(message)(Vg_UserMsg, - "malloc/free: in use at exit: %d bytes in %d blocks.", - ms.nbytes, ms.nblocks); - VG_(message)(Vg_UserMsg, - "malloc/free: %d allocs, %d frees, %u bytes allocated.", - cmalloc_n_mallocs, - cmalloc_n_frees, cmalloc_bs_mallocd); - if (VG_(clo_verbosity) > 1) - VG_(message)(Vg_UserMsg, ""); -} - -/*--------------------------------------------------------------------*/ -/*--- end mac_malloc_wrappers.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mac_needs.c b/VEX/head20041019/memcheck/mac_needs.c deleted file mode 100644 index ce09679bb..000000000 --- a/VEX/head20041019/memcheck/mac_needs.c +++ /dev/null @@ -1,964 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Code that is shared between MemCheck and AddrCheck. ---*/ -/*--- mac_needs.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors, and AddrCheck, a lightweight Valgrind tool - for detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - - -#include "mac_shared.h" - -#include "memcheck.h" /* for VG_USERREQ__* */ - -/*------------------------------------------------------------*/ -/*--- Defns ---*/ -/*------------------------------------------------------------*/ - -/* These many bytes below %ESP are considered addressible if we're - doing the --workaround-gcc296-bugs hack. */ -#define VG_GCC296_BUG_STACK_SLOP 1024 - -/*------------------------------------------------------------*/ -/*--- Command line options ---*/ -/*------------------------------------------------------------*/ - -Bool MAC_(clo_partial_loads_ok) = True; -Int MAC_(clo_freelist_vol) = 1000000; -Bool MAC_(clo_leak_check) = False; -VgRes MAC_(clo_leak_resolution) = Vg_LowRes; -Bool MAC_(clo_show_reachable) = False; -Bool MAC_(clo_workaround_gcc296_bugs) = False; - -Bool MAC_(process_common_cmd_line_option)(Char* arg) -{ - VG_BOOL_CLO("--leak-check", MAC_(clo_leak_check)) - else VG_BOOL_CLO("--partial-loads-ok", MAC_(clo_partial_loads_ok)) - else VG_BOOL_CLO("--show-reachable", MAC_(clo_show_reachable)) - else VG_BOOL_CLO("--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs)) - - else VG_BNUM_CLO("--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000) - - else if (VG_CLO_STREQ(arg, "--leak-resolution=low")) - MAC_(clo_leak_resolution) = Vg_LowRes; - else if (VG_CLO_STREQ(arg, "--leak-resolution=med")) - MAC_(clo_leak_resolution) = Vg_MedRes; - else if (VG_CLO_STREQ(arg, "--leak-resolution=high")) - MAC_(clo_leak_resolution) = Vg_HighRes; - - else - return VG_(replacement_malloc_process_cmd_line_option)(arg); - - return True; -} - -void MAC_(print_common_usage)(void) -{ - VG_(printf)( -" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n" -" --freelist-vol= volume of freed blocks queue [1000000]\n" -" --leak-check=no|yes search for memory leaks at exit? [no]\n" -" --leak-resolution=low|med|high how much bt merging in leak check [low]\n" -" --show-reachable=no|yes show reachable blocks in leak check? [no]\n" -" --workaround-gcc296-bugs=no|yes self explanatory [no]\n" - ); - VG_(replacement_malloc_print_usage)(); -} - -void MAC_(print_common_debug_usage)(void) -{ - VG_(replacement_malloc_print_debug_usage)(); -} - -/*------------------------------------------------------------*/ -/*--- Comparing and printing errors ---*/ -/*------------------------------------------------------------*/ - -static __inline__ -void clear_AddrInfo ( AddrInfo* ai ) -{ - ai->akind = Unknown; - ai->blksize = 0; - ai->rwoffset = 0; - ai->lastchange = NULL; - ai->stack_tid = VG_INVALID_THREADID; - ai->maybe_gcc = False; -} - -void MAC_(clear_MAC_Error) ( MAC_Error* err_extra ) -{ - err_extra->axskind = ReadAxs; - err_extra->size = 0; - clear_AddrInfo ( &err_extra->addrinfo ); - err_extra->isWrite = False; -} - -__attribute__ ((unused)) -static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 ) -{ - if (ai1->akind != Undescribed - && ai2->akind != Undescribed - && ai1->akind != ai2->akind) - return False; - if (ai1->akind == Freed || ai1->akind == Mallocd) { - if (ai1->blksize != ai2->blksize) - return False; - if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange)) - return False; - } - return True; -} - -/* Compare error contexts, to detect duplicates. Note that if they - are otherwise the same, the faulting addrs and associated rwoffsets - are allowed to be different. */ - -Bool SK_(eq_SkinError) ( VgRes res, Error* e1, Error* e2 ) -{ - MAC_Error* e1_extra = VG_(get_error_extra)(e1); - MAC_Error* e2_extra = VG_(get_error_extra)(e2); - - /* Guaranteed by calling function */ - sk_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); - - switch (VG_(get_error_kind)(e1)) { - case CoreMemErr: { - Char *e1s, *e2s; - if (e1_extra->isWrite != e2_extra->isWrite) return False; - e1s = VG_(get_error_string)(e1); - e2s = VG_(get_error_string)(e2); - if (e1s == e2s) return True; - if (0 == VG_(strcmp)(e1s, e2s)) return True; - return False; - } - - case UserErr: - case ParamErr: - if (e1_extra->isWrite != e2_extra->isWrite) return False; - if (VG_(get_error_kind)(e1) == ParamErr - && 0 != VG_(strcmp)(VG_(get_error_string)(e1), - VG_(get_error_string)(e2))) return False; - return True; - - case FreeErr: - case FreeMismatchErr: - /* JRS 2002-Aug-26: comparing addrs seems overkill and can - cause excessive duplication of errors. Not even AddrErr - below does that. So don't compare either the .addr field - or the .addrinfo fields. */ - /* if (e1->addr != e2->addr) return False; */ - /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo)) - return False; - */ - return True; - - case AddrErr: - /* if (e1_extra->axskind != e2_extra->axskind) return False; */ - if (e1_extra->size != e2_extra->size) return False; - /* - if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo)) - return False; - */ - return True; - - case ValueErr: - if (e1_extra->size != e2_extra->size) return False; - return True; - - case OverlapErr: - return True; - - case LeakErr: - VG_(skin_panic)("Shouldn't get LeakErr in SK_(eq_SkinError),\n" - "since it's handled with VG_(unique_error)()!"); - - case IllegalMempoolErr: - return True; - - default: - VG_(printf)("Error:\n unknown error code %d\n", - VG_(get_error_kind)(e1)); - VG_(skin_panic)("unknown error code in SK_(eq_SkinError)"); - } -} - -void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai ) -{ - switch (ai->akind) { - case Stack: - VG_(message)(Vg_UserMsg, - " Address 0x%x is on thread %d's stack", - a, ai->stack_tid); - break; - case Unknown: - if (ai->maybe_gcc) { - VG_(message)(Vg_UserMsg, - " Address 0x%x is just below %%esp. Possibly a bug in GCC/G++", - a); - VG_(message)(Vg_UserMsg, - " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes"); - } else { - VG_(message)(Vg_UserMsg, - " Address 0x%x is not stack'd, malloc'd or (recently) free'd",a); - } - break; - case Freed: case Mallocd: case UserG: case Mempool: { - UInt delta; - UChar* relative; - UChar* kind; - if (ai->akind == Mempool) { - kind = "mempool"; - } else { - kind = "block"; - } - if (ai->rwoffset < 0) { - delta = (UInt)(- ai->rwoffset); - relative = "before"; - } else if (ai->rwoffset >= ai->blksize) { - delta = ai->rwoffset - ai->blksize; - relative = "after"; - } else { - delta = ai->rwoffset; - relative = "inside"; - } - VG_(message)(Vg_UserMsg, - " Address 0x%x is %d bytes %s a %s of size %d %s", - a, delta, relative, kind, - ai->blksize, - ai->akind==Mallocd ? "alloc'd" - : ai->akind==Freed ? "free'd" - : "client-defined"); - VG_(pp_ExeContext)(ai->lastchange); - break; - } - default: - VG_(skin_panic)("MAC_(pp_AddrInfo)"); - } -} - -/* This prints out the message for the error types where Memcheck and - Addrcheck have identical messages */ -void MAC_(pp_shared_SkinError) ( Error* err ) -{ - MAC_Error* err_extra = VG_(get_error_extra)(err); - - switch (VG_(get_error_kind)(err)) { - case FreeErr: - VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]"); - /* fall through */ - case FreeMismatchErr: - if (VG_(get_error_kind)(err) == FreeMismatchErr) - VG_(message)(Vg_UserMsg, - "Mismatched free() / delete / delete []"); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - case AddrErr: - switch (err_extra->axskind) { - case ReadAxs: - VG_(message)(Vg_UserMsg, "Invalid read of size %d", - err_extra->size ); - break; - case WriteAxs: - VG_(message)(Vg_UserMsg, "Invalid write of size %d", - err_extra->size ); - break; - case ExecAxs: - VG_(message)(Vg_UserMsg, "Jump to the invalid address " - "stated on the next line"); - break; - default: - VG_(skin_panic)("SK_(pp_SkinError)(axskind)"); - } - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - case OverlapErr: { - OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err); - if (ov_extra->len == -1) - VG_(message)(Vg_UserMsg, - "Source and destination overlap in %s(%p, %p)", - VG_(get_error_string)(err), - ov_extra->dst, ov_extra->src); - else - VG_(message)(Vg_UserMsg, - "Source and destination overlap in %s(%p, %p, %d)", - VG_(get_error_string)(err), - ov_extra->dst, ov_extra->src, ov_extra->len); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - break; - } - case LeakErr: { - /* Totally abusing the types of these spare fields... oh well. */ - UInt n_this_record = (UInt)VG_(get_error_address)(err); - UInt n_total_records = (UInt)VG_(get_error_string) (err); - - MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records); - break; - } - - case IllegalMempoolErr: - VG_(message)(Vg_UserMsg, "Illegal memory pool address"); - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - default: - VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n", - VG_(get_error_kind)(err)); - VG_(skin_panic)("unknown error code in MAC_(pp_shared_SkinError)"); - } -} - -/*------------------------------------------------------------*/ -/*--- Recording errors ---*/ -/*------------------------------------------------------------*/ - -/* Additional description function for describe_addr(); used by - MemCheck for user blocks, which Addrcheck doesn't support. */ -Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL; - -/* Callback for searching thread stacks */ -static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap) -{ - Addr a = *(Addr *)ap; - - return (stack_min <= a && a <= stack_max); -} - -/* Callback for searching free'd list */ -static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap) -{ - Addr a = *(Addr *)ap; - - return VG_(addr_is_in_block)( a, mc->data, mc->size ); -} - -/* Callback for searching malloc'd lists */ -static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap) -{ - return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap ); -} - -/* Describe an address as best you can, for error messages, - putting the result in ai. */ -static void describe_addr ( Addr a, AddrInfo* ai ) -{ - MAC_Chunk* sc; - ThreadId tid; - - /* Perhaps it's a user-def'd block ? (only check if requested, though) */ - if (NULL != MAC_(describe_addr_supp)) { - if (MAC_(describe_addr_supp)( a, ai )) - return; - } - /* Perhaps it's on a thread's stack? */ - tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a); - if (tid != VG_INVALID_THREADID) { - ai->akind = Stack; - ai->stack_tid = tid; - return; - } - /* Search for a recently freed block which might bracket it. */ - sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a); - if (NULL != sc) { - ai->akind = Freed; - ai->blksize = sc->size; - ai->rwoffset = (Int)a - (Int)sc->data; - ai->lastchange = sc->where; - return; - } - /* Search for a currently malloc'd block which might bracket it. */ - sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a); - if (NULL != sc) { - ai->akind = Mallocd; - ai->blksize = sc->size; - ai->rwoffset = (Int)(a) - (Int)sc->data; - ai->lastchange = sc->where; - return; - } - /* Clueless ... */ - ai->akind = Unknown; - return; -} - -/* Is this address within some small distance below %ESP? Used only - for the --workaround-gcc296-bugs kludge. */ -static Bool is_just_below_ESP( Addr esp, Addr aa ) -{ - if ((UInt)esp > (UInt)aa - && ((UInt)esp - (UInt)aa) <= VG_GCC296_BUG_STACK_SLOP) - return True; - else - return False; -} - -/* This one called from generated code and non-generated code. */ - -void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size, - Bool isWrite ) -{ - MAC_Error err_extra; - Bool just_below_esp; - - just_below_esp = is_just_below_ESP( VG_(get_stack_pointer)(), a ); - - /* If this is caused by an access immediately below %ESP, and the - user asks nicely, we just ignore it. */ - if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp) - return; - - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.axskind = isWrite ? WriteAxs : ReadAxs; - err_extra.size = size; - err_extra.addrinfo.akind = Undescribed; - err_extra.addrinfo.maybe_gcc = just_below_esp; - VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra ); -} - -/* These ones are called from non-generated code */ - -/* This is for memory errors in pthread functions, as opposed to pthread API - errors which are found by the core. */ -void MAC_(record_core_mem_error) ( ThreadId tid, Bool isWrite, Char* msg ) -{ - MAC_Error err_extra; - - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.isWrite = isWrite; - VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra ); -} - -void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isWrite, - Char* msg ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.addrinfo.akind = Undescribed; - err_extra.isWrite = isWrite; - VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra ); -} - -void MAC_(record_jump_error) ( ThreadId tid, Addr a ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.axskind = ExecAxs; - err_extra.size = 1; // size only used for suppressions - err_extra.addrinfo.akind = Undescribed; - VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra ); -} - -void MAC_(record_free_error) ( ThreadId tid, Addr a ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.addrinfo.akind = Undescribed; - VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra ); -} - -void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.addrinfo.akind = Undescribed; - VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra ); -} - -void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.addrinfo.akind = Undescribed; - VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra ); -} - - -// This one not passed a ThreadId, so it grabs it itself. -void MAC_(record_overlap_error) ( Char* function, OverlapExtra* ov_extra ) -{ - VG_(maybe_record_error)( VG_(get_current_or_recent_tid)(), - OverlapErr, /*addr*/0, /*s*/function, ov_extra ); -} - - -/* Updates the copy with address info if necessary (but not for all errors). */ -UInt SK_(update_extra)( Error* err ) -{ - switch (VG_(get_error_kind)(err)) { - case ValueErr: - case CoreMemErr: - case AddrErr: - case ParamErr: - case UserErr: - case FreeErr: - case IllegalMempoolErr: - case FreeMismatchErr: { - MAC_Error* extra = (MAC_Error*)VG_(get_error_extra)(err); - if (extra != NULL && Undescribed == extra->addrinfo.akind) { - describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) ); - } - return sizeof(MAC_Error); - } - /* Don't need to return the correct size -- LeakErrs are always shown with - VG_(unique_error)() so they're not copied anyway. */ - case LeakErr: return 0; - case OverlapErr: return sizeof(OverlapExtra); - default: VG_(skin_panic)("update_extra: bad errkind"); - } -} - - -/*------------------------------------------------------------*/ -/*--- Suppressions ---*/ -/*------------------------------------------------------------*/ - -Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su ) -{ - SuppKind skind; - - if (VG_STREQ(name, "Param")) skind = ParamSupp; - else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp; - else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp; - else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp; - else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp; - else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp; - else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp; - else if (VG_STREQ(name, "Free")) skind = FreeSupp; - else if (VG_STREQ(name, "Leak")) skind = LeakSupp; - else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp; - else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp; - else - return False; - - VG_(set_supp_kind)(su, skind); - return True; -} - -Bool SK_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su ) -{ - Bool eof; - - if (VG_(get_supp_kind)(su) == ParamSupp) { - eof = VG_(get_line) ( fd, buf, nBuf ); - if (eof) return False; - VG_(set_supp_string)(su, VG_(strdup)(buf)); - } - return True; -} - -Bool SK_(error_matches_suppression)(Error* err, Supp* su) -{ - Int su_size; - MAC_Error* err_extra = VG_(get_error_extra)(err); - ErrorKind ekind = VG_(get_error_kind )(err); - - switch (VG_(get_supp_kind)(su)) { - case ParamSupp: - return (ekind == ParamErr - && VG_STREQ(VG_(get_error_string)(err), - VG_(get_supp_string)(su))); - - case CoreMemSupp: - return (ekind == CoreMemErr - && VG_STREQ(VG_(get_error_string)(err), - VG_(get_supp_string)(su))); - - case Value0Supp: su_size = 0; goto value_case; - case Value1Supp: su_size = 1; goto value_case; - case Value2Supp: su_size = 2; goto value_case; - case Value4Supp: su_size = 4; goto value_case; - case Value8Supp: su_size = 8; goto value_case; - case Value16Supp:su_size =16; goto value_case; - value_case: - return (ekind == ValueErr && err_extra->size == su_size); - - case Addr1Supp: su_size = 1; goto addr_case; - case Addr2Supp: su_size = 2; goto addr_case; - case Addr4Supp: su_size = 4; goto addr_case; - case Addr8Supp: su_size = 8; goto addr_case; - case Addr16Supp:su_size =16; goto addr_case; - addr_case: - return (ekind == AddrErr && err_extra->size == su_size); - - case FreeSupp: - return (ekind == FreeErr || ekind == FreeMismatchErr); - - case OverlapSupp: - return (ekind = OverlapErr); - - case LeakSupp: - return (ekind == LeakErr); - - case MempoolSupp: - return (ekind == IllegalMempoolErr); - - default: - VG_(printf)("Error:\n" - " unknown suppression type %d\n", - VG_(get_supp_kind)(su)); - VG_(skin_panic)("unknown suppression type in " - "SK_(error_matches_suppression)"); - } -} - -Char* SK_(get_error_name) ( Error* err ) -{ - Char* s; - switch (VG_(get_error_kind)(err)) { - case ParamErr: return "Param"; - case UserErr: return NULL; /* Can't suppress User errors */ - case FreeMismatchErr: return "Free"; - case IllegalMempoolErr: return "Mempool"; - case FreeErr: return "Free"; - case AddrErr: - switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) { - case 1: return "Addr1"; - case 2: return "Addr2"; - case 4: return "Addr4"; - case 8: return "Addr8"; - case 16: return "Addr16"; - default: VG_(skin_panic)("unexpected size for Addr"); - } - - case ValueErr: - switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) { - case 0: return "Cond"; - case 1: return "Value1"; - case 2: return "Value2"; - case 4: return "Value4"; - case 8: return "Value8"; - case 16: return "Value16"; - default: VG_(skin_panic)("unexpected size for Value"); - } - case CoreMemErr: return "CoreMem"; - case OverlapErr: return "Overlap"; - case LeakErr: return "Leak"; - default: VG_(skin_panic)("get_error_name: unexpected type"); - } - VG_(printf)(s); -} - -void SK_(print_extra_suppression_info) ( Error* err ) -{ - if (ParamErr == VG_(get_error_kind)(err)) { - VG_(printf)(" %s\n", VG_(get_error_string)(err)); - } -} - -/*------------------------------------------------------------*/ -/*--- Crude profiling machinery. ---*/ -/*------------------------------------------------------------*/ - -/* Event index. If just the name of the fn is given, this means the - number of calls to the fn. Otherwise it is the specified event. - Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only. - The rest are shared. - - 10 alloc_secondary_map - - 20 get_abit -M 21 get_vbyte - 22 set_abit -M 23 set_vbyte - 24 get_abits4_ALIGNED -M 25 get_vbytes4_ALIGNED - - 30 set_address_range_perms - 31 set_address_range_perms(lower byte loop) - 32 set_address_range_perms(quadword loop) - 33 set_address_range_perms(upper byte loop) - - 35 make_noaccess - 36 make_writable - 37 make_readable -A 38 make_accessible - - 40 copy_address_range_state - 41 copy_address_range_state(byte loop) - 42 check_writable - 43 check_writable(byte loop) - 44 check_readable - 45 check_readable(byte loop) - 46 check_readable_asciiz - 47 check_readable_asciiz(byte loop) -A 48 check_accessible -A 49 check_accessible(byte loop) - - 50 make_noaccess_aligned - 51 make_writable_aligned - -M 60 helperc_LOADV4 -M 61 helperc_STOREV4 -M 62 helperc_LOADV2 -M 63 helperc_STOREV2 -M 64 helperc_LOADV1 -M 65 helperc_STOREV1 - -A 66 helperc_ACCESS4 -A 67 helperc_ACCESS2 -A 68 helperc_ACCESS1 - -M 70 rim_rd_V4_SLOWLY -M 71 rim_wr_V4_SLOWLY -M 72 rim_rd_V2_SLOWLY -M 73 rim_wr_V2_SLOWLY -M 74 rim_rd_V1_SLOWLY -M 75 rim_wr_V1_SLOWLY - -A 76 ACCESS4_SLOWLY -A 77 ACCESS2_SLOWLY -A 78 ACCESS1_SLOWLY - - 80 fpu_read - 81 fpu_read aligned 4 - 82 fpu_read aligned 8 - 83 fpu_read 2 - 84 fpu_read 10/28/108/512 - -M 85 fpu_write -M 86 fpu_write aligned 4 -M 87 fpu_write aligned 8 -M 88 fpu_write 2 -M 89 fpu_write 10/28/108/512 - - 90 fpu_access - 91 fpu_access aligned 4 - 92 fpu_access aligned 8 - 93 fpu_access 2 - 94 fpu_access 10/28/108/512 - - 100 fpu_access_check_SLOWLY - 101 fpu_access_check_SLOWLY(byte loop) - - 110 new_mem_stack_4 - 111 new_mem_stack_8 - 112 new_mem_stack_12 - 113 new_mem_stack_16 - 114 new_mem_stack_32 - 115 new_mem_stack - - 120 die_mem_stack_4 - 121 die_mem_stack_8 - 122 die_mem_stack_12 - 123 die_mem_stack_16 - 124 die_mem_stack_32 - 125 die_mem_stack -*/ - -#ifdef MAC_PROFILE_MEMORY - -UInt MAC_(event_ctr)[N_PROF_EVENTS]; - -static void init_prof_mem ( void ) -{ - Int i; - for (i = 0; i < N_PROF_EVENTS; i++) - MAC_(event_ctr)[i] = 0; -} - -static void done_prof_mem ( void ) -{ - Int i; - for (i = 0; i < N_PROF_EVENTS; i++) { - if ((i % 10) == 0) - VG_(printf)("\n"); - if (MAC_(event_ctr)[i] > 0) - VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] ); - } - VG_(printf)("\n"); -} - -#else - -static void init_prof_mem ( void ) { } -static void done_prof_mem ( void ) { } - -#endif - -/*------------------------------------------------------------*/ -/*--- Common initialisation + finalisation ---*/ -/*------------------------------------------------------------*/ - -void MAC_(common_pre_clo_init)(void) -{ - MAC_(malloc_list) = VG_(HT_construct)(); - MAC_(mempool_list) = VG_(HT_construct)(); - init_prof_mem(); -} - -void MAC_(common_fini)(void (*leak_check)(void)) -{ - MAC_(print_malloc_stats)(); - - if (VG_(clo_verbosity) == 1) { - if (!MAC_(clo_leak_check)) - VG_(message)(Vg_UserMsg, - "For a detailed leak analysis, rerun with: --leak-check=yes"); - - VG_(message)(Vg_UserMsg, - "For counts of detected errors, rerun with: -v"); - } - if (MAC_(clo_leak_check)) leak_check(); - - done_prof_mem(); -} - -/*------------------------------------------------------------*/ -/*--- Common client request handling ---*/ -/*------------------------------------------------------------*/ - -Bool MAC_(handle_common_client_requests)(ThreadId tid, UInt* arg, UInt* ret ) -{ - Char* err = - "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n" - " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n" - " program to incorporate the updates in the Valgrind header files.\n" - " You shouldn't need to change the text of your program at all.\n" - " Everything should then work as before. Sorry for the bother.\n"; - - // Not using 'tid' here because MAC_(new_block)() and MAC_(handle_free)() - // grab it themselves. But what they grab should match 'tid', check - // this. - sk_assert(tid == VG_(get_current_or_recent_tid)()); - - switch (arg[0]) { - case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */ - UInt** argp = (UInt**)arg; - // MAC_(bytes_leaked) et al were set by the last leak check (or zero - // if no prior leak checks performed). - *argp[1] = MAC_(bytes_leaked); - *argp[2] = MAC_(bytes_dubious); - *argp[3] = MAC_(bytes_reachable); - *argp[4] = MAC_(bytes_suppressed); - *ret = 0; - return True; - } - case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE: - case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE: - VG_(skin_panic)(err); - - case VG_USERREQ__MALLOCLIKE_BLOCK: { - Addr p = (Addr)arg[1]; - UInt sizeB = arg[2]; - UInt rzB = arg[3]; - Bool is_zeroed = (Bool)arg[4]; - - MAC_(new_block) ( p, sizeB, /*ignored*/0, rzB, is_zeroed, - MAC_AllocCustom, MAC_(malloc_list) ); - return True; - } - case VG_USERREQ__FREELIKE_BLOCK: { - Addr p = (Addr)arg[1]; - UInt rzB = arg[2]; - - MAC_(handle_free) ( p, rzB, MAC_AllocCustom ); - return True; - } - - case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP: - *ret = (Addr)MAC_(record_overlap_error); - return True; - - case VG_USERREQ__CREATE_MEMPOOL: { - Addr pool = (Addr)arg[1]; - UInt rzB = arg[2]; - Bool is_zeroed = (Bool)arg[3]; - - MAC_(create_mempool) ( pool, rzB, is_zeroed ); - return True; - } - - case VG_USERREQ__DESTROY_MEMPOOL: { - Addr pool = (Addr)arg[1]; - - MAC_(destroy_mempool) ( pool ); - return True; - } - - case VG_USERREQ__MEMPOOL_ALLOC: { - Addr pool = (Addr)arg[1]; - Addr addr = (Addr)arg[2]; - UInt size = arg[3]; - - MAC_(mempool_alloc) ( pool, addr, size ); - return True; - } - - case VG_USERREQ__MEMPOOL_FREE: { - Addr pool = (Addr)arg[1]; - Addr addr = (Addr)arg[2]; - - MAC_(mempool_free) ( pool, addr ); - return True; - } - - default: - return False; - } -} - -/*------------------------------------------------------------*/ -/*--- Syscall wrappers ---*/ -/*------------------------------------------------------------*/ - -void* SK_(pre_syscall) ( ThreadId tid, UInt syscallno, Bool isBlocking ) -{ - Int sane = SK_(cheap_sanity_check)(); - return (void*)sane; -} - -void SK_(post_syscall) ( ThreadId tid, UInt syscallno, - void* pre_result, Int res, Bool isBlocking ) -{ - Int sane_before_call = (Int)pre_result; - Bool sane_after_call = SK_(cheap_sanity_check)(); - - if ((Int)sane_before_call && (!sane_after_call)) { - VG_(message)(Vg_DebugMsg, "post-syscall: "); - VG_(message)(Vg_DebugMsg, - "probable sanity check failure for syscall number %d\n", - syscallno ); - VG_(skin_panic)("aborting due to the above ... bye!"); - } -} - -/*--------------------------------------------------------------------*/ -/*--- end mac_needs.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mac_replace_strmem.c b/VEX/head20041019/memcheck/mac_replace_strmem.c deleted file mode 100644 index 2552d0711..000000000 --- a/VEX/head20041019/memcheck/mac_replace_strmem.c +++ /dev/null @@ -1,387 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/ -/*--- simulated CPU. ---*/ -/*--- mac_replace_strmem.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" -#include "memcheck.h" -#include "valgrind.h" - -static Addr record_overlap_error; - -static int init_done; - -/* Startup hook - called as init section */ -static void init(void) __attribute__((constructor)); -static void init(void) -{ - if (init_done) - return; - - VALGRIND_MAGIC_SEQUENCE(record_overlap_error, 0, - _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP, - 0, 0, 0, 0); - init_done = 1; -} - -/* --------------------------------------------------------------------- - The normal versions of these functions are hyper-optimised, which fools - Memcheck and cause spurious value warnings. So we replace them with - simpler versions. THEY RUN ON SIMD CPU! - ------------------------------------------------------------------ */ - -/* Figure out if [dst .. dst+dstlen-1] overlaps with - [src .. src+srclen-1]. - We assume that the address ranges do not wrap around - (which is safe since on Linux addresses >= 0xC0000000 - are not accessible and the program will segfault in this - circumstance, presumably). -*/ -static __inline__ -Bool is_overlap ( void* dst, const void* src, UInt dstlen, UInt srclen ) -{ - Addr loS, hiS, loD, hiD; - - if (dstlen == 0 || srclen == 0) - return False; - - loS = (Addr)src; - loD = (Addr)dst; - hiS = loS + srclen - 1; - hiD = loD + dstlen - 1; - - /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */ - if (loS < loD) { - return !(hiS < loD); - } - else if (loD < loS) { - return !(hiD < loS); - } - else { - /* They start at same place. Since we know neither of them has - zero length, they must overlap. */ - return True; - } -} - - -static __inline__ -void complain2 ( Char* s, char* dst, const char* src ) -{ - OverlapExtra extra = { - .src = (Addr)src, .dst = (Addr)dst, .len = -1, - }; - init(); - VALGRIND_NON_SIMD_CALL2( record_overlap_error, s, &extra ); -} - -static __inline__ -void complain3 ( Char* s, void* dst, const void* src, int n ) -{ - /* Must wrap it up here, because we cannot pass 4 args to core */ - OverlapExtra extra = { - .src = (Addr)src, .dst = (Addr)dst, .len = n, - }; - init(); - VALGRIND_NON_SIMD_CALL2( record_overlap_error, s, &extra ); -} - -char* strrchr ( const char* s, int c ) -{ - UChar ch = (UChar)((UInt)c); - UChar* p = (UChar*)s; - UChar* last = NULL; - while (True) { - if (*p == ch) last = p; - if (*p == 0) return last; - p++; - } -} - -char* strchr ( const char* s, int c ) -{ - UChar ch = (UChar)((UInt)c); - UChar* p = (UChar*)s; - while (True) { - if (*p == ch) return p; - if (*p == 0) return NULL; - p++; - } -} - -char* strcat ( char* dst, const char* src ) -{ - const Char* src_orig = src; - Char* dst_orig = dst; - while (*dst) dst++; - while (*src) *dst++ = *src++; - *dst = 0; - - /* This is a bit redundant, I think; any overlap and the strcat will - go forever... or until a seg fault occurs. */ - if (is_overlap(dst_orig, - src_orig, - (Addr)dst-(Addr)dst_orig+1, - (Addr)src-(Addr)src_orig+1)) - complain2("strcat", dst_orig, src_orig); - - return dst_orig; -} - -char* strncat ( char* dst, const char* src, unsigned int n ) -{ - const Char* src_orig = src; - Char* dst_orig = dst; - UInt m = 0; - - while (*dst) dst++; - while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ - *dst = 0; /* always add null */ - - /* This checks for overlap after copying, unavoidable without - pre-counting lengths... should be ok */ - if (is_overlap(dst_orig, - src_orig, - (Addr)dst-(Addr)dst_orig+1, - (Addr)src-(Addr)src_orig+1)) - complain3("strncat", dst_orig, src_orig, n); - - return dst_orig; -} - -unsigned int strnlen ( const char* str, unsigned int n ) -{ - UInt i = 0; - while (i < n && str[i] != 0) i++; - return i; -} - -unsigned int strlen ( const char* str ) -{ - UInt i = 0; - while (str[i] != 0) i++; - return i; -} - -char* strcpy ( char* dst, const char* src ) -{ - const Char* src_orig = src; - Char* dst_orig = dst; - - while (*src) *dst++ = *src++; - *dst = 0; - - /* This checks for overlap after copying, unavoidable without - pre-counting length... should be ok */ - if (is_overlap(dst_orig, - src_orig, - (Addr)dst-(Addr)dst_orig+1, - (Addr)src-(Addr)src_orig+1)) - complain2("strcpy", dst_orig, src_orig); - - return dst_orig; -} - -char* strncpy ( char* dst, const char* src, unsigned int n ) -{ - const Char* src_orig = src; - Char* dst_orig = dst; - UInt m = 0; - - while (m < n && *src) { m++; *dst++ = *src++; } - /* Check for overlap after copying; all n bytes of dst are relevant, - but only m+1 bytes of src if terminator was found */ - if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) - complain3("strncpy", dst, src, n); - while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ - - return dst_orig; -} - -int strncmp ( const char* s1, const char* s2, unsigned int nmax ) -{ - unsigned int n = 0; - while (True) { - if (n >= nmax) return 0; - if (*s1 == 0 && *s2 == 0) return 0; - if (*s1 == 0) return -1; - if (*s2 == 0) return 1; - - if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; - if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; - - s1++; s2++; n++; - } -} - -int strcmp ( const char* s1, const char* s2 ) -{ - register unsigned char c1; - register unsigned char c2; - while (True) { - c1 = *(unsigned char *)s1; - c2 = *(unsigned char *)s2; - if (c1 != c2) break; - if (c1 == 0) break; - s1++; s2++; - } - if ((unsigned char)c1 < (unsigned char)c2) return -1; - if ((unsigned char)c1 > (unsigned char)c2) return 1; - return 0; -} - -void* memchr(const void *s, int c, unsigned int n) -{ - unsigned int i; - UChar c0 = (UChar)c; - UChar* p = (UChar*)s; - for (i = 0; i < n; i++) - if (p[i] == c0) return (void*)(&p[i]); - return NULL; -} - -void* memcpy( void *dst, const void *src, unsigned int len ) -{ - register char *d; - register char *s; - - if (len == 0) - return dst; - - if (is_overlap(dst, src, len, len)) - complain3("memcpy", dst, src, len); - - if ( dst > src ) { - d = (char *)dst + len - 1; - s = (char *)src + len - 1; - while ( len >= 4 ) { - *d-- = *s--; - *d-- = *s--; - *d-- = *s--; - *d-- = *s--; - len -= 4; - } - while ( len-- ) { - *d-- = *s--; - } - } else if ( dst < src ) { - d = (char *)dst; - s = (char *)src; - while ( len >= 4 ) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - len -= 4; - } - while ( len-- ) { - *d++ = *s++; - } - } - return dst; -} - -int memcmp ( const void *s1V, const void *s2V, unsigned int n ) -{ - int res; - unsigned char a0; - unsigned char b0; - unsigned char* s1 = (unsigned char*)s1V; - unsigned char* s2 = (unsigned char*)s2V; - - while (n != 0) { - a0 = s1[0]; - b0 = s2[0]; - s1 += 1; - s2 += 1; - res = ((int)a0) - ((int)b0); - if (res != 0) - return res; - n -= 1; - } - return 0; -} - - -/* Copy SRC to DEST, returning the address of the terminating '\0' in - DEST. (minor variant of strcpy) */ - -char* stpcpy ( char* dst, const char* src ) -{ - const Char* src_orig = src; - Char* dst_orig = dst; - - while (*src) *dst++ = *src++; - *dst = 0; - - /* This checks for overlap after copying, unavoidable without - pre-counting length... should be ok */ - if (is_overlap(dst_orig, - src_orig, - (Addr)dst-(Addr)dst_orig+1, - (Addr)src-(Addr)src_orig+1)) - complain2("stpcpy", dst_orig, src_orig); - - return dst; -} - - -/* Find the first occurrence of C in S or the final NUL byte. */ - -char* glibc232_strchrnul (const char* s, int c_in) -{ - unsigned char c = (unsigned char) c_in; - unsigned char* char_ptr = (unsigned char *)s; - while (1) { - if (*char_ptr == 0) return char_ptr; - if (*char_ptr == c) return char_ptr; - char_ptr++; - } -} - - -/* Find the first occurrence of C in S. */ - -char* glibc232_rawmemchr (const char* s, int c_in) -{ - unsigned char c = (unsigned char) c_in; - unsigned char* char_ptr = (unsigned char *)s; - while (1) { - if (*char_ptr == c) return char_ptr; - char_ptr++; - } -} - - - - -/*--------------------------------------------------------------------*/ -/*--- end mac_replace_strmem.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mac_shared.h b/VEX/head20041019/memcheck/mac_shared.h deleted file mode 100644 index b41f12fb5..000000000 --- a/VEX/head20041019/memcheck/mac_shared.h +++ /dev/null @@ -1,542 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Declarations shared between MemCheck and AddrCheck. ---*/ -/*--- mac_shared.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors, and AddrCheck, a lightweight Valgrind tool - for detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* Note: This header contains the declarations shared between - Addrcheck and Memcheck, and is #included by both. */ - -#ifndef __MAC_SHARED_H -#define __MAC_SHARED_H - -#include "tool.h" - -#define MAC_(str) VGAPPEND(vgMAC_,str) - -/*------------------------------------------------------------*/ -/*--- Errors and suppressions ---*/ -/*------------------------------------------------------------*/ - -/* The classification of a faulting address. */ -typedef - enum { - Undescribed, /* as-yet unclassified */ - Stack, - Unknown, /* classification yielded nothing useful */ - Freed, Mallocd, - UserG, /* in a user-defined block; Addrcheck & Memcheck only */ - Mempool, /* in a mempool; Addrcheck & Memcheck only */ - } - AddrKind; - -/* Records info about a faulting address. */ -typedef - struct { // Used by: - AddrKind akind; // ALL - Int blksize; // Freed, Mallocd - Int rwoffset; // Freed, Mallocd - ExeContext* lastchange; // Freed, Mallocd - ThreadId stack_tid; // Stack - Bool maybe_gcc; // True if just below %esp -- could be a gcc bug. - } - AddrInfo; - -typedef - enum { - ParamSupp, // Bad syscall params - CoreMemSupp, // Memory errors in core (pthread ops, signal handling) - - // Use of invalid values of given size (MemCheck only) - Value0Supp, Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, - - // Invalid read/write attempt at given size - Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, - - FreeSupp, // Invalid or mismatching free - OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc - LeakSupp, // Something to be suppressed in a leak check. - MempoolSupp, // Memory pool suppression. - } - MAC_SuppKind; - -/* What kind of error it is. */ -typedef - enum { ValueErr, /* Memcheck only */ - CoreMemErr, - AddrErr, - ParamErr, UserErr, /* behaves like an anonymous ParamErr */ - FreeErr, FreeMismatchErr, - OverlapErr, - LeakErr, - IllegalMempoolErr, - } - MAC_ErrorKind; - -/* What kind of memory access is involved in the error? */ -typedef - enum { ReadAxs, WriteAxs, ExecAxs } - AxsKind; - -/* Extra context for memory errors */ -typedef - struct { // Used by: - AxsKind axskind; // AddrErr - Int size; // AddrErr, ValueErr - AddrInfo addrinfo; // {Addr,Free,FreeMismatch,Param,User}Err - Bool isWrite; // ParamErr, UserErr, CoreMemErr - } - MAC_Error; - -/* Extra info for overlap errors */ -typedef - struct { - Addr src; - Addr dst; - Int len; // -1 if unused - } - OverlapExtra; - -/* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */ -typedef - enum { - MAC_AllocMalloc = 0, - MAC_AllocNew = 1, - MAC_AllocNewVec = 2, - MAC_AllocCustom = 3 - } - MAC_AllocKind; - -/* Nb: first two fields must match core's VgHashNode. */ -typedef - struct _MAC_Chunk { - struct _MAC_Chunk* next; - Addr data; // ptr to actual block - UInt size : 30; // size requested - MAC_AllocKind allockind : 2; // which wrapper did the allocation - ExeContext* where; // where it was allocated - } - MAC_Chunk; - -/* Memory pool. Nb: first two fields must match core's VgHashNode. */ -typedef - struct _MAC_Mempool { - struct _MAC_Mempool* next; - Addr pool; // pool identifier - UInt rzB; // pool red-zone size - Bool is_zeroed; // allocations from this pool are zeroed - VgHashTable chunks; // chunks associated with this pool - } - MAC_Mempool; - - -/*------------------------------------------------------------*/ -/*--- Profiling of tools and memory events ---*/ -/*------------------------------------------------------------*/ - -typedef - enum { - VgpCheckMem = VgpFini+1, - VgpSetMem, - VgpESPAdj - } - VgpToolCC; - -/* Define to collect detailed performance info. */ -/* #define MAC_PROFILE_MEMORY */ - -#ifdef MAC_PROFILE_MEMORY -# define N_PROF_EVENTS 150 - -extern UInt MAC_(event_ctr)[N_PROF_EVENTS]; - -# define PROF_EVENT(ev) \ - do { sk_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \ - MAC_(event_ctr)[ev]++; \ - } while (False); - -#else - -# define PROF_EVENT(ev) /* */ - -#endif /* MAC_PROFILE_MEMORY */ - -/*------------------------------------------------------------*/ -/*--- V and A bits ---*/ -/*------------------------------------------------------------*/ - -#define IS_DISTINGUISHED_SM(smap) \ - ((smap) == &distinguished_secondary_map) - -#define ENSURE_MAPPABLE(addr,caller) \ - do { \ - if (IS_DISTINGUISHED_SM(primary_map[(addr) >> 16])) { \ - primary_map[(addr) >> 16] = alloc_secondary_map(caller); \ - /* VG_(printf)("new 2map because of %p\n", addr); */ \ - } \ - } while(0) - -#define BITARR_SET(aaa_p,iii_p) \ - do { \ - UInt iii = (UInt)iii_p; \ - UChar* aaa = (UChar*)aaa_p; \ - aaa[iii >> 3] |= (1 << (iii & 7)); \ - } while (0) - -#define BITARR_CLEAR(aaa_p,iii_p) \ - do { \ - UInt iii = (UInt)iii_p; \ - UChar* aaa = (UChar*)aaa_p; \ - aaa[iii >> 3] &= ~(1 << (iii & 7)); \ - } while (0) - -#define BITARR_TEST(aaa_p,iii_p) \ - (0 != (((UChar*)aaa_p)[ ((UInt)iii_p) >> 3 ] \ - & (1 << (((UInt)iii_p) & 7)))) \ - - -#define VGM_BIT_VALID 0 -#define VGM_BIT_INVALID 1 - -#define VGM_NIBBLE_VALID 0 -#define VGM_NIBBLE_INVALID 0xF - -#define VGM_BYTE_VALID 0 -#define VGM_BYTE_INVALID 0xFF - -#define VGM_WORD_VALID 0 -#define VGM_WORD_INVALID 0xFFFFFFFF - -#define VGM_WORD64_VALID 0x0ULL -#define VGM_WORD64_INVALID 0xFFFFFFFFFFFFFFFFULL - -#define VGM_EFLAGS_VALID 0xFFFFFFFE -#define VGM_EFLAGS_INVALID 0xFFFFFFFF /* not used */ - -/*------------------------------------------------------------*/ -/*--- Command line options + defaults ---*/ -/*------------------------------------------------------------*/ - -/* Memcheck defines a couple more. */ - -/* Allow loads from partially-valid addresses? default: YES */ -extern Bool MAC_(clo_partial_loads_ok); - -/* Max volume of the freed blocks queue. */ -extern Int MAC_(clo_freelist_vol); - -/* Do leak check at exit? default: NO */ -extern Bool MAC_(clo_leak_check); - -/* How closely should we compare ExeContexts in leak records? default: 2 */ -extern VgRes MAC_(clo_leak_resolution); - -/* In leak check, show reachable-but-not-freed blocks? default: NO */ -extern Bool MAC_(clo_show_reachable); - -/* Assume accesses immediately below %esp are due to gcc-2.96 bugs. - * default: NO*/ -extern Bool MAC_(clo_workaround_gcc296_bugs); - -extern Bool MAC_(process_common_cmd_line_option) ( Char* arg ); -extern void MAC_(print_common_usage) ( void ); -extern void MAC_(print_common_debug_usage) ( void ); - - -/*------------------------------------------------------------*/ -/*--- Variables ---*/ -/*------------------------------------------------------------*/ - -/* For tracking malloc'd blocks */ -extern VgHashTable MAC_(malloc_list); - -/* For tracking memory pools. */ -extern VgHashTable MAC_(mempool_list); - -/* Function pointers for the two tools to track interesting events. */ -extern void (*MAC_(new_mem_heap)) ( Addr a, UInt len, Bool is_inited ); -extern void (*MAC_(ban_mem_heap)) ( Addr a, UInt len ); -extern void (*MAC_(die_mem_heap)) ( Addr a, UInt len ); -extern void (*MAC_(copy_mem_heap))( Addr from, Addr to, UInt len ); - -/* Function pointers for internal sanity checking. */ -extern Bool (*MAC_(check_noaccess))( Addr a, UInt len, Addr* bad_addr ); - -/* Used in describe_addr() */ -extern Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ); - -/* For VALGRIND_COUNT_LEAKS client request */ -extern Int MAC_(bytes_leaked); -extern Int MAC_(bytes_dubious); -extern Int MAC_(bytes_reachable); -extern Int MAC_(bytes_suppressed); - -/*------------------------------------------------------------*/ -/*--- Functions ---*/ -/*------------------------------------------------------------*/ - -extern void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai ); - -extern void MAC_(clear_MAC_Error) ( MAC_Error* err_extra ); - -extern Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su ); - -extern void* MAC_(new_block) ( Addr p, UInt size, UInt align, UInt rzB, - Bool is_zeroed, MAC_AllocKind kind, - VgHashTable table); -extern void MAC_(handle_free) ( Addr p, UInt rzB, MAC_AllocKind kind ); - -extern void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed); -extern void MAC_(destroy_mempool)(Addr pool); -extern void MAC_(mempool_alloc)(Addr pool, Addr addr, UInt size); -extern void MAC_(mempool_free)(Addr pool, Addr addr); - -extern void MAC_(record_address_error) ( ThreadId tid, Addr a, - Int size, Bool isWrite ); -extern void MAC_(record_core_mem_error) ( ThreadId tid, Bool isWrite, - Char* s ); -extern void MAC_(record_param_error) ( ThreadId tid, Addr a, - Bool isWriteLack, Char* msg ); -extern void MAC_(record_jump_error) ( ThreadId tid, Addr a ); -extern void MAC_(record_free_error) ( ThreadId tid, Addr a ); -extern void MAC_(record_freemismatch_error)( ThreadId tid, Addr a ); -extern void MAC_(record_overlap_error) ( Char* function, OverlapExtra* oe ); -extern void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr pool ); - -extern void MAC_(pp_shared_SkinError) ( Error* err); - -extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*, void*), void* d ); - -extern void MAC_(common_pre_clo_init) ( void ); -extern void MAC_(common_fini) ( void (*leak_check)(void) ); - -extern Bool MAC_(handle_common_client_requests) ( ThreadId tid, - UInt* arg_block, UInt* ret ); - -extern void MAC_(print_malloc_stats) ( void ); - -/* For leak checking */ -extern void MAC_(pp_LeakError)(void* vl, UInt n_this_record, - UInt n_total_records); - -extern void MAC_(do_detect_memory_leaks) ( - Bool is_valid_64k_chunk ( UInt ), - Bool is_valid_address ( Addr ) - ); - -extern REGPARM(1) void MAC_(new_mem_stack_4) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(die_mem_stack_4) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(new_mem_stack_8) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(die_mem_stack_8) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(new_mem_stack_12) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(die_mem_stack_12) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(new_mem_stack_16) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(die_mem_stack_16) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(new_mem_stack_32) ( Addr old_ESP ); -extern REGPARM(1) void MAC_(die_mem_stack_32) ( Addr old_ESP ); -extern void MAC_(die_mem_stack) ( Addr a, UInt len); -extern void MAC_(new_mem_stack) ( Addr a, UInt len); - - -/*------------------------------------------------------------*/ -/*--- Stack pointer adjustment ---*/ -/*------------------------------------------------------------*/ - -/* Some noble preprocessor abuse, to enable Memcheck and Addrcheck to - share this code, but call different functions. - - Note that this code is executed very frequently and must be highly - optimised, which is why I resort to the preprocessor to achieve the - factoring, rather than eg. using function pointers. -*/ - -#define ESP_UPDATE_HANDLERS(ALIGNED4_NEW, ALIGNED4_DIE, \ - ALIGNED8_NEW, ALIGNED8_DIE, \ - UNALIGNED_NEW, UNALIGNED_DIE) \ - \ -void REGPARM(1) MAC_(new_mem_stack_4)(Addr new_ESP) \ -{ \ - PROF_EVENT(110); \ - if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_NEW ( new_ESP ); \ - } else { \ - UNALIGNED_NEW ( new_ESP, 4 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(die_mem_stack_4)(Addr new_ESP) \ -{ \ - PROF_EVENT(120); \ - if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_DIE ( new_ESP-4 ); \ - } else { \ - UNALIGNED_DIE ( new_ESP-4, 4 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(new_mem_stack_8)(Addr new_ESP) \ -{ \ - PROF_EVENT(111); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_NEW ( new_ESP ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_NEW ( new_ESP ); \ - ALIGNED4_NEW ( new_ESP+4 ); \ - } else { \ - UNALIGNED_NEW ( new_ESP, 8 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(die_mem_stack_8)(Addr new_ESP) \ -{ \ - PROF_EVENT(121); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_DIE ( new_ESP-8 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_DIE ( new_ESP-8 ); \ - ALIGNED4_DIE ( new_ESP-4 ); \ - } else { \ - UNALIGNED_DIE ( new_ESP-8, 8 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(new_mem_stack_12)(Addr new_ESP) \ -{ \ - PROF_EVENT(112); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_NEW ( new_ESP ); \ - ALIGNED4_NEW ( new_ESP+8 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_NEW ( new_ESP ); \ - ALIGNED8_NEW ( new_ESP+4 ); \ - } else { \ - UNALIGNED_NEW ( new_ESP, 12 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(die_mem_stack_12)(Addr new_ESP) \ -{ \ - PROF_EVENT(122); \ - /* Note the -12 in the test */ \ - if (IS_ALIGNED8_ADDR(new_ESP-12)) { \ - ALIGNED8_DIE ( new_ESP-12 ); \ - ALIGNED4_DIE ( new_ESP-4 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_DIE ( new_ESP-12 ); \ - ALIGNED8_DIE ( new_ESP-8 ); \ - } else { \ - UNALIGNED_DIE ( new_ESP-12, 12 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(new_mem_stack_16)(Addr new_ESP) \ -{ \ - PROF_EVENT(113); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_NEW ( new_ESP ); \ - ALIGNED8_NEW ( new_ESP+8 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_NEW ( new_ESP ); \ - ALIGNED8_NEW ( new_ESP+4 ); \ - ALIGNED4_NEW ( new_ESP+12 ); \ - } else { \ - UNALIGNED_NEW ( new_ESP, 16 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(die_mem_stack_16)(Addr new_ESP) \ -{ \ - PROF_EVENT(123); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_DIE ( new_ESP-16 ); \ - ALIGNED8_DIE ( new_ESP-8 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_DIE ( new_ESP-16 ); \ - ALIGNED8_DIE ( new_ESP-12 ); \ - ALIGNED4_DIE ( new_ESP-4 ); \ - } else { \ - UNALIGNED_DIE ( new_ESP-16, 16 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(new_mem_stack_32)(Addr new_ESP) \ -{ \ - PROF_EVENT(114); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_NEW ( new_ESP ); \ - ALIGNED8_NEW ( new_ESP+8 ); \ - ALIGNED8_NEW ( new_ESP+16 ); \ - ALIGNED8_NEW ( new_ESP+24 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_NEW ( new_ESP ); \ - ALIGNED8_NEW ( new_ESP+4 ); \ - ALIGNED8_NEW ( new_ESP+12 ); \ - ALIGNED8_NEW ( new_ESP+20 ); \ - ALIGNED4_NEW ( new_ESP+28 ); \ - } else { \ - UNALIGNED_NEW ( new_ESP, 32 ); \ - } \ -} \ - \ -void REGPARM(1) MAC_(die_mem_stack_32)(Addr new_ESP) \ -{ \ - PROF_EVENT(124); \ - if (IS_ALIGNED8_ADDR(new_ESP)) { \ - ALIGNED8_DIE ( new_ESP-32 ); \ - ALIGNED8_DIE ( new_ESP-24 ); \ - ALIGNED8_DIE ( new_ESP-16 ); \ - ALIGNED8_DIE ( new_ESP- 8 ); \ - } else if (IS_ALIGNED4_ADDR(new_ESP)) { \ - ALIGNED4_DIE ( new_ESP-32 ); \ - ALIGNED8_DIE ( new_ESP-28 ); \ - ALIGNED8_DIE ( new_ESP-20 ); \ - ALIGNED8_DIE ( new_ESP-12 ); \ - ALIGNED4_DIE ( new_ESP-4 ); \ - } else { \ - UNALIGNED_DIE ( new_ESP-32, 32 ); \ - } \ -} \ - \ -void MAC_(new_mem_stack) ( Addr a, UInt len ) \ -{ \ - PROF_EVENT(115); \ - UNALIGNED_NEW ( a, len ); \ -} \ - \ -void MAC_(die_mem_stack) ( Addr a, UInt len ) \ -{ \ - PROF_EVENT(125); \ - UNALIGNED_DIE ( a, len ); \ -} - -#endif /* __MAC_SHARED_H */ - -/*--------------------------------------------------------------------*/ -/*--- end mac_shared.h ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mc_asm.h b/VEX/head20041019/memcheck/mc_asm.h deleted file mode 100644 index cf4a736f2..000000000 --- a/VEX/head20041019/memcheck/mc_asm.h +++ /dev/null @@ -1,43 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- mc_asm.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef __MC_ASM_H -#define __MC_ASM_H - -#include "tool_asm.h" - -#define MC_(str) VGAPPEND(vgMemCheck_,str) - -#endif /* __MC_ASM_H */ - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/memcheck/mc_clientreqs.c b/VEX/head20041019/memcheck/mc_clientreqs.c deleted file mode 100644 index 65b5f650f..000000000 --- a/VEX/head20041019/memcheck/mc_clientreqs.c +++ /dev/null @@ -1,288 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- For when the client advises Valgrind about memory ---*/ -/*--- permissions. ---*/ -/*--- mc_clientreqs.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" - -#include "memcheck.h" /* for VG_USERREQ__* */ - - -/*------------------------------------------------------------*/ -/*--- General client block management. ---*/ -/*------------------------------------------------------------*/ - -/* This is managed as an expanding array of client block descriptors. - Indices of live descriptors are issued to the client, so it can ask - to free them later. Therefore we cannot slide live entries down - over dead ones. Instead we must use free/inuse flags and scan for - an empty slot at allocation time. This in turn means allocation is - relatively expensive, so we hope this does not happen too often. -*/ - -typedef - enum { CG_NotInUse, CG_NoAccess, CG_Writable, CG_Readable } - CGenBlockKind; - -typedef - struct { - Addr start; - UInt size; - ExeContext* where; - CGenBlockKind kind; - } - CGenBlock; - -/* This subsystem is self-initialising. */ -static UInt vg_cgb_size = 0; -static UInt vg_cgb_used = 0; -static CGenBlock* vg_cgbs = NULL; - -/* Stats for this subsystem. */ -static UInt vg_cgb_used_MAX = 0; /* Max in use. */ -static UInt vg_cgb_allocs = 0; /* Number of allocs. */ -static UInt vg_cgb_discards = 0; /* Number of discards. */ -static UInt vg_cgb_search = 0; /* Number of searches. */ - - -static -Int vg_alloc_client_block ( void ) -{ - UInt i, sz_new; - CGenBlock* cgbs_new; - - vg_cgb_allocs++; - - for (i = 0; i < vg_cgb_used; i++) { - vg_cgb_search++; - if (vg_cgbs[i].kind == CG_NotInUse) - return i; - } - - /* Not found. Try to allocate one at the end. */ - if (vg_cgb_used < vg_cgb_size) { - vg_cgb_used++; - return vg_cgb_used-1; - } - - /* Ok, we have to allocate a new one. */ - sk_assert(vg_cgb_used == vg_cgb_size); - sz_new = (vg_cgbs == NULL) ? 10 : (2 * vg_cgb_size); - - cgbs_new = VG_(malloc)( sz_new * sizeof(CGenBlock) ); - for (i = 0; i < vg_cgb_used; i++) - cgbs_new[i] = vg_cgbs[i]; - - if (vg_cgbs != NULL) - VG_(free)( vg_cgbs ); - vg_cgbs = cgbs_new; - - vg_cgb_size = sz_new; - vg_cgb_used++; - if (vg_cgb_used > vg_cgb_used_MAX) - vg_cgb_used_MAX = vg_cgb_used; - return vg_cgb_used-1; -} - - -/*------------------------------------------------------------*/ -/*--- Externally visible functions. ---*/ -/*------------------------------------------------------------*/ - -void MC_(show_client_block_stats) ( void ) -{ - VG_(message)(Vg_DebugMsg, - "general CBs: %d allocs, %d discards, %d maxinuse, %d search", - vg_cgb_allocs, vg_cgb_discards, vg_cgb_used_MAX, vg_cgb_search - ); -} - -static Bool find_addr(VgHashNode* sh_ch, void* ap) -{ - MAC_Chunk *m = (MAC_Chunk*)sh_ch; - Addr a = *(Addr*)ap; - - return VG_(addr_is_in_block)(a, m->data, m->size); -} - -Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai ) -{ - UInt i; - /* VG_(printf)("try to identify %d\n", a); */ - - /* Perhaps it's a general block ? */ - for (i = 0; i < vg_cgb_used; i++) { - if (vg_cgbs[i].kind == CG_NotInUse) - continue; - if (VG_(addr_is_in_block)(a, vg_cgbs[i].start, vg_cgbs[i].size)) { - MAC_Mempool **d, *mp; - - /* OK - maybe it's a mempool, too? */ - mp = (MAC_Mempool*)VG_(HT_get_node)(MAC_(mempool_list), - (UInt)vg_cgbs[i].start, - (VgHashNode***)&d); - if(mp != NULL) { - if(mp->chunks != NULL) { - MAC_Chunk *mc; - - mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr, &a); - if(mc != NULL) { - ai->akind = UserG; - ai->blksize = mc->size; - ai->rwoffset = (Int)(a) - (Int)mc->data; - ai->lastchange = mc->where; - return True; - } - } - ai->akind = Mempool; - ai->blksize = vg_cgbs[i].size; - ai->rwoffset = (Int)(a) - (Int)(vg_cgbs[i].start); - ai->lastchange = vg_cgbs[i].where; - return True; - } - ai->akind = UserG; - ai->blksize = vg_cgbs[i].size; - ai->rwoffset = (Int)(a) - (Int)(vg_cgbs[i].start); - ai->lastchange = vg_cgbs[i].where; - return True; - } - } - return False; -} - -Bool SK_(handle_client_request) ( ThreadId tid, UInt* arg, UInt* ret ) -{ - Int i; - Bool ok; - Addr bad_addr; - - if (!VG_IS_SKIN_USERREQ('M','C',arg[0]) - && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0] - && VG_USERREQ__FREELIKE_BLOCK != arg[0] - && VG_USERREQ__CREATE_MEMPOOL != arg[0] - && VG_USERREQ__DESTROY_MEMPOOL != arg[0] - && VG_USERREQ__MEMPOOL_ALLOC != arg[0] - && VG_USERREQ__MEMPOOL_FREE != arg[0]) - return False; - - switch (arg[0]) { - case VG_USERREQ__CHECK_WRITABLE: /* check writable */ - ok = MC_(check_writable) ( arg[1], arg[2], &bad_addr ); - if (!ok) - MC_(record_user_error) ( tid, bad_addr, True ); - *ret = ok ? (UInt)NULL : bad_addr; - break; - - case VG_USERREQ__CHECK_READABLE: /* check readable */ - ok = MC_(check_readable) ( arg[1], arg[2], &bad_addr ); - if (!ok) - MC_(record_user_error) ( tid, bad_addr, False ); - *ret = ok ? (UInt)NULL : bad_addr; - break; - - case VG_USERREQ__DO_LEAK_CHECK: - MC_(detect_memory_leaks)(); - *ret = 0; /* return value is meaningless */ - break; - - case VG_USERREQ__MAKE_NOACCESS: /* make no access */ - i = vg_alloc_client_block(); - /* VG_(printf)("allocated %d %p\n", i, vg_cgbs); */ - vg_cgbs[i].kind = CG_NoAccess; - vg_cgbs[i].start = arg[1]; - vg_cgbs[i].size = arg[2]; - vg_cgbs[i].where = VG_(get_ExeContext) ( tid ); - MC_(make_noaccess) ( arg[1], arg[2] ); - *ret = i; - break; - - case VG_USERREQ__MAKE_WRITABLE: /* make writable */ - i = vg_alloc_client_block(); - vg_cgbs[i].kind = CG_Writable; - vg_cgbs[i].start = arg[1]; - vg_cgbs[i].size = arg[2]; - vg_cgbs[i].where = VG_(get_ExeContext) ( tid ); - MC_(make_writable) ( arg[1], arg[2] ); - *ret = i; - break; - - case VG_USERREQ__MAKE_READABLE: /* make readable */ - i = vg_alloc_client_block(); - vg_cgbs[i].kind = CG_Readable; - vg_cgbs[i].start = arg[1]; - vg_cgbs[i].size = arg[2]; - vg_cgbs[i].where = VG_(get_ExeContext) ( tid ); - MC_(make_readable) ( arg[1], arg[2] ); - *ret = i; - break; - - case VG_USERREQ__DISCARD: /* discard */ - if (vg_cgbs == NULL - || arg[2] >= vg_cgb_used || vg_cgbs[arg[2]].kind == CG_NotInUse) - return 1; - sk_assert(arg[2] >= 0 && arg[2] < vg_cgb_used); - vg_cgbs[arg[2]].kind = CG_NotInUse; - vg_cgb_discards++; - *ret = 0; - break; - - case VG_USERREQ__GET_VBITS: - /* Returns: 1 == OK, 2 == alignment error, 3 == addressing - error. */ - /* VG_(printf)("get_vbits %p %p %d\n", arg[1], arg[2], arg[3] ); */ - *ret = MC_(get_or_set_vbits_for_client) - ( tid, arg[1], arg[2], arg[3], False /* get them */ ); - break; - - case VG_USERREQ__SET_VBITS: - /* Returns: 1 == OK, 2 == alignment error, 3 == addressing - error. */ - /* VG_(printf)("set_vbits %p %p %d\n", arg[1], arg[2], arg[3] ); */ - *ret = MC_(get_or_set_vbits_for_client) - ( tid, arg[1], arg[2], arg[3], True /* set them */ ); - break; - - default: - if (MAC_(handle_common_client_requests)(tid, arg, ret )) { - return True; - } else { - VG_(message)(Vg_UserMsg, - "Warning: unknown memcheck client request code %d", - arg[0]); - return False; - } - } - return True; -} - - -/*--------------------------------------------------------------------*/ -/*--- end mc_clientreqs.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mc_errcontext.c b/VEX/head20041019/memcheck/mc_errcontext.c deleted file mode 100644 index 70e20577b..000000000 --- a/VEX/head20041019/memcheck/mc_errcontext.c +++ /dev/null @@ -1,159 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Management of memory error messages. ---*/ -/*--- mc_errcontext.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" - -/*------------------------------------------------------------*/ -/*--- Printing errors ---*/ -/*------------------------------------------------------------*/ - -void SK_(pp_SkinError) ( Error* err ) -{ - MAC_Error* err_extra = VG_(get_error_extra)(err); - - switch (VG_(get_error_kind)(err)) { - case CoreMemErr: - if (err_extra->isWrite) { - VG_(message)(Vg_UserMsg, - "%s contains unaddressable byte(s)", VG_(get_error_string)(err)); - } else { - VG_(message)(Vg_UserMsg, - "%s contains uninitialised or unaddressable byte(s)", - VG_(get_error_string)(err)); - } - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - break; - - case ValueErr: - if (err_extra->size == 0) { - VG_(message)( - Vg_UserMsg, - "Conditional jump or move depends on uninitialised value(s)"); - } else { - VG_(message)(Vg_UserMsg, - "Use of uninitialised value of size %d", - err_extra->size); - } - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - break; - - case ParamErr: - if (err_extra->isWrite) { - VG_(message)(Vg_UserMsg, - "Syscall param %s contains unaddressable byte(s)", - VG_(get_error_string)(err)); - } else { - VG_(message)(Vg_UserMsg, - "Syscall param %s contains uninitialised or " - "unaddressable byte(s)", - VG_(get_error_string)(err)); - } - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - case UserErr: - if (err_extra->isWrite) { - VG_(message)(Vg_UserMsg, - "Unaddressable byte(s) found during client check request"); - } else { - VG_(message)(Vg_UserMsg, - "Uninitialised or " - "unaddressable byte(s) found during client check request"); - } - VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo); - break; - - default: - MAC_(pp_shared_SkinError)(err); - break; - } -} - -/*------------------------------------------------------------*/ -/*--- Recording errors ---*/ -/*------------------------------------------------------------*/ - -/* Creates a copy of the `extra' part, updates the copy with address info if - necessary, and returns the copy. */ -/* This one called from generated code and non-generated code. */ -void MC_(record_value_error) ( ThreadId tid, Int size ) -{ - MAC_Error err_extra; - - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.size = size; - VG_(maybe_record_error)( tid, ValueErr, /*addr*/0, /*s*/NULL, &err_extra ); -} - -/* This called from non-generated code */ - -void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite ) -{ - MAC_Error err_extra; - - sk_assert(VG_INVALID_THREADID != tid); - MAC_(clear_MAC_Error)( &err_extra ); - err_extra.addrinfo.akind = Undescribed; - err_extra.isWrite = isWrite; - VG_(maybe_record_error)( tid, UserErr, a, /*s*/NULL, &err_extra ); -} - -/*------------------------------------------------------------*/ -/*--- Suppressions ---*/ -/*------------------------------------------------------------*/ - -Bool SK_(recognised_suppression) ( Char* name, Supp* su ) -{ - SuppKind skind; - - if (MAC_(shared_recognised_suppression)(name, su)) - return True; - - /* Extra suppressions not used by Addrcheck */ - else if (VG_STREQ(name, "Cond")) skind = Value0Supp; - else if (VG_STREQ(name, "Value0")) skind = Value0Supp;/* backwards compat */ - else if (VG_STREQ(name, "Value1")) skind = Value1Supp; - else if (VG_STREQ(name, "Value2")) skind = Value2Supp; - else if (VG_STREQ(name, "Value4")) skind = Value4Supp; - else if (VG_STREQ(name, "Value8")) skind = Value8Supp; - else if (VG_STREQ(name, "Value16")) skind = Value16Supp; - else - return False; - - VG_(set_supp_kind)(su, skind); - return True; -} - -/*--------------------------------------------------------------------*/ -/*--- end mc_errcontext.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mc_from_ucode.c b/VEX/head20041019/memcheck/mc_from_ucode.c deleted file mode 100644 index f6f6b2ed4..000000000 --- a/VEX/head20041019/memcheck/mc_from_ucode.c +++ /dev/null @@ -1,665 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Generate code for tool-specific UInstrs. ---*/ -/*--- mc_from_ucode.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" - -/*------------------------------------------------------------*/ -/*--- Renamings of frequently-used global functions. ---*/ -/*------------------------------------------------------------*/ - -#define dis VG_(print_codegen) - -/*------------------------------------------------------------*/ -/*--- Instruction emission -- turning final uinstrs back ---*/ -/*--- into x86 code. ---*/ -/*------------------------------------------------------------*/ - -/* See the corresponding comment at the top of vg_from_ucode.c to find out - * how all this works */ - -#if 0 - -/*----------------------------------------------------*/ -/*--- v-size (4, or 2 with OSO) insn emitters ---*/ -/*----------------------------------------------------*/ - -static void emit_testv_lit_reg ( Int sz, UInt lit, Int reg ) -{ - VG_(new_emit)(False, FlagsEmpty, FlagsOSZACP); - if (sz == 2) { - VG_(emitB) ( 0x66 ); - } else { - sk_assert(sz == 4); - } - VG_(emitB) ( 0xF7 ); /* Grp3 Ev */ - VG_(emit_amode_ereg_greg) ( reg, 0 /* Grp3 subopcode for TEST */ ); - if (sz == 2) VG_(emitW) ( lit ); else VG_(emitL) ( lit ); - if (dis) - VG_(printf)("\n\t\ttest%c $0x%x, %s\n", nameISize(sz), - lit, nameIReg(sz,reg)); -} - -static void emit_testv_lit_offregmem ( Int sz, UInt lit, Int off, Int reg ) -{ - VG_(new_emit)(False, FlagsEmpty, FlagsOSZACP); - if (sz == 2) { - VG_(emitB) ( 0x66 ); - } else { - sk_assert(sz == 4); - } - VG_(emitB) ( 0xF7 ); /* Grp3 Ev */ - VG_(emit_amode_offregmem_reg) ( off, reg, 0 /* Grp3 subopcode for TEST */ ); - if (sz == 2) VG_(emitW) ( lit ); else VG_(emitL) ( lit ); - if (dis) - VG_(printf)("\n\t\ttest%c $%d, 0x%x(%s)\n", - nameISize(sz), lit, off, nameIReg(4,reg) ); -} - -/*----------------------------------------------------*/ -/*--- Instruction synthesisers ---*/ -/*----------------------------------------------------*/ - -/* Synthesise a minimal test (and which discards result) of reg32 - against lit. It's always safe do simply - emit_testv_lit_reg ( 4, lit, reg32 ) - but we try to do better when possible. -*/ -static void synth_minimal_test_lit_reg ( UInt lit, Int reg32 ) -{ - if ((lit & 0xFFFFFF00) == 0 && reg32 < 4) { - /* We can get away with a byte insn. */ - VG_(emit_testb_lit_reg) ( False, lit, reg32 ); - } - else - if ((lit & 0xFFFF0000) == 0) { - /* Literal fits in 16 bits; do a word insn. */ - emit_testv_lit_reg ( 2, lit, reg32 ); - } - else { - /* Totally general ... */ - emit_testv_lit_reg ( 4, lit, reg32 ); - } -} - -/*----------------------------------------------------*/ -/*--- Top level of the uinstr -> x86 translation. ---*/ -/*----------------------------------------------------*/ - -static void synth_LOADV ( Int sz, Int a_reg, Int tv_reg, - RRegSet regs_live_before, - RRegSet regs_live_after ) -{ - Addr helper; - UInt argv[] = { a_reg }; - UInt tagv[] = { RealReg }; - - switch (sz) { - case 4: helper = (Addr) & MC_(helperc_LOADV4); break; - case 2: helper = (Addr) & MC_(helperc_LOADV2); break; - case 1: helper = (Addr) & MC_(helperc_LOADV1); break; - default: VG_(skin_panic)("synth_LOADV"); - } - VG_(synth_ccall) ( helper, 1, 1, argv, tagv, tv_reg, - regs_live_before, regs_live_after ); -} - - -static void synth_STOREV ( Int sz, Int tv_tag, Int tv_val, Int a_reg, - RRegSet regs_live_before, - RRegSet regs_live_after ) -{ - Addr helper; - UInt argv[] = { a_reg, tv_val }; - Tag tagv[] = { RealReg, tv_tag }; - - sk_assert(tv_tag == RealReg || tv_tag == Literal); - switch (sz) { - case 4: helper = (Addr) MC_(helperc_STOREV4); break; - case 2: helper = (Addr) MC_(helperc_STOREV2); break; - case 1: helper = (Addr) MC_(helperc_STOREV1); break; - default: VG_(skin_panic)("synth_STOREV"); - } - VG_(synth_ccall) ( helper, 2, 2, argv, tagv, INVALID_REALREG, - regs_live_before, regs_live_after ); -} - - -static void synth_SETV ( Int sz, Int reg ) -{ - UInt val; - switch (sz) { - case 4: val = 0x00000000; break; - case 2: val = 0xFFFF0000; break; - case 1: val = 0xFFFFFF00; break; - case 0: val = 0xFFFFFFFE; break; - default: VG_(skin_panic)("synth_SETV"); - } - VG_(emit_movv_lit_reg) ( 4, val, reg ); -} - - -static void synth_TESTV ( Int sz, Int tag, Int val ) -{ - Int tgt; /* jump target */ - - /* Important note. Note that that the calls to - MC_(helper_value_check[0124]_fail) must be compact helpers due to - the codegen scheme used below. Since there are a shortage of - compact helper slots, and since the size==1 case is never - actually used, we assert against it. */ - sk_assert(sz == 0 || sz == 2 || sz == 4); - - VG_(init_target)(&tgt); - - sk_assert(tag == ArchReg || tag == RealReg); - if (tag == ArchReg) { - switch (sz) { - case 4: - emit_testv_lit_offregmem ( - 4, 0xFFFFFFFF, VG_(shadow_reg_offset)(val), R_EBP ); - break; - case 2: - emit_testv_lit_offregmem ( - 4, 0x0000FFFF, VG_(shadow_reg_offset)(val), R_EBP ); - break; - case 1: - if (val < 4) { - emit_testv_lit_offregmem ( - 4, 0x000000FF, VG_(shadow_reg_offset)(val), R_EBP ); - } else { - emit_testv_lit_offregmem ( - 4, 0x0000FF00, VG_(shadow_reg_offset)(val-4), R_EBP ); - } - break; - case 0: - /* should never happen */ - default: - VG_(skin_panic)("synth_TESTV(ArchReg)"); - } - } else { - switch (sz) { - case 4: - /* Works, but holds the entire 32-bit literal, hence - generating a 6-byte insn. We want to know if any bits - in the reg are set, but since this is for the full reg, - we might as well compare it against zero, which can be - done with a shorter insn. */ - /* synth_minimal_test_lit_reg ( 0xFFFFFFFF, val ); */ - VG_(emit_cmpl_zero_reg) ( False, val ); - break; - case 2: - synth_minimal_test_lit_reg ( 0x0000FFFF, val ); - break; - case 1: - synth_minimal_test_lit_reg ( 0x000000FF, val ); - break; - case 0: - synth_minimal_test_lit_reg ( 0x00000001, val ); - break; - default: - VG_(skin_panic)("synth_TESTV(RealReg)"); - } - } - - /* predict taken because we assume failures are rare */ - VG_(emit_jcondshort_target) ( False, CondZ, &tgt, JP_TAKEN ); - - VG_(synth_call) ( - False, - ( sz==4 - ? VG_(helper_offset)((Addr) & MC_(helper_value_check4_fail)) - : ( sz==2 - ? VG_(helper_offset)((Addr) & MC_(helper_value_check2_fail)) - : ( sz==1 - ? VG_(helper_offset)((Addr) & MC_(helper_value_check1_fail)) - : VG_(helper_offset)((Addr) & MC_(helper_value_check0_fail))))), - False, FlagsEmpty, FlagsOSZACP /* helpers don't preserve flags */ - ); - VG_(target_forward)(&tgt); -} - - -static void synth_GETV ( Int sz, Int arch, Int reg ) -{ - /* VG_(printf)("synth_GETV %d of Arch %s\n", sz, nameIReg(sz, arch)); */ - switch (sz) { - case 4: - VG_(emit_movv_offregmem_reg) ( 4, VG_(shadow_reg_offset)(arch), - R_EBP, reg ); - break; - case 2: - VG_(emit_movzwl_offregmem_reg) ( False, VG_(shadow_reg_offset)(arch), - R_EBP, reg ); - VG_(emit_nonshiftopv_lit_reg) ( False, 4, OR, 0xFFFF0000, reg ); - break; - case 1: - if (arch < 4) { - VG_(emit_movzbl_offregmem_reg) ( False, VG_(shadow_reg_offset)(arch), - R_EBP, reg ); - } else { - VG_(emit_movzbl_offregmem_reg) ( False, VG_(shadow_reg_offset)(arch-4)+1, - R_EBP, reg ); - } - VG_(emit_nonshiftopv_lit_reg) ( False, 4, OR, 0xFFFFFF00, reg ); - break; - default: - VG_(skin_panic)("synth_GETV"); - } -} - - -static void synth_PUTV ( Int sz, Int srcTag, UInt lit_or_reg, Int arch ) -{ - if (srcTag == Literal) { - /* PUTV with a Literal is only ever used to set the corresponding - ArchReg to `all valid'. Should really be a kind of SETV. */ - UInt lit = lit_or_reg; - switch (sz) { - case 4: - sk_assert(lit == 0x00000000); - VG_(emit_movv_lit_offregmem) ( 4, 0x00000000, - VG_(shadow_reg_offset)(arch), R_EBP ); - break; - case 2: - sk_assert(lit == 0xFFFF0000); - VG_(emit_movv_lit_offregmem) ( 2, 0x0000, - VG_(shadow_reg_offset)(arch), R_EBP ); - break; - case 1: - sk_assert(lit == 0xFFFFFF00); - if (arch < 4) { - VG_(emit_movb_lit_offregmem) ( 0x00, - VG_(shadow_reg_offset)(arch), R_EBP ); - } else { - VG_(emit_movb_lit_offregmem) ( 0x00, - VG_(shadow_reg_offset)(arch-4)+1, - R_EBP ); - } - break; - default: - VG_(skin_panic)("synth_PUTV(lit)"); - } - - } else { - - UInt reg; - sk_assert(srcTag == RealReg); - - if (sz == 1 && lit_or_reg >= 4) { - VG_(emit_swapl_reg_EAX) ( lit_or_reg ); - reg = R_EAX; - } else { - reg = lit_or_reg; - } - - if (sz == 1) sk_assert(reg < 4); - - switch (sz) { - case 4: - VG_(emit_movv_reg_offregmem) ( 4, reg, - VG_(shadow_reg_offset)(arch), R_EBP ); - break; - case 2: - VG_(emit_movv_reg_offregmem) ( 2, reg, - VG_(shadow_reg_offset)(arch), R_EBP ); - break; - case 1: - if (arch < 4) { - VG_(emit_movb_reg_offregmem) ( reg, - VG_(shadow_reg_offset)(arch), R_EBP ); - } else { - VG_(emit_movb_reg_offregmem) ( reg, - VG_(shadow_reg_offset)(arch-4)+1, R_EBP ); - } - break; - default: - VG_(skin_panic)("synth_PUTV(reg)"); - } - - if (sz == 1 && lit_or_reg >= 4) { - VG_(emit_swapl_reg_EAX) ( lit_or_reg ); - } - } -} - - -static void synth_GETVF ( Int reg ) -{ - VG_(emit_movv_offregmem_reg) ( 4, VG_(shadow_flags_offset)(), R_EBP, reg ); - /* paranoia only; should be unnecessary ... */ - /* VG_(emit_nonshiftopv_lit_reg) ( 4, OR, 0xFFFFFFFE, reg ); */ -} - - -static void synth_PUTVF ( UInt reg ) -{ - VG_(emit_movv_reg_offregmem) ( 4, reg, VG_(shadow_flags_offset)(), R_EBP ); -} - - -static void synth_TAG1_op ( TagOp op, Int reg, RRegSet regs_live_after ) -{ - switch (op) { - - /* Scheme is - neg %reg -- CF = %reg==0 ? 0 : 1 - sbbl %reg, %reg -- %reg = -CF - or 0xFFFFFFFE, %reg -- invalidate all bits except lowest - */ - case Tag_PCast40: - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFFFE, reg); - break; - case Tag_PCast20: - VG_(emit_unaryopv_reg)(False, 2, NEG, reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFFFE, reg); - break; - case Tag_PCast10: - if (reg >= 4) { - VG_(emit_swapl_reg_EAX)(reg); - VG_(emit_unaryopb_reg)(False, NEG, R_EAX); - VG_(emit_swapl_reg_EAX)(reg); - } else { - VG_(emit_unaryopb_reg)(False, NEG, reg); - } - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFFFE, reg); - break; - - /* Scheme is - andl $1, %reg -- %reg is 0 or 1 - negl %reg -- %reg is 0 or 0xFFFFFFFF - and possibly an OR to invalidate unused bits. - */ - case Tag_PCast04: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x00000001, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - break; - case Tag_PCast02: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x00000001, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, reg); - break; - case Tag_PCast01: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x00000001, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFF00, reg); - break; - - /* Scheme is - shl $24, %reg -- make irrelevant bits disappear - negl %reg -- CF = %reg==0 ? 0 : 1 - sbbl %reg, %reg -- %reg = -CF - and possibly an OR to invalidate unused bits. - */ - case Tag_PCast14: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 24, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - break; - case Tag_PCast12: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 24, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, reg); - break; - case Tag_PCast11: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 24, reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, SBB, reg, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFF00, reg); - break; - - /* We use any non-live reg (except %reg) as a temporary, - or push/pop %ebp if none available: - (%dead_reg = any dead reg, else choose anything other than %reg) - (pushl %dead_reg if live) - movl %reg, %dead_reg - negl %dead_reg - orl %dead_reg, %reg - (popl %dead_reg if live) - This sequence turns out to be correct regardless of the - operation width. - */ - case Tag_Left4: - case Tag_Left2: - case Tag_Left1: { - Bool push = True; - UInt dead_reg = R_ESP; - Int i, reg_of_i; - - for (i = 0; i < VG_MAX_REALREGS; i++) { - if (! IS_RREG_LIVE(i, regs_live_after)) { - reg_of_i = VG_(rank_to_realreg)(i); - if (reg != reg_of_i) { - dead_reg = reg_of_i; - push = False; - break; - } - } - } - - if (push) { - dead_reg = (reg != R_EAX) ? R_EAX : R_EBX; - VG_(emit_pushv_reg)(4, dead_reg); - } - - VG_(emit_movv_reg_reg)(4, reg, dead_reg); - VG_(emit_unaryopv_reg)(False, 4, NEG, dead_reg); - VG_(emit_nonshiftopv_reg_reg)(False, 4, OR, dead_reg, reg); - - if (push) - VG_(emit_popv_reg)(4, dead_reg); - break; - } - - /* These are all fairly obvious; do the op and then, if - necessary, invalidate unused bits. */ - case Tag_SWiden14: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 24, reg); - VG_(emit_shiftopv_lit_reg)(False, 4, SAR, 24, reg); - break; - case Tag_SWiden24: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 16, reg); - VG_(emit_shiftopv_lit_reg)(False, 4, SAR, 16, reg); - break; - case Tag_SWiden12: - VG_(emit_shiftopv_lit_reg)(False, 4, SHL, 24, reg); - VG_(emit_shiftopv_lit_reg)(False, 4, SAR, 24, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, reg); - break; - case Tag_ZWiden14: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x000000FF, reg); - break; - case Tag_ZWiden24: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x0000FFFF, reg); - break; - case Tag_ZWiden12: - VG_(emit_nonshiftopv_lit_reg)(False, 4, AND, 0x000000FF, reg); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, reg); - break; - - default: - VG_(skin_panic)("synth_TAG1_op"); - } -} - - -static void synth_TAG2_op ( TagOp op, Int regs, Int regd ) -{ - switch (op) { - - /* UifU is implemented by OR, since 1 means Undefined. */ - case Tag_UifU4: - case Tag_UifU2: - case Tag_UifU1: - case Tag_UifU0: - VG_(emit_nonshiftopv_reg_reg)(False, 4, OR, regs, regd); - break; - - /* DifD is implemented by AND, since 0 means Defined. */ - case Tag_DifD4: - case Tag_DifD2: - case Tag_DifD1: - VG_(emit_nonshiftopv_reg_reg)(False, 4, AND, regs, regd); - break; - - /* ImproveAND(value, tags) = value OR tags. - Defined (0) value 0s give defined (0); all other -> undefined (1). - value is in regs; tags is in regd. - Be paranoid and invalidate unused bits; I don't know whether - or not this is actually necessary. */ - case Tag_ImproveAND4_TQ: - VG_(emit_nonshiftopv_reg_reg)(False, 4, OR, regs, regd); - break; - case Tag_ImproveAND2_TQ: - VG_(emit_nonshiftopv_reg_reg)(False, 4, OR, regs, regd); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, regd); - break; - case Tag_ImproveAND1_TQ: - VG_(emit_nonshiftopv_reg_reg)(False, 4, OR, regs, regd); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFF00, regd); - break; - - /* ImproveOR(value, tags) = (not value) OR tags. - Defined (0) value 1s give defined (0); all other -> undefined (1). - value is in regs; tags is in regd. - To avoid trashing value, this is implemented (re de Morgan) as - not (value AND (not tags)) - Be paranoid and invalidate unused bits; I don't know whether - or not this is actually necessary. */ - case Tag_ImproveOR4_TQ: - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - VG_(emit_nonshiftopv_reg_reg)(False, 4, AND, regs, regd); - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - break; - case Tag_ImproveOR2_TQ: - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - VG_(emit_nonshiftopv_reg_reg)(False, 4, AND, regs, regd); - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFF0000, regd); - break; - case Tag_ImproveOR1_TQ: - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - VG_(emit_nonshiftopv_reg_reg)(False, 4, AND, regs, regd); - VG_(emit_unaryopv_reg)(False, 4, NOT, regd); - VG_(emit_nonshiftopv_lit_reg)(False, 4, OR, 0xFFFFFF00, regd); - break; - - default: - VG_(skin_panic)("synth_TAG2_op"); - } -} - -/*----------------------------------------------------*/ -/*--- Generate code for a single UInstr. ---*/ -/*----------------------------------------------------*/ - -void SK_(emit_XUInstr) ( UInstr* u, RRegSet regs_live_before ) -{ - switch (u->opcode) { - - case SETV: - sk_assert(u->tag1 == RealReg); - synth_SETV ( u->size, u->val1 ); - break; - - case STOREV: - sk_assert(u->tag1 == RealReg || u->tag1 == Literal); - sk_assert(u->tag2 == RealReg); - synth_STOREV ( u->size, u->tag1, - u->tag1==Literal ? u->lit32 : u->val1, - u->val2, - regs_live_before, u->regs_live_after ); - break; - - case LOADV: - sk_assert(u->tag1 == RealReg); - sk_assert(u->tag2 == RealReg); - if (0) - VG_(emit_AMD_prefetch_reg) ( u->val1 ); - synth_LOADV ( u->size, u->val1, u->val2, - regs_live_before, u->regs_live_after ); - break; - - case TESTV: - sk_assert(u->tag1 == RealReg || u->tag1 == ArchReg); - synth_TESTV(u->size, u->tag1, u->val1); - break; - - case GETV: - sk_assert(u->tag1 == ArchReg); - sk_assert(u->tag2 == RealReg); - synth_GETV(u->size, u->val1, u->val2); - break; - - case GETVF: - sk_assert(u->tag1 == RealReg); - sk_assert(u->size == 0); - synth_GETVF(u->val1); - break; - - case PUTV: - sk_assert(u->tag1 == RealReg || u->tag1 == Literal); - sk_assert(u->tag2 == ArchReg); - synth_PUTV(u->size, u->tag1, - u->tag1==Literal ? u->lit32 : u->val1, - u->val2 ); - break; - - case PUTVF: - sk_assert(u->tag1 == RealReg); - sk_assert(u->size == 0); - synth_PUTVF(u->val1); - break; - - case TAG1: - synth_TAG1_op ( u->val3, u->val1, u->regs_live_after ); - break; - - case TAG2: - synth_TAG2_op ( u->val3, u->val1, u->val2 ); - break; - - default: - VG_(printf)("emit_XUInstr: unhandled extension insn:\n"); - VG_(pp_UInstr)(0,u); - VG_(skin_panic)("emit_XUInstr: unhandled extension opcode"); - } -} - -#endif - -/*--------------------------------------------------------------------*/ -/*--- end mc_from_ucode.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mc_helpers.S b/VEX/head20041019/memcheck/mc_helpers.S deleted file mode 100644 index c56642de9..000000000 --- a/VEX/head20041019/memcheck/mc_helpers.S +++ /dev/null @@ -1,67 +0,0 @@ - -##--------------------------------------------------------------------## -##--- Support routines for the memory checker. ---## -##--- mc_helpers.S ---## -##--------------------------------------------------------------------## - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_asm.h" - -.global MC_(helper_value_check0_fail) -MC_(helper_value_check0_fail): - pushal - call MC_(helperc_value_check0_fail) - popal - ret - -.global MC_(helper_value_check1_fail) -MC_(helper_value_check1_fail): - pushal - call MC_(helperc_value_check1_fail) - popal - ret - -.global MC_(helper_value_check2_fail) -MC_(helper_value_check2_fail): - pushal - call MC_(helperc_value_check2_fail) - popal - ret - -.global MC_(helper_value_check4_fail) -MC_(helper_value_check4_fail): - pushal - call MC_(helperc_value_check4_fail) - popal - ret - -/* Let the linker know we don't need an executable stack */ -.section .note.GNU-stack,"",@progbits - -##--------------------------------------------------------------------## -##--- end mc_helpers.S ---## -##--------------------------------------------------------------------## diff --git a/VEX/head20041019/memcheck/mc_include.h b/VEX/head20041019/memcheck/mc_include.h deleted file mode 100644 index 3cf120c7f..000000000 --- a/VEX/head20041019/memcheck/mc_include.h +++ /dev/null @@ -1,169 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- A header file for all parts of the MemCheck tool. ---*/ -/*--- mc_include.h ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -/* Note: this header should contain declarations that are for use by - Memcheck only -- declarations shared with Addrcheck go in mac_shared.h. -*/ - -#ifndef __MC_INCLUDE_H -#define __MC_INCLUDE_H - -#include "mac_shared.h" -#include "mc_asm.h" - -/*------------------------------------------------------------*/ -/*--- Types ---*/ -/*------------------------------------------------------------*/ - -/* UCode extension for efficient memory checking operations */ -typedef - enum { - /* uinstrs which are not needed for mere translation of x86 code, - only for instrumentation of it. */ - LOADV = DUMMY_FINAL_UOPCODE + 1, - STOREV, - GETV, - PUTV, - TESTV, - SETV, - /* Get/set the v-bit (and it is only one bit) for the simulated - %eflags register. */ - GETVF, - PUTVF, - - /* Do a unary or binary tag op. Only for post-instrumented - code. For TAG1, first and only arg is a TempReg, and is both - arg and result reg. For TAG2, first arg is src, second is - dst, in the normal way; both are TempRegs. In both cases, - 3rd arg is a RiCHelper with a Lit16 tag. This indicates - which tag op to do. */ - TAG1, - TAG2 - } - MemCheckOpcode; - - -/* Lists the names of value-tag operations used in instrumented - code. These are the third argument to TAG1 and TAG2 uinsns. */ -typedef - enum { - /* Unary. */ - Tag_PCast40, Tag_PCast20, Tag_PCast10, - Tag_PCast01, Tag_PCast02, Tag_PCast04, - - Tag_PCast14, Tag_PCast12, Tag_PCast11, - - Tag_Left4, Tag_Left2, Tag_Left1, - - Tag_SWiden14, Tag_SWiden24, Tag_SWiden12, - Tag_ZWiden14, Tag_ZWiden24, Tag_ZWiden12, - - /* Binary; 1st is rd; 2nd is rd+wr */ - Tag_UifU4, Tag_UifU2, Tag_UifU1, Tag_UifU0, - Tag_DifD4, Tag_DifD2, Tag_DifD1, - - Tag_ImproveAND4_TQ, Tag_ImproveAND2_TQ, Tag_ImproveAND1_TQ, - Tag_ImproveOR4_TQ, Tag_ImproveOR2_TQ, Tag_ImproveOR1_TQ, - Tag_DebugFn - } - TagOp; - - -/*------------------------------------------------------------*/ -/*--- Command line options ---*/ -/*------------------------------------------------------------*/ - -/* DEBUG: clean up instrumented code? default: YES */ -extern Bool MC_(clo_cleanup); - -/* When instrumenting, omit some checks if tell-tale literals for - inlined strlen() are visible in the basic block. default: YES */ -extern Bool MC_(clo_avoid_strlen_errors); - - -/*------------------------------------------------------------*/ -/*--- Functions ---*/ -/*------------------------------------------------------------*/ - -/* Functions defined in mc_main.c */ -extern REGPARM(1) void MC_(helperc_complain_undef) ( HWord ); -extern void MC_(helperc_value_check4_fail) ( void ); -extern void MC_(helperc_value_check1_fail) ( void ); -extern void MC_(helperc_value_check0_fail) ( void ); - -extern REGPARM(1) void MC_(helperc_STOREV8) ( Addr, ULong ); -extern REGPARM(2) void MC_(helperc_STOREV4) ( Addr, UInt ); -extern REGPARM(2) void MC_(helperc_STOREV2) ( Addr, UInt ); -extern REGPARM(2) void MC_(helperc_STOREV1) ( Addr, UInt ); - -extern REGPARM(1) UInt MC_(helperc_LOADV1) ( Addr ); -extern REGPARM(1) UInt MC_(helperc_LOADV2) ( Addr ); -extern REGPARM(1) UInt MC_(helperc_LOADV4) ( Addr ); -extern REGPARM(1) ULong MC_(helperc_LOADV8) ( Addr ); - -extern REGPARM(2) void MC_(fpu_write_check) ( Addr addr, Int size ); -extern REGPARM(2) void MC_(fpu_read_check) ( Addr addr, Int size ); - - -/* For client requests */ -extern void MC_(make_noaccess) ( Addr a, UInt len ); -extern void MC_(make_readable) ( Addr a, UInt len ); -extern void MC_(make_writable) ( Addr a, UInt len ); - -extern Bool MC_(check_writable) ( Addr a, UInt len, Addr* bad_addr ); -extern Bool MC_(check_readable) ( Addr a, UInt len, Addr* bad_addr ); - -extern void MC_(detect_memory_leaks) ( void ); - -extern Int MC_(get_or_set_vbits_for_client) ( - ThreadId tid, - Addr dataV, - Addr vbitsV, - UInt size, - Bool setting /* True <=> set vbits, False <=> get vbits */ - ); - -/* Functions defined in mc_clientreqs.c */ -extern Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai ); -extern void MC_(show_client_block_stats) ( void ); - - -/* Functions defined in mc_errcontext.c */ -extern void MC_(record_value_error) ( ThreadId tid, Int size ); -extern void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isWrite ); - - -#endif - -/*--------------------------------------------------------------------*/ -/*--- end mc_include.h ---*/ -/*--------------------------------------------------------------------*/ - diff --git a/VEX/head20041019/memcheck/mc_main.c b/VEX/head20041019/memcheck/mc_main.c deleted file mode 100644 index 7bc2708a8..000000000 --- a/VEX/head20041019/memcheck/mc_main.c +++ /dev/null @@ -1,1943 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- MemCheck: Maintain bitmaps of memory, tracking the ---*/ -/*--- accessibility (A) and validity (V) status of each byte. ---*/ -/*--- mc_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" -#include "memcheck.h" /* for client requests */ -//#include "vg_profile.c" - -/* Define to debug the mem audit system. */ -/* #define VG_DEBUG_MEMORY */ - -#define DEBUG(fmt, args...) //VG_(printf)(fmt, ## args) - -/*------------------------------------------------------------*/ -/*--- Low-level support for memory checking. ---*/ -/*------------------------------------------------------------*/ - -/* All reads and writes are checked against a memory map, which - records the state of all memory in the process. The memory map is - organised like this: - - The top 16 bits of an address are used to index into a top-level - map table, containing 65536 entries. Each entry is a pointer to a - second-level map, which records the accesibililty and validity - permissions for the 65536 bytes indexed by the lower 16 bits of the - address. Each byte is represented by nine bits, one indicating - accessibility, the other eight validity. So each second-level map - contains 73728 bytes. This two-level arrangement conveniently - divides the 4G address space into 64k lumps, each size 64k bytes. - - All entries in the primary (top-level) map must point to a valid - secondary (second-level) map. Since most of the 4G of address - space will not be in use -- ie, not mapped at all -- there is a - distinguished secondary map, which indicates `not addressible and - not valid' writeable for all bytes. Entries in the primary map for - which the entire 64k is not in use at all point at this - distinguished map. - - [...] lots of stuff deleted due to out of date-ness - - As a final optimisation, the alignment and address checks for - 4-byte loads and stores are combined in a neat way. The primary - map is extended to have 262144 entries (2^18), rather than 2^16. - The top 3/4 of these entries are permanently set to the - distinguished secondary map. For a 4-byte load/store, the - top-level map is indexed not with (addr >> 16) but instead f(addr), - where - - f( XXXX XXXX XXXX XXXX ____ ____ ____ __YZ ) - = ____ ____ ____ __YZ XXXX XXXX XXXX XXXX or - = ____ ____ ____ __ZY XXXX XXXX XXXX XXXX - - ie the lowest two bits are placed above the 16 high address bits. - If either of these two bits are nonzero, the address is misaligned; - this will select a secondary map from the upper 3/4 of the primary - map. Because this is always the distinguished secondary map, a - (bogus) address check failure will result. The failure handling - code can then figure out whether this is a genuine addr check - failure or whether it is a possibly-legitimate access at a - misaligned address. -*/ - - -/*------------------------------------------------------------*/ -/*--- Function declarations. ---*/ -/*------------------------------------------------------------*/ - -static ULong mc_rd_V8_SLOWLY ( Addr a ); -static UInt mc_rd_V4_SLOWLY ( Addr a ); -static UInt mc_rd_V2_SLOWLY ( Addr a ); -static UInt mc_rd_V1_SLOWLY ( Addr a ); - -static void mc_wr_V8_SLOWLY ( Addr a, ULong vbytes ); -static void mc_wr_V4_SLOWLY ( Addr a, UInt vbytes ); -static void mc_wr_V2_SLOWLY ( Addr a, UInt vbytes ); -static void mc_wr_V1_SLOWLY ( Addr a, UInt vbytes ); - -static void mc_fpu_read_check_SLOWLY ( Addr addr, Int size ); -static void mc_fpu_write_check_SLOWLY ( Addr addr, Int size ); - -/*------------------------------------------------------------*/ -/*--- Data defns. ---*/ -/*------------------------------------------------------------*/ - -typedef - struct { - UChar abits[8192]; - UChar vbyte[65536]; - } - SecMap; - -static SecMap* primary_map[ /*65536*/ 262144 ]; -static SecMap distinguished_secondary_map; - -static void init_shadow_memory ( void ) -{ - Int i; - - for (i = 0; i < 8192; i++) /* Invalid address */ - distinguished_secondary_map.abits[i] = VGM_BYTE_INVALID; - for (i = 0; i < 65536; i++) /* Invalid Value */ - distinguished_secondary_map.vbyte[i] = VGM_BYTE_INVALID; - - /* These entries gradually get overwritten as the used address - space expands. */ - for (i = 0; i < 65536; i++) - primary_map[i] = &distinguished_secondary_map; - - /* These ones should never change; it's a bug in Valgrind if they do. */ - for (i = 65536; i < 262144; i++) - primary_map[i] = &distinguished_secondary_map; -} - -/*------------------------------------------------------------*/ -/*--- Basic bitmap management, reading and writing. ---*/ -/*------------------------------------------------------------*/ - -/* Allocate and initialise a secondary map. */ - -static SecMap* alloc_secondary_map ( __attribute__ ((unused)) - Char* caller ) -{ - SecMap* map; - UInt i; - PROF_EVENT(10); - - /* Mark all bytes as invalid access and invalid value. */ - map = (SecMap *)VG_(shadow_alloc)(sizeof(SecMap)); - - for (i = 0; i < 8192; i++) - map->abits[i] = VGM_BYTE_INVALID; /* Invalid address */ - for (i = 0; i < 65536; i++) - map->vbyte[i] = VGM_BYTE_INVALID; /* Invalid Value */ - - /* VG_(printf)("ALLOC_2MAP(%s)\n", caller ); */ - return map; -} - - -/* Basic reading/writing of the bitmaps, for byte-sized accesses. */ - -static __inline__ UChar get_abit ( Addr a ) -{ - SecMap* sm = primary_map[a >> 16]; - UInt sm_off = a & 0xFFFF; - PROF_EVENT(20); -# if 0 - if (IS_DISTINGUISHED_SM(sm)) - VG_(message)(Vg_DebugMsg, - "accessed distinguished 2ndary (A)map! 0x%x\n", a); -# endif - return BITARR_TEST(sm->abits, sm_off) - ? VGM_BIT_INVALID : VGM_BIT_VALID; -} - -static __inline__ UChar get_vbyte ( Addr a ) -{ - SecMap* sm = primary_map[a >> 16]; - UInt sm_off = a & 0xFFFF; - PROF_EVENT(21); -# if 0 - if (IS_DISTINGUISHED_SM(sm)) - VG_(message)(Vg_DebugMsg, - "accessed distinguished 2ndary (V)map! 0x%x\n", a); -# endif - return sm->vbyte[sm_off]; -} - -static /* __inline__ */ void set_abit ( Addr a, UChar abit ) -{ - SecMap* sm; - UInt sm_off; - PROF_EVENT(22); - ENSURE_MAPPABLE(a, "set_abit"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - if (abit) - BITARR_SET(sm->abits, sm_off); - else - BITARR_CLEAR(sm->abits, sm_off); -} - -static __inline__ void set_vbyte ( Addr a, UChar vbyte ) -{ - SecMap* sm; - UInt sm_off; - PROF_EVENT(23); - ENSURE_MAPPABLE(a, "set_vbyte"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->vbyte[sm_off] = vbyte; -} - - -/* Reading/writing of the bitmaps, for aligned word-sized accesses. */ - -static __inline__ UChar get_abits4_ALIGNED ( Addr a ) -{ - SecMap* sm; - UInt sm_off; - UChar abits8; - PROF_EVENT(24); -# ifdef VG_DEBUG_MEMORY - sk_assert(IS_ALIGNED4_ADDR(a)); -# endif - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - abits8 = sm->abits[sm_off >> 3]; - abits8 >>= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - abits8 &= 0x0F; - return abits8; -} - -static UInt __inline__ get_vbytes4_ALIGNED ( Addr a ) -{ - SecMap* sm = primary_map[a >> 16]; - UInt sm_off = a & 0xFFFF; - PROF_EVENT(25); -# ifdef VG_DEBUG_MEMORY - sk_assert(IS_ALIGNED4_ADDR(a)); -# endif - return ((UInt*)(sm->vbyte))[sm_off >> 2]; -} - - -static void __inline__ set_vbytes4_ALIGNED ( Addr a, UInt vbytes ) -{ - SecMap* sm; - UInt sm_off; - ENSURE_MAPPABLE(a, "set_vbytes4_ALIGNED"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - PROF_EVENT(23); -# ifdef VG_DEBUG_MEMORY - sk_assert(IS_ALIGNED4_ADDR(a)); -# endif - ((UInt*)(sm->vbyte))[sm_off >> 2] = vbytes; -} - - -/*------------------------------------------------------------*/ -/*--- Setting permissions over address ranges. ---*/ -/*------------------------------------------------------------*/ - -static void set_address_range_perms ( Addr a, UInt len, - UInt example_a_bit, - UInt example_v_bit ) -{ - UChar vbyte, abyte8; - UInt vword4, sm_off; - SecMap* sm; - - PROF_EVENT(30); - - if (len == 0) - return; - - if (VG_(clo_verbosity) > 0) { - if (len > 100 * 1000 * 1000) { - VG_(message)(Vg_UserMsg, - "Warning: set address range perms: " - "large range %u, a %d, v %d", - len, example_a_bit, example_v_bit ); - } - } - - VGP_PUSHCC(VgpSetMem); - - /* Requests to change permissions of huge address ranges may - indicate bugs in our machinery. 30,000,000 is arbitrary, but so - far all legitimate requests have fallen beneath that size. */ - /* 4 Mar 02: this is just stupid; get rid of it. */ - /* sk_assert(len < 30000000); */ - - /* Check the permissions make sense. */ - sk_assert(example_a_bit == VGM_BIT_VALID - || example_a_bit == VGM_BIT_INVALID); - sk_assert(example_v_bit == VGM_BIT_VALID - || example_v_bit == VGM_BIT_INVALID); - if (example_a_bit == VGM_BIT_INVALID) - sk_assert(example_v_bit == VGM_BIT_INVALID); - - /* The validity bits to write. */ - vbyte = example_v_bit==VGM_BIT_VALID - ? VGM_BYTE_VALID : VGM_BYTE_INVALID; - - /* In order that we can charge through the address space at 8 - bytes/main-loop iteration, make up some perms. */ - abyte8 = (example_a_bit << 7) - | (example_a_bit << 6) - | (example_a_bit << 5) - | (example_a_bit << 4) - | (example_a_bit << 3) - | (example_a_bit << 2) - | (example_a_bit << 1) - | (example_a_bit << 0); - vword4 = (vbyte << 24) | (vbyte << 16) | (vbyte << 8) | vbyte; - -# ifdef VG_DEBUG_MEMORY - /* Do it ... */ - while (True) { - PROF_EVENT(31); - if (len == 0) break; - set_abit ( a, example_a_bit ); - set_vbyte ( a, vbyte ); - a++; - len--; - } - -# else - /* Slowly do parts preceding 8-byte alignment. */ - while (True) { - PROF_EVENT(31); - if (len == 0) break; - if ((a % 8) == 0) break; - set_abit ( a, example_a_bit ); - set_vbyte ( a, vbyte ); - a++; - len--; - } - - if (len == 0) { - VGP_POPCC(VgpSetMem); - return; - } - sk_assert((a % 8) == 0 && len > 0); - - /* Once aligned, go fast. */ - while (True) { - PROF_EVENT(32); - if (len < 8) break; - ENSURE_MAPPABLE(a, "set_address_range_perms(fast)"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = abyte8; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 0] = vword4; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 1] = vword4; - a += 8; - len -= 8; - } - - if (len == 0) { - VGP_POPCC(VgpSetMem); - return; - } - sk_assert((a % 8) == 0 && len > 0 && len < 8); - - /* Finish the upper fragment. */ - while (True) { - PROF_EVENT(33); - if (len == 0) break; - set_abit ( a, example_a_bit ); - set_vbyte ( a, vbyte ); - a++; - len--; - } -# endif - - /* Check that zero page and highest page have not been written to - -- this could happen with buggy syscall wrappers. Today - (2001-04-26) had precisely such a problem with __NR_setitimer. */ - sk_assert(SK_(cheap_sanity_check)()); - VGP_POPCC(VgpSetMem); -} - -/* Set permissions for address ranges ... */ - -void MC_(make_noaccess) ( Addr a, UInt len ) -{ - PROF_EVENT(35); - DEBUG("MC_(make_noaccess)(%p, %x)\n", a, len); - set_address_range_perms ( a, len, VGM_BIT_INVALID, VGM_BIT_INVALID ); -} - -void MC_(make_writable) ( Addr a, UInt len ) -{ - PROF_EVENT(36); - DEBUG("MC_(make_writable)(%p, %x)\n", a, len); - set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_INVALID ); -} - -void MC_(make_readable) ( Addr a, UInt len ) -{ - PROF_EVENT(37); - DEBUG("MC_(make_readable)(%p, 0x%x)\n", a, len); - set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_VALID ); -} - -static __inline__ -void make_aligned_word_writable(Addr a) -{ - SecMap* sm; - UInt sm_off; - UChar mask; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_word_writable"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - ((UInt*)(sm->vbyte))[sm_off >> 2] = VGM_WORD_INVALID; - mask = 0x0F; - mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - /* mask now contains 1s where we wish to make address bits invalid (0s). */ - sm->abits[sm_off >> 3] &= ~mask; - VGP_POPCC(VgpESPAdj); -} - -static __inline__ -void make_aligned_word_noaccess(Addr a) -{ - SecMap* sm; - UInt sm_off; - UChar mask; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_word_noaccess"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - ((UInt*)(sm->vbyte))[sm_off >> 2] = VGM_WORD_INVALID; - mask = 0x0F; - mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */ - /* mask now contains 1s where we wish to make address bits invalid (1s). */ - sm->abits[sm_off >> 3] |= mask; - VGP_POPCC(VgpESPAdj); -} - -/* Nb: by "aligned" here we mean 8-byte aligned */ -static __inline__ -void make_aligned_doubleword_writable(Addr a) -{ - SecMap* sm; - UInt sm_off; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_doubleword_writable"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = VGM_BYTE_VALID; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 0] = VGM_WORD_INVALID; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 1] = VGM_WORD_INVALID; - VGP_POPCC(VgpESPAdj); -} - -static __inline__ -void make_aligned_doubleword_noaccess(Addr a) -{ - SecMap* sm; - UInt sm_off; - - VGP_PUSHCC(VgpESPAdj); - ENSURE_MAPPABLE(a, "make_aligned_doubleword_noaccess"); - sm = primary_map[a >> 16]; - sm_off = a & 0xFFFF; - sm->abits[sm_off >> 3] = VGM_BYTE_INVALID; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 0] = VGM_WORD_INVALID; - ((UInt*)(sm->vbyte))[(sm_off >> 2) + 1] = VGM_WORD_INVALID; - VGP_POPCC(VgpESPAdj); -} - -/* The %esp update handling functions */ -ESP_UPDATE_HANDLERS ( make_aligned_word_writable, - make_aligned_word_noaccess, - make_aligned_doubleword_writable, - make_aligned_doubleword_noaccess, - MC_(make_writable), - MC_(make_noaccess) - ); - -/* Block-copy permissions (needed for implementing realloc()). */ -static void mc_copy_address_range_state ( Addr src, Addr dst, UInt len ) -{ - UInt i; - - DEBUG("mc_copy_address_range_state\n"); - - PROF_EVENT(40); - for (i = 0; i < len; i++) { - UChar abit = get_abit ( src+i ); - UChar vbyte = get_vbyte ( src+i ); - PROF_EVENT(41); - set_abit ( dst+i, abit ); - set_vbyte ( dst+i, vbyte ); - } -} - - -/* Check permissions for address range. If inadequate permissions - exist, *bad_addr is set to the offending address, so the caller can - know what it is. */ - -/* Returns True if [a .. a+len) is not addressible. Otherwise, - returns False, and if bad_addr is non-NULL, sets *bad_addr to - indicate the lowest failing address. Functions below are - similar. */ -Bool MC_(check_noaccess) ( Addr a, UInt len, Addr* bad_addr ) -{ - UInt i; - UChar abit; - PROF_EVENT(42); - for (i = 0; i < len; i++) { - PROF_EVENT(43); - abit = get_abit(a); - if (abit == VGM_BIT_VALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - a++; - } - return True; -} - -Bool MC_(check_writable) ( Addr a, UInt len, Addr* bad_addr ) -{ - UInt i; - UChar abit; - PROF_EVENT(42); - for (i = 0; i < len; i++) { - PROF_EVENT(43); - abit = get_abit(a); - if (abit == VGM_BIT_INVALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - a++; - } - return True; -} - -Bool MC_(check_readable) ( Addr a, UInt len, Addr* bad_addr ) -{ - UInt i; - UChar abit; - UChar vbyte; - - PROF_EVENT(44); - DEBUG("MC_(check_readable)\n"); - for (i = 0; i < len; i++) { - abit = get_abit(a); - vbyte = get_vbyte(a); - PROF_EVENT(45); - if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - a++; - } - return True; -} - - -/* Check a zero-terminated ascii string. Tricky -- don't want to - examine the actual bytes, to find the end, until we're sure it is - safe to do so. */ - -static Bool mc_check_readable_asciiz ( Addr a, Addr* bad_addr ) -{ - UChar abit; - UChar vbyte; - PROF_EVENT(46); - DEBUG("mc_check_readable_asciiz\n"); - while (True) { - PROF_EVENT(47); - abit = get_abit(a); - vbyte = get_vbyte(a); - if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) { - if (bad_addr != NULL) *bad_addr = a; - return False; - } - /* Ok, a is safe to read. */ - if (* ((UChar*)a) == 0) return True; - a++; - } -} - - -/*------------------------------------------------------------*/ -/*--- Memory event handlers ---*/ -/*------------------------------------------------------------*/ - -static -void mc_check_is_writable ( CorePart part, ThreadId tid, Char* s, - Addr base, UInt size ) -{ - Bool ok; - Addr bad_addr; - - VGP_PUSHCC(VgpCheckMem); - - /* VG_(message)(Vg_DebugMsg,"check is writable: %x .. %x", - base,base+size-1); */ - ok = MC_(check_writable) ( base, size, &bad_addr ); - if (!ok) { - switch (part) { - case Vg_CoreSysCall: - MAC_(record_param_error) ( tid, bad_addr, /*isWrite =*/True, s ); - break; - - case Vg_CorePThread: - case Vg_CoreSignal: - MAC_(record_core_mem_error)( tid, /*isWrite=*/True, s ); - break; - - default: - VG_(skin_panic)("mc_check_is_writable: unexpected CorePart"); - } - } - - VGP_POPCC(VgpCheckMem); -} - -static -void mc_check_is_readable ( CorePart part, ThreadId tid, Char* s, - Addr base, UInt size ) -{ - Bool ok; - Addr bad_addr; - - VGP_PUSHCC(VgpCheckMem); - - /* VG_(message)(Vg_DebugMsg,"check is readable: %x .. %x", - base,base+size-1); */ - ok = MC_(check_readable) ( base, size, &bad_addr ); - if (!ok) { - switch (part) { - case Vg_CoreSysCall: - MAC_(record_param_error) ( tid, bad_addr, /*isWrite =*/False, s ); - break; - - case Vg_CorePThread: - MAC_(record_core_mem_error)( tid, /*isWrite=*/False, s ); - break; - - /* If we're being asked to jump to a silly address, record an error - message before potentially crashing the entire system. */ - case Vg_CoreTranslate: - MAC_(record_jump_error)( tid, bad_addr ); - break; - - default: - VG_(skin_panic)("mc_check_is_readable: unexpected CorePart"); - } - } - VGP_POPCC(VgpCheckMem); -} - -static -void mc_check_is_readable_asciiz ( CorePart part, ThreadId tid, - Char* s, Addr str ) -{ - Bool ok = True; - Addr bad_addr; - /* VG_(message)(Vg_DebugMsg,"check is readable asciiz: 0x%x",str); */ - - VGP_PUSHCC(VgpCheckMem); - - sk_assert(part == Vg_CoreSysCall); - ok = mc_check_readable_asciiz ( (Addr)str, &bad_addr ); - if (!ok) { - MAC_(record_param_error) ( tid, bad_addr, /*is_writable =*/False, s ); - } - - VGP_POPCC(VgpCheckMem); -} - - -static -void mc_new_mem_startup( Addr a, UInt len, Bool rr, Bool ww, Bool xx ) -{ - /* Ignore the permissions, just make it readable. Seems to work... */ - DEBUG("mc_new_mem_startup(%p, %u, rr=%u, ww=%u, xx=%u)\n", a,len,rr,ww,xx); - MC_(make_readable)(a, len); -} - -static -void mc_new_mem_heap ( Addr a, UInt len, Bool is_inited ) -{ - if (is_inited) { - MC_(make_readable)(a, len); - } else { - MC_(make_writable)(a, len); - } -} - -static -void mc_set_perms (Addr a, UInt len, Bool rr, Bool ww, Bool xx) -{ - DEBUG("mc_set_perms(%p, %u, rr=%u ww=%u, xx=%u)\n", a, len, rr, ww, xx); - if (rr) MC_(make_readable)(a, len); - else if (ww) MC_(make_writable)(a, len); - else MC_(make_noaccess)(a, len); -} - - -/*------------------------------------------------------------*/ -/*--- Register event handlers ---*/ -/*------------------------------------------------------------*/ - -static void mc_post_regs_write_init ( void ) -{ -#if 0 - UInt i; - for (i = FIRST_ARCH_REG; i <= LAST_ARCH_REG; i++) - VG_(set_shadow_archreg)( i, VGM_WORD_VALID ); - VG_(set_shadow_eflags)( VGM_EFLAGS_VALID ); -#else - //VG_(printf)("mc_post_regs_write_init()\n"); -#endif -} - -static void mc_post_reg_write(ThreadId tid, UInt reg) -{ - VG_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID ); -} - -static void mc_post_reg_write_clientcall(ThreadId tid, UInt reg, Addr f ) -{ - VG_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID ); -} - - -/*------------------------------------------------------------*/ -/*--- Functions called directly from generated code. ---*/ -/*------------------------------------------------------------*/ - -static __inline__ UInt rotateRight16 ( UInt x ) -{ - /* Amazingly, gcc turns this into a single rotate insn. */ - return (x >> 16) | (x << 16); -} - - -static __inline__ UInt shiftRight16 ( UInt x ) -{ - return x >> 16; -} - - -/* Read/write 1/2/4/8 sized V bytes, and emit an address error if - needed. */ - -/* MC_(helperc_{LD,ST}V{1,2,4,8}) handle the common case fast. - Under all other circumstances, it defers to the relevant _SLOWLY - function, which can handle all situations. -*/ - -/* ------------------------ Size = 8 ------------------------ */ - -REGPARM(1) -ULong MC_(helperc_LOADV8) ( Addr a ) -{ -# ifdef VG_DEBUG_MEMORY - return mc_rd_V8_SLOWLY(a); -# else - if (IS_ALIGNED8_ADDR(a)) { - UInt sec_no = shiftRight16(a) & 0xFFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - UChar abits = sm->abits[a_off]; - if (abits == VGM_BYTE_VALID) { - /* a is 8-aligned, mapped, and addressible. */ - UInt v_off = a & 0xFFFF; - /* LITTLE-ENDIAN */ - UInt vLo = ((UInt*)(sm->vbyte))[ (v_off >> 2) ]; - UInt vHi = ((UInt*)(sm->vbyte))[ (v_off >> 2) + 1 ]; - return ( ((ULong)vHi) << 32 ) | ((ULong)vLo); - } else { - return mc_rd_V8_SLOWLY(a); - } - } - else - if (IS_ALIGNED4_ADDR(a)) { - /* LITTLE-ENDIAN */ - UInt vLo = MC_(helperc_LOADV4)(a+0); - UInt vHi = MC_(helperc_LOADV4)(a+4); - return ( ((ULong)vHi) << 32 ) | ((ULong)vLo); - } - else - return mc_rd_V8_SLOWLY(a); -# endif -} - -REGPARM(1) -void MC_(helperc_STOREV8) ( Addr a, ULong vbytes ) -{ -# ifdef VG_DEBUG_MEMORY - mc_wr_V8_SLOWLY(a, vbytes); -# else - if (IS_ALIGNED8_ADDR(a)) { - UInt sec_no = shiftRight16(a) & 0xFFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - UChar abits = sm->abits[a_off]; - if (abits == VGM_BYTE_VALID) { - /* a is 8-aligned, mapped, and addressible. */ - UInt v_off = a & 0xFFFF; - UInt vHi = (UInt)(vbytes >> 32); - UInt vLo = (UInt)vbytes; - /* LITTLE-ENDIAN */ - ((UInt*)(sm->vbyte))[ (v_off >> 2) ] = vLo; - ((UInt*)(sm->vbyte))[ (v_off >> 2) + 1 ] = vHi; - } else { - mc_wr_V8_SLOWLY(a, vbytes); - } - return; - } - else - if (IS_ALIGNED4_ADDR(a)) { - UInt vHi = (UInt)(vbytes >> 32); - UInt vLo = (UInt)vbytes; - /* LITTLE-ENDIAN */ - MC_(helperc_STOREV4)(a+0, vLo); - MC_(helperc_STOREV4)(a+4, vHi); - return; - } - else - mc_wr_V8_SLOWLY(a, vbytes); -# endif -} - -/* ------------------------ Size = 4 ------------------------ */ - -REGPARM(1) -UInt MC_(helperc_LOADV4) ( Addr a ) -{ -# ifdef VG_DEBUG_MEMORY - return mc_rd_V4_SLOWLY(a); -# else - UInt sec_no = rotateRight16(a) & 0x3FFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - UChar abits = sm->abits[a_off]; - abits >>= (a & 4); - abits &= 15; - PROF_EVENT(60); - if (abits == VGM_NIBBLE_VALID) { - /* Handle common case quickly: a is suitably aligned, is mapped, - and is addressible. */ - UInt v_off = a & 0xFFFF; - return ((UInt*)(sm->vbyte))[ v_off >> 2 ]; - } else { - /* Slow but general case. */ - return mc_rd_V4_SLOWLY(a); - } -# endif -} - -REGPARM(2) -void MC_(helperc_STOREV4) ( Addr a, UInt vbytes ) -{ -# ifdef VG_DEBUG_MEMORY - mc_wr_V4_SLOWLY(a, vbytes); -# else - UInt sec_no = rotateRight16(a) & 0x3FFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - UChar abits = sm->abits[a_off]; - abits >>= (a & 4); - abits &= 15; - PROF_EVENT(61); - if (abits == VGM_NIBBLE_VALID) { - /* Handle common case quickly: a is suitably aligned, is mapped, - and is addressible. */ - UInt v_off = a & 0xFFFF; - ((UInt*)(sm->vbyte))[ v_off >> 2 ] = vbytes; - } else { - /* Slow but general case. */ - mc_wr_V4_SLOWLY(a, vbytes); - } -# endif -} - -/* ------------------------ Size = 2 ------------------------ */ - -REGPARM(1) -UInt MC_(helperc_LOADV2) ( Addr a ) -{ -# ifdef VG_DEBUG_MEMORY - return mc_rd_V2_SLOWLY(a); -# else - UInt sec_no = rotateRight16(a) & 0x1FFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(62); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - UInt v_off = a & 0xFFFF; - return 0xFFFF0000 - | - (UInt)( ((UShort*)(sm->vbyte))[ v_off >> 1 ] ); - } else { - /* Slow but general case. */ - return mc_rd_V2_SLOWLY(a); - } -# endif -} - -REGPARM(2) -void MC_(helperc_STOREV2) ( Addr a, UInt vbytes ) -{ -# ifdef VG_DEBUG_MEMORY - mc_wr_V2_SLOWLY(a, vbytes); -# else - UInt sec_no = rotateRight16(a) & 0x1FFFF; - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(63); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - UInt v_off = a & 0xFFFF; - ((UShort*)(sm->vbyte))[ v_off >> 1 ] = vbytes & 0x0000FFFF; - } else { - /* Slow but general case. */ - mc_wr_V2_SLOWLY(a, vbytes); - } -# endif -} - -/* ------------------------ Size = 1 ------------------------ */ - -REGPARM(1) -UInt MC_(helperc_LOADV1) ( Addr a ) -{ -# ifdef VG_DEBUG_MEMORY - return mc_rd_V1_SLOWLY(a); -# else - UInt sec_no = shiftRight16(a); - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(64); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - UInt v_off = a & 0xFFFF; - return 0xFFFFFF00 - | - (UInt)( ((UChar*)(sm->vbyte))[ v_off ] ); - } else { - /* Slow but general case. */ - return mc_rd_V1_SLOWLY(a); - } -# endif -} - -REGPARM(2) -void MC_(helperc_STOREV1) ( Addr a, UInt vbytes ) -{ -# ifdef VG_DEBUG_MEMORY - mc_wr_V1_SLOWLY(a, vbytes); -# else - UInt sec_no = shiftRight16(a); - SecMap* sm = primary_map[sec_no]; - UInt a_off = (a & 0xFFFF) >> 3; - PROF_EVENT(65); - if (sm->abits[a_off] == VGM_BYTE_VALID) { - /* Handle common case quickly. */ - UInt v_off = a & 0xFFFF; - ((UChar*)(sm->vbyte))[ v_off ] = vbytes & 0x000000FF; - } else { - /* Slow but general case. */ - mc_wr_V1_SLOWLY(a, vbytes); - } -# endif -} - - -/*------------------------------------------------------------*/ -/*--- Fallback functions to handle cases that the above ---*/ -/*--- MC_(helperc_{LD,ST}V{1,2,4,8}) can't manage. ---*/ -/*------------------------------------------------------------*/ - -/* ------------------------ Size = 8 ------------------------ */ - -static ULong mc_rd_V8_SLOWLY ( Addr a ) -{ - Bool a0ok, a1ok, a2ok, a3ok, a4ok, a5ok, a6ok, a7ok; - UInt vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7; - - PROF_EVENT(70); - - /* First establish independently the addressibility of the 4 bytes - involved. */ - a0ok = get_abit(a+0) == VGM_BIT_VALID; - a1ok = get_abit(a+1) == VGM_BIT_VALID; - a2ok = get_abit(a+2) == VGM_BIT_VALID; - a3ok = get_abit(a+3) == VGM_BIT_VALID; - a4ok = get_abit(a+4) == VGM_BIT_VALID; - a5ok = get_abit(a+5) == VGM_BIT_VALID; - a6ok = get_abit(a+6) == VGM_BIT_VALID; - a7ok = get_abit(a+7) == VGM_BIT_VALID; - - /* Also get the validity bytes for the address. */ - vb0 = (UInt)get_vbyte(a+0); - vb1 = (UInt)get_vbyte(a+1); - vb2 = (UInt)get_vbyte(a+2); - vb3 = (UInt)get_vbyte(a+3); - vb4 = (UInt)get_vbyte(a+4); - vb5 = (UInt)get_vbyte(a+5); - vb6 = (UInt)get_vbyte(a+6); - vb7 = (UInt)get_vbyte(a+7); - - /* Now distinguish 3 cases */ - - /* Case 1: the address is completely valid, so: - - no addressing error - - return V bytes as read from memory - */ - if (a0ok && a1ok && a2ok && a3ok && a4ok && a5ok && a6ok && a7ok) { - ULong vw = VGM_WORD64_INVALID; - vw <<= 8; vw |= vb7; - vw <<= 8; vw |= vb6; - vw <<= 8; vw |= vb5; - vw <<= 8; vw |= vb4; - vw <<= 8; vw |= vb3; - vw <<= 8; vw |= vb2; - vw <<= 8; vw |= vb1; - vw <<= 8; vw |= vb0; - return vw; - } - - /* Case 2: the address is completely invalid. - - emit addressing error - - return V word indicating validity. - This sounds strange, but if we make loads from invalid addresses - give invalid data, we also risk producing a number of confusing - undefined-value errors later, which confuses the fact that the - error arose in the first place from an invalid address. - */ - /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok); */ - if (!MAC_(clo_partial_loads_ok) - || ((a & 7) != 0) - || (!a0ok && !a1ok && !a2ok && !a3ok && !a4ok && !a5ok && !a6ok && !a7ok)) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 8, False ); - return VGM_WORD64_VALID; - } - - /* Case 3: the address is partially valid. - - no addressing error - - returned V word is invalid where the address is invalid, - and contains V bytes from memory otherwise. - Case 3 is only allowed if MC_(clo_partial_loads_ok) is True - (which is the default), and the address is 4-aligned. - If not, Case 2 will have applied. - */ - sk_assert(MAC_(clo_partial_loads_ok)); - { - ULong vw = VGM_WORD64_INVALID; - vw <<= 8; vw |= (a7ok ? vb7 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a6ok ? vb6 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a5ok ? vb5 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a4ok ? vb4 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a3ok ? vb3 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a2ok ? vb2 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a1ok ? vb1 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a0ok ? vb0 : VGM_BYTE_INVALID); - return vw; - } -} - -static void mc_wr_V8_SLOWLY ( Addr a, ULong vbytes ) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(71); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+1) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+2) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+3) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+4) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+5) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+6) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+7) != VGM_BIT_VALID) aerr = True; - - /* Store the V bytes, remembering to do it little-endian-ly. */ - set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+1, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+2, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+3, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+4, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+5, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+6, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+7, vbytes & 0x000000FF ); - - /* If an address error has happened, report it. */ - if (aerr) - MAC_(record_address_error)( VG_(get_current_tid)(), a, 8, True ); -} - -/* ------------------------ Size = 4 ------------------------ */ - -static UInt mc_rd_V4_SLOWLY ( Addr a ) -{ - Bool a0ok, a1ok, a2ok, a3ok; - UInt vb0, vb1, vb2, vb3; - - PROF_EVENT(70); - - /* First establish independently the addressibility of the 4 bytes - involved. */ - a0ok = get_abit(a+0) == VGM_BIT_VALID; - a1ok = get_abit(a+1) == VGM_BIT_VALID; - a2ok = get_abit(a+2) == VGM_BIT_VALID; - a3ok = get_abit(a+3) == VGM_BIT_VALID; - - /* Also get the validity bytes for the address. */ - vb0 = (UInt)get_vbyte(a+0); - vb1 = (UInt)get_vbyte(a+1); - vb2 = (UInt)get_vbyte(a+2); - vb3 = (UInt)get_vbyte(a+3); - - /* Now distinguish 3 cases */ - - /* Case 1: the address is completely valid, so: - - no addressing error - - return V bytes as read from memory - */ - if (a0ok && a1ok && a2ok && a3ok) { - UInt vw = VGM_WORD_INVALID; - vw <<= 8; vw |= vb3; - vw <<= 8; vw |= vb2; - vw <<= 8; vw |= vb1; - vw <<= 8; vw |= vb0; - return vw; - } - - /* Case 2: the address is completely invalid. - - emit addressing error - - return V word indicating validity. - This sounds strange, but if we make loads from invalid addresses - give invalid data, we also risk producing a number of confusing - undefined-value errors later, which confuses the fact that the - error arose in the first place from an invalid address. - */ - /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok); */ - if (!MAC_(clo_partial_loads_ok) - || ((a & 3) != 0) - || (!a0ok && !a1ok && !a2ok && !a3ok)) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 4, False ); - return (VGM_BYTE_VALID << 24) | (VGM_BYTE_VALID << 16) - | (VGM_BYTE_VALID << 8) | VGM_BYTE_VALID; - } - - /* Case 3: the address is partially valid. - - no addressing error - - returned V word is invalid where the address is invalid, - and contains V bytes from memory otherwise. - Case 3 is only allowed if MC_(clo_partial_loads_ok) is True - (which is the default), and the address is 4-aligned. - If not, Case 2 will have applied. - */ - sk_assert(MAC_(clo_partial_loads_ok)); - { - UInt vw = VGM_WORD_INVALID; - vw <<= 8; vw |= (a3ok ? vb3 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a2ok ? vb2 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a1ok ? vb1 : VGM_BYTE_INVALID); - vw <<= 8; vw |= (a0ok ? vb0 : VGM_BYTE_INVALID); - return vw; - } -} - -static void mc_wr_V4_SLOWLY ( Addr a, UInt vbytes ) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(71); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+1) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+2) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+3) != VGM_BIT_VALID) aerr = True; - - /* Store the V bytes, remembering to do it little-endian-ly. */ - set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+1, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+2, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+3, vbytes & 0x000000FF ); - - /* If an address error has happened, report it. */ - if (aerr) - MAC_(record_address_error)( VG_(get_current_tid)(), a, 4, True ); -} - -/* ------------------------ Size = 2 ------------------------ */ - -static UInt mc_rd_V2_SLOWLY ( Addr a ) -{ - /* Check the address for validity. */ - UInt vw = VGM_WORD_INVALID; - Bool aerr = False; - PROF_EVENT(72); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+1) != VGM_BIT_VALID) aerr = True; - - /* Fetch the V bytes, remembering to do it little-endian-ly. */ - vw <<= 8; vw |= (UInt)get_vbyte(a+1); - vw <<= 8; vw |= (UInt)get_vbyte(a+0); - - /* If an address error has happened, report it. */ - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 2, False ); - vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16) - | (VGM_BYTE_VALID << 8) | (VGM_BYTE_VALID); - } - return vw; -} - -static void mc_wr_V2_SLOWLY ( Addr a, UInt vbytes ) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(73); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - if (get_abit(a+1) != VGM_BIT_VALID) aerr = True; - - /* Store the V bytes, remembering to do it little-endian-ly. */ - set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>= 8; - set_vbyte( a+1, vbytes & 0x000000FF ); - - /* If an address error has happened, report it. */ - if (aerr) - MAC_(record_address_error)( VG_(get_current_tid)(), a, 2, True ); -} - -/* ------------------------ Size = 1 ------------------------ */ - -static UInt mc_rd_V1_SLOWLY ( Addr a ) -{ - /* Check the address for validity. */ - UInt vw = VGM_WORD_INVALID; - Bool aerr = False; - PROF_EVENT(74); - - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - - /* Fetch the V byte. */ - vw <<= 8; vw |= (UInt)get_vbyte(a+0); - - /* If an address error has happened, report it. */ - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), a, 1, False ); - vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16) - | (VGM_BYTE_INVALID << 8) | (VGM_BYTE_VALID); - } - return vw; -} - -static void mc_wr_V1_SLOWLY ( Addr a, UInt vbytes ) -{ - /* Check the address for validity. */ - Bool aerr = False; - PROF_EVENT(75); - if (get_abit(a+0) != VGM_BIT_VALID) aerr = True; - - /* Store the V bytes, remembering to do it little-endian-ly. */ - set_vbyte( a+0, vbytes & 0x000000FF ); - - /* If an address error has happened, report it. */ - if (aerr) - MAC_(record_address_error)( VG_(get_current_tid)(), a, 1, True ); -} - - -/* --------------------------------------------------------------------- - Called from generated code, or from the assembly helpers. - Handlers for value check failures. - ------------------------------------------------------------------ */ - -void MC_(helperc_value_check0_fail) ( void ) -{ - MC_(record_value_error) ( VG_(get_current_tid)(), 0 ); -} - -void MC_(helperc_value_check1_fail) ( void ) -{ - MC_(record_value_error) ( VG_(get_current_tid)(), 1 ); -} - -void MC_(helperc_value_check2_fail) ( void ) -{ - MC_(record_value_error) ( VG_(get_current_tid)(), 2 ); -} - -void MC_(helperc_value_check4_fail) ( void ) -{ - MC_(record_value_error) ( VG_(get_current_tid)(), 4 ); -} - -REGPARM(1) void MC_(helperc_complain_undef) ( HWord sz ) -{ - MC_(record_value_error) ( VG_(get_current_tid)(), (Int)sz ); -} - - -/* --------------------------------------------------------------------- - FPU load and store checks, called from generated code. - ------------------------------------------------------------------ */ - -REGPARM(2) -void MC_(fpu_read_check) ( Addr addr, Int size ) -{ - /* Ensure the read area is both addressible and valid (ie, - readable). If there's an address error, don't report a value - error too; but if there isn't an address error, check for a - value error. - - Try to be reasonably fast on the common case; wimp out and defer - to mc_fpu_read_check_SLOWLY for everything else. */ - - SecMap* sm; - UInt sm_off, v_off, a_off; - Addr addr4; - - PROF_EVENT(80); - -# ifdef VG_DEBUG_MEMORY - mc_fpu_read_check_SLOWLY ( addr, size ); -# else - - if (size == 4) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow4; - PROF_EVENT(81); - /* Properly aligned. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow4; - /* Properly aligned and addressible. */ - v_off = addr & 0xFFFF; - if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID) - goto slow4; - /* Properly aligned, addressible and with valid data. */ - return; - slow4: - mc_fpu_read_check_SLOWLY ( addr, 4 ); - return; - } - - if (size == 8) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow8; - PROF_EVENT(82); - /* Properly aligned. Do it in two halves. */ - addr4 = addr + 4; - /* First half. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* First half properly aligned and addressible. */ - v_off = addr & 0xFFFF; - if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID) - goto slow8; - /* Second half. */ - sm = primary_map[addr4 >> 16]; - sm_off = addr4 & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* Second half properly aligned and addressible. */ - v_off = addr4 & 0xFFFF; - if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID) - goto slow8; - /* Both halves properly aligned, addressible and with valid - data. */ - return; - slow8: - mc_fpu_read_check_SLOWLY ( addr, 8 ); - return; - } - - /* Can't be bothered to huff'n'puff to make these (allegedly) rare - cases go quickly. */ - if (size == 2) { - PROF_EVENT(83); - mc_fpu_read_check_SLOWLY ( addr, 2 ); - return; - } - - if (size == 16 /*SSE*/ - || size == 10 || size == 28 || size == 108 || size == 512) { - PROF_EVENT(84); - mc_fpu_read_check_SLOWLY ( addr, size ); - return; - } - - VG_(printf)("size is %d\n", size); - VG_(skin_panic)("MC_(fpu_read_check): unhandled size"); -# endif -} - - -REGPARM(2) -void MC_(fpu_write_check) ( Addr addr, Int size ) -{ - /* Ensure the written area is addressible, and moan if otherwise. - If it is addressible, make it valid, otherwise invalid. - */ - - SecMap* sm; - UInt sm_off, v_off, a_off; - Addr addr4; - - PROF_EVENT(85); - -# ifdef VG_DEBUG_MEMORY - mc_fpu_write_check_SLOWLY ( addr, size ); -# else - - if (size == 4) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow4; - PROF_EVENT(86); - /* Properly aligned. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow4; - /* Properly aligned and addressible. Make valid. */ - v_off = addr & 0xFFFF; - ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID; - return; - slow4: - mc_fpu_write_check_SLOWLY ( addr, 4 ); - return; - } - - if (size == 8) { - if (!IS_ALIGNED4_ADDR(addr)) goto slow8; - PROF_EVENT(87); - /* Properly aligned. Do it in two halves. */ - addr4 = addr + 4; - /* First half. */ - sm = primary_map[addr >> 16]; - sm_off = addr & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* First half properly aligned and addressible. Make valid. */ - v_off = addr & 0xFFFF; - ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID; - /* Second half. */ - sm = primary_map[addr4 >> 16]; - sm_off = addr4 & 0xFFFF; - a_off = sm_off >> 3; - if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8; - /* Second half properly aligned and addressible. */ - v_off = addr4 & 0xFFFF; - ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID; - /* Properly aligned, addressible and with valid data. */ - return; - slow8: - mc_fpu_write_check_SLOWLY ( addr, 8 ); - return; - } - - /* Can't be bothered to huff'n'puff to make these (allegedly) rare - cases go quickly. */ - if (size == 2) { - PROF_EVENT(88); - mc_fpu_write_check_SLOWLY ( addr, 2 ); - return; - } - - if (size == 16 /*SSE*/ - || size == 10 || size == 28 || size == 108 || size == 512) { - PROF_EVENT(89); - mc_fpu_write_check_SLOWLY ( addr, size ); - return; - } - - VG_(printf)("size is %d\n", size); - VG_(skin_panic)("MC_(fpu_write_check): unhandled size"); -# endif -} - - -/* --------------------------------------------------------------------- - Slow, general cases for FPU load and store checks. - ------------------------------------------------------------------ */ - -/* Generic version. Test for both addr and value errors, but if - there's an addr error, don't report a value error even if it - exists. */ - -void mc_fpu_read_check_SLOWLY ( Addr addr, Int size ) -{ - Int i; - Bool aerr = False; - Bool verr = False; - PROF_EVENT(90); - for (i = 0; i < size; i++) { - PROF_EVENT(91); - if (get_abit(addr+i) != VGM_BIT_VALID) - aerr = True; - if (get_vbyte(addr+i) != VGM_BYTE_VALID) - verr = True; - } - - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), addr, size, False ); - } else { - if (verr) - MC_(record_value_error)( VG_(get_current_tid)(), size ); - } -} - - -/* Generic version. Test for addr errors. Valid addresses are - given valid values, and invalid addresses invalid values. */ - -void mc_fpu_write_check_SLOWLY ( Addr addr, Int size ) -{ - Int i; - Addr a_here; - Bool a_ok; - Bool aerr = False; - PROF_EVENT(92); - for (i = 0; i < size; i++) { - PROF_EVENT(93); - a_here = addr+i; - a_ok = get_abit(a_here) == VGM_BIT_VALID; - if (a_ok) { - set_vbyte(a_here, VGM_BYTE_VALID); - } else { - set_vbyte(a_here, VGM_BYTE_INVALID); - aerr = True; - } - } - if (aerr) { - MAC_(record_address_error)( VG_(get_current_tid)(), addr, size, True ); - } -} - - -/*------------------------------------------------------------*/ -/*--- Metadata get/set functions, for client requests. ---*/ -/*------------------------------------------------------------*/ - -/* Copy Vbits for src into vbits. Returns: 1 == OK, 2 == alignment - error, 3 == addressing error. */ -Int MC_(get_or_set_vbits_for_client) ( - ThreadId tid, - Addr dataV, - Addr vbitsV, - UInt size, - Bool setting /* True <=> set vbits, False <=> get vbits */ -) -{ - Bool addressibleD = True; - Bool addressibleV = True; - UInt* data = (UInt*)dataV; - UInt* vbits = (UInt*)vbitsV; - UInt szW = size / 4; /* sigh */ - UInt i; - UInt* dataP = NULL; /* bogus init to keep gcc happy */ - UInt* vbitsP = NULL; /* ditto */ - - /* Check alignment of args. */ - if (!(IS_ALIGNED4_ADDR(data) && IS_ALIGNED4_ADDR(vbits))) - return 2; - if ((size & 3) != 0) - return 2; - - /* Check that arrays are addressible. */ - for (i = 0; i < szW; i++) { - dataP = &data[i]; - vbitsP = &vbits[i]; - if (get_abits4_ALIGNED((Addr)dataP) != VGM_NIBBLE_VALID) { - addressibleD = False; - break; - } - if (get_abits4_ALIGNED((Addr)vbitsP) != VGM_NIBBLE_VALID) { - addressibleV = False; - break; - } - } - if (!addressibleD) { - MAC_(record_address_error)( tid, (Addr)dataP, 4, - setting ? True : False ); - return 3; - } - if (!addressibleV) { - MAC_(record_address_error)( tid, (Addr)vbitsP, 4, - setting ? False : True ); - return 3; - } - - /* Do the copy */ - if (setting) { - /* setting */ - for (i = 0; i < szW; i++) { - if (get_vbytes4_ALIGNED( (Addr)&vbits[i] ) != VGM_WORD_VALID) - MC_(record_value_error)(tid, 4); - set_vbytes4_ALIGNED( (Addr)&data[i], vbits[i] ); - } - } else { - /* getting */ - for (i = 0; i < szW; i++) { - vbits[i] = get_vbytes4_ALIGNED( (Addr)&data[i] ); - set_vbytes4_ALIGNED( (Addr)&vbits[i], VGM_WORD_VALID ); - } - } - - return 1; -} - - -/*------------------------------------------------------------*/ -/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/ -/*------------------------------------------------------------*/ - -/* For the memory leak detector, say whether an entire 64k chunk of - address space is possibly in use, or not. If in doubt return - True. -*/ -static -Bool mc_is_valid_64k_chunk ( UInt chunk_number ) -{ - sk_assert(chunk_number >= 0 && chunk_number < 65536); - if (IS_DISTINGUISHED_SM(primary_map[chunk_number])) { - /* Definitely not in use. */ - return False; - } else { - return True; - } -} - - -/* For the memory leak detector, say whether or not a given word - address is to be regarded as valid. */ -static -Bool mc_is_valid_address ( Addr a ) -{ - UInt vbytes; - UChar abits; - sk_assert(IS_ALIGNED4_ADDR(a)); - abits = get_abits4_ALIGNED(a); - vbytes = get_vbytes4_ALIGNED(a); - if (abits == VGM_NIBBLE_VALID && vbytes == VGM_WORD_VALID) { - return True; - } else { - return False; - } -} - - -/* Leak detector for this tool. We don't actually do anything, merely - run the generic leak detector with suitable parameters for this - tool. */ -void MC_(detect_memory_leaks) ( void ) -{ - MAC_(do_detect_memory_leaks) ( mc_is_valid_64k_chunk, mc_is_valid_address ); -} - - -/* --------------------------------------------------------------------- - Sanity check machinery (permanently engaged). - ------------------------------------------------------------------ */ - -Bool SK_(cheap_sanity_check) ( void ) -{ - /* nothing useful we can rapidly check */ - return True; -} - -Bool SK_(expensive_sanity_check) ( void ) -{ - Int i; - - /* Make sure nobody changed the distinguished secondary. */ - for (i = 0; i < 8192; i++) - if (distinguished_secondary_map.abits[i] != VGM_BYTE_INVALID) - return False; - - for (i = 0; i < 65536; i++) - if (distinguished_secondary_map.vbyte[i] != VGM_BYTE_INVALID) - return False; - - /* Make sure that the upper 3/4 of the primary map hasn't - been messed with. */ - for (i = 65536; i < 262144; i++) - if (primary_map[i] != & distinguished_secondary_map) - return False; - - return True; -} - -/* --------------------------------------------------------------------- - Debugging machinery (turn on to debug). Something of a mess. - ------------------------------------------------------------------ */ - -#if 0 -/* Print the value tags on the 8 integer registers & flag reg. */ - -static void uint_to_bits ( UInt x, Char* str ) -{ - Int i; - Int w = 0; - /* str must point to a space of at least 36 bytes. */ - for (i = 31; i >= 0; i--) { - str[w++] = (x & ( ((UInt)1) << i)) ? '1' : '0'; - if (i == 24 || i == 16 || i == 8) - str[w++] = ' '; - } - str[w++] = 0; - sk_assert(w == 36); -} - -/* Caution! Not vthread-safe; looks in VG_(baseBlock), not the thread - state table. */ - -static void vg_show_reg_tags ( void ) -{ - Char buf1[36]; - Char buf2[36]; - UInt z_eax, z_ebx, z_ecx, z_edx, - z_esi, z_edi, z_ebp, z_esp, z_eflags; - - z_eax = VG_(baseBlock)[VGOFF_(sh_eax)]; - z_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)]; - z_ecx = VG_(baseBlock)[VGOFF_(sh_ecx)]; - z_edx = VG_(baseBlock)[VGOFF_(sh_edx)]; - z_esi = VG_(baseBlock)[VGOFF_(sh_esi)]; - z_edi = VG_(baseBlock)[VGOFF_(sh_edi)]; - z_ebp = VG_(baseBlock)[VGOFF_(sh_ebp)]; - z_esp = VG_(baseBlock)[VGOFF_(sh_esp)]; - z_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)]; - - uint_to_bits(z_eflags, buf1); - VG_(message)(Vg_DebugMsg, "efl %s\n", buf1); - - uint_to_bits(z_eax, buf1); - uint_to_bits(z_ebx, buf2); - VG_(message)(Vg_DebugMsg, "eax %s ebx %s\n", buf1, buf2); - - uint_to_bits(z_ecx, buf1); - uint_to_bits(z_edx, buf2); - VG_(message)(Vg_DebugMsg, "ecx %s edx %s\n", buf1, buf2); - - uint_to_bits(z_esi, buf1); - uint_to_bits(z_edi, buf2); - VG_(message)(Vg_DebugMsg, "esi %s edi %s\n", buf1, buf2); - - uint_to_bits(z_ebp, buf1); - uint_to_bits(z_esp, buf2); - VG_(message)(Vg_DebugMsg, "ebp %s esp %s\n", buf1, buf2); -} - - -/* For debugging only. Scan the address space and touch all allegedly - addressible words. Useful for establishing where Valgrind's idea of - addressibility has diverged from what the kernel believes. */ - -static -void zzzmemscan_notify_word ( Addr a, UInt w ) -{ -} - -void zzzmemscan ( void ) -{ - Int n_notifies - = VG_(scan_all_valid_memory)( zzzmemscan_notify_word ); - VG_(printf)("zzzmemscan: n_bytes = %d\n", 4 * n_notifies ); -} -#endif - - - - -#if 0 -static Int zzz = 0; - -void show_bb ( Addr eip_next ) -{ - VG_(printf)("[%4d] ", zzz); - vg_show_reg_tags( &VG_(m_shadow ); - VG_(translate) ( eip_next, NULL, NULL, NULL ); -} -#endif /* 0 */ - - -/*------------------------------------------------------------*/ -/*--- Command line args ---*/ -/*------------------------------------------------------------*/ - -Bool MC_(clo_avoid_strlen_errors) = True; -Bool MC_(clo_cleanup) = True; - -Bool SK_(process_cmd_line_option)(Char* arg) -{ - VG_BOOL_CLO("--avoid-strlen-errors", MC_(clo_avoid_strlen_errors)) - else VG_BOOL_CLO("--cleanup", MC_(clo_cleanup)) - else - return MAC_(process_common_cmd_line_option)(arg); - - return True; -} - -void SK_(print_usage)(void) -{ - MAC_(print_common_usage)(); - VG_(printf)( -" --avoid-strlen-errors=no|yes suppress errs from inlined strlen [yes]\n" - ); -} - -void SK_(print_debug_usage)(void) -{ - MAC_(print_common_debug_usage)(); - VG_(printf)( -" --cleanup=no|yes improve after instrumentation? [yes]\n" - ); -} - - -/*------------------------------------------------------------*/ -/*--- Setup ---*/ -/*------------------------------------------------------------*/ - -void SK_(pre_clo_init)(void) -{ - VG_(details_name) ("Memcheck"); - VG_(details_version) (NULL); - VG_(details_description) ("a memory error detector"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - VG_(details_avg_translation_sizeB) ( 228 ); - - VG_(needs_core_errors) (); - VG_(needs_skin_errors) (); - VG_(needs_libc_freeres) (); - VG_(needs_shadow_regs) (); - VG_(needs_command_line_options)(); - VG_(needs_client_requests) (); - VG_(needs_extended_UCode) (); - VG_(needs_syscall_wrapper) (); - VG_(needs_sanity_checks) (); - VG_(needs_shadow_memory) (); - - MAC_( new_mem_heap) = & mc_new_mem_heap; - MAC_( ban_mem_heap) = & MC_(make_noaccess); - MAC_(copy_mem_heap) = & mc_copy_address_range_state; - MAC_( die_mem_heap) = & MC_(make_noaccess); - MAC_(check_noaccess) = & MC_(check_noaccess); - - VG_(init_new_mem_startup) ( & mc_new_mem_startup ); - VG_(init_new_mem_stack_signal) ( & MC_(make_writable) ); - VG_(init_new_mem_brk) ( & MC_(make_writable) ); - VG_(init_new_mem_mmap) ( & mc_set_perms ); - - VG_(init_copy_mem_remap) ( & mc_copy_address_range_state ); - VG_(init_change_mem_mprotect) ( & mc_set_perms ); - - VG_(init_die_mem_stack_signal) ( & MC_(make_noaccess) ); - VG_(init_die_mem_brk) ( & MC_(make_noaccess) ); - VG_(init_die_mem_munmap) ( & MC_(make_noaccess) ); - - VG_(init_new_mem_stack_4) ( & MAC_(new_mem_stack_4) ); - VG_(init_new_mem_stack_8) ( & MAC_(new_mem_stack_8) ); - VG_(init_new_mem_stack_12) ( & MAC_(new_mem_stack_12) ); - VG_(init_new_mem_stack_16) ( & MAC_(new_mem_stack_16) ); - VG_(init_new_mem_stack_32) ( & MAC_(new_mem_stack_32) ); - VG_(init_new_mem_stack) ( & MAC_(new_mem_stack) ); - - VG_(init_die_mem_stack_4) ( & MAC_(die_mem_stack_4) ); - VG_(init_die_mem_stack_8) ( & MAC_(die_mem_stack_8) ); - VG_(init_die_mem_stack_12) ( & MAC_(die_mem_stack_12) ); - VG_(init_die_mem_stack_16) ( & MAC_(die_mem_stack_16) ); - VG_(init_die_mem_stack_32) ( & MAC_(die_mem_stack_32) ); - VG_(init_die_mem_stack) ( & MAC_(die_mem_stack) ); - - VG_(init_ban_mem_stack) ( & MC_(make_noaccess) ); - - VG_(init_pre_mem_read) ( & mc_check_is_readable ); - VG_(init_pre_mem_read_asciiz) ( & mc_check_is_readable_asciiz ); - VG_(init_pre_mem_write) ( & mc_check_is_writable ); - VG_(init_post_mem_write) ( & MC_(make_readable) ); - - VG_(init_post_regs_write_init) ( & mc_post_regs_write_init ); - VG_(init_post_reg_write_syscall_return) ( & mc_post_reg_write ); - VG_(init_post_reg_write_deliver_signal) ( & mc_post_reg_write ); - VG_(init_post_reg_write_pthread_return) ( & mc_post_reg_write ); - VG_(init_post_reg_write_clientreq_return) ( & mc_post_reg_write ); - VG_(init_post_reg_write_clientcall_return) ( & mc_post_reg_write_clientcall ); - - VGP_(register_profile_event) ( VgpSetMem, "set-mem-perms" ); - VGP_(register_profile_event) ( VgpCheckMem, "check-mem-perms" ); - VGP_(register_profile_event) ( VgpESPAdj, "adjust-ESP" ); - - /* Additional block description for VG_(describe_addr)() */ - MAC_(describe_addr_supp) = MC_(client_perm_maybe_describe); - - init_shadow_memory(); - MAC_(common_pre_clo_init)(); -} - -void SK_(post_clo_init) ( void ) -{ -} - -void SK_(fini) ( Int exitcode ) -{ - MAC_(common_fini)( MC_(detect_memory_leaks) ); - - if (0) { - VG_(message)(Vg_DebugMsg, - "------ Valgrind's client block stats follow ---------------" ); - MC_(show_client_block_stats)(); - } -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 9./8) - -/*--------------------------------------------------------------------*/ -/*--- end mc_main.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/mc_translate.c b/VEX/head20041019/memcheck/mc_translate.c deleted file mode 100644 index f60deeb5d..000000000 --- a/VEX/head20041019/memcheck/mc_translate.c +++ /dev/null @@ -1,1648 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Instrument IR to perform memory checking operations. ---*/ -/*--- mc_translate.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "mc_include.h" - - -/*------------------------------------------------------------*/ -/*--- Forward decls ---*/ -/*------------------------------------------------------------*/ - -struct _MCEnv; - -static IRType shadowType ( IRType ty ); -static IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e ); - - -/*------------------------------------------------------------*/ -/*--- Memcheck running state, and tmp management. ---*/ -/*------------------------------------------------------------*/ - -/* Carries around state during memcheck instrumentation. */ -typedef - struct _MCEnv { - /* MODIFIED: the bb being constructed. IRStmts are added. */ - IRBB* bb; - - /* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps - original temps to their current their current shadow temp. - Initially all entries are IRTemp_INVALID. Entries are added - lazily since many original temps are not used due to - optimisation prior to instrumentation. Note that floating - point original tmps are shadowed by integer tmps of the same - size, and Bit-typed original tmps are shadowed by the type - Ity_I8. See comment below. */ - IRTemp* tmpMap; - Int n_originalTmps; /* for range checking */ - - /* READONLY: the guest layout. This indicates which parts of - the guest state should be regarded as 'always defined'. */ - VexGuestLayout* layout; - /* READONLY: the host word type. Needed for constructing - arguments of type 'HWord' to be passed to helper functions. - Ity_I32 or Ity_I64 only. */ - IRType hWordTy; - } - MCEnv; - -/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on - demand), as they are encountered. This is for two reasons. - - (1) (less important reason): Many original tmps are unused due to - initial IR optimisation, and we do not want to spaces in tables - tracking them. - - Shadow IRTemps are therefore allocated on demand. mce.tmpMap is a - table indexed [0 .. n_types-1], which gives the current shadow for - each original tmp, or INVALID_IRTEMP if none is so far assigned. - It is necessary to support making multiple assignments to a shadow - -- specifically, after testing a shadow for definedness, it needs - to be made defined. But IR's SSA property disallows this. - - (2) (more important reason): Therefore, when a shadow needs to get - a new value, a new temporary is created, the value is assigned to - that, and the tmpMap is updated to reflect the new binding. - - A corollary is that if the tmpMap maps a given tmp to - INVALID_IRTEMP and we are hoping to read that shadow tmp, it means - there's a read-before-write error in the original tmps. The IR - sanity checker should catch all such anomalies, however. -*/ - -/* Find the tmp currently shadowing the given original tmp. If none - so far exists, allocate one. */ -static IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig ) -{ - sk_assert(orig < mce->n_originalTmps); - if (mce->tmpMap[orig] == IRTemp_INVALID) { - mce->tmpMap[orig] - = newIRTemp(mce->bb->tyenv, - shadowType(mce->bb->tyenv->types[orig])); - } - return mce->tmpMap[orig]; -} - -/* Allocate a new shadow for the given original tmp. This means any - previous shadow is abandoned. This is needed because it is - necessary to give a new value to a shadow once it has been tested - for undefinedness, but unfortunately IR's SSA property disallows - this. Instead we must abandon the old shadow, allocate a new one - and use that instead. */ -static void newShadowTmp ( MCEnv* mce, IRTemp orig ) -{ - sk_assert(orig < mce->n_originalTmps); - mce->tmpMap[orig] - = newIRTemp(mce->bb->tyenv, - shadowType(mce->bb->tyenv->types[orig])); -} - - -/*------------------------------------------------------------*/ -/*--- IRAtoms -- a subset of IRExprs ---*/ -/*------------------------------------------------------------*/ - -/* An atom is either an IRExpr_Const or an IRExpr_Tmp, as defined by - isAtom() in libvex_ir.h. Because this instrumenter expects flat - input, most of this code deals in atoms. Usefully, a value atom - always has a V-value which is also an atom: constants are shadowed - by constants, and temps are shadowed by the corresponding shadow - temporary. */ - -typedef IRExpr IRAtom; - -/* (used for sanity checks only): is this an atom which looks - like it's from original code? */ -static Bool isOriginalAtom ( MCEnv* mce, IRAtom* a1 ) -{ - if (a1->tag == Iex_Const) - return True; - if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp < mce->n_originalTmps) - return True; - return False; -} - -/* (used for sanity checks only): is this an atom which looks - like it's from shadow code? */ -static Bool isShadowAtom ( MCEnv* mce, IRAtom* a1 ) -{ - if (a1->tag == Iex_Const) - return True; - if (a1->tag == Iex_Tmp && a1->Iex.Tmp.tmp >= mce->n_originalTmps) - return True; - return False; -} - -/* (used for sanity checks only): check that both args are atoms and - are identically-kinded. */ -static Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 ) -{ - if (a1->tag == Iex_Tmp && a1->tag == Iex_Tmp) - return True; - if (a1->tag == Iex_Const && a1->tag == Iex_Const) - return True; - return False; -} - - -/*------------------------------------------------------------*/ -/*--- Type management ---*/ -/*------------------------------------------------------------*/ - -/* Shadow state is always accessed using integer types. This returns - an integer type with the same size (as per sizeofIRType) as the - given type. The only valid shadow types are Bit, I8, I16, I32, - I64. */ - -static IRType shadowType ( IRType ty ) -{ - switch (ty) { - case Ity_I1: - case Ity_I8: - case Ity_I16: - case Ity_I32: - case Ity_I64: return ty; - case Ity_F32: return Ity_I32; - case Ity_F64: return Ity_I64; - default: ppIRType(ty); - VG_(skin_panic)("memcheck:shadowType"); - } -} - -/* Produce a 'defined' value of the given shadow type. Should only be - supplied shadow types (Bit/I8/I16/I32/UI64). */ -static IRExpr* definedOfType ( IRType ty ) { - switch (ty) { - case Ity_I1: return IRExpr_Const(IRConst_U1(False)); - case Ity_I8: return IRExpr_Const(IRConst_U8(0)); - case Ity_I16: return IRExpr_Const(IRConst_U16(0)); - case Ity_I32: return IRExpr_Const(IRConst_U32(0)); - case Ity_I64: return IRExpr_Const(IRConst_U64(0)); - default: VG_(skin_panic)("memcheck:definedOfType"); - } -} - - -/*------------------------------------------------------------*/ -/*--- Constructing IR fragments ---*/ -/*------------------------------------------------------------*/ - -/* assign value to tmp */ -#define assign(_bb,_tmp,_expr) \ - addStmtToIRBB((_bb), IRStmt_Tmp((_tmp),(_expr))) - -/* add stmt to a bb */ -#define stmt(_bb,_stmt) \ - addStmtToIRBB((_bb), (_stmt)) - -/* build various kinds of expressions */ -#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2)) -#define unop(_op, _arg) IRExpr_Unop((_op),(_arg)) -#define mkU8(_n) IRExpr_Const(IRConst_U8(_n)) -#define mkU16(_n) IRExpr_Const(IRConst_U16(_n)) -#define mkU32(_n) IRExpr_Const(IRConst_U32(_n)) -#define mkU64(_n) IRExpr_Const(IRConst_U64(_n)) -#define mkexpr(_tmp) IRExpr_Tmp((_tmp)) - -/* bind the given expression to a new temporary, and return the - temporary. This effectively converts an arbitrary expression into - an atom. */ -static IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) { - IRTemp t = newIRTemp(mce->bb->tyenv, ty); - assign(mce->bb, t, e); - return mkexpr(t); -} - - -/*------------------------------------------------------------*/ -/*--- Constructing definedness primitive ops ---*/ -/*------------------------------------------------------------*/ - -/* --------- Defined-if-either-defined --------- */ - -static IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I8, binop(Iop_And8, a1, a2)); -} - -static IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I16, binop(Iop_And16, a1, a2)); -} - -static IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I32, binop(Iop_And32, a1, a2)); -} - -/* --------- Undefined-if-either-undefined --------- */ - -static IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I8, binop(Iop_Or8, a1, a2)); -} - -static IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I16, binop(Iop_Or16, a1, a2)); -} - -static IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2)); -} - -static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) { - sk_assert(isShadowAtom(mce,a1)); - sk_assert(isShadowAtom(mce,a2)); - return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2)); -} - -static IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) { - switch (vty) { - case Ity_I16: return mkUifU16(mce, a1, a2); - case Ity_I32: return mkUifU32(mce, a1, a2); - case Ity_I64: return mkUifU64(mce, a1, a2); - default: - VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n"); - VG_(skin_panic)("memcheck:mkUifU"); - } -} - -/* --------- The Left-family of operations. --------- */ - -static IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) { - sk_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I8, - binop(Iop_Or8, a1, - assignNew(mce, Ity_I8, - /* unop(Iop_Neg8, a1)))); */ - binop(Iop_Sub8, mkU8(0), a1) ))); -} - -static IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) { - sk_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I16, - binop(Iop_Or16, a1, - assignNew(mce, Ity_I16, - /* unop(Iop_Neg16, a1)))); */ - binop(Iop_Sub16, mkU16(0), a1) ))); -} - -static IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) { - sk_assert(isShadowAtom(mce,a1)); - /* It's safe to duplicate a1 since it's only an atom */ - return assignNew(mce, Ity_I32, - binop(Iop_Or32, a1, - assignNew(mce, Ity_I32, - /* unop(Iop_Neg32, a1)))); */ - binop(Iop_Sub32, mkU32(0), a1) ))); -} - -/* --------- 'Improvement' functions for AND/OR. --------- */ - -/* ImproveAND(data, vbits) = data OR vbits. Defined (0) data 0s give - defined (0); all other -> undefined (1). -*/ -static IRAtom* mkImproveAND8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I8, binop(Iop_Or8, data, vbits)); -} - -static IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I16, binop(Iop_Or16, data, vbits)); -} - -static IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew(mce, Ity_I32, binop(Iop_Or32, data, vbits)); -} - -/* ImproveOR(data, vbits) = ~data OR vbits. Defined (0) data 1s give - defined (0); all other -> undefined (1). -*/ -static IRAtom* mkImproveOR8 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I8, - binop(Iop_Or8, - assignNew(mce, Ity_I8, unop(Iop_Not8, data)), - vbits) ); -} - -static IRAtom* mkImproveOR16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I16, - binop(Iop_Or16, - assignNew(mce, Ity_I16, unop(Iop_Not16, data)), - vbits) ); -} - -static IRAtom* mkImproveOR32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits ) -{ - sk_assert(isOriginalAtom(mce, data)); - sk_assert(isShadowAtom(mce, vbits)); - sk_assert(sameKindedAtoms(data, vbits)); - return assignNew( - mce, Ity_I32, - binop(Iop_Or32, - assignNew(mce, Ity_I32, unop(Iop_Not32, data)), - vbits) ); -} - -/* --------- Pessimising casts. --------- */ - -static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) -{ - /* Note, dst_ty is a shadow type, not an original type. */ - /* First of all, collapse vbits down to a single bit. */ - sk_assert(isShadowAtom(mce,vbits)); - IRType ty = typeOfIRExpr(mce->bb->tyenv, vbits); - IRAtom* tmp1 = NULL; - switch (ty) { - case Ity_I1: - tmp1 = vbits; - break; - case Ity_I8: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE8, vbits, mkU8(0))); - break; - case Ity_I16: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE16, vbits, mkU16(0))); - break; - case Ity_I32: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE32, vbits, mkU32(0))); - break; - case Ity_I64: - tmp1 = assignNew(mce, Ity_I1, binop(Iop_CmpNE64, vbits, mkU64(0))); - break; - default: - VG_(skin_panic)("mkPCastTo(1)"); - } - sk_assert(tmp1); - /* Now widen up to the dst type. */ - switch (dst_ty) { - case Ity_I1: - return tmp1; - case Ity_I8: - return assignNew(mce, Ity_I8, unop(Iop_1Sto8, tmp1)); - case Ity_I16: - return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1)); - case Ity_I32: - return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1)); - case Ity_I64: - return assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1)); - default: - ppIRType(dst_ty); - VG_(skin_panic)("mkPCastTo(2)"); - } -} - - -/*------------------------------------------------------------*/ -/*--- Emit a test and complaint if something is undefined. ---*/ -/*------------------------------------------------------------*/ - -/* Set the annotations on a dirty helper to indicate that the stack - pointer and instruction pointers might be read. This is the - behaviour of all 'emit-a-complaint' style functions we might - call. */ - -static void setHelperAnns ( MCEnv* mce, IRDirty* di ) { - di->nFxState = 2; - di->fxState[0].fx = Ifx_Read; - di->fxState[0].offset = mce->layout->offset_SP; - di->fxState[0].size = mce->layout->sizeof_SP; - di->fxState[1].fx = Ifx_Read; - di->fxState[1].offset = mce->layout->offset_IP; - di->fxState[1].size = mce->layout->sizeof_IP; -} - - -/* Check the supplied **original** atom for undefinedness, and emit a - complaint if so. Once that happens, mark it as defined. This is - possible because the atom is either a tmp or literal. If it's a - tmp, it will be shadowed by a tmp, and so we can set the shadow to - be defined. In fact as mentioned above, we will have to allocate a - new tmp to carry the new 'defined' shadow value, and update the - original->tmp mapping accordingly; we cannot simply assign a new - value to an existing shadow tmp as this breaks SSAness -- resulting - in the post-instrumentation sanity checker spluttering in disapproval. -*/ -static void complainIfUndefined ( MCEnv* mce, IRAtom* atom ) -{ - /* Since the original expression is atomic, there's no duplicated - work generated by making multiple V-expressions for it. So we - don't really care about the possibility that someone else may - also create a V-interpretion for it. */ - sk_assert(isOriginalAtom(mce, atom)); - IRAtom* vatom = expr2vbits( mce, atom ); - sk_assert(isShadowAtom(mce, vatom)); - sk_assert(sameKindedAtoms(atom, vatom)); - - IRType ty = typeOfIRExpr(mce->bb->tyenv, vatom); - - /* sz is only used for constructing the error message */ - Int sz = ty==Ity_I1 ? 0 : sizeofIRType(ty); - - IRAtom* cond = mkPCastTo( mce, Ity_I1, vatom ); - /* cond will be 0 if all defined, and 1 if any not defined. */ - - IRDirty* di; - switch (sz) { - case 0: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check0_fail)", - &MC_(helperc_value_check0_fail), - mkIRExprVec_0() - ); - break; - case 1: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check1_fail)", - &MC_(helperc_value_check1_fail), - mkIRExprVec_0() - ); - break; - case 4: - di = unsafeIRDirty_0_N( 0/*regparms*/, - "MC_(helperc_value_check4_fail)", - &MC_(helperc_value_check4_fail), - mkIRExprVec_0() - ); - break; - default: - di = unsafeIRDirty_0_N( 1/*regparms*/, - "MC_(helperc_complain_undef)", - &MC_(helperc_complain_undef), - mkIRExprVec_1( mkIRExpr_HWord( sz )) - ); - break; - } - di->guard = cond; - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di)); - - /* Set the shadow tmp to be defined. First, update the - orig->shadow tmp mapping to reflect the fact that this shadow is - getting a new value. */ - sk_assert(isAtom(vatom)); - /* sameKindedAtoms ... */ - if (vatom->tag == Iex_Tmp) { - sk_assert(atom->tag == Iex_Tmp); - newShadowTmp(mce, atom->Iex.Tmp.tmp); - assign(mce->bb, findShadowTmp(mce, atom->Iex.Tmp.tmp), - definedOfType(ty)); - } -} - - -/*------------------------------------------------------------*/ -/*--- Shadowing PUTs/GETs, and indexed variants thereof ---*/ -/*------------------------------------------------------------*/ - -/* Examine the always-defined sections declared in layout to see if - the (offset,size) section is within one. Note, is is an error to - partially fall into such a region: (offset,size) should either be - completely in such a region or completely not-in such a region. -*/ -static Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size ) -{ - Int minoffD, maxoffD, i; - Int minoff = offset; - Int maxoff = minoff + size - 1; - sk_assert((minoff & ~0xFFFF) == 0); - sk_assert((maxoff & ~0xFFFF) == 0); - - for (i = 0; i < mce->layout->n_alwaysDefd; i++) { - minoffD = mce->layout->alwaysDefd[i].offset; - maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1; - sk_assert((minoffD & ~0xFFFF) == 0); - sk_assert((maxoffD & ~0xFFFF) == 0); - - if (maxoff < minoffD || maxoffD < minoff) - continue; /* no overlap */ - if (minoff >= minoffD && maxoff <= maxoffD) - return True; /* completely contained in an always-defd section */ - - VG_(skin_panic)("memcheck:isAlwaysDefd:partial overlap"); - } - return False; /* could not find any containing section */ -} - - -/* Generate into bb suitable actions to shadow this Put. If the state - slice is marked 'always defined', do nothing. Otherwise, write the - supplied V bits to the shadow state. We can pass in either an - original atom or a V-atom, but not both. In the former case the - relevant V-bits are then generated from the original. -*/ -static -void do_shadow_PUT ( MCEnv* mce, Int offset, - IRAtom* atom, IRAtom* vatom ) -{ - if (atom) { - sk_assert(!vatom); - sk_assert(isOriginalAtom(mce, atom)); - vatom = expr2vbits( mce, atom ); - } else { - sk_assert(vatom); - sk_assert(isShadowAtom(mce, vatom)); - } - - IRType ty = typeOfIRExpr(mce->bb->tyenv, vatom); - sk_assert(ty != Ity_I1); - if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { - /* later: no ... */ - /* emit code to emit a complaint if any of the vbits are 1. */ - /* complainIfUndefined(mce, atom); */ - } else { - /* Do a plain shadow Put. */ - stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) ); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GETI (passed in in pieces). -*/ -static -void do_shadow_PUTI ( MCEnv* mce, - IRArray* descr, IRAtom* ix, Int bias, IRAtom* atom ) -{ - sk_assert(isOriginalAtom(mce,atom)); - IRAtom* vatom = expr2vbits( mce, atom ); - sk_assert(sameKindedAtoms(atom, vatom)); - IRType ty = descr->elemTy; - IRType tyS = shadowType(ty); - Int arrSize = descr->nElems * sizeofIRType(ty); - sk_assert(ty != Ity_I1); - sk_assert(isOriginalAtom(mce,ix)); - complainIfUndefined(mce,ix); - if (isAlwaysDefd(mce, descr->base, arrSize)) { - /* later: no ... */ - /* emit code to emit a complaint if any of the vbits are 1. */ - /* complainIfUndefined(mce, atom); */ - } else { - /* Do a cloned version of the Put that refers to the shadow - area. */ - IRArray* new_descr - = mkIRArray( descr->base + mce->layout->total_sizeB, - tyS, descr->nElems); - stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom )); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GET (passed in in pieces). -*/ -static -IRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty ) -{ - IRType tyS = shadowType(ty); - sk_assert(ty != Ity_I1); - if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) { - /* Always defined, return all zeroes of the relevant type */ - return definedOfType(tyS); - } else { - /* return a cloned version of the Get that refers to the shadow - area. */ - return IRExpr_Get( offset + mce->layout->total_sizeB, tyS ); - } -} - - -/* Return an expression which contains the V bits corresponding to the - given GETI (passed in in pieces). -*/ -static -IRExpr* shadow_GETI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias ) -{ - IRType ty = descr->elemTy; - IRType tyS = shadowType(ty); - Int arrSize = descr->nElems * sizeofIRType(ty); - sk_assert(ty != Ity_I1); - sk_assert(isOriginalAtom(mce,ix)); - complainIfUndefined(mce,ix); - if (isAlwaysDefd(mce, descr->base, arrSize)) { - /* Always defined, return all zeroes of the relevant type */ - return definedOfType(tyS); - } else { - /* return a cloned version of the Get that refers to the shadow - area. */ - IRArray* new_descr - = mkIRArray( descr->base + mce->layout->total_sizeB, - tyS, descr->nElems); - return IRExpr_GetI( new_descr, ix, bias ); - } -} - - -/*------------------------------------------------------------*/ -/*--- Generating approximations for unknown operations, ---*/ -/*--- using lazy-propagate semantics ---*/ -/*------------------------------------------------------------*/ - -/* Lazy propagation of undefinedness from two values, resulting in the - specified shadow type. -*/ -static -IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 ) -{ - /* force everything via 32-bit intermediaries. */ - IRAtom* at; - sk_assert(isShadowAtom(mce,va1)); - sk_assert(isShadowAtom(mce,va2)); - at = mkPCastTo(mce, Ity_I32, va1); - at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2)); - at = mkPCastTo(mce, finalVty, at); - return at; -} - - -/* Do the lazy propagation game from a null-terminated vector of - atoms. This is presumably the arguments to a helper call, so the - IRCallee info is also supplied in order that we can know which - arguments should be ignored (via the .mcx_mask field). -*/ -static -IRAtom* mkLazyN ( MCEnv* mce, - IRAtom** exprvec, IRType finalVtype, IRCallee* cee ) -{ - Int i; - IRAtom* here; - IRAtom* curr = definedOfType(Ity_I32); - for (i = 0; exprvec[i]; i++) { - sk_assert(i < 32); - sk_assert(isOriginalAtom(mce, exprvec[i])); - /* Only take notice of this arg if the callee's mc-exclusion - mask does not say it is to be excluded. */ - if (cee->mcx_mask & (1<name, i); - } else { - /* calculate the arg's definedness, and pessimistically merge - it in. */ - here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, exprvec[i]) ); - curr = mkUifU32(mce, here, curr); - } - } - return mkPCastTo(mce, finalVtype, curr ); -} - - -/*------------------------------------------------------------*/ -/*--- Generating expensive sequences for exact carry-chain ---*/ -/*--- propagation in add/sub and related operations. ---*/ -/*------------------------------------------------------------*/ - -static -IRAtom* expensiveAdd32 ( MCEnv* mce, IRAtom* qaa, IRAtom* qbb, - IRAtom* aa, IRAtom* bb ) -{ - sk_assert(isShadowAtom(mce,qaa)); - sk_assert(isShadowAtom(mce,qbb)); - sk_assert(isOriginalAtom(mce,aa)); - sk_assert(isOriginalAtom(mce,bb)); - sk_assert(sameKindedAtoms(qaa,aa)); - sk_assert(sameKindedAtoms(qbb,bb)); - - IRType ty = Ity_I32; - IROp opAND = Iop_And32; - IROp opOR = Iop_Or32; - IROp opXOR = Iop_Xor32; - IROp opNOT = Iop_Not32; - IROp opADD = Iop_Add32; - - IRAtom *a_min, *b_min, *a_max, *b_max; - - // a_min = aa & ~qaa - a_min = assignNew(mce,ty, - binop(opAND, aa, - assignNew(mce,ty, unop(opNOT, qaa)))); - - // b_min = bb & ~qbb - b_min = assignNew(mce,ty, - binop(opAND, bb, - assignNew(mce,ty, unop(opNOT, qbb)))); - - // a_max = aa | qaa - a_max = assignNew(mce,ty, binop(opOR, aa, qaa)); - - // b_max = bb | qbb - b_max = assignNew(mce,ty, binop(opOR, bb, qbb)); - - // result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max)) - return - assignNew(mce,ty, - binop( opOR, - assignNew(mce,ty, binop(opOR, qaa, qbb)), - assignNew(mce,ty, - binop(opXOR, assignNew(mce,ty, binop(opADD, a_min, b_min)), - assignNew(mce,ty, binop(opADD, a_max, b_max)) - ) - ) - ) - ); -} - - -/*------------------------------------------------------------*/ -/*--- Generate shadow values from all kinds of IRExprs. ---*/ -/*------------------------------------------------------------*/ - -static -IRAtom* expr2vbits_Binop ( MCEnv* mce, - IROp op, - IRAtom* atom1, IRAtom* atom2 ) -{ - IRType and_or_ty; - IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*); - IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*); - IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*); - - IRAtom* vatom1 = expr2vbits( mce, atom1 ); - IRAtom* vatom2 = expr2vbits( mce, atom2 ); - - sk_assert(isOriginalAtom(mce,atom1)); - sk_assert(isOriginalAtom(mce,atom2)); - sk_assert(isShadowAtom(mce,vatom1)); - sk_assert(isShadowAtom(mce,vatom2)); - sk_assert(sameKindedAtoms(atom1,vatom1)); - sk_assert(sameKindedAtoms(atom2,vatom2)); - switch (op) { - - case Iop_RoundF64: - case Iop_F64toI64: - /* First arg is I32 (rounding mode), second is F64 (data). */ - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_PRemC3210F64: case Iop_PRem1C3210F64: - /* Takes two F64 args. */ - case Iop_F64toI32: - /* First arg is I32 (rounding mode), second is F64 (data). */ - return mkLazy2(mce, Ity_I32, vatom1, vatom2); - - case Iop_F64toI16: - /* First arg is I32 (rounding mode), second is F64 (data). */ - return mkLazy2(mce, Ity_I16, vatom1, vatom2); - - case Iop_ScaleF64: - case Iop_Yl2xF64: - case Iop_Yl2xp1F64: - case Iop_PRemF64: - case Iop_AtanF64: - case Iop_AddF64: - case Iop_DivF64: - case Iop_SubF64: - case Iop_MulF64: - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_CmpF64: - return mkLazy2(mce, Ity_I32, vatom1, vatom2); - - /* non-FP after here */ - - case Iop_DivModU64to32: - case Iop_DivModS64to32: - return mkLazy2(mce, Ity_I64, vatom1, vatom2); - - case Iop_16HLto32: - return assignNew(mce, Ity_I32, - binop(Iop_16HLto32, vatom1, vatom2)); - case Iop_32HLto64: - return assignNew(mce, Ity_I64, - binop(Iop_32HLto64, vatom1, vatom2)); - - case Iop_MullS32: - case Iop_MullU32: { - IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); - IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32); - return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32)); - } - - case Iop_MullS16: - case Iop_MullU16: { - IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); - IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16); - return assignNew(mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16)); - } - - case Iop_MullS8: - case Iop_MullU8: { - IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); - IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8); - return assignNew(mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8)); - } - - case Iop_Add32: -# if 0 - return expensiveAdd32(mce, vatom1,vatom2, atom1,atom2); -# endif - case Iop_Sub32: - case Iop_Mul32: - return mkLeft32(mce, mkUifU32(mce, vatom1,vatom2)); - - case Iop_Mul16: - case Iop_Add16: - case Iop_Sub16: - return mkLeft16(mce, mkUifU16(mce, vatom1,vatom2)); - - case Iop_Sub8: - case Iop_Add8: - return mkLeft8(mce, mkUifU8(mce, vatom1,vatom2)); - - case Iop_CmpLE32S: case Iop_CmpLE32U: - case Iop_CmpLT32U: case Iop_CmpLT32S: - case Iop_CmpEQ32: case Iop_CmpNE32: - return mkPCastTo(mce, Ity_I1, mkUifU32(mce, vatom1,vatom2)); - - case Iop_CmpEQ16: case Iop_CmpNE16: - return mkPCastTo(mce, Ity_I1, mkUifU16(mce, vatom1,vatom2)); - - case Iop_CmpEQ8: case Iop_CmpNE8: - return mkPCastTo(mce, Ity_I1, mkUifU8(mce, vatom1,vatom2)); - - case Iop_Shl32: case Iop_Shr32: case Iop_Sar32: - /* Complain if the shift amount is undefined. Then simply - shift the first arg's V bits by the real shift amount. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I32, binop(op, vatom1, atom2)); - - case Iop_Shl16: case Iop_Shr16: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I16, binop(op, vatom1, atom2)); - - case Iop_Shl8: case Iop_Shr8: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I8, binop(op, vatom1, atom2)); - - case Iop_Shl64: case Iop_Shr64: - /* Same scheme as with 32-bit shifts. */ - complainIfUndefined(mce, atom2); - return assignNew(mce, Ity_I64, binop(op, vatom1, atom2)); - - case Iop_And32: - uifu = mkUifU32; difd = mkDifD32; - and_or_ty = Ity_I32; improve = mkImproveAND32; goto do_And_Or; - case Iop_And16: - uifu = mkUifU16; difd = mkDifD16; - and_or_ty = Ity_I16; improve = mkImproveAND16; goto do_And_Or; - case Iop_And8: - uifu = mkUifU8; difd = mkDifD8; - and_or_ty = Ity_I8; improve = mkImproveAND8; goto do_And_Or; - - case Iop_Or32: - uifu = mkUifU32; difd = mkDifD32; - and_or_ty = Ity_I32; improve = mkImproveOR32; goto do_And_Or; - case Iop_Or16: - uifu = mkUifU16; difd = mkDifD16; - and_or_ty = Ity_I16; improve = mkImproveOR16; goto do_And_Or; - case Iop_Or8: - uifu = mkUifU8; difd = mkDifD8; - and_or_ty = Ity_I8; improve = mkImproveOR8; goto do_And_Or; - - do_And_Or: - return - assignNew( - mce, - and_or_ty, - difd(mce, uifu(mce, vatom1, vatom2), - difd(mce, improve(mce, atom1, vatom1), - improve(mce, atom2, vatom2) ) ) ); - - case Iop_Xor8: - return mkUifU8(mce, vatom1, vatom2); - case Iop_Xor16: - return mkUifU16(mce, vatom1, vatom2); - case Iop_Xor32: - return mkUifU32(mce, vatom1, vatom2); - - default: - ppIROp(op); - VG_(skin_panic)("memcheck:expr2vbits_Binop"); - } -} - - -static -IRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom ) -{ - IRAtom* vatom = expr2vbits( mce, atom ); - sk_assert(isOriginalAtom(mce,atom)); - switch (op) { - - case Iop_F32toF64: - case Iop_I32toF64: - case Iop_I64toF64: - case Iop_NegF64: - case Iop_SinF64: - case Iop_CosF64: - case Iop_TanF64: - case Iop_SqrtF64: - case Iop_AbsF64: - case Iop_2xm1F64: - return mkPCastTo(mce, Ity_I64, vatom); - - case Iop_F64toF32: - case Iop_Clz32: - case Iop_Ctz32: - return mkPCastTo(mce, Ity_I32, vatom); - - case Iop_32Sto64: - case Iop_32Uto64: - return assignNew(mce, Ity_I64, unop(op, vatom)); - - case Iop_64to32: - case Iop_64HIto32: - case Iop_1Uto32: - case Iop_8Uto32: - case Iop_16Uto32: - case Iop_16Sto32: - case Iop_8Sto32: - return assignNew(mce, Ity_I32, unop(op, vatom)); - - case Iop_8Sto16: - case Iop_8Uto16: - case Iop_32to16: - case Iop_32HIto16: - return assignNew(mce, Ity_I16, unop(op, vatom)); - - case Iop_1Uto8: - case Iop_16to8: - case Iop_32to8: - return assignNew(mce, Ity_I8, unop(op, vatom)); - - case Iop_32to1: - return assignNew(mce, Ity_I1, unop(Iop_32to1, vatom)); - - case Iop_ReinterpF64asI64: - case Iop_ReinterpI64asF64: - case Iop_Not32: - case Iop_Not16: - case Iop_Not8: - case Iop_Not1: - return vatom; - default: - ppIROp(op); - VG_(skin_panic)("memcheck:expr2vbits_Unop"); - } -} - - -static -IRAtom* expr2vbits_LDle ( MCEnv* mce, IRType ty, IRAtom* addr, UInt bias ) -{ - void* helper; - Char* hname; - IRDirty* di; - IRTemp datavbits; - IRAtom* addrAct; - - sk_assert(isOriginalAtom(mce,addr)); - - /* First, emit a definedness test for the address. This also sets - the address (shadow) to 'defined' following the test. */ - complainIfUndefined( mce, addr ); - - /* Now cook up a call to the relevant helper function, to read the - data V bits from shadow memory. */ - ty = shadowType(ty); - switch (ty) { - case Ity_I64: helper = &MC_(helperc_LOADV8); - hname = "MC_(helperc_LOADV8)"; - break; - case Ity_I32: helper = &MC_(helperc_LOADV4); - hname = "MC_(helperc_LOADV4)"; - break; - case Ity_I16: helper = &MC_(helperc_LOADV2); - hname = "MC_(helperc_LOADV2)"; - break; - case Ity_I8: helper = &MC_(helperc_LOADV1); - hname = "MC_(helperc_LOADV1)"; - break; - default: ppIRType(ty); - VG_(skin_panic)("memcheck:do_shadow_LDle"); - } - - /* Generate the actual address into addrAct. */ - if (bias == 0) { - addrAct = addr; - } else { - IRType tyAddr = mce->hWordTy; - sk_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); - IROp mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; - IRAtom* eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); - addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) ); - } - - /* We need to have a place to park the V bits we're just about to - read. */ - datavbits = newIRTemp(mce->bb->tyenv, ty); - di = unsafeIRDirty_1_N( datavbits, - 1/*regparms*/, hname, helper, - mkIRExprVec_1( addrAct )); - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di) ); - - return mkexpr(datavbits); -} - - -static -IRAtom* expr2vbits_Mux0X ( MCEnv* mce, - IRAtom* cond, IRAtom* expr0, IRAtom* exprX ) -{ - IRAtom *vbitsC, *vbits0, *vbitsX; - IRType ty; - /* Given Mux0X(cond,expr0,exprX), generate - Mux0X(cond,expr0#,exprX#) `UifU` PCast(cond#) - That is, steer the V bits like the originals, but trash the - result if the steering value is undefined. This gives - lazy propagation. */ - sk_assert(isOriginalAtom(mce, cond)); - sk_assert(isOriginalAtom(mce, expr0)); - sk_assert(isOriginalAtom(mce, exprX)); - - vbitsC = expr2vbits(mce, cond); - vbits0 = expr2vbits(mce, expr0); - vbitsX = expr2vbits(mce, exprX); - ty = typeOfIRExpr(mce->bb->tyenv, vbits0); - - return - mkUifU(mce, ty, assignNew(mce, ty, IRExpr_Mux0X(cond, vbits0, vbitsX)), - mkPCastTo(mce, ty, vbitsC) ); -} - -/* --------- This is the main expression-handling function. --------- */ - -static -IRExpr* expr2vbits ( MCEnv* mce, IRExpr* e ) -{ - switch (e->tag) { - - case Iex_Get: - return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty ); - - case Iex_GetI: - return shadow_GETI( mce, e->Iex.GetI.descr, - e->Iex.GetI.ix, e->Iex.GetI.bias ); - - case Iex_Tmp: - return IRExpr_Tmp( findShadowTmp(mce, e->Iex.Tmp.tmp) ); - - case Iex_Const: - return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e))); - - case Iex_Binop: - return expr2vbits_Binop( - mce, - e->Iex.Binop.op, - e->Iex.Binop.arg1, e->Iex.Binop.arg2 - ); - - case Iex_Unop: - return expr2vbits_Unop( mce, e->Iex.Unop.op, e->Iex.Unop.arg ); - - case Iex_LDle: - return expr2vbits_LDle( mce, e->Iex.LDle.ty, - e->Iex.LDle.addr, 0/*addr bias*/ ); - - case Iex_CCall: - return mkLazyN( mce, e->Iex.CCall.args, - e->Iex.CCall.retty, - e->Iex.CCall.cee ); - - case Iex_Mux0X: - return expr2vbits_Mux0X( mce, e->Iex.Mux0X.cond, e->Iex.Mux0X.expr0, - e->Iex.Mux0X.exprX); - - default: - VG_(printf)("\n"); - ppIRExpr(e); - VG_(printf)("\n"); - VG_(skin_panic)("memcheck: expr2vbits"); - } -} - -/*------------------------------------------------------------*/ -/*--- Generate shadow stmts from all kinds of IRStmts. ---*/ -/*------------------------------------------------------------*/ - -/* Widen a value to the host word size. */ - -static -IRExpr* zwidenToHostWord ( MCEnv* mce, IRAtom* vatom ) -{ - /* vatom is vbits-value and as such can only have a shadow type. */ - sk_assert(isShadowAtom(mce,vatom)); - - IRType ty = typeOfIRExpr(mce->bb->tyenv, vatom); - IRType tyH = mce->hWordTy; - - if (tyH == Ity_I32) { - switch (ty) { - case Ity_I32: return vatom; - case Ity_I16: return assignNew(mce, tyH, unop(Iop_16Uto32, vatom)); - case Ity_I8: return assignNew(mce, tyH, unop(Iop_8Uto32, vatom)); - default: goto unhandled; - } - } else { - goto unhandled; - } - unhandled: - VG_(printf)("\nty = "); ppIRType(ty); VG_(printf)("\n"); - VG_(skin_panic)("zwidenToHostWord"); -} - - -/* Generate a shadow store. addr is always the original address atom. - You can pass in either originals or V-bits for the data atom, but - obviously not both. */ - -static -void do_shadow_STle ( MCEnv* mce, - IRAtom* addr, UInt bias, - IRAtom* data, IRAtom* vdata ) -{ - IRType ty; - IRDirty* di; - void* helper = NULL; - Char* hname = NULL; - IRAtom* addrAct; - - if (data) { - sk_assert(!vdata); - sk_assert(isOriginalAtom(mce, data)); - sk_assert(bias == 0); - vdata = expr2vbits( mce, data ); - } else { - sk_assert(vdata); - } - - sk_assert(isOriginalAtom(mce,addr)); - sk_assert(isShadowAtom(mce,vdata)); - - ty = typeOfIRExpr(mce->bb->tyenv, vdata); - - /* First, emit a definedness test for the address. This also sets - the address (shadow) to 'defined' following the test. */ - complainIfUndefined( mce, addr ); - - /* Now cook up a call to the relevant helper function, to write the - data V bits into shadow memory. */ - switch (ty) { - case Ity_I64: helper = &MC_(helperc_STOREV8); - hname = "MC_(helperc_STOREV8)"; - break; - case Ity_I32: helper = &MC_(helperc_STOREV4); - hname = "MC_(helperc_STOREV4)"; - break; - case Ity_I16: helper = &MC_(helperc_STOREV2); - hname = "MC_(helperc_STOREV2)"; - break; - case Ity_I8: helper = &MC_(helperc_STOREV1); - hname = "MC_(helperc_STOREV1)"; - break; - default: VG_(skin_panic)("memcheck:do_shadow_STle"); - } - - /* Generate the actual address into addrAct. */ - if (bias == 0) { - addrAct = addr; - } else { - IRType tyAddr = mce->hWordTy; - sk_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 ); - IROp mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64; - IRAtom* eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias); - addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) ); - } - - if (ty == Ity_I64) { - /* We can't do this with regparm 2 on 32-bit platforms, since - the back ends aren't clever enough to handle 64-bit regparm - args. Therefore be different. */ - di = unsafeIRDirty_0_N( - 1/*regparms*/, hname, helper, - mkIRExprVec_2( addrAct, vdata )); - } else { - di = unsafeIRDirty_0_N( - 2/*regparms*/, hname, helper, - mkIRExprVec_2( addrAct, - zwidenToHostWord( mce, vdata ))); - } - setHelperAnns( mce, di ); - stmt( mce->bb, IRStmt_Dirty(di) ); -} - - -/* Do lazy pessimistic propagation through a dirty helper call, by - looking at the annotations on it. This is the most complex part of - Memcheck. */ - -static IRType szToITy ( Int n ) -{ - switch (n) { - case 1: return Ity_I8; - case 2: return Ity_I16; - case 4: return Ity_I32; - case 8: return Ity_I64; - default: VG_(skin_panic)("szToITy(memcheck)"); - } -} - -static -void do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) -{ - Int i, offset, toDo; - IRAtom* src; - IRType tyAddr, tySrc, tyDst; - IRTemp dst; - - /* First check the guard. */ - complainIfUndefined(mce, d->guard); - - /* Now round up all inputs and PCast over them. */ - IRAtom* here; - IRAtom* curr = definedOfType(Ity_I32); - - /* Inputs: unmasked args */ - for (i = 0; d->args[i]; i++) { - if (d->cee->mcx_mask & (1<args[i]) ); - curr = mkUifU32(mce, here, curr); - } - } - - /* Inputs: guest state that we read. */ - for (i = 0; i < d->nFxState; i++) { - sk_assert(d->fxState[i].fx != Ifx_None); - if (d->fxState[i].fx == Ifx_Write) - continue; - /* This state element is read or modified. So we need to - consider it. */ - tySrc = szToITy( d->fxState[i].size ); - src = assignNew( mce, tySrc, - shadow_GET(mce, d->fxState[i].offset, tySrc ) ); - here = mkPCastTo( mce, Ity_I32, src ); - curr = mkUifU32(mce, here, curr); - } - - /* Inputs: memory. First set up some info needed regardless of - whether we're doing reads or writes. */ - tyAddr = Ity_INVALID; - - if (d->mFx != Ifx_None) { - /* Because we may do multiple shadow loads/stores from the same - base address, it's best to do a single test of its - definedness right now. Post-instrumentation optimisation - should remove all but this test. */ - sk_assert(d->mAddr); - complainIfUndefined(mce, d->mAddr); - - tyAddr = typeOfIRExpr(mce->bb->tyenv, d->mAddr); - sk_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64); - sk_assert(tyAddr == mce->hWordTy); /* not really right */ - } - - /* Deal with memory inputs (reads or modifies) */ - if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) { - offset = 0; - toDo = d->mSize; - /* chew off 32-bit chunks */ - while (toDo >= 4) { - here = mkPCastTo( - mce, Ity_I32, - expr2vbits_LDle ( mce, Ity_I32, - d->mAddr, d->mSize - toDo ) - ); - curr = mkUifU32(mce, here, curr); - toDo -= 4; - } - /* chew off 16-bit chunks */ - while (toDo >= 2) { - here = mkPCastTo( - mce, Ity_I32, - expr2vbits_LDle ( mce, Ity_I16, - d->mAddr, d->mSize - toDo ) - ); - curr = mkUifU32(mce, here, curr); - toDo -= 2; - } - sk_assert(toDo == 0); /* also need to handle 1-byte excess */ - } - - /* Whew! So curr is a 32-bit V-value summarising pessimistically - all the inputs to the helper. Now we need to re-distribute the - results to all destinations. */ - - /* Outputs: the destination temporary, if there is one. */ - if (d->tmp != IRTemp_INVALID) { - dst = findShadowTmp(mce, d->tmp); - tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp); - assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) ); - } - - /* Outputs: guest state that we write or modify. */ - for (i = 0; i < d->nFxState; i++) { - sk_assert(d->fxState[i].fx != Ifx_None); - if (d->fxState[i].fx == Ifx_Read) - continue; - /* this state element is written or modified. So we need to - consider it. */ - tyDst = szToITy( d->fxState[i].size ); - do_shadow_PUT( mce, d->fxState[i].offset, - NULL, /* original atom */ - mkPCastTo( mce, tyDst, curr ) ); - } - - /* Outputs: memory that we write or modify. */ - if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) { - offset = 0; - toDo = d->mSize; - /* chew off 32-bit chunks */ - while (toDo >= 4) { - do_shadow_STle( mce, d->mAddr, d->mSize - toDo, - NULL, /* original data */ - mkPCastTo( mce, Ity_I32, curr ) ); - toDo -= 4; - } - /* chew off 16-bit chunks */ - while (toDo >= 2) { - do_shadow_STle( mce, d->mAddr, d->mSize - toDo, - NULL, /* original data */ - mkPCastTo( mce, Ity_I16, curr ) ); - toDo -= 2; - } - sk_assert(toDo == 0); /* also need to handle 1-byte excess */ - } - -} - - -/*------------------------------------------------------------*/ -/*--- Memcheck main ---*/ -/*------------------------------------------------------------*/ - -#if 0 /* UNUSED */ -static Bool isBogusAtom ( IRAtom* at ) -{ - ULong n = 0; - IRConst* con; - sk_assert(isAtom(at)); - if (at->tag == Iex_Tmp) - return False; - sk_assert(at->tag == Iex_Const); - con = at->Iex.Const.con; - switch (con->tag) { - case Ico_U8: n = (ULong)con->Ico.U8; break; - case Ico_U16: n = (ULong)con->Ico.U16; break; - case Ico_U32: n = (ULong)con->Ico.U32; break; - case Ico_U64: n = (ULong)con->Ico.U64; break; - default: ppIRExpr(at); sk_assert(0); - } - /* VG_(printf)("%llx\n", n); */ - return (n == 0xFEFEFEFF - || n == 0x80808080 - || n == 0x1010101 - || n == 1010100); -} - -static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st ) -{ - Int i; - IRExpr* e; - switch (st->tag) { - case Ist_Tmp: - e = st->Ist.Tmp.data; - switch (e->tag) { - case Iex_Get: - case Iex_Tmp: - return False; - case Iex_Unop: - return isBogusAtom(e->Iex.Unop.arg); - case Iex_Binop: - return isBogusAtom(e->Iex.Binop.arg1) - || isBogusAtom(e->Iex.Binop.arg2); - case Iex_Mux0X: - return isBogusAtom(e->Iex.Mux0X.cond) - || isBogusAtom(e->Iex.Mux0X.expr0) - || isBogusAtom(e->Iex.Mux0X.exprX); - case Iex_LDle: - return isBogusAtom(e->Iex.LDle.addr); - case Iex_CCall: - for (i = 0; e->Iex.CCall.args[i]; i++) - if (isBogusAtom(e->Iex.CCall.args[i])) - return True; - return False; - default: - goto unhandled; - } - case Ist_Put: - return isBogusAtom(st->Ist.Put.data); - case Ist_STle: - return isBogusAtom(st->Ist.STle.addr) - || isBogusAtom(st->Ist.STle.data); - case Ist_Exit: - return isBogusAtom(st->Ist.Exit.cond); - default: - unhandled: - ppIRStmt(st); - VG_(skin_panic)("hasBogusLiterals"); - } -} -#endif /* UNUSED */ - - -IRBB* SK_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, IRType hWordTy ) -{ - Bool verboze = False; //True; - - /* Bool hasBogusLiterals = False; */ - - Int i, j, first_stmt; - IRStmt* st; - MCEnv mce; - - /* Set up BB */ - IRBB* bb = emptyIRBB(); - bb->tyenv = dopyIRTypeEnv(bb_in->tyenv); - bb->next = dopyIRExpr(bb_in->next); - bb->jumpkind = bb_in->jumpkind; - - /* Set up the running environment. Only .bb is modified as we go - along. */ - mce.bb = bb; - mce.layout = layout; - mce.n_originalTmps = bb->tyenv->types_used; - mce.hWordTy = hWordTy; - mce.tmpMap = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp)); - for (i = 0; i < mce.n_originalTmps; i++) - mce.tmpMap[i] = IRTemp_INVALID; - - /* Iterate over the stmts. */ - - for (i = 0; i < bb_in->stmts_used; i++) { - st = bb_in->stmts[i]; - if (!st) continue; - - sk_assert(isFlatIRStmt(st)); - - /* - if (!hasBogusLiterals) { - hasBogusLiterals = checkForBogusLiterals(st); - if (hasBogusLiterals) { - VG_(printf)("bogus: "); - ppIRStmt(st); - VG_(printf)("\n"); - } - } - */ - first_stmt = bb->stmts_used; - - if (verboze) { - ppIRStmt(st); - VG_(printf)("\n\n"); - } - - switch (st->tag) { - - case Ist_Tmp: - assign( bb, findShadowTmp(&mce, st->Ist.Tmp.tmp), - expr2vbits( &mce, st->Ist.Tmp.data) ); - break; - - case Ist_Put: - do_shadow_PUT( &mce, - st->Ist.Put.offset, - st->Ist.Put.data, - NULL /* shadow atom */ ); - break; - - case Ist_PutI: - do_shadow_PUTI( &mce, - st->Ist.PutI.descr, - st->Ist.PutI.ix, - st->Ist.PutI.bias, - st->Ist.PutI.data ); - break; - - case Ist_STle: - do_shadow_STle( &mce, st->Ist.STle.addr, 0/* addr bias */, - st->Ist.STle.data, - NULL /* shadow data */ ); - break; - - case Ist_Exit: - /* if (!hasBogusLiterals) */ - complainIfUndefined( &mce, st->Ist.Exit.guard ); - break; - - case Ist_Dirty: - do_shadow_Dirty( &mce, st->Ist.Dirty.details ); - break; - - default: - VG_(printf)("\n"); - ppIRStmt(st); - VG_(printf)("\n"); - VG_(skin_panic)("memcheck: unhandled IRStmt"); - - } /* switch (st->tag) */ - - if (verboze) { - for (j = first_stmt; j < bb->stmts_used; j++) { - VG_(printf)(" "); - ppIRStmt(bb->stmts[j]); - VG_(printf)("\n"); - } - VG_(printf)("\n"); - } - - addStmtToIRBB(bb, st); - - } - - /* Now we need to complain if the jump target is undefined. */ - first_stmt = bb->stmts_used; - - if (verboze) { - VG_(printf)("bb->next = "); - ppIRExpr(bb->next); - VG_(printf)("\n\n"); - } - - complainIfUndefined( &mce, bb->next ); - - if (verboze) { - for (j = first_stmt; j < bb->stmts_used; j++) { - VG_(printf)(" "); - ppIRStmt(bb->stmts[j]); - VG_(printf)("\n"); - } - VG_(printf)("\n"); - } - - return bb; -} - -/*--------------------------------------------------------------------*/ -/*--- end mc_translate.c ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/memcheck/memcheck.h b/VEX/head20041019/memcheck/memcheck.h deleted file mode 100644 index 4b2458d23..000000000 --- a/VEX/head20041019/memcheck/memcheck.h +++ /dev/null @@ -1,259 +0,0 @@ - -/* - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (memcheck.h) only. The entire rest of Valgrind is licensed - under the terms of the GNU General Public License, version 2. See - the COPYING file in the source distribution for details. - - ---------------------------------------------------------------- - - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2004 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (memcheck.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -#ifndef __MEMCHECK_H -#define __MEMCHECK_H - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query memory permissions - inside your own programs. - - See comment near the top of valgrind.h on how to use them. -*/ - -#include "valgrind.h" - -typedef - enum { - VG_USERREQ__MAKE_NOACCESS = VG_USERREQ_SKIN_BASE('M','C'), - VG_USERREQ__MAKE_WRITABLE, - VG_USERREQ__MAKE_READABLE, - VG_USERREQ__DISCARD, - VG_USERREQ__CHECK_WRITABLE, - VG_USERREQ__CHECK_READABLE, - VG_USERREQ__DO_LEAK_CHECK, - VG_USERREQ__COUNT_LEAKS, - - /* These two have been moved into core, because they are useful for - any tool that tracks heap blocks. Hence the suffix. But they're - still here for backwards compatibility, although Valgrind will - abort with an explanatory message if you use them. */ - VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE, - VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE, - - VG_USERREQ__GET_VBITS, - VG_USERREQ__SET_VBITS, - - /* This is just for memcheck's internal use - don't use it */ - _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP = VG_USERREQ_SKIN_BASE('M','C')+256 - } Vg_MemCheckClientRequest; - - - -/* Client-code macros to manipulate the state of memory. */ - -/* Mark memory at _qzz_addr as unaddressible and undefined for - _qzz_len bytes. Returns an int handle pertaining to the block - descriptions Valgrind will use in subsequent error messages. */ -#define VALGRIND_MAKE_NOACCESS(_qzz_addr,_qzz_len) \ - (__extension__({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_NOACCESS, \ - _qzz_addr, _qzz_len, 0, 0); \ - _qzz_res; \ - })) - -/* Similarly, mark memory at _qzz_addr as addressible but undefined - for _qzz_len bytes. */ -#define VALGRIND_MAKE_WRITABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_WRITABLE, \ - _qzz_addr, _qzz_len, 0, 0); \ - _qzz_res; \ - })) - -/* Similarly, mark memory at _qzz_addr as addressible and defined - for _qzz_len bytes. */ -#define VALGRIND_MAKE_READABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_READABLE, \ - _qzz_addr, _qzz_len, 0, 0); \ - _qzz_res; \ - })) - -/* Discard a block-description-handle obtained from the above three - macros. After this, Valgrind will no longer be able to relate - addressing errors to the user-defined block associated with the - handle. The permissions settings associated with the handle remain - in place. Returns 1 for an invalid handle, 0 for a valid - handle. */ -#define VALGRIND_DISCARD(_qzz_blkindex) \ - (__extension__ ({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */, \ - VG_USERREQ__DISCARD, \ - 0, _qzz_blkindex, 0, 0); \ - _qzz_res; \ - })) - - -/* Client-code macros to check the state of memory. */ - -/* Check that memory at _qzz_addr is addressible for _qzz_len bytes. - If suitable addressibility is not established, Valgrind prints an - error message and returns the address of the first offending byte. - Otherwise it returns zero. */ -#define VALGRIND_CHECK_WRITABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__CHECK_WRITABLE, \ - _qzz_addr, _qzz_len, 0, 0); \ - _qzz_res; \ - })) - -/* Check that memory at _qzz_addr is addressible and defined for - _qzz_len bytes. If suitable addressibility and definedness are not - established, Valgrind prints an error message and returns the - address of the first offending byte. Otherwise it returns zero. */ -#define VALGRIND_CHECK_READABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__CHECK_READABLE, \ - _qzz_addr, _qzz_len, 0, 0); \ - _qzz_res; \ - })) - -/* Use this macro to force the definedness and addressibility of a - value to be checked. If suitable addressibility and definedness - are not established, Valgrind prints an error message and returns - the address of the first offending byte. Otherwise it returns - zero. */ -#define VALGRIND_CHECK_DEFINED(__lvalue) \ - VALGRIND_CHECK_READABLE( \ - (volatile unsigned char *)&(__lvalue), \ - (unsigned int)(sizeof (__lvalue))) - -/* Do a memory leak check mid-execution. */ -#define VALGRIND_DO_LEAK_CHECK \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__DO_LEAK_CHECK, \ - 0, 0, 0, 0); \ - } - -/* Return number of leaked, dubious, reachable and suppressed bytes found by - all previous leak checks. They must be lvalues. */ -#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__COUNT_LEAKS, \ - &leaked, &dubious, &reachable, &suppressed);\ - } - - -/* These two have been moved to valgrind.h; still here so that a warning can - be printed out for any programs using the old ones. */ -#define VALGRIND_MALLOCLIKE_BLOCK__OLD_DO_NOT_USE(addr, sizeB, rzB, is_zeroed)\ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed); \ - } -#define VALGRIND_FREELIKE_BLOCK__OLD_DO_NOT_USE(addr, rzB) \ - {unsigned int _qzz_res; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0); \ - } - - -/* Get in zzvbits the validity data for the zznbytes starting at - zzsrc. Return values: - 0 if not running on valgrind - 1 success - 2 if zzsrc/zzvbits arrays are not aligned 0 % 4, or - zznbytes is not 0 % 4. - 3 if any parts of zzsrc/zzvbits are not addressible. - The metadata is not copied in cases 0, 2 or 3 so it should be - impossible to segfault your system by using this call. -*/ -#define VALGRIND_GET_VBITS(zzsrc,zzvbits,zznbytes) \ - (__extension__({unsigned int _qzz_res; \ - char* czzsrc = (char*)zzsrc; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__GET_VBITS, \ - czzsrc, czzvbits, zznbytes,0 ); \ - _qzz_res; \ - })) - -/* Apply the validity data in zzvbits to the zznbytes starting at - zzdst. Return values: - 0 if not running on valgrind - 1 success - 2 if zzdst/zzvbits arrays are not aligned 0 % 4, or - zznbytes is not 0 % 4. - 3 if any parts of zzdst/zzvbits are not addressible. - The metadata is not copied in cases 0, 2 or 3 so it should be - impossible to segfault your system by using this call. -*/ -#define VALGRIND_SET_VBITS(zzdst,zzvbits,zznbytes) \ - (__extension__({unsigned int _qzz_res; \ - char* czzdst = (char*)zzdst; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \ - VG_USERREQ__SET_VBITS, \ - czzdst, czzvbits, zznbytes,0 ); \ - _qzz_res; \ - })) - -#endif - diff --git a/VEX/head20041019/memcheck/tests/.cvsignore b/VEX/head20041019/memcheck/tests/.cvsignore deleted file mode 100644 index 27a7a5b83..000000000 --- a/VEX/head20041019/memcheck/tests/.cvsignore +++ /dev/null @@ -1,68 +0,0 @@ -Makefile.in -Makefile -badaddrvalue -badfree -badjump -badjump2 -badloop -buflen_check -clientperm -clientstackperm -custom_alloc -dir -doublefree -error_counts -errs1 -execve -execve2 -exitprog -filter_leak_check_size -filter_stderr -fpeflags -fprw -fwrite -hello -inits -inline -malloc1 -malloc2 -malloc3 -manuel1 -manuel2 -manuel3 -memalign_test -memalign2 -memcmptest -mempool -mismatches -mmaptest -nanoleak -new_override -null_socket -overlap -pushfpopf -realloc1 -realloc2 -sigaltstack -signal2 -supp1 -supp2 -suppfree -trivialleak -tronical -vgtest_ume -weirdioctl -*.stdout.diff -*.stderr.diff* -*.stdout.out -*.stderr.out -badrw -brk -brk2 -metadata -new_nothrow -realloc3 -threadederrno -vgcore.pid* -writev -zeropage diff --git a/VEX/head20041019/memcheck/tests/CVS/Entries b/VEX/head20041019/memcheck/tests/CVS/Entries deleted file mode 100644 index 0423d5161..000000000 --- a/VEX/head20041019/memcheck/tests/CVS/Entries +++ /dev/null @@ -1,230 +0,0 @@ -/.cvsignore/1.18/Sat Oct 16 11:02:33 2004// -/Makefile.am/1.46/Mon Oct 18 11:52:17 2004// -/badaddrvalue.c/1.2/Mon Sep 23 09:36:25 2002// -/badaddrvalue.stderr.exp/1.8/Thu Nov 13 17:53:43 2003// -/badaddrvalue.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/badaddrvalue.vgtest/1.3/Sun Jul 6 23:24:18 2003// -/badfree-2trace.stderr.exp/1.6/Tue Apr 13 08:36:35 2004// -/badfree-2trace.vgtest/1.3/Sun Jul 6 23:43:01 2003// -/badfree.c/1.2/Mon Sep 23 09:36:25 2002// -/badfree.stderr.exp/1.10/Tue Apr 13 08:36:35 2004// -/badfree.vgtest/1.3/Sun Jul 6 23:43:01 2003// -/badjump.c/1.2/Mon Sep 23 09:36:25 2002// -/badjump.stderr.exp/1.9/Tue Apr 13 08:36:35 2004// -/badjump.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/badjump2.c/1.1/Wed Oct 13 09:47:24 2004// -/badjump2.stderr.exp/1.1/Wed Oct 13 09:47:24 2004// -/badjump2.vgtest/1.1/Wed Oct 13 09:47:24 2004// -/badloop.c/1.2/Mon Sep 23 09:36:25 2002// -/badloop.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/badloop.vgtest/1.3/Sun Jul 6 23:43:01 2003// -/badrw.c/1.2/Wed Jan 7 08:47:03 2004// -/badrw.stderr.exp/1.4/Wed Jan 7 08:47:03 2004// -/badrw.vgtest/1.1/Fri Sep 5 23:29:33 2003// -/brk.c/1.1/Thu Sep 4 20:57:51 2003// -/brk.stderr.exp/1.1/Thu Sep 4 20:57:51 2003// -/brk.vgtest/1.1/Thu Sep 4 20:57:51 2003// -/brk2.c/1.1/Wed Aug 25 13:43:44 2004// -/brk2.stderr.exp/1.1/Wed Aug 25 13:43:44 2004// -/brk2.vgtest/1.1/Wed Aug 25 13:43:44 2004// -/buflen_check.c/1.2/Mon Sep 23 09:36:25 2002// -/buflen_check.stderr.exp/1.9/Tue Apr 13 19:08:34 2004// -/buflen_check.vgtest/1.3/Sun Jul 6 23:43:01 2003// -/clientperm.c/1.1/Fri Oct 4 14:16:35 2002// -/clientperm.stderr.exp/1.5/Thu Nov 13 17:35:04 2003// -/clientperm.stdout.exp/1.1/Fri Oct 4 14:16:35 2002// -/clientperm.vgtest/1.2/Sun Jul 6 23:43:01 2003// -/custom_alloc.c/1.2/Sat Jan 3 14:18:02 2004// -/custom_alloc.stderr.exp/1.5/Tue Apr 13 08:36:35 2004// -/custom_alloc.vgtest/1.2/Sun Jul 6 23:43:01 2003// -/doublefree.c/1.2/Mon Sep 23 09:36:25 2002// -/doublefree.stderr.exp/1.9/Thu Nov 13 17:53:43 2003// -/doublefree.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/error_counts.c/1.4/Tue Jul 22 22:03:58 2003// -/error_counts.stderr.exp/1.1/Mon Apr 21 13:24:40 2003// -/error_counts.stdout.exp/1.1/Mon Apr 21 13:24:40 2003// -/error_counts.vgtest/1.2/Mon Jun 21 12:42:35 2004// -/errs1.c/1.2/Mon Sep 23 09:36:25 2002// -/errs1.stderr.exp/1.5/Thu Nov 13 17:53:43 2003// -/errs1.vgtest/1.3/Sun Jul 13 22:35:55 2003// -/execve.c/1.1/Thu Feb 12 14:34:14 2004// -/execve.stderr.exp/1.2/Tue Apr 13 08:36:35 2004// -/execve.vgtest/1.1/Thu Feb 12 14:34:14 2004// -/execve2.c/1.1/Mon Aug 9 12:21:57 2004// -/execve2.stderr.exp/1.1/Mon Aug 9 12:21:57 2004// -/execve2.vgtest/1.1/Mon Aug 9 12:21:57 2004// -/exitprog.c/1.3/Mon Jul 7 00:32:44 2003// -/exitprog.stderr.exp/1.10/Thu Nov 13 17:53:43 2003// -/exitprog.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/filter_allocs/1.3/Sat Jan 3 14:18:02 2004// -/filter_leak_check_size/1.4/Sat Jan 3 14:18:02 2004// -/filter_pushfpopf/1.2/Mon May 5 16:18:51 2003// -/filter_stderr/1.11/Tue Mar 9 09:59:26 2004// -/filter_stderr_backtrace/1.1/Thu Apr 24 00:40:38 2003// -/filter_tronical/1.2/Mon May 5 16:18:51 2003// -/fpeflags.c/1.2/Thu Oct 14 09:48:55 2004// -/fpeflags.stderr.exp/1.1/Sun Mar 28 11:26:29 2004// -/fpeflags.vgtest/1.1/Sun Mar 28 11:26:29 2004// -/fprw.c/1.2/Mon Sep 23 09:36:25 2002// -/fprw.stderr.exp/1.10/Tue Apr 13 08:36:35 2004// -/fprw.vgtest/1.4/Tue Dec 16 02:05:15 2003// -/fwrite.c/1.2/Mon Sep 23 09:36:25 2002// -/fwrite.stderr.exp/1.9/Mon Dec 15 09:00:21 2003// -/fwrite.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/fwrite.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/hello.c/1.1/Thu Oct 14 08:38:06 2004// -/inits.c/1.2/Mon Sep 23 09:36:25 2002// -/inits.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/inits.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/inline.c/1.2/Mon Sep 23 09:36:25 2002// -/inline.stderr.exp/1.9/Thu Nov 13 17:53:43 2003// -/inline.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/inline.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/insn_basic.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_basic.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_cmov.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_fpu.stderr.exp/1.1/Sat Mar 27 18:02:37 2004// -/insn_fpu.stdout.exp/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.vgtest/1.1/Sat Mar 27 18:02:37 2004// -/insn_mmx.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.stdout.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmx.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_mmxext.stderr.exp/1.2/Tue Mar 9 08:50:02 2004// -/insn_mmxext.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_mmxext.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stderr.exp/1.1/Tue Mar 9 01:44:11 2004// -/insn_sse2.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse2.vgtest/1.1/Tue Mar 9 01:44:11 2004// -/malloc1.c/1.2/Mon Sep 23 09:36:25 2002// -/malloc1.stderr.exp/1.9/Thu Nov 13 17:53:43 2003// -/malloc1.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/malloc2.c/1.2/Mon Sep 23 09:36:25 2002// -/malloc2.stderr.exp/1.9/Thu Nov 13 17:53:43 2003// -/malloc2.vgtest/1.3/Mon Jul 7 00:23:23 2003// -/malloc3.c/1.1/Tue Apr 15 13:03:20 2003// -/malloc3.stderr.exp/1.2/Mon Jul 7 00:23:23 2003// -/malloc3.stdout.exp/1.1/Tue Apr 15 13:03:20 2003// -/malloc3.vgtest/1.2/Mon Jul 7 00:23:23 2003// -/manuel1.c/1.2/Mon Sep 23 09:36:25 2002// -/manuel1.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/manuel1.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/manuel1.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/manuel2.c/1.3/Sat Jan 3 14:18:02 2004// -/manuel2.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/manuel2.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/manuel2.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/manuel3.c/1.3/Sat Jan 3 14:18:02 2004// -/manuel3.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/manuel3.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/memalign2.c/1.2/Fri Sep 3 14:04:40 2004// -/memalign2.stderr.exp/1.1/Wed Aug 11 09:40:52 2004// -/memalign2.vgtest/1.1/Wed Aug 11 09:40:52 2004// -/memalign_test.c/1.2/Mon Sep 23 09:36:25 2002// -/memalign_test.stderr.exp/1.9/Thu Nov 13 17:53:43 2003// -/memalign_test.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/memcmptest.c/1.2/Mon Sep 23 09:36:25 2002// -/memcmptest.stderr.exp/1.7/Thu Nov 13 17:35:04 2003// -/memcmptest.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/memcmptest.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/mempool.c/1.1/Sat Jun 19 18:12:36 2004// -/mempool.stderr.exp/1.1/Sat Jun 19 18:12:36 2004// -/mempool.vgtest/1.1/Sat Jun 19 18:12:36 2004// -/metadata.c/1.2/Sat Jan 3 14:18:02 2004// -/metadata.stderr.exp/1.2/Thu Nov 13 17:35:04 2003// -/metadata.stdout.exp/1.1/Mon Jul 7 00:03:52 2003// -/metadata.vgtest/1.1/Mon Jul 7 00:03:52 2003// -/mismatches.cpp/1.2/Mon Sep 23 09:36:25 2002// -/mismatches.stderr.exp/1.10/Thu Nov 13 17:53:43 2003// -/mismatches.stderr.exp2/1.1/Sun Mar 7 19:40:33 2004// -/mismatches.vgtest/1.5/Tue Sep 30 16:52:47 2003// -/mmaptest.c/1.2/Mon Sep 23 09:36:25 2002// -/mmaptest.stderr.exp/1.3/Mon Jul 7 00:43:34 2003// -/mmaptest.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/nanoleak.c/1.3/Sat Jan 3 14:18:02 2004// -/nanoleak.stderr.exp/1.9/Tue Dec 2 10:17:44 2003// -/nanoleak.supp/1.2/Tue Dec 16 02:05:15 2003// -/nanoleak.vgtest/1.3/Mon Jul 7 00:43:34 2003// -/nanoleak_supp.stderr.exp/1.3/Tue Dec 2 10:17:44 2003// -/nanoleak_supp.vgtest/1.2/Mon Jul 7 23:56:10 2003// -/new_nothrow.cpp/1.1/Thu Oct 9 15:40:38 2003// -/new_nothrow.stderr.exp/1.1/Thu Oct 9 15:40:38 2003// -/new_nothrow.vgtest/1.1/Thu Oct 9 15:40:38 2003// -/new_override.cpp/1.3/Tue Apr 13 19:11:27 2004// -/new_override.stderr.exp/1.6/Sun Jun 1 20:04:10 2003// -/new_override.stdout.exp/1.1/Tue Apr 13 19:11:27 2004// -/new_override.vgtest/1.3/Wed Feb 26 10:16:02 2003// -/null_socket.c/1.1/Fri May 2 16:19:10 2003// -/null_socket.stderr.exp/1.2/Mon Jul 7 23:56:10 2003// -/null_socket.vgtest/1.2/Mon Jul 7 23:56:10 2003// -/overlap.c/1.3/Sun Nov 2 17:43:27 2003// -/overlap.stderr.exp/1.7/Thu Nov 13 17:35:04 2003// -/overlap.stdout.exp/1.1/Tue Apr 15 13:03:21 2003// -/overlap.vgtest/1.2/Mon Jul 7 23:56:10 2003// -/pth_once.stderr.exp/1.1/Thu Oct 30 09:11:03 2003// -/pth_once.stdout.exp/1.1/Thu Oct 30 09:11:03 2003// -/pth_once.vgtest/1.1/Thu Oct 30 09:11:03 2003// -/pushfpopf.stderr.exp/1.7/Thu Nov 13 17:35:04 2003// -/pushfpopf.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/pushfpopf.vgtest/1.4/Mon Jul 7 23:56:10 2003// -/pushfpopf_c.c/1.2/Mon Sep 23 09:36:25 2002// -/pushfpopf_s.s/1.2/Mon Sep 23 09:36:25 2002// -/realloc1.c/1.3/Mon Jul 7 23:56:10 2003// -/realloc1.stderr.exp/1.3/Mon Jul 7 23:56:10 2003// -/realloc1.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/realloc2.c/1.3/Sat Jan 3 14:18:02 2004// -/realloc2.stderr.exp/1.3/Mon Jul 7 23:56:10 2003// -/realloc2.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/realloc3.c/1.1/Thu Jul 24 17:39:59 2003// -/realloc3.stderr.exp/1.3/Thu Nov 13 17:53:43 2003// -/realloc3.vgtest/1.1/Thu Jul 24 17:39:59 2003// -/sigaltstack.c/1.7/Sat Jan 3 14:18:02 2004// -/sigaltstack.stderr.exp/1.8/Tue Dec 16 02:05:15 2003// -/sigaltstack.vgtest/1.4/Mon Jul 7 23:56:10 2003// -/signal2.c/1.2/Mon Sep 23 09:36:25 2002// -/signal2.stderr.exp/1.9/Tue Apr 13 08:36:35 2004// -/signal2.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/signal2.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/supp.c/1.3/Mon Jul 7 23:56:10 2003// -/supp.supp/1.5/Mon Oct 7 14:46:07 2002// -/supp1.stderr.exp/1.3/Mon Jul 7 23:56:10 2003// -/supp1.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/supp2.stderr.exp/1.6/Thu Nov 13 17:35:04 2003// -/supp2.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/suppfree.c/1.2/Mon Sep 23 09:36:25 2002// -/suppfree.stderr.exp/1.5/Thu Nov 13 17:53:43 2003// -/suppfree.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/threadederrno.c/1.4/Wed Jan 21 17:40:16 2004// -/threadederrno.stderr.exp/1.2/Tue Dec 16 02:05:15 2003// -/threadederrno.stdout.exp/1.4/Wed Jan 21 17:40:16 2004// -/threadederrno.vgtest/1.1/Sun Jul 13 11:13:37 2003// -/toobig-allocs.stderr.exp/1.1/Sat Jul 10 14:56:27 2004// -/toobig-allocs.vgtest/1.1/Sat Jul 10 14:56:27 2004// -/trivialleak.c/1.2/Mon Sep 23 09:36:25 2002// -/trivialleak.stderr.exp/1.8/Tue Dec 2 10:17:44 2003// -/trivialleak.stderr.exp2/1.1/Sat Apr 10 00:53:45 2004// -/trivialleak.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/tronical.S/1.3/Sun Oct 6 00:08:57 2002// -/tronical.stderr.exp/1.7/Thu Nov 13 17:35:04 2003// -/tronical.vgtest/1.4/Mon Jul 7 23:56:10 2003// -/vgtest_ume.c/1.4/Mon Oct 18 11:52:17 2004// -/vgtest_ume.stderr.exp/1.3/Thu Oct 14 09:28:11 2004// -/vgtest_ume.vgtest/1.1/Thu Oct 14 08:38:06 2004// -/weirdioctl.c/1.2/Mon Sep 23 09:36:25 2002// -/weirdioctl.stderr.exp/1.8/Mon Dec 15 09:00:21 2003// -/weirdioctl.stdout.exp/1.3/Mon Jul 7 23:56:10 2003// -/weirdioctl.vgtest/1.3/Mon Jul 7 23:56:10 2003// -/writev.c/1.1/Fri Sep 5 23:02:38 2003// -/writev.stderr.exp/1.6/Tue Apr 13 08:36:35 2004// -/writev.stderr.exp2/1.2/Tue Oct 12 08:38:19 2004// -/writev.vgtest/1.1/Fri Sep 5 23:02:38 2003// -/zeropage.c/1.3/Tue Aug 3 13:29:09 2004// -/zeropage.stderr.exp/1.2/Tue Dec 16 02:05:15 2003// -/zeropage.stderr.exp2/1.1/Wed Oct 13 16:48:21 2004// -/zeropage.vgtest/1.1/Tue Dec 2 14:56:04 2003// -D diff --git a/VEX/head20041019/memcheck/tests/CVS/Repository b/VEX/head20041019/memcheck/tests/CVS/Repository deleted file mode 100644 index 357815a7e..000000000 --- a/VEX/head20041019/memcheck/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/memcheck/tests diff --git a/VEX/head20041019/memcheck/tests/CVS/Root b/VEX/head20041019/memcheck/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/memcheck/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/memcheck/tests/CVS/Template b/VEX/head20041019/memcheck/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/Makefile.am b/VEX/head20041019/memcheck/tests/Makefile.am deleted file mode 100644 index f3e7f947a..000000000 --- a/VEX/head20041019/memcheck/tests/Makefile.am +++ /dev/null @@ -1,172 +0,0 @@ -##--------------------------------------------------------------------------- -## Need more tests: -## - lots more mmap/munmap/mremap/mprotect ones -##--------------------------------------------------------------------------- - -noinst_SCRIPTS = filter_allocs filter_leak_check_size \ - filter_stderr filter_stderr_backtrace filter_pushfpopf \ - filter_tronical - -INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2 - -EXTRA_DIST = $(noinst_SCRIPTS) \ - badaddrvalue.stderr.exp \ - badaddrvalue.stdout.exp badaddrvalue.vgtest \ - badfree-2trace.stderr.exp badfree-2trace.vgtest \ - badfree.stderr.exp badfree.vgtest \ - badjump.stderr.exp badjump.vgtest \ - badjump2.stderr.exp badjump2.vgtest \ - badloop.stderr.exp badloop.vgtest \ - badrw.stderr.exp badrw.vgtest \ - brk.stderr.exp brk.vgtest \ - brk2.stderr.exp brk2.vgtest \ - buflen_check.stderr.exp buflen_check.vgtest \ - clientperm.stderr.exp \ - clientperm.stdout.exp clientperm.vgtest \ - custom_alloc.stderr.exp custom_alloc.vgtest \ - doublefree.stderr.exp doublefree.vgtest \ - error_counts.stderr.exp error_counts.stdout.exp error_counts.vgtest \ - errs1.stderr.exp errs1.vgtest \ - exitprog.stderr.exp exitprog.vgtest \ - execve.stderr.exp execve.vgtest \ - execve2.stderr.exp execve2.vgtest \ - fpeflags.stderr.exp fpeflags.vgtest \ - fprw.stderr.exp fprw.vgtest \ - fwrite.stderr.exp fwrite.stdout.exp fwrite.vgtest \ - inits.stderr.exp inits.vgtest \ - inline.stderr.exp inline.stdout.exp inline.vgtest \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ - $(addsuffix .stdout.exp,$(INSN_TESTS)) \ - $(addsuffix .vgtest,$(INSN_TESTS)) \ - malloc1.stderr.exp malloc1.vgtest \ - malloc2.stderr.exp malloc2.vgtest \ - malloc3.stderr.exp malloc3.stdout.exp malloc3.vgtest \ - manuel1.stderr.exp manuel1.stdout.exp manuel1.vgtest \ - manuel2.stderr.exp manuel2.stdout.exp manuel2.vgtest \ - manuel3.stderr.exp manuel3.vgtest \ - memalign_test.stderr.exp memalign_test.vgtest \ - memalign2.stderr.exp memalign2.vgtest \ - memcmptest.stderr.exp memcmptest.stdout.exp memcmptest.vgtest \ - mempool.stderr.exp mempool.vgtest \ - mismatches.stderr.exp mismatches.vgtest \ - mmaptest.stderr.exp mmaptest.vgtest \ - nanoleak.stderr.exp nanoleak.vgtest \ - nanoleak_supp.stderr.exp nanoleak_supp.vgtest nanoleak.supp \ - new_nothrow.stderr.exp new_nothrow.vgtest \ - new_override.stderr.exp new_override.stdout.exp new_override.vgtest \ - null_socket.stderr.exp null_socket.vgtest \ - overlap.stderr.exp overlap.stdout.exp overlap.vgtest \ - pth_once.stderr.exp pth_once.stdout.exp pth_once.vgtest \ - pushfpopf.stderr.exp pushfpopf.stdout.exp pushfpopf.vgtest \ - realloc1.stderr.exp realloc1.vgtest \ - realloc2.stderr.exp realloc2.vgtest \ - realloc3.stderr.exp realloc3.vgtest \ - sigaltstack.stderr.exp sigaltstack.vgtest \ - signal2.stderr.exp \ - signal2.stdout.exp signal2.vgtest \ - supp1.stderr.exp supp1.vgtest \ - supp2.stderr.exp supp2.vgtest \ - supp.supp \ - suppfree.stderr.exp suppfree.vgtest \ - toobig-allocs.stderr.exp toobig-allocs.vgtest \ - trivialleak.stderr.exp trivialleak.vgtest \ - tronical.stderr.exp tronical.vgtest \ - weirdioctl.stderr.exp weirdioctl.stdout.exp weirdioctl.vgtest \ - metadata.stderr.exp metadata.stdout.exp metadata.vgtest \ - threadederrno.stderr.exp threadederrno.stdout.exp \ - threadederrno.vgtest \ - vgtest_ume.stderr.exp vgtest_ume.vgtest \ - writev.stderr.exp writev.vgtest \ - zeropage.stderr.exp zeropage.stderr.exp2 zeropage.vgtest - -check_PROGRAMS = \ - badaddrvalue badfree badjump badjump2 \ - badloop badrw brk brk2 buflen_check \ - clientperm custom_alloc \ - doublefree error_counts errs1 exitprog execve execve2 \ - fpeflags fprw fwrite hello inits inline \ - malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \ - memalign_test memalign2 memcmptest mempool mmaptest \ - nanoleak new_nothrow \ - null_socket overlap pushfpopf \ - realloc1 realloc2 realloc3 sigaltstack signal2 supp1 supp2 suppfree \ - trivialleak tronical weirdioctl \ - mismatches new_override metadata threadederrno \ - vgtest_ume \ - writev zeropage - - -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -AM_CXXFLAGS = $(AM_CFLAGS) - -# C ones -badaddrvalue_SOURCES = badaddrvalue.c -badfree_SOURCES = badfree.c -badjump_SOURCES = badjump.c -badjump2_SOURCES = badjump2.c -badloop_SOURCES = badloop.c -badrw_SOURCES = badrw.c -brk_SOURCES = brk.c -brk2_SOURCES = brk2.c -buflen_check_SOURCES = buflen_check.c -clientperm_SOURCES = clientperm.c -custom_alloc_SOURCES = custom_alloc.c -doublefree_SOURCES = doublefree.c -error_counts_SOURCES = error_counts.c -errs1_SOURCES = errs1.c -execve_SOURCES = execve.c -execve2_SOURCES = execve2.c -exitprog_SOURCES = exitprog.c -fpeflags_SOURCES = fpeflags.c -fprw_SOURCES = fprw.c -fwrite_SOURCES = fwrite.c -inits_SOURCES = inits.c -inline_SOURCES = inline.c -malloc1_SOURCES = malloc1.c -malloc2_SOURCES = malloc2.c -malloc3_SOURCES = malloc3.c -manuel1_SOURCES = manuel1.c -manuel2_SOURCES = manuel2.c -manuel3_SOURCES = manuel3.c -mmaptest_SOURCES = mmaptest.c -memalign_test_SOURCES = memalign_test.c -memalign2_SOURCES = memalign2.c -memcmptest_SOURCES = memcmptest.c -mempool_SOURCES = mempool.c -nanoleak_SOURCES = nanoleak.c -null_socket_SOURCES = null_socket.c -overlap_SOURCES = overlap.c -pushfpopf_SOURCES = pushfpopf_c.c pushfpopf_s.s -realloc1_SOURCES = realloc1.c -realloc2_SOURCES = realloc2.c -realloc3_SOURCES = realloc3.c -signal2_SOURCES = signal2.c -supp1_SOURCES = supp.c -supp2_SOURCES = supp.c -suppfree_SOURCES = suppfree.c -sigaltstack_SOURCES = sigaltstack.c -trivialleak_SOURCES = trivialleak.c -tronical_SOURCES = tronical.S -weirdioctl_SOURCES = weirdioctl.c -metadata_SOURCES = metadata.c -threadederrno_SOURCES = threadederrno.c -threadederrno_LDADD = -lpthread -writev_SOURCES = writev.c -zeropage_SOURCES = zeropage.c - -# C++ ones -mismatches_SOURCES = mismatches.cpp -new_nothrow_SOURCES = new_nothrow.cpp -new_override_SOURCES = new_override.cpp - -# Valgrind unit self-tests -hello_SOURCES = hello.c -hello_LDFLAGS = -Wl,-defsym,kickstart_base=0x50000000 \ - -Wl,-T,../../coregrind/${VG_ARCH}/stage2.lds -vgtest_ume_SOURCES = vgtest_ume.c -vgtest_ume_LDADD = ../../coregrind/ume.o \ - ../../coregrind/jmp_with_stack.o - -# must be built with these flags -- bug only occurred with them -fpeflags.o: CFLAGS += -march=i686 diff --git a/VEX/head20041019/memcheck/tests/badaddrvalue.c b/VEX/head20041019/memcheck/tests/badaddrvalue.c deleted file mode 100644 index 1bb204747..000000000 --- a/VEX/head20041019/memcheck/tests/badaddrvalue.c +++ /dev/null @@ -1,12 +0,0 @@ - -#include -#include - -int main ( void ) -{ - char* aa = malloc(8); - aa[-1] = 17; - if (aa[-1] == 17) - printf("17\n"); else printf("not 17\n"); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/badaddrvalue.stderr.exp b/VEX/head20041019/memcheck/tests/badaddrvalue.stderr.exp deleted file mode 100644 index f71df0bb0..000000000 --- a/VEX/head20041019/memcheck/tests/badaddrvalue.stderr.exp +++ /dev/null @@ -1,11 +0,0 @@ -Invalid write of size 1 - at 0x........: main (badaddrvalue.c:8) - Address 0x........ is 1 bytes before a block of size 8 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badaddrvalue.c:7) - -Invalid read of size 1 - at 0x........: main (badaddrvalue.c:9) - Address 0x........ is 1 bytes before a block of size 8 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badaddrvalue.c:7) diff --git a/VEX/head20041019/memcheck/tests/badaddrvalue.stdout.exp b/VEX/head20041019/memcheck/tests/badaddrvalue.stdout.exp deleted file mode 100644 index 98d9bcb75..000000000 --- a/VEX/head20041019/memcheck/tests/badaddrvalue.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -17 diff --git a/VEX/head20041019/memcheck/tests/badaddrvalue.vgtest b/VEX/head20041019/memcheck/tests/badaddrvalue.vgtest deleted file mode 100644 index 4d4b7f680..000000000 --- a/VEX/head20041019/memcheck/tests/badaddrvalue.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: badaddrvalue -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/badfree-2trace.stderr.exp b/VEX/head20041019/memcheck/tests/badfree-2trace.stderr.exp deleted file mode 100644 index fe7c5577b..000000000 --- a/VEX/head20041019/memcheck/tests/badfree-2trace.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (badfree.c:12) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (badfree.c:15) - Address 0x........ is on thread 1's stack diff --git a/VEX/head20041019/memcheck/tests/badfree-2trace.vgtest b/VEX/head20041019/memcheck/tests/badfree-2trace.vgtest deleted file mode 100644 index afeb3bb78..000000000 --- a/VEX/head20041019/memcheck/tests/badfree-2trace.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: --num-callers=2 -q -prog: badfree diff --git a/VEX/head20041019/memcheck/tests/badfree.c b/VEX/head20041019/memcheck/tests/badfree.c deleted file mode 100644 index 3a2256776..000000000 --- a/VEX/head20041019/memcheck/tests/badfree.c +++ /dev/null @@ -1,18 +0,0 @@ - - -#include -#include - -int main ( void ) -{ - void* p = (void*)0x87654321; - int q[] = { 1, 2, 3 }; - - /* Free a pointer to Never-Never Land */ - free(p); - - /* Free a pointer to a stack block */ - free(q); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/badfree.stderr.exp b/VEX/head20041019/memcheck/tests/badfree.stderr.exp deleted file mode 100644 index fe7c5577b..000000000 --- a/VEX/head20041019/memcheck/tests/badfree.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (badfree.c:12) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (badfree.c:15) - Address 0x........ is on thread 1's stack diff --git a/VEX/head20041019/memcheck/tests/badfree.vgtest b/VEX/head20041019/memcheck/tests/badfree.vgtest deleted file mode 100644 index dfe6e4227..000000000 --- a/VEX/head20041019/memcheck/tests/badfree.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: badfree -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/badjump.c b/VEX/head20041019/memcheck/tests/badjump.c deleted file mode 100644 index 053663be4..000000000 --- a/VEX/head20041019/memcheck/tests/badjump.c +++ /dev/null @@ -1,6 +0,0 @@ - -int main ( void ) -{ - char* p = (char*)0xE000000; - return ((int(*)(void)) p) (); -} diff --git a/VEX/head20041019/memcheck/tests/badjump.stderr.exp b/VEX/head20041019/memcheck/tests/badjump.stderr.exp deleted file mode 100644 index 155c5bafb..000000000 --- a/VEX/head20041019/memcheck/tests/badjump.stderr.exp +++ /dev/null @@ -1,18 +0,0 @@ - -Jump to the invalid address stated on the next line - at 0x........: ??? - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Process terminating with default action of signal 11 (SIGSEGV) - Access not within mapped region at address 0x........ - at 0x........: ??? - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - -ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 0 allocs, 0 frees, 0 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/badjump.vgtest b/VEX/head20041019/memcheck/tests/badjump.vgtest deleted file mode 100644 index 1e82b868d..000000000 --- a/VEX/head20041019/memcheck/tests/badjump.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: badjump diff --git a/VEX/head20041019/memcheck/tests/badjump2.c b/VEX/head20041019/memcheck/tests/badjump2.c deleted file mode 100644 index 361966b6c..000000000 --- a/VEX/head20041019/memcheck/tests/badjump2.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -#include - -// Regression test for bug 91162: if a client had a SEGV signal handler, -// and jumped to a bogus address, Valgrind would abort. With the fix, -// the following test runs to completion correctly. - -static jmp_buf myjmpbuf; - -static -void SIGSEGV_handler(int signum) -{ - __builtin_longjmp(myjmpbuf, 1); -} - -int main(void) -{ - struct sigaction sigsegv_new, sigsegv_saved; - int res; - - /* Install own SIGSEGV handler */ - sigsegv_new.sa_handler = SIGSEGV_handler; - sigsegv_new.sa_flags = 0; - sigsegv_new.sa_restorer = NULL; - res = sigemptyset( &sigsegv_new.sa_mask ); - assert(res == 0); - - res = sigaction( SIGSEGV, &sigsegv_new, &sigsegv_saved ); - assert(res == 0); - - if (__builtin_setjmp(myjmpbuf) == 0) { - // Jump to zero; will cause seg fault - void (*fn)(void) = 0; - fn(); - fprintf(stderr, "Got here??\n"); - } else { - fprintf(stderr, "Signal caught, as expected\n"); - } - - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/badjump2.stderr.exp b/VEX/head20041019/memcheck/tests/badjump2.stderr.exp deleted file mode 100644 index 04db2d9b7..000000000 --- a/VEX/head20041019/memcheck/tests/badjump2.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ -Jump to the invalid address stated on the next line - at 0x........: ??? - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Signal caught, as expected diff --git a/VEX/head20041019/memcheck/tests/badjump2.vgtest b/VEX/head20041019/memcheck/tests/badjump2.vgtest deleted file mode 100644 index 4256086d5..000000000 --- a/VEX/head20041019/memcheck/tests/badjump2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: badjump2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/badloop.c b/VEX/head20041019/memcheck/tests/badloop.c deleted file mode 100644 index 8780cf7f8..000000000 --- a/VEX/head20041019/memcheck/tests/badloop.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include - -int main ( void ) -{ - int a[5]; - int i, s; - a[0] = a[1] = a[3] = a[4] = 0; - s = 0; - for (i = 0; i < 5; i++) - s += a[i]; - if (s == 377) - printf("sum is %d\n", s); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/badloop.stderr.exp b/VEX/head20041019/memcheck/tests/badloop.stderr.exp deleted file mode 100644 index 4c53707ae..000000000 --- a/VEX/head20041019/memcheck/tests/badloop.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (badloop.c:12) diff --git a/VEX/head20041019/memcheck/tests/badloop.vgtest b/VEX/head20041019/memcheck/tests/badloop.vgtest deleted file mode 100644 index f0e215875..000000000 --- a/VEX/head20041019/memcheck/tests/badloop.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: badloop -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/badrw.c b/VEX/head20041019/memcheck/tests/badrw.c deleted file mode 100644 index d711ec969..000000000 --- a/VEX/head20041019/memcheck/tests/badrw.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -int main(void) -{ - void* x = malloc(10); - - int *x4; - short *x2; - char *x1; - int y4; - short y2; - char y1; - - x4 = x-4; - x2 = x-4; - x1 = x-1; - - // Invalid reads and writes of sizes 4, 2, 1 - y4 = *x4; - *x4 = y4; - - y2 = *x2; - *x2 = y2; - - y1 = *x1; - *x1 = y1; - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/badrw.stderr.exp b/VEX/head20041019/memcheck/tests/badrw.stderr.exp deleted file mode 100644 index 77c3f4a21..000000000 --- a/VEX/head20041019/memcheck/tests/badrw.stderr.exp +++ /dev/null @@ -1,35 +0,0 @@ -Invalid read of size 4 - at 0x........: main (badrw.c:19) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 4 - at 0x........: main (badrw.c:20) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid read of size 2 - at 0x........: main (badrw.c:22) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 2 - at 0x........: main (badrw.c:23) - Address 0x........ is 4 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid read of size 1 - at 0x........: main (badrw.c:25) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) - -Invalid write of size 1 - at 0x........: main (badrw.c:26) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (badrw.c:5) diff --git a/VEX/head20041019/memcheck/tests/badrw.vgtest b/VEX/head20041019/memcheck/tests/badrw.vgtest deleted file mode 100644 index 09c70a0ec..000000000 --- a/VEX/head20041019/memcheck/tests/badrw.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: badrw -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/brk.c b/VEX/head20041019/memcheck/tests/brk.c deleted file mode 100644 index 58c42604a..000000000 --- a/VEX/head20041019/memcheck/tests/brk.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include -#include - -// kernel brk() and libc brk() act quite differently... - -int main(void) -{ - int i; - void* orig_ds = sbrk(0); - void* ds = orig_ds; - void* vals[10]; - void* res; - - vals[0] = (void*)0; - vals[1] = (void*)1; - vals[2] = ds - 0x1; // small shrink - vals[3] = ds; - vals[4] = ds + 0x1000; // small growth - vals[5] = ds + 0x40000000; // too-big growth - vals[6] = ds + 0x500; // shrink a little, but still above start size - vals[7] = ds - 0x1; // shrink below start size -// vals[8] = ds - 0x1000; // shrink a lot below start size (into text) -// vals[9] = (void*)0xffffffff; - vals[8] = (void*)0xffffffff; - - for (i = 0; (void*)0xffffffff != vals[i]; i++) { - res = (void*)syscall(__NR_brk, vals[i]); - } - - assert( 0 == brk(orig_ds) ); // libc brk() - - for (i = 0; (void*)0xffffffff != vals[i]; i++) { - res = (void*)brk(vals[i]); - } - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/brk.stderr.exp b/VEX/head20041019/memcheck/tests/brk.stderr.exp deleted file mode 100644 index c4aa6f04f..000000000 --- a/VEX/head20041019/memcheck/tests/brk.stderr.exp +++ /dev/null @@ -1,7 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 0 allocs, 0 frees, 0 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/brk.vgtest b/VEX/head20041019/memcheck/tests/brk.vgtest deleted file mode 100644 index b1766ffc3..000000000 --- a/VEX/head20041019/memcheck/tests/brk.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: brk diff --git a/VEX/head20041019/memcheck/tests/brk2.c b/VEX/head20041019/memcheck/tests/brk2.c deleted file mode 100644 index 3a881335e..000000000 --- a/VEX/head20041019/memcheck/tests/brk2.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#define MAX 3000 - -// At one time, this was causing a seg fault within Valgrind -- it was when -// extending the brk segment onto a new page. Fixed in vg_syscalls.c 1.129. - -int main () { - char* ptr; - int i; - - for (i=0; i -#include -#include - -int main(void) -{ - struct sockaddr name; - int res1, res2; - int len = 10; - - res1 = socket(PF_UNIX, SOCK_STREAM, 0); - if (res1 == 0) { - fprintf(stderr, "socket() failed\n"); - exit(1); - } - - /* Valgrind 1.0.X doesn't report the second error */ - res1 = getsockname(-1, NULL, &len); /* NULL is bogus */ - res2 = getsockname(-1, &name, NULL); /* NULL is bogus */ - if (res1 == -1) { - fprintf(stderr, "getsockname(1) failed\n"); - } - if (res2 == -1) { - fprintf(stderr, "getsockname(2) failed\n"); - } - - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/buflen_check.stderr.exp b/VEX/head20041019/memcheck/tests/buflen_check.stderr.exp deleted file mode 100644 index 090ef489b..000000000 --- a/VEX/head20041019/memcheck/tests/buflen_check.stderr.exp +++ /dev/null @@ -1,13 +0,0 @@ -Syscall param socketcall.getsockname(name) contains unaddressable byte(s) - at 0x........: getsockname (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param socketcall.getsockname(namelen_in) contains uninitialised or unaddressable byte(s) - at 0x........: getsockname (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is not stack'd, malloc'd or (recently) free'd -getsockname(1) failed -getsockname(2) failed diff --git a/VEX/head20041019/memcheck/tests/buflen_check.vgtest b/VEX/head20041019/memcheck/tests/buflen_check.vgtest deleted file mode 100644 index c4c2f3dd5..000000000 --- a/VEX/head20041019/memcheck/tests/buflen_check.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: buflen_check -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/clientperm.c b/VEX/head20041019/memcheck/tests/clientperm.c deleted file mode 100644 index 27cb11a07..000000000 --- a/VEX/head20041019/memcheck/tests/clientperm.c +++ /dev/null @@ -1,39 +0,0 @@ - -#include -#include - -#include "../memcheck.h" - -int main1 ( void ) -{ - int xxx, i; - for (i = 0; i < 10; i++) VALGRIND_CHECK_DEFINED(xxx); - return 0; -} - -int main ( void ) -{ - int i, sum, m; - char* aa = calloc(100,1); - sum = 0; - - VALGRIND_CHECK_READABLE(aa,100); - - m = VALGRIND_MAKE_WRITABLE( &aa[49], 1 ); - VALGRIND_CHECK_WRITABLE(aa,100); - - printf("m_na: returned value is %d\n", m ); - - for (i = 0; i < 100; i++) - sum += aa[i]; - printf("sum is %s\n", sum > 0 ? "positive" : "non-positive"); - - m = VALGRIND_DISCARD(m); - printf("m_rm: returned value is %d\n", m ); - - for (i = 0; i < 100; i++) - sum += aa[i]; - printf("sum is %s\n", sum > 0 ? "positive" : "non-positive"); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/clientperm.stderr.exp b/VEX/head20041019/memcheck/tests/clientperm.stderr.exp deleted file mode 100644 index 5f93d81a2..000000000 --- a/VEX/head20041019/memcheck/tests/clientperm.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (clientperm.c:29) - -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (clientperm.c:36) diff --git a/VEX/head20041019/memcheck/tests/clientperm.stdout.exp b/VEX/head20041019/memcheck/tests/clientperm.stdout.exp deleted file mode 100644 index 7ab39d358..000000000 --- a/VEX/head20041019/memcheck/tests/clientperm.stdout.exp +++ /dev/null @@ -1,4 +0,0 @@ -m_na: returned value is 0 -sum is non-positive -m_rm: returned value is 0 -sum is non-positive diff --git a/VEX/head20041019/memcheck/tests/clientperm.vgtest b/VEX/head20041019/memcheck/tests/clientperm.vgtest deleted file mode 100644 index 7ddd5af99..000000000 --- a/VEX/head20041019/memcheck/tests/clientperm.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: clientperm -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/custom_alloc.c b/VEX/head20041019/memcheck/tests/custom_alloc.c deleted file mode 100644 index 36c7952e5..000000000 --- a/VEX/head20041019/memcheck/tests/custom_alloc.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include - -#include "../memcheck.h" - -#define SUPERBLOCK_SIZE 100000 - -//------------------------------------------------------------------------- -// Allocator -//------------------------------------------------------------------------- - -void* get_superblock(void) -{ - void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_ANON, -1, 0 ); - - assert(p != ((void*)(-1))); - - // Mark it no access; although it's addressible we don't want the - // program to be using it unless its handed out by custom_alloc() - - // with redzones, better not to have it - VALGRIND_MAKE_NOACCESS(p, SUPERBLOCK_SIZE); - - return p; -} - -// has a redzone -static void* custom_alloc(int size) -{ -#define RZ 8 - static void* hp = 0; // current heap pointer - static void* hp_lim = 0; // maximum usable byte in current block - int size2 = size + RZ*2; - void* p; - - if (hp + size2 > hp_lim) { - hp = get_superblock(); - hp_lim = hp + SUPERBLOCK_SIZE - 1; - } - - p = hp + RZ; - hp += size2; - - VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 ); - return (void*)p; -} - -static void custom_free(void* p) -{ - // don't actually free any memory... but mark it as freed - VALGRIND_FREELIKE_BLOCK( p, RZ ); -} -#undef RZ - - - -//------------------------------------------------------------------------- -// Rest -//------------------------------------------------------------------------- - -void make_leak(void) -{ - int* array2 = custom_alloc(sizeof(int) * 10); - array2 = 0; // leak - return; -} - -int main(void) -{ - int* array; - int* array3; - - array = custom_alloc(sizeof(int) * 10); - array[8] = 8; - array[9] = 8; - array[10] = 10; // invalid write (ok w/o MALLOCLIKE -- in superblock) - - custom_free(array); // ok - - custom_free(NULL); // invalid free (ok without MALLOCLIKE) - - array3 = malloc(sizeof(int) * 10); - custom_free(array3); // mismatched free (ok without MALLOCLIKE) - - make_leak(); - return array[0]; // use after free (ok without MALLOCLIKE/MAKE_NOACCESS) - // (nb: initialised because is_zeroed==1 above) - // unfortunately not identified as being in a free'd - // block because the freeing of the block and shadow - // chunk isn't postponed. - - // leak from make_leak() -} diff --git a/VEX/head20041019/memcheck/tests/custom_alloc.stderr.exp b/VEX/head20041019/memcheck/tests/custom_alloc.stderr.exp deleted file mode 100644 index b727b5fd1..000000000 --- a/VEX/head20041019/memcheck/tests/custom_alloc.stderr.exp +++ /dev/null @@ -1,25 +0,0 @@ -Invalid write of size 4 - at 0x........: main (custom_alloc.c:79) - Address 0x........ is 48 bytes inside a block of size 100000 client-defined - at 0x........: get_superblock (custom_alloc.c:25) - by 0x........: custom_alloc (custom_alloc.c:40) - by 0x........: main (custom_alloc.c:76) - -Invalid free() / delete / delete[] - at 0x........: custom_free (custom_alloc.c:54) - by 0x........: main (custom_alloc.c:83) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Mismatched free() / delete / delete [] - at 0x........: custom_free (custom_alloc.c:54) - by 0x........: main (custom_alloc.c:86) - Address 0x........ is 0 bytes inside a block of size 40 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (custom_alloc.c:85) - -Invalid read of size 4 - at 0x........: main (custom_alloc.c:89) - Address 0x........ is 8 bytes inside a block of size 100000 client-defined - at 0x........: get_superblock (custom_alloc.c:25) - by 0x........: custom_alloc (custom_alloc.c:40) - by 0x........: main (custom_alloc.c:76) diff --git a/VEX/head20041019/memcheck/tests/custom_alloc.vgtest b/VEX/head20041019/memcheck/tests/custom_alloc.vgtest deleted file mode 100644 index 9c7fa4106..000000000 --- a/VEX/head20041019/memcheck/tests/custom_alloc.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: custom_alloc -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/doublefree.c b/VEX/head20041019/memcheck/tests/doublefree.c deleted file mode 100644 index 3c2705081..000000000 --- a/VEX/head20041019/memcheck/tests/doublefree.c +++ /dev/null @@ -1,12 +0,0 @@ - -#include -#include - -int main ( void ) -{ - int i; - void* p = malloc(177); - for (i = 0; i < 2; i++) - free(p); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/doublefree.stderr.exp b/VEX/head20041019/memcheck/tests/doublefree.stderr.exp deleted file mode 100644 index 364f73842..000000000 --- a/VEX/head20041019/memcheck/tests/doublefree.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (doublefree.c:10) - Address 0x........ is 0 bytes inside a block of size 177 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (doublefree.c:10) diff --git a/VEX/head20041019/memcheck/tests/doublefree.vgtest b/VEX/head20041019/memcheck/tests/doublefree.vgtest deleted file mode 100644 index f2be68ce0..000000000 --- a/VEX/head20041019/memcheck/tests/doublefree.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: doublefree -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/error_counts.c b/VEX/head20041019/memcheck/tests/error_counts.c deleted file mode 100644 index 2cf1060b3..000000000 --- a/VEX/head20041019/memcheck/tests/error_counts.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include "../memcheck.h" - -int main(void) -{ - int x; - int y = 0; - int* reachable; - int* dubious; - int* leaked; - int n_reachable = 0; - int n_dubious = 0; - int n_leaked = 0; - int n_suppressed = 0; - - /* Error counting */ - printf("errors: %d\n", VALGRIND_COUNT_ERRORS); - - if (x == 0) { - y++; - } else { - y--; - } - - printf("errors: %d\n", VALGRIND_COUNT_ERRORS); - - /* Leak checking */ - VALGRIND_DO_LEAK_CHECK; - VALGRIND_COUNT_LEAKS(n_leaked, n_dubious, n_reachable, n_suppressed); - if (n_reachable == 24) n_reachable = 0; /* handle glibc differences */ - printf("leaks: %dB, %dB, %dB, %dB\n", - n_leaked, n_dubious, n_reachable, n_suppressed); - - leaked = malloc(77); - leaked = 0; - - dubious = malloc(88); - dubious += 10; - - reachable = malloc(99); - - VALGRIND_DO_LEAK_CHECK; - VALGRIND_DO_LEAK_CHECK; - VALGRIND_COUNT_LEAKS(n_leaked, n_dubious, n_reachable, n_suppressed); - if (n_reachable == 147) n_reachable = 99; /* handle glibc differences */ - printf("leaks: %dB, %dB, %dB, %dB\n", - n_leaked, n_dubious, n_reachable, n_suppressed); - - printf("errors: %d\n", VALGRIND_COUNT_ERRORS); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/error_counts.stderr.exp b/VEX/head20041019/memcheck/tests/error_counts.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/error_counts.stdout.exp b/VEX/head20041019/memcheck/tests/error_counts.stdout.exp deleted file mode 100644 index ea11aad9b..000000000 --- a/VEX/head20041019/memcheck/tests/error_counts.stdout.exp +++ /dev/null @@ -1,5 +0,0 @@ -errors: 0 -errors: 1 -leaks: 0B, 0B, 0B, 0B -leaks: 77B, 88B, 99B, 0B -errors: 1 diff --git a/VEX/head20041019/memcheck/tests/error_counts.vgtest b/VEX/head20041019/memcheck/tests/error_counts.vgtest deleted file mode 100644 index a2bed401c..000000000 --- a/VEX/head20041019/memcheck/tests/error_counts.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: --log-fd=-1 -prog: error_counts diff --git a/VEX/head20041019/memcheck/tests/errs1.c b/VEX/head20041019/memcheck/tests/errs1.c deleted file mode 100644 index 754f84443..000000000 --- a/VEX/head20041019/memcheck/tests/errs1.c +++ /dev/null @@ -1,17 +0,0 @@ - -#include -#include - -char* p; - -void ddd ( void ) { p[-1] += 'z'; } -void ccc ( void ) { ddd(); } -void bbb ( void ) { ccc(); } -void aaa ( void ) { bbb(); } - -void zzzzzzz ( void ) { p = malloc(10); } -void yyy ( void ) { zzzzzzz(); } -void xxx ( void ) { yyy(); } -void www ( void ) { xxx(); } - -int main ( void ) { www(); aaa(); return 0; } diff --git a/VEX/head20041019/memcheck/tests/errs1.stderr.exp b/VEX/head20041019/memcheck/tests/errs1.stderr.exp deleted file mode 100644 index 7b5f0fe2f..000000000 --- a/VEX/head20041019/memcheck/tests/errs1.stderr.exp +++ /dev/null @@ -1,21 +0,0 @@ -Invalid read of size 1 - at 0x........: ddd (errs1.c:7) - by 0x........: bbb (errs1.c:9) - by 0x........: aaa (errs1.c:10) - by 0x........: main (errs1.c:17) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: zzzzzzz (errs1.c:12) - by 0x........: yyy (errs1.c:13) - by 0x........: xxx (errs1.c:14) - -Invalid write of size 1 - at 0x........: ddd (errs1.c:7) - by 0x........: bbb (errs1.c:9) - by 0x........: aaa (errs1.c:10) - by 0x........: main (errs1.c:17) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: zzzzzzz (errs1.c:12) - by 0x........: yyy (errs1.c:13) - by 0x........: xxx (errs1.c:14) diff --git a/VEX/head20041019/memcheck/tests/errs1.vgtest b/VEX/head20041019/memcheck/tests/errs1.vgtest deleted file mode 100644 index bd780f9af..000000000 --- a/VEX/head20041019/memcheck/tests/errs1.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: errs1 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/execve.c b/VEX/head20041019/memcheck/tests/execve.c deleted file mode 100644 index 0e8222d43..000000000 --- a/VEX/head20041019/memcheck/tests/execve.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -int main(void) -{ - char* bad[2] = { (char*)1, NULL }; - char* good[1] = { NULL }; - - execve(NULL, bad, bad); - execve("/bin/true", good, good); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/execve.stderr.exp b/VEX/head20041019/memcheck/tests/execve.stderr.exp deleted file mode 100644 index 14dd1d13f..000000000 --- a/VEX/head20041019/memcheck/tests/execve.stderr.exp +++ /dev/null @@ -1,14 +0,0 @@ -Syscall param execve(filename) contains uninitialised or unaddressable byte(s) - at 0x........: execve (in /...libc...) - by 0x........: main (execve.c:8) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param execve(argv[i]) contains uninitialised or unaddressable byte(s) - at 0x........: execve (in /...libc...) - by 0x........: main (execve.c:8) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Syscall param execve(envp[i]) contains uninitialised or unaddressable byte(s) - at 0x........: execve (in /...libc...) - by 0x........: main (execve.c:8) - Address 0x........ is not stack'd, malloc'd or (recently) free'd diff --git a/VEX/head20041019/memcheck/tests/execve.vgtest b/VEX/head20041019/memcheck/tests/execve.vgtest deleted file mode 100644 index 51a8d514c..000000000 --- a/VEX/head20041019/memcheck/tests/execve.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: execve -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/execve2.c b/VEX/head20041019/memcheck/tests/execve2.c deleted file mode 100644 index c3eae2c2f..000000000 --- a/VEX/head20041019/memcheck/tests/execve2.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main(void) -{ - execve(NULL, NULL, NULL); - execve("../../tests/true", NULL, NULL); - assert(0); // shouldn't get here -} diff --git a/VEX/head20041019/memcheck/tests/execve2.stderr.exp b/VEX/head20041019/memcheck/tests/execve2.stderr.exp deleted file mode 100644 index c2cadf7d9..000000000 --- a/VEX/head20041019/memcheck/tests/execve2.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ -Syscall param execve(filename) contains uninitialised or unaddressable byte(s) - at 0x........: execve (in /...libc...) - by 0x........: main (execve2.c:6) - Address 0x........ is not stack'd, malloc'd or (recently) free'd diff --git a/VEX/head20041019/memcheck/tests/execve2.vgtest b/VEX/head20041019/memcheck/tests/execve2.vgtest deleted file mode 100644 index 9636ad835..000000000 --- a/VEX/head20041019/memcheck/tests/execve2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: execve2 -vgopts: -q --trace-children=yes diff --git a/VEX/head20041019/memcheck/tests/exitprog.c b/VEX/head20041019/memcheck/tests/exitprog.c deleted file mode 100644 index 4f1c46a88..000000000 --- a/VEX/head20041019/memcheck/tests/exitprog.c +++ /dev/null @@ -1,26 +0,0 @@ - - -#include -#include -#include - -#define ZILLION 1000000 - -void foo ( void ); -void bar ( void ); - -int main ( void ) -{ - int i; - char* a = malloc(ZILLION * sizeof(char)); - for (i = 0; i <= ZILLION; i++) { - foo(); - a[i] = 0; - bar(); - } - a = (char*)177; - _exit(1); -} - -void foo ( void ) { } -void bar ( void ) { } diff --git a/VEX/head20041019/memcheck/tests/exitprog.stderr.exp b/VEX/head20041019/memcheck/tests/exitprog.stderr.exp deleted file mode 100644 index c1fa55be7..000000000 --- a/VEX/head20041019/memcheck/tests/exitprog.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ -Invalid write of size 1 - at 0x........: main (exitprog.c:18) - Address 0x........ is 0 bytes after a block of size 1000000 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (exitprog.c:15) diff --git a/VEX/head20041019/memcheck/tests/exitprog.vgtest b/VEX/head20041019/memcheck/tests/exitprog.vgtest deleted file mode 100644 index 970762ad8..000000000 --- a/VEX/head20041019/memcheck/tests/exitprog.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: exitprog -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/filter_allocs b/VEX/head20041019/memcheck/tests/filter_allocs deleted file mode 100755 index 9ad6d23c4..000000000 --- a/VEX/head20041019/memcheck/tests/filter_allocs +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh - -./filter_stderr | -sed "s/malloc\/free: in use at exit: [0-9]* bytes in [0-9]* blocks./malloc\/free: in use at exit: ... bytes in ... blocks./" | -sed "s/malloc.free: [0-9]* allocs, [0-9]* frees, [0-9]* bytes allocated./malloc\/free: ... allocs, ... frees, ... bytes allocated./" - diff --git a/VEX/head20041019/memcheck/tests/filter_leak_check_size b/VEX/head20041019/memcheck/tests/filter_leak_check_size deleted file mode 100755 index 0cb482a46..000000000 --- a/VEX/head20041019/memcheck/tests/filter_leak_check_size +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh - -./filter_stderr | -sed "s/checked [0-9]* bytes./checked ... bytes./" diff --git a/VEX/head20041019/memcheck/tests/filter_pushfpopf b/VEX/head20041019/memcheck/tests/filter_pushfpopf deleted file mode 100755 index 90e3d70c1..000000000 --- a/VEX/head20041019/memcheck/tests/filter_pushfpopf +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/sh - -./filter_stderr | -sed "s/: fooble ([^)]*)/: fooble (...)/" - diff --git a/VEX/head20041019/memcheck/tests/filter_stderr b/VEX/head20041019/memcheck/tests/filter_stderr deleted file mode 100755 index 4c583fbad..000000000 --- a/VEX/head20041019/memcheck/tests/filter_stderr +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh - -dir=`dirname $0` - -$dir/../../tests/filter_stderr_basic | - -# Anonymise addresses -$dir/../../tests/filter_addresses | - -# Anonymise line numbers in mac_replace_strmem.c -sed "s/mac_replace_strmem.c:[0-9]*/mac_replace_strmem.c:.../" | - -$dir/../../tests/filter_test_paths | - -# Anonymise paths like "(in /foo/bar/libc-baz.so)" -sed "s/(in \/.*libc.*)$/(in \/...libc...)/" | - -# Anonymise paths like "(within /foo/bar/libc-baz.so)" -sed "s/(within \/.*libc.*)$/(within \/...libc...)/" | - -# Anonymise paths like "xxx (../sysdeps/unix/sysv/linux/quux.c:129)" -sed "s/(\.\.\/sysdeps\/unix\/sysv\/linux\/.*\.c:[0-9]*)$/(in \/...libc...)/" | - -# Anonymise paths like "__libc_start_main (../foo/bar/libc-quux.c:129)" -sed "s/__libc_\(.*\) (.*)$/__libc_\1 (...libc...)/" - diff --git a/VEX/head20041019/memcheck/tests/filter_stderr_backtrace b/VEX/head20041019/memcheck/tests/filter_stderr_backtrace deleted file mode 100755 index f5ba472f4..000000000 --- a/VEX/head20041019/memcheck/tests/filter_stderr_backtrace +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -./filter_stderr | -sed "/^ by 0x........: /d" diff --git a/VEX/head20041019/memcheck/tests/filter_tronical b/VEX/head20041019/memcheck/tests/filter_tronical deleted file mode 100755 index e1739bbd9..000000000 --- a/VEX/head20041019/memcheck/tests/filter_tronical +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh - -./filter_stderr | \ -sed "s/: get ([^)]*)/: get (...)/" | -sed "s/: main ([^)]*)/: main (...)/" - diff --git a/VEX/head20041019/memcheck/tests/fpeflags.c b/VEX/head20041019/memcheck/tests/fpeflags.c deleted file mode 100644 index 4bedcd5b4..000000000 --- a/VEX/head20041019/memcheck/tests/fpeflags.c +++ /dev/null @@ -1,22 +0,0 @@ -#include - -struct instance -{ - unsigned myVal:1; -}; - -static struct instance* myInstance; - -int main(int argc, char** argv) -{ - float g = 1.0f; - - myInstance = malloc(sizeof(struct instance)); - - myInstance->myVal = 1; - - if (g == 1.0f) - return 0; - else - return 1; -} diff --git a/VEX/head20041019/memcheck/tests/fpeflags.stderr.exp b/VEX/head20041019/memcheck/tests/fpeflags.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/fpeflags.vgtest b/VEX/head20041019/memcheck/tests/fpeflags.vgtest deleted file mode 100644 index 88ae11d59..000000000 --- a/VEX/head20041019/memcheck/tests/fpeflags.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: fpeflags diff --git a/VEX/head20041019/memcheck/tests/fprw.c b/VEX/head20041019/memcheck/tests/fprw.c deleted file mode 100644 index 556d8a035..000000000 --- a/VEX/head20041019/memcheck/tests/fprw.c +++ /dev/null @@ -1,26 +0,0 @@ - -/* most of the nasties in this are in the same bb, so you need to run -with --single-step=yes to get them properly distinguished. */ - -#include - -int main ( void ) -{ - volatile double d; - volatile float f; - double* dp = malloc(sizeof(double)); - float* fp = malloc(sizeof(float)); - int* ip = (int*)0x1234567; - d += 1.0; - f += 10.0; - *dp += 2.0; - *fp += 20.0; - free(dp); - free(fp); - *dp += 3.0; - *fp += 30.0; - free(ip); - ip = malloc(sizeof(int)); - * ((double*)ip) = 1.2 + d; - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/fprw.stderr.exp b/VEX/head20041019/memcheck/tests/fprw.stderr.exp deleted file mode 100644 index cf082691b..000000000 --- a/VEX/head20041019/memcheck/tests/fprw.stderr.exp +++ /dev/null @@ -1,46 +0,0 @@ -Use of uninitialised value of size 8 - at 0x........: main (fprw.c:14) - -Use of uninitialised value of size 4 - at 0x........: main (fprw.c:15) - -Use of uninitialised value of size 8 - at 0x........: main (fprw.c:16) - -Use of uninitialised value of size 4 - at 0x........: main (fprw.c:17) - -Invalid read of size 8 - at 0x........: main (fprw.c:20) - Address 0x........ is 0 bytes inside a block of size 8 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:18) - -Invalid write of size 8 - at 0x........: main (fprw.c:20) - Address 0x........ is 0 bytes inside a block of size 8 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:18) - -Invalid read of size 4 - at 0x........: main (fprw.c:21) - Address 0x........ is 0 bytes inside a block of size 4 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:19) - -Invalid write of size 4 - at 0x........: main (fprw.c:21) - Address 0x........ is 0 bytes inside a block of size 4 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:19) - -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:22) - Address 0x........ is not stack'd, malloc'd or (recently) free'd - -Invalid write of size 8 - at 0x........: main (fprw.c:24) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (fprw.c:23) diff --git a/VEX/head20041019/memcheck/tests/fprw.vgtest b/VEX/head20041019/memcheck/tests/fprw.vgtest deleted file mode 100644 index 6dfbf0cb4..000000000 --- a/VEX/head20041019/memcheck/tests/fprw.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: fprw diff --git a/VEX/head20041019/memcheck/tests/fwrite.c b/VEX/head20041019/memcheck/tests/fwrite.c deleted file mode 100644 index 1eec4a4f8..000000000 --- a/VEX/head20041019/memcheck/tests/fwrite.c +++ /dev/null @@ -1,9 +0,0 @@ - -#include -#include -int main ( void ) -{ - char* arr = malloc(10); - (void) write( 1 /* stdout */, arr, 10 ); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/fwrite.stderr.exp b/VEX/head20041019/memcheck/tests/fwrite.stderr.exp deleted file mode 100644 index 76f922190..000000000 --- a/VEX/head20041019/memcheck/tests/fwrite.stderr.exp +++ /dev/null @@ -1,7 +0,0 @@ -Syscall param write(buf) contains uninitialised or unaddressable byte(s) - at 0x........: write (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is 0 bytes inside a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (fwrite.c:6) diff --git a/VEX/head20041019/memcheck/tests/fwrite.stdout.exp b/VEX/head20041019/memcheck/tests/fwrite.stdout.exp deleted file mode 100644 index cb43b5ce1..000000000 Binary files a/VEX/head20041019/memcheck/tests/fwrite.stdout.exp and /dev/null differ diff --git a/VEX/head20041019/memcheck/tests/fwrite.vgtest b/VEX/head20041019/memcheck/tests/fwrite.vgtest deleted file mode 100644 index 83d2341ee..000000000 --- a/VEX/head20041019/memcheck/tests/fwrite.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: fwrite -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/hello.c b/VEX/head20041019/memcheck/tests/hello.c deleted file mode 100644 index 836b36f2c..000000000 --- a/VEX/head20041019/memcheck/tests/hello.c +++ /dev/null @@ -1,9 +0,0 @@ - -#include - -int main(void) -{ - fprintf(stderr, "Hello, world!\n"); - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/inits.c b/VEX/head20041019/memcheck/tests/inits.c deleted file mode 100644 index 7dd0c93c0..000000000 --- a/VEX/head20041019/memcheck/tests/inits.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include - -/* Static and global vars are inited to zero, non-static local vars aren't. */ - -int g; -static int gs; - -int main(void) -{ - int l; - static int ls; - - if (gs == 0xDEADBEEF) printf("1!\n"); - if (g == 0xDEADBEEF) printf("2!\n"); - if (ls == 0xDEADBEEF) printf("3!\n"); - if (l == 0xDEADBEEF) printf("4!\n"); // complains - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/inits.stderr.exp b/VEX/head20041019/memcheck/tests/inits.stderr.exp deleted file mode 100644 index a190cfa91..000000000 --- a/VEX/head20041019/memcheck/tests/inits.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (inits.c:17) diff --git a/VEX/head20041019/memcheck/tests/inits.vgtest b/VEX/head20041019/memcheck/tests/inits.vgtest deleted file mode 100644 index 6d77500c5..000000000 --- a/VEX/head20041019/memcheck/tests/inits.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: inits -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/inline.c b/VEX/head20041019/memcheck/tests/inline.c deleted file mode 100644 index cb023b27d..000000000 --- a/VEX/head20041019/memcheck/tests/inline.c +++ /dev/null @@ -1,21 +0,0 @@ - -#include -#include - -__inline__ -static int addemup ( int* arr ) -{ - int i, j = 0; - for (i = 0; i <= 10; i++) - j += arr[i]; - return j; -} - -int main ( void ) -{ - int sum; - int* a = calloc(10, sizeof(int)); - sum = addemup(a); - printf("sum is %d\n", sum); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/inline.stderr.exp b/VEX/head20041019/memcheck/tests/inline.stderr.exp deleted file mode 100644 index 639b31e97..000000000 --- a/VEX/head20041019/memcheck/tests/inline.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ -Invalid read of size 4 - at 0x........: addemup (inline.c:10) - by 0x........: main (inline.c:18) - Address 0x........ is 0 bytes after a block of size 40 alloc'd - at 0x........: calloc (vg_replace_malloc.c:...) - by 0x........: main (inline.c:17) diff --git a/VEX/head20041019/memcheck/tests/inline.stdout.exp b/VEX/head20041019/memcheck/tests/inline.stdout.exp deleted file mode 100644 index ad1401ed8..000000000 --- a/VEX/head20041019/memcheck/tests/inline.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -sum is 0 diff --git a/VEX/head20041019/memcheck/tests/inline.vgtest b/VEX/head20041019/memcheck/tests/inline.vgtest deleted file mode 100644 index 4f5e14367..000000000 --- a/VEX/head20041019/memcheck/tests/inline.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: inline -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/insn_basic.stderr.exp b/VEX/head20041019/memcheck/tests/insn_basic.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_basic.stdout.exp b/VEX/head20041019/memcheck/tests/insn_basic.stdout.exp deleted file mode 100644 index 40cabbcd0..000000000 --- a/VEX/head20041019/memcheck/tests/insn_basic.stdout.exp +++ /dev/null @@ -1,1083 +0,0 @@ -aaa_1 ... ok -aaa_2 ... ok -aaa_3 ... ok -aaa_4 ... ok -aaa_5 ... ok -aaa_6 ... ok -aaa_7 ... ok -aaa_8 ... ok -aad_1 ... ok -aad_2 ... ok -aam_1 ... ok -aam_2 ... ok -aas_1 ... ok -aas_2 ... ok -aas_3 ... ok -aas_4 ... ok -aas_5 ... ok -aas_6 ... ok -aas_7 ... ok -aas_8 ... ok -adcb_1 ... ok -adcb_2 ... ok -adcb_3 ... ok -adcb_4 ... ok -adcb_5 ... ok -adcb_6 ... ok -adcb_7 ... ok -adcb_8 ... ok -adcb_9 ... ok -adcb_10 ... ok -adcb_11 ... ok -adcb_12 ... ok -adcw_1 ... ok -adcw_2 ... ok -adcw_3 ... ok -adcw_4 ... ok -adcw_5 ... ok -adcw_6 ... ok -adcw_7 ... ok -adcw_8 ... ok -adcw_9 ... ok -adcw_10 ... ok -adcw_11 ... ok -adcw_12 ... ok -adcw_13 ... ok -adcw_14 ... ok -adcl_1 ... ok -adcl_2 ... ok -adcl_3 ... ok -adcl_4 ... ok -adcl_5 ... ok -adcl_6 ... ok -adcl_7 ... ok -adcl_8 ... ok -adcl_9 ... ok -adcl_10 ... ok -adcl_11 ... ok -adcl_12 ... ok -adcl_13 ... ok -adcl_14 ... ok -addb_1 ... ok -addb_2 ... ok -addb_3 ... ok -addb_4 ... ok -addb_5 ... ok -addb_6 ... ok -addw_1 ... ok -addw_2 ... ok -addw_3 ... ok -addw_4 ... ok -addw_5 ... ok -addw_6 ... ok -addw_7 ... ok -addl_1 ... ok -addl_2 ... ok -addl_3 ... ok -addl_4 ... ok -addl_5 ... ok -addl_6 ... ok -addl_7 ... ok -andb_1 ... ok -andb_2 ... ok -andb_3 ... ok -andb_4 ... ok -andb_5 ... ok -andb_6 ... ok -andw_1 ... ok -andw_2 ... ok -andw_3 ... ok -andw_4 ... ok -andw_5 ... ok -andw_6 ... ok -andw_7 ... ok -andl_1 ... ok -andl_2 ... ok -andl_3 ... ok -andl_4 ... ok -andl_5 ... ok -andl_6 ... ok -andl_7 ... ok -bsfw_1 ... ok -bsfw_2 ... ok -bsfl_1 ... ok -bsfl_2 ... ok -bsrw_1 ... ok -bsrw_2 ... ok -bsrl_1 ... ok -bsrl_2 ... ok -bswapl_1 ... ok -btw_1 ... ok -btw_2 ... ok -btw_3 ... ok -btw_4 ... ok -btw_5 ... ok -btw_6 ... ok -btw_7 ... ok -btw_8 ... ok -btl_1 ... ok -btl_2 ... ok -btl_3 ... ok -btl_4 ... ok -btl_5 ... ok -btl_6 ... ok -btl_7 ... ok -btl_8 ... ok -btcw_1 ... ok -btcw_2 ... ok -btcw_3 ... ok -btcw_4 ... ok -btcw_5 ... ok -btcw_6 ... ok -btcw_7 ... ok -btcw_8 ... ok -btcl_1 ... ok -btcl_2 ... ok -btcl_3 ... ok -btcl_4 ... ok -btcl_5 ... ok -btcl_6 ... ok -btcl_7 ... ok -btcl_8 ... ok -btrw_1 ... ok -btrw_2 ... ok -btrw_3 ... ok -btrw_4 ... ok -btrw_5 ... ok -btrw_6 ... ok -btrw_7 ... ok -btrw_8 ... ok -btrl_1 ... ok -btrl_2 ... ok -btrl_3 ... ok -btrl_4 ... ok -btrl_5 ... ok -btrl_6 ... ok -btrl_7 ... ok -btrl_8 ... ok -btsw_1 ... ok -btsw_2 ... ok -btsw_3 ... ok -btsw_4 ... ok -btsw_5 ... ok -btsw_6 ... ok -btsw_7 ... ok -btsw_8 ... ok -btsl_1 ... ok -btsl_2 ... ok -btsl_3 ... ok -btsl_4 ... ok -btsl_5 ... ok -btsl_6 ... ok -btsl_7 ... ok -btsl_8 ... ok -cbw_1 ... ok -cbw_2 ... ok -cdq_1 ... ok -cdq_2 ... ok -clc_1 ... ok -clc_2 ... ok -cld_1 ... ok -cld_2 ... ok -cmc_1 ... ok -cmc_2 ... ok -cmpb_1 ... ok -cmpb_2 ... ok -cmpb_3 ... ok -cmpb_4 ... ok -cmpb_5 ... ok -cmpb_6 ... ok -cmpb_7 ... ok -cmpb_8 ... ok -cmpb_9 ... ok -cmpb_10 ... ok -cmpb_11 ... ok -cmpb_12 ... ok -cmpb_13 ... ok -cmpb_14 ... ok -cmpb_15 ... ok -cmpb_16 ... ok -cmpb_17 ... ok -cmpb_18 ... ok -cmpb_19 ... ok -cmpb_20 ... ok -cmpb_21 ... ok -cmpb_22 ... ok -cmpb_23 ... ok -cmpb_24 ... ok -cmpb_25 ... ok -cmpb_26 ... ok -cmpb_27 ... ok -cmpb_28 ... ok -cmpb_29 ... ok -cmpb_30 ... ok -cmpb_31 ... ok -cmpb_32 ... ok -cmpb_33 ... ok -cmpb_34 ... ok -cmpb_35 ... ok -cmpb_36 ... ok -cmpb_37 ... ok -cmpb_38 ... ok -cmpb_39 ... ok -cmpb_40 ... ok -cmpb_41 ... ok -cmpb_42 ... ok -cmpb_43 ... ok -cmpb_44 ... ok -cmpb_45 ... ok -cmpb_46 ... ok -cmpb_47 ... ok -cmpb_48 ... ok -cmpb_49 ... ok -cmpb_50 ... ok -cmpb_51 ... ok -cmpb_52 ... ok -cmpb_53 ... ok -cmpb_54 ... ok -cmpb_55 ... ok -cmpb_56 ... ok -cmpb_57 ... ok -cmpb_58 ... ok -cmpb_59 ... ok -cmpb_60 ... ok -cmpw_1 ... ok -cmpw_2 ... ok -cmpw_3 ... ok -cmpw_4 ... ok -cmpw_5 ... ok -cmpw_6 ... ok -cmpw_7 ... ok -cmpw_8 ... ok -cmpw_9 ... ok -cmpw_10 ... ok -cmpw_11 ... ok -cmpw_12 ... ok -cmpw_13 ... ok -cmpw_14 ... ok -cmpw_15 ... ok -cmpw_16 ... ok -cmpw_17 ... ok -cmpw_18 ... ok -cmpw_19 ... ok -cmpw_20 ... ok -cmpw_21 ... ok -cmpw_22 ... ok -cmpw_23 ... ok -cmpw_24 ... ok -cmpw_25 ... ok -cmpw_26 ... ok -cmpw_27 ... ok -cmpw_28 ... ok -cmpw_29 ... ok -cmpw_30 ... ok -cmpw_31 ... ok -cmpw_32 ... ok -cmpw_33 ... ok -cmpw_34 ... ok -cmpw_35 ... ok -cmpw_36 ... ok -cmpw_37 ... ok -cmpw_38 ... ok -cmpw_39 ... ok -cmpw_40 ... ok -cmpw_41 ... ok -cmpw_42 ... ok -cmpw_43 ... ok -cmpw_44 ... ok -cmpw_45 ... ok -cmpw_46 ... ok -cmpw_47 ... ok -cmpw_48 ... ok -cmpw_49 ... ok -cmpw_50 ... ok -cmpw_51 ... ok -cmpw_52 ... ok -cmpw_53 ... ok -cmpw_54 ... ok -cmpw_55 ... ok -cmpw_56 ... ok -cmpw_57 ... ok -cmpw_58 ... ok -cmpw_59 ... ok -cmpw_60 ... ok -cmpw_61 ... ok -cmpw_62 ... ok -cmpw_63 ... ok -cmpw_64 ... ok -cmpw_65 ... ok -cmpw_66 ... ok -cmpw_67 ... ok -cmpw_68 ... ok -cmpw_69 ... ok -cmpw_70 ... ok -cmpw_71 ... ok -cmpw_72 ... ok -cmpw_73 ... ok -cmpw_74 ... ok -cmpw_75 ... ok -cmpw_76 ... ok -cmpw_77 ... ok -cmpw_78 ... ok -cmpw_79 ... ok -cmpw_80 ... ok -cmpl_1 ... ok -cmpl_2 ... ok -cmpl_3 ... ok -cmpl_4 ... ok -cmpl_5 ... ok -cmpl_6 ... ok -cmpl_7 ... ok -cmpl_8 ... ok -cmpl_9 ... ok -cmpl_10 ... ok -cmpl_11 ... ok -cmpl_12 ... ok -cmpl_13 ... ok -cmpl_14 ... ok -cmpl_15 ... ok -cmpl_16 ... ok -cmpl_17 ... ok -cmpl_18 ... ok -cmpl_19 ... ok -cmpl_20 ... ok -cmpl_21 ... ok -cmpl_22 ... ok -cmpl_23 ... ok -cmpl_24 ... ok -cmpl_25 ... ok -cmpl_26 ... ok -cmpl_27 ... ok -cmpl_28 ... ok -cmpl_29 ... ok -cmpl_30 ... ok -cmpl_31 ... ok -cmpl_32 ... ok -cmpl_33 ... ok -cmpl_34 ... ok -cmpl_35 ... ok -cmpl_36 ... ok -cmpl_37 ... ok -cmpl_38 ... ok -cmpl_39 ... ok -cmpl_40 ... ok -cmpl_41 ... ok -cmpl_42 ... ok -cmpl_43 ... ok -cmpl_44 ... ok -cmpl_45 ... ok -cmpl_46 ... ok -cmpl_47 ... ok -cmpl_48 ... ok -cmpl_49 ... ok -cmpl_50 ... ok -cmpl_51 ... ok -cmpl_52 ... ok -cmpl_53 ... ok -cmpl_54 ... ok -cmpl_55 ... ok -cmpl_56 ... ok -cmpl_57 ... ok -cmpl_58 ... ok -cmpl_59 ... ok -cmpl_60 ... ok -cmpl_61 ... ok -cmpl_62 ... ok -cmpl_63 ... ok -cmpl_64 ... ok -cmpl_65 ... ok -cmpl_66 ... ok -cmpl_67 ... ok -cmpl_68 ... ok -cmpl_69 ... ok -cmpl_70 ... ok -cmpl_71 ... ok -cmpl_72 ... ok -cmpl_73 ... ok -cmpl_74 ... ok -cmpl_75 ... ok -cmpl_76 ... ok -cmpl_77 ... ok -cmpl_78 ... ok -cmpl_79 ... ok -cmpl_80 ... ok -cmpxchgb_1 ... ok -cmpxchgb_2 ... ok -cmpxchgb_3 ... ok -cmpxchgb_4 ... ok -cmpxchgw_1 ... ok -cmpxchgw_2 ... ok -cmpxchgw_3 ... ok -cmpxchgw_4 ... ok -cmpxchgl_1 ... ok -cmpxchgl_2 ... ok -cmpxchgl_3 ... ok -cmpxchgl_4 ... ok -cwd_1 ... ok -cwd_2 ... ok -cwde_1 ... ok -cwde_2 ... ok -daa_1 ... ok -daa_2 ... ok -das_1 ... ok -decb_1 ... ok -decb_2 ... ok -decw_1 ... ok -decw_2 ... ok -decl_1 ... ok -decl_2 ... ok -divb_1 ... ok -divb_2 ... ok -divw_1 ... ok -divw_2 ... ok -divl_1 ... ok -divl_2 ... ok -idivb_1 ... ok -idivb_2 ... ok -idivw_1 ... ok -idivw_2 ... ok -idivl_1 ... ok -idivl_2 ... ok -imulb_1 ... ok -imulb_2 ... ok -imulw_1 ... ok -imulw_2 ... ok -imull_1 ... ok -imull_2 ... ok -imulw_3 ... ok -imulw_4 ... ok -imulw_5 ... ok -imulw_6 ... ok -imulw_7 ... ok -imulw_8 ... ok -imulw_9 ... ok -imulw_10 ... ok -imull_3 ... ok -imull_4 ... ok -imull_5 ... ok -imull_6 ... ok -imull_7 ... ok -imull_8 ... ok -imull_9 ... ok -imull_10 ... ok -incb_1 ... ok -incb_2 ... ok -incw_1 ... ok -incw_2 ... ok -incl_1 ... ok -incl_2 ... ok -lahf_1 ... ok -lahf_2 ... ok -movb_1 ... ok -movb_2 ... ok -movb_3 ... ok -movb_4 ... ok -movb_5 ... ok -movw_1 ... ok -movw_2 ... ok -movw_3 ... ok -movw_4 ... ok -movw_5 ... ok -movl_1 ... ok -movl_2 ... ok -movl_3 ... ok -movl_4 ... ok -movl_5 ... ok -movsbw_1 ... ok -movsbw_2 ... ok -movsbl_1 ... ok -movsbl_2 ... ok -movswl_1 ... ok -movswl_2 ... ok -movzbw_1 ... ok -movzbw_2 ... ok -movzbl_1 ... ok -movzbl_2 ... ok -movzwl_1 ... ok -movzwl_2 ... ok -mulb_1 ... ok -mulb_2 ... ok -mulw_1 ... ok -mulw_2 ... ok -mull_1 ... ok -mull_2 ... ok -negb_1 ... ok -negb_2 ... ok -negw_1 ... ok -negw_2 ... ok -negl_1 ... ok -negl_2 ... ok -notb_1 ... ok -notb_2 ... ok -notw_1 ... ok -notw_2 ... ok -notl_1 ... ok -notl_2 ... ok -orb_1 ... ok -orb_2 ... ok -orb_3 ... ok -orb_4 ... ok -orb_5 ... ok -orb_6 ... ok -orw_1 ... ok -orw_2 ... ok -orw_3 ... ok -orw_4 ... ok -orw_5 ... ok -orw_6 ... ok -orw_7 ... ok -orl_1 ... ok -orl_2 ... ok -orl_3 ... ok -orl_4 ... ok -orl_5 ... ok -orl_6 ... ok -orl_7 ... ok -rclb_1 ... ok -rclb_2 ... ok -rclb_3 ... ok -rclb_4 ... ok -rclb_5 ... ok -rclb_6 ... ok -rclw_1 ... ok -rclw_2 ... ok -rclw_3 ... ok -rclw_4 ... ok -rclw_5 ... ok -rclw_6 ... ok -rcll_1 ... ok -rcll_2 ... ok -rcll_3 ... ok -rcll_4 ... ok -rcll_5 ... ok -rcll_6 ... ok -rcrb_1 ... ok -rcrb_2 ... ok -rcrb_3 ... ok -rcrb_4 ... ok -rcrb_5 ... ok -rcrb_6 ... ok -rcrw_1 ... ok -rcrw_2 ... ok -rcrw_3 ... ok -rcrw_4 ... ok -rcrw_5 ... ok -rcrw_6 ... ok -rcrl_1 ... ok -rcrl_2 ... ok -rcrl_3 ... ok -rcrl_4 ... ok -rcrl_5 ... ok -rcrl_6 ... ok -rolb_1 ... ok -rolb_2 ... ok -rolb_3 ... ok -rolb_4 ... ok -rolb_5 ... ok -rolb_6 ... ok -rolw_1 ... ok -rolw_2 ... ok -rolw_3 ... ok -rolw_4 ... ok -rolw_5 ... ok -rolw_6 ... ok -roll_1 ... ok -roll_2 ... ok -roll_3 ... ok -roll_4 ... ok -roll_5 ... ok -roll_6 ... ok -rorb_1 ... ok -rorb_2 ... ok -rorb_3 ... ok -rorb_4 ... ok -rorb_5 ... ok -rorb_6 ... ok -rorw_1 ... ok -rorw_2 ... ok -rorw_3 ... ok -rorw_4 ... ok -rorw_5 ... ok -rorw_6 ... ok -rorl_1 ... ok -rorl_2 ... ok -rorl_3 ... ok -rorl_4 ... ok -rorl_5 ... ok -rorl_6 ... ok -sahf_1 ... ok -sahf_2 ... ok -salb_1 ... ok -salb_2 ... ok -salb_3 ... ok -salb_4 ... ok -salb_5 ... ok -salb_6 ... ok -salw_1 ... ok -salw_2 ... ok -salw_3 ... ok -salw_4 ... ok -salw_5 ... ok -salw_6 ... ok -sall_1 ... ok -sall_2 ... ok -sall_3 ... ok -sall_4 ... ok -sall_5 ... ok -sall_6 ... ok -sarb_1 ... ok -sarb_2 ... ok -sarb_3 ... ok -sarb_4 ... ok -sarb_5 ... ok -sarb_6 ... ok -sarw_1 ... ok -sarw_2 ... ok -sarw_3 ... ok -sarw_4 ... ok -sarw_5 ... ok -sarw_6 ... ok -sarl_1 ... ok -sarl_2 ... ok -sarl_3 ... ok -sarl_4 ... ok -sarl_5 ... ok -sarl_6 ... ok -sbbb_1 ... ok -sbbb_2 ... ok -sbbb_3 ... ok -sbbb_4 ... ok -sbbb_5 ... ok -sbbb_6 ... ok -sbbb_7 ... ok -sbbb_8 ... ok -sbbb_9 ... ok -sbbb_10 ... ok -sbbb_11 ... ok -sbbb_12 ... ok -sbbw_1 ... ok -sbbw_2 ... ok -sbbw_3 ... ok -sbbw_4 ... ok -sbbw_5 ... ok -sbbw_6 ... ok -sbbw_7 ... ok -sbbw_8 ... ok -sbbw_9 ... ok -sbbw_10 ... ok -sbbw_11 ... ok -sbbw_12 ... ok -sbbw_13 ... ok -sbbw_14 ... ok -sbbl_1 ... ok -sbbl_2 ... ok -sbbl_3 ... ok -sbbl_4 ... ok -sbbl_5 ... ok -sbbl_6 ... ok -sbbl_7 ... ok -sbbl_8 ... ok -sbbl_9 ... ok -sbbl_10 ... ok -sbbl_11 ... ok -sbbl_12 ... ok -sbbl_13 ... ok -sbbl_14 ... ok -seta_1 ... ok -seta_2 ... ok -seta_3 ... ok -seta_4 ... ok -seta_5 ... ok -seta_6 ... ok -seta_7 ... ok -seta_8 ... ok -setae_1 ... ok -setae_2 ... ok -setae_3 ... ok -setae_4 ... ok -setb_1 ... ok -setb_2 ... ok -setb_3 ... ok -setb_4 ... ok -setbe_1 ... ok -setbe_2 ... ok -setbe_3 ... ok -setbe_4 ... ok -setbe_5 ... ok -setbe_6 ... ok -setbe_7 ... ok -setbe_8 ... ok -setc_1 ... ok -setc_2 ... ok -setc_3 ... ok -setc_4 ... ok -sete_1 ... ok -sete_2 ... ok -sete_3 ... ok -sete_4 ... ok -setg_1 ... ok -setg_2 ... ok -setg_3 ... ok -setg_4 ... ok -setg_5 ... ok -setg_6 ... ok -setg_7 ... ok -setg_8 ... ok -setg_9 ... ok -setg_10 ... ok -setg_11 ... ok -setg_12 ... ok -setg_13 ... ok -setg_14 ... ok -setg_15 ... ok -setg_16 ... ok -setge_1 ... ok -setge_2 ... ok -setge_3 ... ok -setge_4 ... ok -setge_5 ... ok -setge_6 ... ok -setge_7 ... ok -setge_8 ... ok -setl_1 ... ok -setl_2 ... ok -setl_3 ... ok -setl_4 ... ok -setl_5 ... ok -setl_6 ... ok -setl_7 ... ok -setl_8 ... ok -setle_1 ... ok -setle_2 ... ok -setle_3 ... ok -setle_4 ... ok -setle_5 ... ok -setle_6 ... ok -setle_7 ... ok -setle_8 ... ok -setle_9 ... ok -setle_10 ... ok -setle_11 ... ok -setle_12 ... ok -setle_13 ... ok -setle_14 ... ok -setle_15 ... ok -setle_16 ... ok -setna_1 ... ok -setna_2 ... ok -setna_3 ... ok -setna_4 ... ok -setna_5 ... ok -setna_6 ... ok -setna_7 ... ok -setna_8 ... ok -setnae_1 ... ok -setnae_2 ... ok -setnae_3 ... ok -setnae_4 ... ok -setnb_1 ... ok -setnb_2 ... ok -setnb_3 ... ok -setnb_4 ... ok -setnbe_1 ... ok -setnbe_2 ... ok -setnbe_3 ... ok -setnbe_4 ... ok -setnbe_5 ... ok -setnbe_6 ... ok -setnbe_7 ... ok -setnbe_8 ... ok -setnc_1 ... ok -setnc_2 ... ok -setnc_3 ... ok -setnc_4 ... ok -setne_1 ... ok -setne_2 ... ok -setne_3 ... ok -setne_4 ... ok -setng_1 ... ok -setng_2 ... ok -setng_3 ... ok -setng_4 ... ok -setng_5 ... ok -setng_6 ... ok -setng_7 ... ok -setng_8 ... ok -setng_9 ... ok -setng_10 ... ok -setng_11 ... ok -setng_12 ... ok -setng_13 ... ok -setng_14 ... ok -setng_15 ... ok -setng_16 ... ok -setnge_1 ... ok -setnge_2 ... ok -setnge_3 ... ok -setnge_4 ... ok -setnge_5 ... ok -setnge_6 ... ok -setnge_7 ... ok -setnge_8 ... ok -setnl_1 ... ok -setnl_2 ... ok -setnl_3 ... ok -setnl_4 ... ok -setnl_5 ... ok -setnl_6 ... ok -setnl_7 ... ok -setnl_8 ... ok -setnle_1 ... ok -setnle_2 ... ok -setnle_3 ... ok -setnle_4 ... ok -setnle_5 ... ok -setnle_6 ... ok -setnle_7 ... ok -setnle_8 ... ok -setnle_9 ... ok -setnle_10 ... ok -setnle_11 ... ok -setnle_12 ... ok -setnle_13 ... ok -setnle_14 ... ok -setnle_15 ... ok -setnle_16 ... ok -setno_1 ... ok -setno_2 ... ok -setno_3 ... ok -setno_4 ... ok -setnp_1 ... ok -setnp_2 ... ok -setnp_3 ... ok -setnp_4 ... ok -setns_1 ... ok -setns_2 ... ok -setns_3 ... ok -setns_4 ... ok -setnz_1 ... ok -setnz_2 ... ok -setnz_3 ... ok -setnz_4 ... ok -seto_1 ... ok -seto_2 ... ok -seto_3 ... ok -seto_4 ... ok -setp_1 ... ok -setp_2 ... ok -setp_3 ... ok -setp_4 ... ok -sets_1 ... ok -sets_2 ... ok -sets_3 ... ok -sets_4 ... ok -setz_1 ... ok -setz_2 ... ok -setz_3 ... ok -setz_4 ... ok -shlb_1 ... ok -shlb_2 ... ok -shlb_3 ... ok -shlb_4 ... ok -shlb_5 ... ok -shlb_6 ... ok -shlw_1 ... ok -shlw_2 ... ok -shlw_3 ... ok -shlw_4 ... ok -shlw_5 ... ok -shlw_6 ... ok -shll_1 ... ok -shll_2 ... ok -shll_3 ... ok -shll_4 ... ok -shll_5 ... ok -shll_6 ... ok -shrb_1 ... ok -shrb_2 ... ok -shrb_3 ... ok -shrb_4 ... ok -shrb_5 ... ok -shrb_6 ... ok -shrw_1 ... ok -shrw_2 ... ok -shrw_3 ... ok -shrw_4 ... ok -shrw_5 ... ok -shrw_6 ... ok -shrl_1 ... ok -shrl_2 ... ok -shrl_3 ... ok -shrl_4 ... ok -shrl_5 ... ok -shrl_6 ... ok -shldw_1 ... ok -shldw_2 ... ok -shldw_3 ... ok -shldw_4 ... ok -shldw_5 ... ok -shldw_6 ... ok -shldw_7 ... ok -shldw_8 ... ok -shldl_1 ... ok -shldl_2 ... ok -shldl_3 ... ok -shldl_4 ... ok -shldl_5 ... ok -shldl_6 ... ok -shldl_7 ... ok -shldl_8 ... ok -shrdw_1 ... ok -shrdw_2 ... ok -shrdw_3 ... ok -shrdw_4 ... ok -shrdw_5 ... ok -shrdw_6 ... ok -shrdw_7 ... ok -shrdw_8 ... ok -shrdl_1 ... ok -shrdl_2 ... ok -shrdl_3 ... ok -shrdl_4 ... ok -shrdl_5 ... ok -shrdl_6 ... ok -shrdl_7 ... ok -shrdl_8 ... ok -stc_1 ... ok -stc_2 ... ok -std_1 ... ok -std_2 ... ok -subb_1 ... ok -subb_2 ... ok -subb_3 ... ok -subb_4 ... ok -subb_5 ... ok -subb_6 ... ok -subw_1 ... ok -subw_2 ... ok -subw_3 ... ok -subw_4 ... ok -subw_5 ... ok -subw_6 ... ok -subw_7 ... ok -subl_1 ... ok -subl_2 ... ok -subl_3 ... ok -subl_4 ... ok -subl_5 ... ok -subl_6 ... ok -subl_7 ... ok -testb_1 ... ok -testb_2 ... ok -testb_3 ... ok -testb_4 ... ok -testb_5 ... ok -testb_6 ... ok -testb_7 ... ok -testb_8 ... ok -testb_9 ... ok -testb_10 ... ok -testb_11 ... ok -testb_12 ... ok -testb_13 ... ok -testb_14 ... ok -testb_15 ... ok -testb_16 ... ok -testb_17 ... ok -testb_18 ... ok -testb_19 ... ok -testb_20 ... ok -testb_21 ... ok -testb_22 ... ok -testb_23 ... ok -testb_24 ... ok -testb_25 ... ok -testw_1 ... ok -testw_2 ... ok -testw_3 ... ok -testw_4 ... ok -testw_5 ... ok -testw_6 ... ok -testw_7 ... ok -testw_8 ... ok -testw_9 ... ok -testw_10 ... ok -testw_11 ... ok -testw_12 ... ok -testw_13 ... ok -testw_14 ... ok -testw_15 ... ok -testw_16 ... ok -testw_17 ... ok -testw_18 ... ok -testw_19 ... ok -testw_20 ... ok -testw_21 ... ok -testw_22 ... ok -testw_23 ... ok -testw_24 ... ok -testw_25 ... ok -testl_1 ... ok -testl_2 ... ok -testl_3 ... ok -testl_4 ... ok -testl_5 ... ok -testl_6 ... ok -testl_7 ... ok -testl_8 ... ok -testl_9 ... ok -testl_10 ... ok -testl_11 ... ok -testl_12 ... ok -testl_13 ... ok -testl_14 ... ok -testl_15 ... ok -testl_16 ... ok -testl_17 ... ok -testl_18 ... ok -testl_19 ... ok -testl_20 ... ok -testl_21 ... ok -testl_22 ... ok -testl_23 ... ok -testl_24 ... ok -testl_25 ... ok -xaddb_1 ... ok -xaddb_2 ... ok -xaddw_1 ... ok -xaddw_2 ... ok -xaddl_1 ... ok -xaddl_2 ... ok -xchgb_1 ... ok -xchgb_2 ... ok -xchgb_3 ... ok -xchgw_1 ... ok -xchgw_2 ... ok -xchgw_3 ... ok -xchgw_4 ... ok -xchgw_5 ... ok -xchgl_1 ... ok -xchgl_2 ... ok -xchgl_3 ... ok -xchgl_4 ... ok -xchgl_5 ... ok -xorb_1 ... ok -xorb_2 ... ok -xorb_3 ... ok -xorb_4 ... ok -xorb_5 ... ok -xorb_6 ... ok -xorw_1 ... ok -xorw_2 ... ok -xorw_3 ... ok -xorw_4 ... ok -xorw_5 ... ok -xorw_6 ... ok -xorw_7 ... ok -xorl_1 ... ok -xorl_2 ... ok -xorl_3 ... ok -xorl_4 ... ok -xorl_5 ... ok -xorl_6 ... ok -xorl_7 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_basic.vgtest b/VEX/head20041019/memcheck/tests/insn_basic.vgtest deleted file mode 100644 index f5329ea81..000000000 --- a/VEX/head20041019/memcheck/tests/insn_basic.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_basic diff --git a/VEX/head20041019/memcheck/tests/insn_cmov.stderr.exp b/VEX/head20041019/memcheck/tests/insn_cmov.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_cmov.stdout.exp b/VEX/head20041019/memcheck/tests/insn_cmov.stdout.exp deleted file mode 100644 index 31ac17204..000000000 --- a/VEX/head20041019/memcheck/tests/insn_cmov.stdout.exp +++ /dev/null @@ -1,384 +0,0 @@ -cmova_1 ... ok -cmova_2 ... ok -cmova_3 ... ok -cmova_4 ... ok -cmova_5 ... ok -cmova_6 ... ok -cmova_7 ... ok -cmova_8 ... ok -cmovae_1 ... ok -cmovae_2 ... ok -cmovae_3 ... ok -cmovae_4 ... ok -cmovb_1 ... ok -cmovb_2 ... ok -cmovb_3 ... ok -cmovb_4 ... ok -cmovbe_1 ... ok -cmovbe_2 ... ok -cmovbe_3 ... ok -cmovbe_4 ... ok -cmovbe_5 ... ok -cmovbe_6 ... ok -cmovbe_7 ... ok -cmovbe_8 ... ok -cmovc_1 ... ok -cmovc_2 ... ok -cmovc_3 ... ok -cmovc_4 ... ok -cmove_1 ... ok -cmove_2 ... ok -cmove_3 ... ok -cmove_4 ... ok -cmovg_1 ... ok -cmovg_2 ... ok -cmovg_3 ... ok -cmovg_4 ... ok -cmovg_5 ... ok -cmovg_6 ... ok -cmovg_7 ... ok -cmovg_8 ... ok -cmovg_9 ... ok -cmovg_10 ... ok -cmovg_11 ... ok -cmovg_12 ... ok -cmovg_13 ... ok -cmovg_14 ... ok -cmovg_15 ... ok -cmovg_16 ... ok -cmovge_1 ... ok -cmovge_2 ... ok -cmovge_3 ... ok -cmovge_4 ... ok -cmovge_5 ... ok -cmovge_6 ... ok -cmovge_7 ... ok -cmovge_8 ... ok -cmovl_1 ... ok -cmovl_2 ... ok -cmovl_3 ... ok -cmovl_4 ... ok -cmovl_5 ... ok -cmovl_6 ... ok -cmovl_7 ... ok -cmovl_8 ... ok -cmovle_1 ... ok -cmovle_2 ... ok -cmovle_3 ... ok -cmovle_4 ... ok -cmovle_5 ... ok -cmovle_6 ... ok -cmovle_7 ... ok -cmovle_8 ... ok -cmovle_9 ... ok -cmovle_10 ... ok -cmovle_11 ... ok -cmovle_12 ... ok -cmovle_13 ... ok -cmovle_14 ... ok -cmovle_15 ... ok -cmovle_16 ... ok -cmovna_1 ... ok -cmovna_2 ... ok -cmovna_3 ... ok -cmovna_4 ... ok -cmovna_5 ... ok -cmovna_6 ... ok -cmovna_7 ... ok -cmovna_8 ... ok -cmovnae_1 ... ok -cmovnae_2 ... ok -cmovnae_3 ... ok -cmovnae_4 ... ok -cmovnb_1 ... ok -cmovnb_2 ... ok -cmovnb_3 ... ok -cmovnb_4 ... ok -cmovnbe_1 ... ok -cmovnbe_2 ... ok -cmovnbe_3 ... ok -cmovnbe_4 ... ok -cmovnbe_5 ... ok -cmovnbe_6 ... ok -cmovnbe_7 ... ok -cmovnbe_8 ... ok -cmovnc_1 ... ok -cmovnc_2 ... ok -cmovnc_3 ... ok -cmovnc_4 ... ok -cmovne_1 ... ok -cmovne_2 ... ok -cmovne_3 ... ok -cmovne_4 ... ok -cmovng_1 ... ok -cmovng_2 ... ok -cmovng_3 ... ok -cmovng_4 ... ok -cmovng_5 ... ok -cmovng_6 ... ok -cmovng_7 ... ok -cmovng_8 ... ok -cmovng_9 ... ok -cmovng_10 ... ok -cmovng_11 ... ok -cmovng_12 ... ok -cmovng_13 ... ok -cmovng_14 ... ok -cmovng_15 ... ok -cmovng_16 ... ok -cmovnge_1 ... ok -cmovnge_2 ... ok -cmovnge_3 ... ok -cmovnge_4 ... ok -cmovnge_5 ... ok -cmovnge_6 ... ok -cmovnge_7 ... ok -cmovnge_8 ... ok -cmovnl_1 ... ok -cmovnl_2 ... ok -cmovnl_3 ... ok -cmovnl_4 ... ok -cmovnl_5 ... ok -cmovnl_6 ... ok -cmovnl_7 ... ok -cmovnl_8 ... ok -cmovnle_1 ... ok -cmovnle_2 ... ok -cmovnle_3 ... ok -cmovnle_4 ... ok -cmovnle_5 ... ok -cmovnle_6 ... ok -cmovnle_7 ... ok -cmovnle_8 ... ok -cmovnle_9 ... ok -cmovnle_10 ... ok -cmovnle_11 ... ok -cmovnle_12 ... ok -cmovnle_13 ... ok -cmovnle_14 ... ok -cmovnle_15 ... ok -cmovnle_16 ... ok -cmovno_1 ... ok -cmovno_2 ... ok -cmovno_3 ... ok -cmovno_4 ... ok -cmovnp_1 ... ok -cmovnp_2 ... ok -cmovnp_3 ... ok -cmovnp_4 ... ok -cmovns_1 ... ok -cmovns_2 ... ok -cmovns_3 ... ok -cmovns_4 ... ok -cmovnz_1 ... ok -cmovnz_2 ... ok -cmovnz_3 ... ok -cmovnz_4 ... ok -cmovo_1 ... ok -cmovo_2 ... ok -cmovo_3 ... ok -cmovo_4 ... ok -cmovp_1 ... ok -cmovp_2 ... ok -cmovp_3 ... ok -cmovp_4 ... ok -cmovs_1 ... ok -cmovs_2 ... ok -cmovs_3 ... ok -cmovs_4 ... ok -cmovz_1 ... ok -cmovz_2 ... ok -cmovz_3 ... ok -cmovz_4 ... ok -cmova_9 ... ok -cmova_10 ... ok -cmova_11 ... ok -cmova_12 ... ok -cmova_13 ... ok -cmova_14 ... ok -cmova_15 ... ok -cmova_16 ... ok -cmovae_5 ... ok -cmovae_6 ... ok -cmovae_7 ... ok -cmovae_8 ... ok -cmovb_5 ... ok -cmovb_6 ... ok -cmovb_7 ... ok -cmovb_8 ... ok -cmovbe_9 ... ok -cmovbe_10 ... ok -cmovbe_11 ... ok -cmovbe_12 ... ok -cmovbe_13 ... ok -cmovbe_14 ... ok -cmovbe_15 ... ok -cmovbe_16 ... ok -cmovc_5 ... ok -cmovc_6 ... ok -cmovc_7 ... ok -cmovc_8 ... ok -cmove_5 ... ok -cmove_6 ... ok -cmove_7 ... ok -cmove_8 ... ok -cmovg_17 ... ok -cmovg_18 ... ok -cmovg_19 ... ok -cmovg_20 ... ok -cmovg_21 ... ok -cmovg_22 ... ok -cmovg_23 ... ok -cmovg_24 ... ok -cmovg_25 ... ok -cmovg_26 ... ok -cmovg_27 ... ok -cmovg_28 ... ok -cmovg_29 ... ok -cmovg_30 ... ok -cmovg_31 ... ok -cmovg_32 ... ok -cmovge_9 ... ok -cmovge_10 ... ok -cmovge_11 ... ok -cmovge_12 ... ok -cmovge_13 ... ok -cmovge_14 ... ok -cmovge_15 ... ok -cmovge_16 ... ok -cmovl_9 ... ok -cmovl_10 ... ok -cmovl_11 ... ok -cmovl_12 ... ok -cmovl_13 ... ok -cmovl_14 ... ok -cmovl_15 ... ok -cmovl_16 ... ok -cmovle_17 ... ok -cmovle_18 ... ok -cmovle_19 ... ok -cmovle_20 ... ok -cmovle_21 ... ok -cmovle_22 ... ok -cmovle_23 ... ok -cmovle_24 ... ok -cmovle_25 ... ok -cmovle_26 ... ok -cmovle_27 ... ok -cmovle_28 ... ok -cmovle_29 ... ok -cmovle_30 ... ok -cmovle_31 ... ok -cmovle_32 ... ok -cmovna_9 ... ok -cmovna_10 ... ok -cmovna_11 ... ok -cmovna_12 ... ok -cmovna_13 ... ok -cmovna_14 ... ok -cmovna_15 ... ok -cmovna_16 ... ok -cmovnae_5 ... ok -cmovnae_6 ... ok -cmovnae_7 ... ok -cmovnae_8 ... ok -cmovnb_5 ... ok -cmovnb_6 ... ok -cmovnb_7 ... ok -cmovnb_8 ... ok -cmovnbe_9 ... ok -cmovnbe_10 ... ok -cmovnbe_11 ... ok -cmovnbe_12 ... ok -cmovnbe_13 ... ok -cmovnbe_14 ... ok -cmovnbe_15 ... ok -cmovnbe_16 ... ok -cmovnc_5 ... ok -cmovnc_6 ... ok -cmovnc_7 ... ok -cmovnc_8 ... ok -cmovne_5 ... ok -cmovne_6 ... ok -cmovne_7 ... ok -cmovne_8 ... ok -cmovng_17 ... ok -cmovng_18 ... ok -cmovng_19 ... ok -cmovng_20 ... ok -cmovng_21 ... ok -cmovng_22 ... ok -cmovng_23 ... ok -cmovng_24 ... ok -cmovng_25 ... ok -cmovng_26 ... ok -cmovng_27 ... ok -cmovng_28 ... ok -cmovng_29 ... ok -cmovng_30 ... ok -cmovng_31 ... ok -cmovng_32 ... ok -cmovnge_9 ... ok -cmovnge_10 ... ok -cmovnge_11 ... ok -cmovnge_12 ... ok -cmovnge_13 ... ok -cmovnge_14 ... ok -cmovnge_15 ... ok -cmovnge_16 ... ok -cmovnl_9 ... ok -cmovnl_10 ... ok -cmovnl_11 ... ok -cmovnl_12 ... ok -cmovnl_13 ... ok -cmovnl_14 ... ok -cmovnl_15 ... ok -cmovnl_16 ... ok -cmovnle_17 ... ok -cmovnle_18 ... ok -cmovnle_19 ... ok -cmovnle_20 ... ok -cmovnle_21 ... ok -cmovnle_22 ... ok -cmovnle_23 ... ok -cmovnle_24 ... ok -cmovnle_25 ... ok -cmovnle_26 ... ok -cmovnle_27 ... ok -cmovnle_28 ... ok -cmovnle_29 ... ok -cmovnle_30 ... ok -cmovnle_31 ... ok -cmovnle_32 ... ok -cmovno_5 ... ok -cmovno_6 ... ok -cmovno_7 ... ok -cmovno_8 ... ok -cmovnp_5 ... ok -cmovnp_6 ... ok -cmovnp_7 ... ok -cmovnp_8 ... ok -cmovns_5 ... ok -cmovns_6 ... ok -cmovns_7 ... ok -cmovns_8 ... ok -cmovnz_5 ... ok -cmovnz_6 ... ok -cmovnz_7 ... ok -cmovnz_8 ... ok -cmovo_5 ... ok -cmovo_6 ... ok -cmovo_7 ... ok -cmovo_8 ... ok -cmovp_5 ... ok -cmovp_6 ... ok -cmovp_7 ... ok -cmovp_8 ... ok -cmovs_5 ... ok -cmovs_6 ... ok -cmovs_7 ... ok -cmovs_8 ... ok -cmovz_5 ... ok -cmovz_6 ... ok -cmovz_7 ... ok -cmovz_8 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_cmov.vgtest b/VEX/head20041019/memcheck/tests/insn_cmov.vgtest deleted file mode 100644 index 0321a3ca8..000000000 --- a/VEX/head20041019/memcheck/tests/insn_cmov.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_cmov -cpu_test: cmov diff --git a/VEX/head20041019/memcheck/tests/insn_fpu.stderr.exp b/VEX/head20041019/memcheck/tests/insn_fpu.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_fpu.stdout.exp b/VEX/head20041019/memcheck/tests/insn_fpu.stdout.exp deleted file mode 100644 index 2dbaa07ce..000000000 --- a/VEX/head20041019/memcheck/tests/insn_fpu.stdout.exp +++ /dev/null @@ -1,452 +0,0 @@ -fabs_1 ... ok -fabs_2 ... ok -fabs_3 ... ok -fabs_4 ... ok -fadds_1 ... ok -fadds_2 ... ok -fadds_3 ... ok -fadds_4 ... ok -faddl_1 ... ok -faddl_2 ... ok -faddl_3 ... ok -faddl_4 ... ok -fadd_1 ... ok -fadd_2 ... ok -fadd_3 ... ok -fadd_4 ... ok -fadd_5 ... ok -fadd_6 ... ok -fadd_7 ... ok -fadd_8 ... ok -fadd_9 ... ok -fadd_10 ... ok -fadd_11 ... ok -fadd_12 ... ok -fadd_13 ... ok -fadd_14 ... ok -fadd_15 ... ok -fadd_16 ... ok -faddp_1 ... ok -faddp_2 ... ok -faddp_3 ... ok -faddp_4 ... ok -faddp_5 ... ok -faddp_6 ... ok -faddp_7 ... ok -faddp_8 ... ok -faddp_9 ... ok -faddp_10 ... ok -faddp_11 ... ok -faddp_12 ... ok -faddp_13 ... ok -faddp_14 ... ok -faddp_15 ... ok -faddp_16 ... ok -fiadds_1 ... ok -fiadds_2 ... ok -fiadds_3 ... ok -fiadds_4 ... ok -fiadds_5 ... ok -fiadds_6 ... ok -fiadds_7 ... ok -fiadds_8 ... ok -fiaddl_1 ... ok -fiaddl_2 ... ok -fiaddl_3 ... ok -fiaddl_4 ... ok -fiaddl_5 ... ok -fiaddl_6 ... ok -fiaddl_7 ... ok -fiaddl_8 ... ok -fcomi_1 ... ok -fcomi_2 ... ok -fcomi_3 ... ok -fcomi_4 ... ok -fcomi_5 ... ok -fcomi_6 ... ok -fcomip_1 ... ok -fcomip_2 ... ok -fcomip_3 ... ok -fcomip_4 ... ok -fcomip_5 ... ok -fcomip_6 ... ok -fucomi_1 ... ok -fucomi_2 ... ok -fucomi_3 ... ok -fucomi_4 ... ok -fucomi_5 ... ok -fucomi_6 ... ok -fucomip_1 ... ok -fucomip_2 ... ok -fucomip_3 ... ok -fucomip_4 ... ok -fucomip_5 ... ok -fucomip_6 ... ok -fchs_1 ... ok -fchs_2 ... ok -fchs_3 ... ok -fchs_4 ... ok -fdivs_1 ... ok -fdivs_2 ... ok -fdivs_3 ... ok -fdivs_4 ... ok -fdivl_1 ... ok -fdivl_2 ... ok -fdivl_3 ... ok -fdivl_4 ... ok -fdiv_1 ... ok -fdiv_2 ... ok -fdiv_3 ... ok -fdiv_4 ... ok -fdiv_5 ... ok -fdiv_6 ... ok -fdiv_7 ... ok -fdiv_8 ... ok -fdiv_9 ... ok -fdiv_10 ... ok -fdiv_11 ... ok -fdiv_12 ... ok -fdiv_13 ... ok -fdiv_14 ... ok -fdiv_15 ... ok -fdiv_16 ... ok -fdivp_1 ... ok -fdivp_2 ... ok -fdivp_3 ... ok -fdivp_4 ... ok -fdivp_5 ... ok -fdivp_6 ... ok -fdivp_7 ... ok -fdivp_8 ... ok -fdivp_9 ... ok -fdivp_10 ... ok -fdivp_11 ... ok -fdivp_12 ... ok -fdivp_13 ... ok -fdivp_14 ... ok -fdivp_15 ... ok -fdivp_16 ... ok -fidivs_1 ... ok -fidivs_2 ... ok -fidivs_3 ... ok -fidivs_4 ... ok -fidivs_5 ... ok -fidivs_6 ... ok -fidivs_7 ... ok -fidivs_8 ... ok -fidivl_1 ... ok -fidivl_2 ... ok -fidivl_3 ... ok -fidivl_4 ... ok -fidivl_5 ... ok -fidivl_6 ... ok -fidivl_7 ... ok -fidivl_8 ... ok -fdivrs_1 ... ok -fdivrs_2 ... ok -fdivrs_3 ... ok -fdivrs_4 ... ok -fdivrl_1 ... ok -fdivrl_2 ... ok -fdivrl_3 ... ok -fdivrl_4 ... ok -fdivr_1 ... ok -fdivr_2 ... ok -fdivr_3 ... ok -fdivr_4 ... ok -fdivr_5 ... ok -fdivr_6 ... ok -fdivr_7 ... ok -fdivr_8 ... ok -fdivr_9 ... ok -fdivr_10 ... ok -fdivr_11 ... ok -fdivr_12 ... ok -fdivr_13 ... ok -fdivr_14 ... ok -fdivr_15 ... ok -fdivr_16 ... ok -fdivrp_1 ... ok -fdivrp_2 ... ok -fdivrp_3 ... ok -fdivrp_4 ... ok -fdivrp_5 ... ok -fdivrp_6 ... ok -fdivrp_7 ... ok -fdivrp_8 ... ok -fdivrp_9 ... ok -fdivrp_10 ... ok -fdivrp_11 ... ok -fdivrp_12 ... ok -fdivrp_13 ... ok -fdivrp_14 ... ok -fdivrp_15 ... ok -fdivrp_16 ... ok -fidivrs_1 ... ok -fidivrs_2 ... ok -fidivrs_3 ... ok -fidivrs_4 ... ok -fidivrs_5 ... ok -fidivrs_6 ... ok -fidivrs_7 ... ok -fidivrs_8 ... ok -fidivrl_1 ... ok -fidivrl_2 ... ok -fidivrl_3 ... ok -fidivrl_4 ... ok -fidivrl_5 ... ok -fidivrl_6 ... ok -fidivrl_7 ... ok -fidivrl_8 ... ok -filds_1 ... ok -filds_2 ... ok -filds_3 ... ok -filds_4 ... ok -fildl_1 ... ok -fildl_2 ... ok -fildl_3 ... ok -fildl_4 ... ok -fildq_1 ... ok -fildq_2 ... ok -fildq_3 ... ok -fildq_4 ... ok -fists_1 ... ok -fists_2 ... ok -fists_3 ... ok -fists_4 ... ok -fists_5 ... ok -fists_6 ... ok -fists_7 ... ok -fists_8 ... ok -fistl_1 ... ok -fistl_2 ... ok -fistl_3 ... ok -fistl_4 ... ok -fistl_5 ... ok -fistl_6 ... ok -fistl_7 ... ok -fistl_8 ... ok -fistps_1 ... ok -fistps_2 ... ok -fistps_3 ... ok -fistps_4 ... ok -fistps_5 ... ok -fistps_6 ... ok -fistps_7 ... ok -fistps_8 ... ok -fistpl_1 ... ok -fistpl_2 ... ok -fistpl_3 ... ok -fistpl_4 ... ok -fistpl_5 ... ok -fistpl_6 ... ok -fistpl_7 ... ok -fistpl_8 ... ok -fistpq_1 ... ok -fistpq_2 ... ok -fistpq_3 ... ok -fistpq_4 ... ok -fistpq_5 ... ok -fistpq_6 ... ok -fistpq_7 ... ok -fistpq_8 ... ok -flds_1 ... ok -flds_2 ... ok -fldl_1 ... ok -fldl_2 ... ok -fld_1 ... ok -fld_2 ... ok -fld_3 ... ok -fld1_1 ... ok -fldl2t_1 ... ok -fldl2e_1 ... ok -fldpi_1 ... ok -fldlg2_1 ... ok -fldln2_1 ... ok -fldz_1 ... ok -fmuls_1 ... ok -fmuls_2 ... ok -fmuls_3 ... ok -fmuls_4 ... ok -fmull_1 ... ok -fmull_2 ... ok -fmull_3 ... ok -fmull_4 ... ok -fmul_1 ... ok -fmul_2 ... ok -fmul_3 ... ok -fmul_4 ... ok -fmul_5 ... ok -fmul_6 ... ok -fmul_7 ... ok -fmul_8 ... ok -fmul_9 ... ok -fmul_10 ... ok -fmul_11 ... ok -fmul_12 ... ok -fmul_13 ... ok -fmul_14 ... ok -fmul_15 ... ok -fmul_16 ... ok -fmulp_1 ... ok -fmulp_2 ... ok -fmulp_3 ... ok -fmulp_4 ... ok -fmulp_5 ... ok -fmulp_6 ... ok -fmulp_7 ... ok -fmulp_8 ... ok -fmulp_9 ... ok -fmulp_10 ... ok -fmulp_11 ... ok -fmulp_12 ... ok -fmulp_13 ... ok -fmulp_14 ... ok -fmulp_15 ... ok -fmulp_16 ... ok -fimuls_1 ... ok -fimuls_2 ... ok -fimuls_3 ... ok -fimuls_4 ... ok -fimuls_5 ... ok -fimuls_6 ... ok -fimuls_7 ... ok -fimuls_8 ... ok -fimull_1 ... ok -fimull_2 ... ok -fimull_3 ... ok -fimull_4 ... ok -fimull_5 ... ok -fimull_6 ... ok -fimull_7 ... ok -fimull_8 ... ok -frndint_1 ... ok -frndint_2 ... ok -frndint_3 ... ok -frndint_4 ... ok -frndint_5 ... ok -frndint_6 ... ok -frndint_7 ... ok -frndint_8 ... ok -frndint_9 ... ok -frndint_10 ... ok -frndint_11 ... ok -frndint_12 ... ok -frndint_13 ... ok -frndint_14 ... ok -frndint_15 ... ok -frndint_16 ... ok -fsubs_1 ... ok -fsubs_2 ... ok -fsubs_3 ... ok -fsubs_4 ... ok -fsubl_1 ... ok -fsubl_2 ... ok -fsubl_3 ... ok -fsubl_4 ... ok -fsub_1 ... ok -fsub_2 ... ok -fsub_3 ... ok -fsub_4 ... ok -fsub_5 ... ok -fsub_6 ... ok -fsub_7 ... ok -fsub_8 ... ok -fsub_9 ... ok -fsub_10 ... ok -fsub_11 ... ok -fsub_12 ... ok -fsub_13 ... ok -fsub_14 ... ok -fsub_15 ... ok -fsub_16 ... ok -fsubp_1 ... ok -fsubp_2 ... ok -fsubp_3 ... ok -fsubp_4 ... ok -fsubp_5 ... ok -fsubp_6 ... ok -fsubp_7 ... ok -fsubp_8 ... ok -fsubp_9 ... ok -fsubp_10 ... ok -fsubp_11 ... ok -fsubp_12 ... ok -fsubp_13 ... ok -fsubp_14 ... ok -fsubp_15 ... ok -fsubp_16 ... ok -fisubs_1 ... ok -fisubs_2 ... ok -fisubs_3 ... ok -fisubs_4 ... ok -fisubs_5 ... ok -fisubs_6 ... ok -fisubs_7 ... ok -fisubs_8 ... ok -fisubl_1 ... ok -fisubl_2 ... ok -fisubl_3 ... ok -fisubl_4 ... ok -fisubl_5 ... ok -fisubl_6 ... ok -fisubl_7 ... ok -fisubl_8 ... ok -fsubrs_1 ... ok -fsubrs_2 ... ok -fsubrs_3 ... ok -fsubrs_4 ... ok -fsubrl_1 ... ok -fsubrl_2 ... ok -fsubrl_3 ... ok -fsubrl_4 ... ok -fsubr_1 ... ok -fsubr_2 ... ok -fsubr_3 ... ok -fsubr_4 ... ok -fsubr_5 ... ok -fsubr_6 ... ok -fsubr_7 ... ok -fsubr_8 ... ok -fsubr_9 ... ok -fsubr_10 ... ok -fsubr_11 ... ok -fsubr_12 ... ok -fsubr_13 ... ok -fsubr_14 ... ok -fsubr_15 ... ok -fsubr_16 ... ok -fsubrp_1 ... ok -fsubrp_2 ... ok -fsubrp_3 ... ok -fsubrp_4 ... ok -fsubrp_5 ... ok -fsubrp_6 ... ok -fsubrp_7 ... ok -fsubrp_8 ... ok -fsubrp_9 ... ok -fsubrp_10 ... ok -fsubrp_11 ... ok -fsubrp_12 ... ok -fsubrp_13 ... ok -fsubrp_14 ... ok -fsubrp_15 ... ok -fsubrp_16 ... ok -fisubrs_1 ... ok -fisubrs_2 ... ok -fisubrs_3 ... ok -fisubrs_4 ... ok -fisubrs_5 ... ok -fisubrs_6 ... ok -fisubrs_7 ... ok -fisubrs_8 ... ok -fisubrl_1 ... ok -fisubrl_2 ... ok -fisubrl_3 ... ok -fisubrl_4 ... ok -fisubrl_5 ... ok -fisubrl_6 ... ok -fisubrl_7 ... ok -fisubrl_8 ... ok -fxch_1 ... ok -fxch_2 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_fpu.vgtest b/VEX/head20041019/memcheck/tests/insn_fpu.vgtest deleted file mode 100644 index 1b9546f54..000000000 --- a/VEX/head20041019/memcheck/tests/insn_fpu.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_fpu -cpu_test: fpu diff --git a/VEX/head20041019/memcheck/tests/insn_mmx.stderr.exp b/VEX/head20041019/memcheck/tests/insn_mmx.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_mmx.stdout.exp b/VEX/head20041019/memcheck/tests/insn_mmx.stdout.exp deleted file mode 100644 index 95cbae160..000000000 --- a/VEX/head20041019/memcheck/tests/insn_mmx.stdout.exp +++ /dev/null @@ -1,103 +0,0 @@ -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movq_1 ... ok -movq_2 ... ok -movq_3 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -por_1 ... ok -por_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_mmx.vgtest b/VEX/head20041019/memcheck/tests/insn_mmx.vgtest deleted file mode 100644 index ddbb97726..000000000 --- a/VEX/head20041019/memcheck/tests/insn_mmx.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmx -cpu_test: mmx diff --git a/VEX/head20041019/memcheck/tests/insn_mmxext.stderr.exp b/VEX/head20041019/memcheck/tests/insn_mmxext.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_mmxext.stdout.exp b/VEX/head20041019/memcheck/tests/insn_mmxext.stdout.exp deleted file mode 100644 index 23b2e55ab..000000000 --- a/VEX/head20041019/memcheck/tests/insn_mmxext.stdout.exp +++ /dev/null @@ -1,29 +0,0 @@ -movntq_1 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -sfence_1 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_mmxext.vgtest b/VEX/head20041019/memcheck/tests/insn_mmxext.vgtest deleted file mode 100644 index bb667097f..000000000 --- a/VEX/head20041019/memcheck/tests/insn_mmxext.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_mmxext -cpu_test: mmxext diff --git a/VEX/head20041019/memcheck/tests/insn_sse.stderr.exp b/VEX/head20041019/memcheck/tests/insn_sse.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_sse.stdout.exp b/VEX/head20041019/memcheck/tests/insn_sse.stdout.exp deleted file mode 100644 index f15bd81f0..000000000 --- a/VEX/head20041019/memcheck/tests/insn_sse.stdout.exp +++ /dev/null @@ -1,142 +0,0 @@ -addps_1 ... ok -addps_2 ... ok -addss_1 ... ok -addss_2 ... ok -andnps_1 ... ok -andnps_2 ... ok -andps_1 ... ok -andps_2 ... ok -cmpeqps_1 ... ok -cmpeqps_2 ... ok -cmpeqss_1 ... ok -cmpeqss_2 ... ok -cmpleps_1 ... ok -cmpleps_2 ... ok -cmpless_1 ... ok -cmpless_2 ... ok -cmpltps_1 ... ok -cmpltps_2 ... ok -cmpltss_1 ... ok -cmpltss_2 ... ok -cmpneqps_1 ... ok -cmpneqps_2 ... ok -cmpneqss_1 ... ok -cmpneqss_2 ... ok -cmpnleps_1 ... ok -cmpnleps_2 ... ok -cmpnless_1 ... ok -cmpnless_2 ... ok -cmpnltps_1 ... ok -cmpnltps_2 ... ok -cmpnltss_1 ... ok -cmpnltss_2 ... ok -comiss_1 ... ok -comiss_2 ... ok -comiss_3 ... ok -comiss_4 ... ok -comiss_5 ... ok -comiss_6 ... ok -cvtpi2ps_1 ... ok -cvtpi2ps_2 ... ok -cvtps2pi_1 ... ok -cvtps2pi_2 ... ok -cvtsi2ss_1 ... ok -cvtsi2ss_2 ... ok -cvtss2si_1 ... ok -cvtss2si_2 ... ok -cvttps2pi_1 ... ok -cvttps2pi_2 ... ok -cvttss2si_1 ... ok -cvttss2si_2 ... ok -divps_1 ... ok -divps_2 ... ok -divss_1 ... ok -divss_2 ... ok -maxps_1 ... ok -maxps_2 ... ok -maxss_1 ... ok -maxss_2 ... ok -minps_1 ... ok -minps_2 ... ok -minss_1 ... ok -minss_2 ... ok -movaps_1 ... ok -movaps_2 ... ok -movhlps_1 ... ok -movhps_1 ... ok -movhps_2 ... ok -movlhps_1 ... ok -movlps_1 ... ok -movlps_2 ... ok -movmskps_1 ... ok -movntps_1 ... ok -movntq_1 ... ok -movss_1 ... ok -movss_2 ... ok -movss_3 ... ok -movups_1 ... ok -movups_2 ... ok -mulps_1 ... ok -mulps_2 ... ok -mulss_1 ... ok -mulss_2 ... ok -orps_1 ... ok -orps_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufw_1 ... ok -pshufw_2 ... ok -rcpps_1 ... ok -rcpps_2 ... ok -rcpss_1 ... ok -rcpss_2 ... ok -rsqrtps_1 ... ok -rsqrtps_2 ... ok -rsqrtss_1 ... ok -rsqrtss_2 ... ok -sfence_1 ... ok -shufps_1 ... ok -shufps_2 ... ok -sqrtps_1 ... ok -sqrtps_2 ... ok -sqrtss_1 ... ok -sqrtss_2 ... ok -subps_1 ... ok -subps_2 ... ok -subss_1 ... ok -subss_2 ... ok -ucomiss_1 ... ok -ucomiss_2 ... ok -ucomiss_3 ... ok -ucomiss_4 ... ok -ucomiss_5 ... ok -ucomiss_6 ... ok -unpckhps_1 ... ok -unpckhps_2 ... ok -unpcklps_1 ... ok -unpcklps_2 ... ok -xorps_1 ... ok -xorps_2 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_sse.vgtest b/VEX/head20041019/memcheck/tests/insn_sse.vgtest deleted file mode 100644 index 167c8e290..000000000 --- a/VEX/head20041019/memcheck/tests/insn_sse.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse -cpu_test: sse diff --git a/VEX/head20041019/memcheck/tests/insn_sse2.stderr.exp b/VEX/head20041019/memcheck/tests/insn_sse2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/insn_sse2.stdout.exp b/VEX/head20041019/memcheck/tests/insn_sse2.stdout.exp deleted file mode 100644 index 9c24f7262..000000000 --- a/VEX/head20041019/memcheck/tests/insn_sse2.stdout.exp +++ /dev/null @@ -1,294 +0,0 @@ -addpd_1 ... ok -addpd_2 ... ok -addsd_1 ... ok -addsd_2 ... ok -andpd_1 ... ok -andpd_2 ... ok -andnpd_1 ... ok -andnpd_2 ... ok -cmpeqpd_1 ... ok -cmpeqpd_2 ... ok -cmpltpd_1 ... ok -cmpltpd_2 ... ok -cmplepd_1 ... ok -cmplepd_2 ... ok -cmpneqpd_1 ... ok -cmpneqpd_2 ... ok -cmpnltpd_1 ... ok -cmpnltpd_2 ... ok -cmpnlepd_1 ... ok -cmpnlepd_2 ... ok -cmpeqsd_1 ... ok -cmpeqsd_2 ... ok -cmpltsd_1 ... ok -cmpltsd_2 ... ok -cmplesd_1 ... ok -cmplesd_2 ... ok -cmpneqsd_1 ... ok -cmpneqsd_2 ... ok -cmpnltsd_1 ... ok -cmpnltsd_2 ... ok -cmpnlesd_1 ... ok -cmpnlesd_2 ... ok -comisd_1 ... ok -comisd_2 ... ok -comisd_3 ... ok -comisd_4 ... ok -comisd_5 ... ok -comisd_6 ... ok -cvtdq2pd_1 ... ok -cvtdq2pd_2 ... ok -cvtdq2ps_1 ... ok -cvtdq2ps_2 ... ok -cvtpd2dq_1 ... ok -cvtpd2dq_2 ... ok -cvtpd2pi_1 ... ok -cvtpd2pi_2 ... ok -cvtpd2ps_1 ... ok -cvtpd2ps_2 ... ok -cvtpi2pd_1 ... ok -cvtpi2pd_2 ... ok -cvtps2dq_1 ... ok -cvtps2dq_2 ... ok -cvtps2pd_1 ... ok -cvtps2pd_2 ... ok -cvtsd2si_1 ... ok -cvtsd2si_2 ... ok -cvtsd2ss_1 ... ok -cvtsd2ss_2 ... ok -cvtsi2sd_1 ... ok -cvtsi2sd_2 ... ok -cvtss2sd_1 ... ok -cvtss2sd_2 ... ok -cvttpd2pi_1 ... ok -cvttpd2pi_2 ... ok -cvttpd2dq_1 ... ok -cvttpd2dq_2 ... ok -cvttps2dq_1 ... ok -cvttps2dq_2 ... ok -cvttsd2si_1 ... ok -cvttsd2si_2 ... ok -divpd_1 ... ok -divpd_2 ... ok -divsd_1 ... ok -divsd_2 ... ok -lfence_1 ... ok -maxpd_1 ... ok -maxpd_2 ... ok -maxsd_1 ... ok -maxsd_2 ... ok -mfence_1 ... ok -minpd_1 ... ok -minpd_2 ... ok -minsd_1 ... ok -minsd_2 ... ok -movapd_1 ... ok -movapd_2 ... ok -movd_1 ... ok -movd_2 ... ok -movd_3 ... ok -movd_4 ... ok -movdqa_1 ... ok -movdqa_2 ... ok -movdqa_3 ... ok -movdqu_1 ... ok -movdqu_2 ... ok -movdqu_3 ... ok -movdq2q_1 ... ok -movhpd_1 ... ok -movhpd_2 ... ok -movlpd_1 ... ok -movlpd_2 ... ok -movmskpd_1 ... ok -movntdq_1 ... ok -movnti_1 ... ok -movntpd_1 ... ok -movq2dq_1 ... ok -movsd_1 ... ok -movsd_2 ... ok -movsd_3 ... ok -movupd_1 ... ok -movupd_2 ... ok -mulpd_1 ... ok -mulpd_2 ... ok -mulsd_1 ... ok -mulsd_2 ... ok -orpd_1 ... ok -orpd_2 ... ok -packssdw_1 ... ok -packssdw_2 ... ok -packsswb_1 ... ok -packsswb_2 ... ok -packuswb_1 ... ok -packuswb_2 ... ok -paddb_1 ... ok -paddb_2 ... ok -paddd_1 ... ok -paddd_2 ... ok -paddq_1 ... ok -paddq_2 ... ok -paddq_3 ... ok -paddq_4 ... ok -paddsb_1 ... ok -paddsb_2 ... ok -paddsw_1 ... ok -paddsw_2 ... ok -paddusb_1 ... ok -paddusb_2 ... ok -paddusw_1 ... ok -paddusw_2 ... ok -paddw_1 ... ok -paddw_2 ... ok -pand_1 ... ok -pand_2 ... ok -pandn_1 ... ok -pandn_2 ... ok -pavgb_1 ... ok -pavgb_2 ... ok -pavgw_1 ... ok -pavgw_2 ... ok -pcmpeqb_1 ... ok -pcmpeqb_2 ... ok -pcmpeqd_1 ... ok -pcmpeqd_2 ... ok -pcmpeqw_1 ... ok -pcmpeqw_2 ... ok -pcmpgtb_1 ... ok -pcmpgtb_2 ... ok -pcmpgtd_1 ... ok -pcmpgtd_2 ... ok -pcmpgtw_1 ... ok -pcmpgtw_2 ... ok -pextrw_1 ... ok -pextrw_2 ... ok -pextrw_3 ... ok -pextrw_4 ... ok -pextrw_5 ... ok -pextrw_6 ... ok -pextrw_7 ... ok -pextrw_8 ... ok -pinsrw_1 ... ok -pinsrw_2 ... ok -pinsrw_3 ... ok -pinsrw_4 ... ok -pinsrw_5 ... ok -pinsrw_6 ... ok -pinsrw_7 ... ok -pinsrw_8 ... ok -pmaddwd_1 ... ok -pmaddwd_2 ... ok -pmaxsw_1 ... ok -pmaxsw_2 ... ok -pmaxub_1 ... ok -pmaxub_2 ... ok -pminsw_1 ... ok -pminsw_2 ... ok -pminub_1 ... ok -pminub_2 ... ok -pmovmskb_1 ... ok -pmulhuw_1 ... ok -pmulhuw_2 ... ok -pmulhw_1 ... ok -pmulhw_2 ... ok -pmullw_1 ... ok -pmullw_2 ... ok -pmuludq_1 ... ok -pmuludq_2 ... ok -pmuludq_3 ... ok -pmuludq_4 ... ok -por_1 ... ok -por_2 ... ok -psadbw_1 ... ok -psadbw_2 ... ok -pshufd_1 ... ok -pshufd_2 ... ok -pshufhw_1 ... ok -pshufhw_2 ... ok -pshuflw_1 ... ok -pshuflw_2 ... ok -pslld_1 ... ok -pslld_2 ... ok -pslld_3 ... ok -pslldq_1 ... ok -pslldq_2 ... ok -psllq_1 ... ok -psllq_2 ... ok -psllq_3 ... ok -psllw_1 ... ok -psllw_2 ... ok -psllw_3 ... ok -psrad_1 ... ok -psrad_2 ... ok -psrad_3 ... ok -psraw_1 ... ok -psraw_2 ... ok -psraw_3 ... ok -psrld_1 ... ok -psrld_2 ... ok -psrld_3 ... ok -psrldq_1 ... ok -psrldq_2 ... ok -psrlq_1 ... ok -psrlq_2 ... ok -psrlq_3 ... ok -psrlw_1 ... ok -psrlw_2 ... ok -psrlw_3 ... ok -psubb_1 ... ok -psubb_2 ... ok -psubd_1 ... ok -psubd_2 ... ok -psubq_1 ... ok -psubq_2 ... ok -psubq_3 ... ok -psubq_4 ... ok -psubsb_1 ... ok -psubsb_2 ... ok -psubsw_1 ... ok -psubsw_2 ... ok -psubusb_1 ... ok -psubusb_2 ... ok -psubusw_1 ... ok -psubusw_2 ... ok -psubw_1 ... ok -psubw_2 ... ok -punpckhbw_1 ... ok -punpckhbw_2 ... ok -punpckhdq_1 ... ok -punpckhdq_2 ... ok -punpckhqdq_1 ... ok -punpckhqdq_2 ... ok -punpckhwd_1 ... ok -punpckhwd_2 ... ok -punpcklbw_1 ... ok -punpcklbw_2 ... ok -punpckldq_1 ... ok -punpckldq_2 ... ok -punpcklqdq_1 ... ok -punpcklqdq_2 ... ok -punpcklwd_1 ... ok -punpcklwd_2 ... ok -pxor_1 ... ok -pxor_2 ... ok -shufpd_1 ... ok -shufpd_2 ... ok -sqrtpd_1 ... ok -sqrtpd_2 ... ok -sqrtsd_1 ... ok -sqrtsd_2 ... ok -subpd_1 ... ok -subpd_2 ... ok -subsd_1 ... ok -subsd_2 ... ok -ucomisd_1 ... ok -ucomisd_2 ... ok -ucomisd_3 ... ok -ucomisd_4 ... ok -ucomisd_5 ... ok -ucomisd_6 ... ok -unpckhpd_1 ... ok -unpckhpd_2 ... ok -unpcklpd_1 ... ok -unpcklpd_2 ... ok -xorpd_1 ... ok -xorpd_2 ... ok diff --git a/VEX/head20041019/memcheck/tests/insn_sse2.vgtest b/VEX/head20041019/memcheck/tests/insn_sse2.vgtest deleted file mode 100644 index 42e82f38d..000000000 --- a/VEX/head20041019/memcheck/tests/insn_sse2.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: -q -prog: ../../none/tests/insn_sse2 -cpu_test: sse2 diff --git a/VEX/head20041019/memcheck/tests/malloc1.c b/VEX/head20041019/memcheck/tests/malloc1.c deleted file mode 100644 index dff5250eb..000000000 --- a/VEX/head20041019/memcheck/tests/malloc1.c +++ /dev/null @@ -1,24 +0,0 @@ - -#include -#include - -void really ( void ); - -int main ( void ) -{ - really(); - return 0; -} - -void really ( void ) -{ - int i; - char* p = malloc(10); - for (i = 0; i < 10; i++) - p[i] = 'z'; - free(p); - p[1] = 'z'; - p = malloc(10); - p[2] = 'z'; - p[-1] = 'z'; -} diff --git a/VEX/head20041019/memcheck/tests/malloc1.stderr.exp b/VEX/head20041019/memcheck/tests/malloc1.stderr.exp deleted file mode 100644 index 9739e92c0..000000000 --- a/VEX/head20041019/memcheck/tests/malloc1.stderr.exp +++ /dev/null @@ -1,15 +0,0 @@ -Invalid write of size 1 - at 0x........: really (malloc1.c:20) - by 0x........: main (malloc1.c:9) - Address 0x........ is 1 bytes inside a block of size 10 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: really (malloc1.c:19) - by 0x........: main (malloc1.c:9) - -Invalid write of size 1 - at 0x........: really (malloc1.c:23) - by 0x........: main (malloc1.c:9) - Address 0x........ is 1 bytes before a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: really (malloc1.c:21) - by 0x........: main (malloc1.c:9) diff --git a/VEX/head20041019/memcheck/tests/malloc1.vgtest b/VEX/head20041019/memcheck/tests/malloc1.vgtest deleted file mode 100644 index 5849aa77f..000000000 --- a/VEX/head20041019/memcheck/tests/malloc1.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: malloc1 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/malloc2.c b/VEX/head20041019/memcheck/tests/malloc2.c deleted file mode 100644 index 44cc7bb3d..000000000 --- a/VEX/head20041019/memcheck/tests/malloc2.c +++ /dev/null @@ -1,49 +0,0 @@ - -#include -#include - -/* The original test driver machinery. */ -#define N_TEST_TRANSACTIONS 500 -#define N_TEST_ARR 2000 - -#define M_TEST_MALLOC 1000 - -void* test_arr[N_TEST_ARR]; - -int main ( int argc, char** argv ) -{ - int i, j, k, nbytes; - unsigned char* chp; - - for (i = 0; i < N_TEST_ARR; i++) - test_arr[i] = NULL; - - for (i = 0; i < N_TEST_TRANSACTIONS; i++) { - j = random() % N_TEST_ARR; - if (test_arr[j]) { - free(test_arr[j]); - test_arr[j] = NULL; - } else { - nbytes = 1 + random() % M_TEST_MALLOC; - if (random()%64 == 32) - nbytes *= 17; - test_arr[j] = malloc( nbytes ); - chp = test_arr[j]; - for (k = 1; k < nbytes; k++) - chp[k] = (unsigned char)(k + 99); - } - } - - for (i = 0; test_arr[i] == NULL; i++) ; - free(test_arr[i]); - ((char*)test_arr[i])[0] = 0; - - for (i = 0; i < N_TEST_ARR; i++) { - if (test_arr[i]) { - free(test_arr[i]); - test_arr[i] = NULL; - } - } - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/malloc2.stderr.exp b/VEX/head20041019/memcheck/tests/malloc2.stderr.exp deleted file mode 100644 index 29ad57251..000000000 --- a/VEX/head20041019/memcheck/tests/malloc2.stderr.exp +++ /dev/null @@ -1,12 +0,0 @@ -Invalid write of size 1 - at 0x........: main (malloc2.c:39) - Address 0x........ is 0 bytes inside a block of size 429 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (malloc2.c:38) - -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (malloc2.c:43) - Address 0x........ is 0 bytes inside a block of size 429 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (malloc2.c:38) diff --git a/VEX/head20041019/memcheck/tests/malloc2.vgtest b/VEX/head20041019/memcheck/tests/malloc2.vgtest deleted file mode 100644 index 4191dae50..000000000 --- a/VEX/head20041019/memcheck/tests/malloc2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: malloc2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/malloc3.c b/VEX/head20041019/memcheck/tests/malloc3.c deleted file mode 100644 index 896645c3e..000000000 --- a/VEX/head20041019/memcheck/tests/malloc3.c +++ /dev/null @@ -1,32 +0,0 @@ - -/* test of plausible behaviour with malloc and stupid args */ - -#include -#include - -int main ( void ) -{ - char* p; - - p = malloc(0); - printf("malloc(0) = %p\n", p); - free(p); - - p = malloc(-1); - printf("malloc(-1) = %p\n", p); - free(p); - - p = calloc(0,1); - printf("calloc(0,1) = %p\n", p); - free(p); - - p = calloc(0,-1); - printf("calloc(0,-1) = %p\n", p); - free(p); - - p = calloc(-1,-1); - printf("calloc(-1,-1) = %p\n", p); - free(p); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/malloc3.stderr.exp b/VEX/head20041019/memcheck/tests/malloc3.stderr.exp deleted file mode 100644 index 30a6968a3..000000000 --- a/VEX/head20041019/memcheck/tests/malloc3.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Warning: silly arg (-1) to malloc() -Warning: silly args (0,-1) to calloc() -Warning: silly args (-1,-1) to calloc() diff --git a/VEX/head20041019/memcheck/tests/malloc3.stdout.exp b/VEX/head20041019/memcheck/tests/malloc3.stdout.exp deleted file mode 100644 index 681c9ece2..000000000 --- a/VEX/head20041019/memcheck/tests/malloc3.stdout.exp +++ /dev/null @@ -1,5 +0,0 @@ -malloc(0) = 0x........ -malloc(-1) = (nil) -calloc(0,1) = 0x........ -calloc(0,-1) = (nil) -calloc(-1,-1) = (nil) diff --git a/VEX/head20041019/memcheck/tests/malloc3.vgtest b/VEX/head20041019/memcheck/tests/malloc3.vgtest deleted file mode 100644 index 417cbedca..000000000 --- a/VEX/head20041019/memcheck/tests/malloc3.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: malloc3 -stdout_filter: ../../tests/filter_addresses -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/manuel1.c b/VEX/head20041019/memcheck/tests/manuel1.c deleted file mode 100644 index ac1f3c89e..000000000 --- a/VEX/head20041019/memcheck/tests/manuel1.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -int main () -{ - int x; - - printf ("x = %d\n", x==0xDEADBEEF ? 99 : 88); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/manuel1.stderr.exp b/VEX/head20041019/memcheck/tests/manuel1.stderr.exp deleted file mode 100644 index 34f0a9378..000000000 --- a/VEX/head20041019/memcheck/tests/manuel1.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (manuel1.c:7) diff --git a/VEX/head20041019/memcheck/tests/manuel1.stdout.exp b/VEX/head20041019/memcheck/tests/manuel1.stdout.exp deleted file mode 100644 index d26cbc968..000000000 --- a/VEX/head20041019/memcheck/tests/manuel1.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -x = 88 diff --git a/VEX/head20041019/memcheck/tests/manuel1.vgtest b/VEX/head20041019/memcheck/tests/manuel1.vgtest deleted file mode 100644 index 853f8dfdb..000000000 --- a/VEX/head20041019/memcheck/tests/manuel1.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: manuel1 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/manuel2.c b/VEX/head20041019/memcheck/tests/manuel2.c deleted file mode 100644 index 8c6f85b71..000000000 --- a/VEX/head20041019/memcheck/tests/manuel2.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int main () -{ - int *x; - - printf ("x = %d\n", *x==0xDEADBEEF ? 99 : 88); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/manuel2.stderr.exp b/VEX/head20041019/memcheck/tests/manuel2.stderr.exp deleted file mode 100644 index 2d66c1dc7..000000000 --- a/VEX/head20041019/memcheck/tests/manuel2.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Use of uninitialised value of size 4 - at 0x........: main (manuel2.c:8) diff --git a/VEX/head20041019/memcheck/tests/manuel2.stdout.exp b/VEX/head20041019/memcheck/tests/manuel2.stdout.exp deleted file mode 100644 index d26cbc968..000000000 --- a/VEX/head20041019/memcheck/tests/manuel2.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -x = 88 diff --git a/VEX/head20041019/memcheck/tests/manuel2.vgtest b/VEX/head20041019/memcheck/tests/manuel2.vgtest deleted file mode 100644 index b3729b166..000000000 --- a/VEX/head20041019/memcheck/tests/manuel2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: manuel2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/manuel3.c b/VEX/head20041019/memcheck/tests/manuel3.c deleted file mode 100644 index 91030fc65..000000000 --- a/VEX/head20041019/memcheck/tests/manuel3.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -int gcc_cant_inline_me ( int ); - -int main () -{ - int *x, y; - - x = (int *) malloc (sizeof (int)); - - y = *x == 173; - - if (gcc_cant_inline_me(y)) { } - - return 0; -} - -/* must be AFTER main */ -int gcc_cant_inline_me ( int n ) -{ - if (n == 42) - return 1; /* forty-two, dudes! */ - else - return 0; /* some other number, dudes! */ -} - - diff --git a/VEX/head20041019/memcheck/tests/manuel3.stderr.exp b/VEX/head20041019/memcheck/tests/manuel3.stderr.exp deleted file mode 100644 index 2f56776ea..000000000 --- a/VEX/head20041019/memcheck/tests/manuel3.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: gcc_cant_inline_me (manuel3.c:22) - by 0x........: main (manuel3.c:14) diff --git a/VEX/head20041019/memcheck/tests/manuel3.vgtest b/VEX/head20041019/memcheck/tests/manuel3.vgtest deleted file mode 100644 index 14e5f24f3..000000000 --- a/VEX/head20041019/memcheck/tests/manuel3.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: manuel3 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/memalign2.c b/VEX/head20041019/memcheck/tests/memalign2.c deleted file mode 100644 index 0da0b4f32..000000000 --- a/VEX/head20041019/memcheck/tests/memalign2.c +++ /dev/null @@ -1,69 +0,0 @@ - -// These #defines attempt to ensure that posix_memalign() is declared, and -// so no spurious warning is given about using it. - -// Advertise compliance of the code to the XSI (a POSIX superset that -// defines what a system must be like to be called "UNIX") -#undef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 - -// Advertise compliance to POSIX -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L - -#include -#include -#include -#include -#include - -int main ( void ) -{ - // Nb: assuming VG_MIN_MALLOC_SZB is 8! - // Should work with both 32-bit and 64-bit pointers, though. - - int* p; - int res; - assert(sizeof(long int) == sizeof(void*)); - - p = memalign(0, 100); assert(0 == (long)p % 8); - p = memalign(1, 100); assert(0 == (long)p % 8); - p = memalign(2, 100); assert(0 == (long)p % 8); - p = memalign(3, 100); assert(0 == (long)p % 8); - p = memalign(4, 100); assert(0 == (long)p % 8); - p = memalign(5, 100); assert(0 == (long)p % 8); - - p = memalign(7, 100); assert(0 == (long)p % 8); - p = memalign(8, 100); assert(0 == (long)p % 8); - p = memalign(9, 100); assert(0 == (long)p % 16); - - p = memalign(31, 100); assert(0 == (long)p % 32); - p = memalign(32, 100); assert(0 == (long)p % 32); - p = memalign(33, 100); assert(0 == (long)p % 64); - - p = memalign(4095, 100); assert(0 == (long)p % 4096); - p = memalign(4096, 100); assert(0 == (long)p % 4096); - p = memalign(4097, 100); assert(0 == (long)p % 8192); - - #define PM(a,b,c) posix_memalign((void**)a, b, c) - - res = PM(&p, -1,100); assert(EINVAL == res); - res = PM(&p, 0, 100); assert(0 == res && 0 == (long)p % 8); - res = PM(&p, 1, 100); assert(EINVAL == res); - res = PM(&p, 2, 100); assert(EINVAL == res); - res = PM(&p, 3, 100); assert(EINVAL == res); - res = PM(&p, sizeof(void*), 100); - assert(0 == res && 0 == (long)p % sizeof(void*)); - - res = PM(&p, 31, 100); assert(EINVAL == res); - res = PM(&p, 32, 100); assert(0 == res && - 0 == (long)p % 32); - res = PM(&p, 33, 100); assert(EINVAL == res); - - res = PM(&p, 4095, 100); assert(EINVAL == res); - res = PM(&p, 4096, 100); assert(0 == res && - 0 == (long)p % 4096); - res = PM(&p, 4097, 100); assert(EINVAL == res); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/memalign2.stderr.exp b/VEX/head20041019/memcheck/tests/memalign2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/memalign2.vgtest b/VEX/head20041019/memcheck/tests/memalign2.vgtest deleted file mode 100644 index f15cb6320..000000000 --- a/VEX/head20041019/memcheck/tests/memalign2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: memalign2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/memalign_test.c b/VEX/head20041019/memcheck/tests/memalign_test.c deleted file mode 100644 index a24808c55..000000000 --- a/VEX/head20041019/memcheck/tests/memalign_test.c +++ /dev/null @@ -1,19 +0,0 @@ - -#include -#include - -int main ( void ) -{ - void* a[10]; - int i; - for (i = 0; i < 10; i++) { - a[i] = valloc(11111 * (i+1)); - // printf("I acquire %p\n", a[i]); - } - for (i = 0; i < 10; i++) { - // printf("I release %p\n", a[i]); - free(a[i]); - } - free(a[9]); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/memalign_test.stderr.exp b/VEX/head20041019/memcheck/tests/memalign_test.stderr.exp deleted file mode 100644 index a43369c6f..000000000 --- a/VEX/head20041019/memcheck/tests/memalign_test.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (memalign_test.c:17) - Address 0x........ is 0 bytes inside a block of size 111110 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (memalign_test.c:15) diff --git a/VEX/head20041019/memcheck/tests/memalign_test.vgtest b/VEX/head20041019/memcheck/tests/memalign_test.vgtest deleted file mode 100644 index 097ceddab..000000000 --- a/VEX/head20041019/memcheck/tests/memalign_test.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: memalign_test -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/memcmptest.c b/VEX/head20041019/memcheck/tests/memcmptest.c deleted file mode 100644 index 83eb2d466..000000000 --- a/VEX/head20041019/memcheck/tests/memcmptest.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include -#include - -char* s1; -char* s2; - -int main ( void ) -{ - s1 = malloc(10); strcpy(s1,"fooble"); - s2 = malloc(10); strcpy(s2,"fooble"); - if (memcmp(s1, s2, 8) != 0) - printf("different\n"); - else - printf("same (?!)\n"); - return 0; -} - - diff --git a/VEX/head20041019/memcheck/tests/memcmptest.stderr.exp b/VEX/head20041019/memcheck/tests/memcmptest.stderr.exp deleted file mode 100644 index 71367f932..000000000 --- a/VEX/head20041019/memcheck/tests/memcmptest.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: memcmp (mac_replace_strmem.c:...) - by 0x........: main (memcmptest.c:13) diff --git a/VEX/head20041019/memcheck/tests/memcmptest.stdout.exp b/VEX/head20041019/memcheck/tests/memcmptest.stdout.exp deleted file mode 100644 index 716480476..000000000 --- a/VEX/head20041019/memcheck/tests/memcmptest.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -same (?!) diff --git a/VEX/head20041019/memcheck/tests/memcmptest.vgtest b/VEX/head20041019/memcheck/tests/memcmptest.vgtest deleted file mode 100644 index 0509f9fad..000000000 --- a/VEX/head20041019/memcheck/tests/memcmptest.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: memcmptest -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/mempool.c b/VEX/head20041019/memcheck/tests/mempool.c deleted file mode 100644 index f40c1b88a..000000000 --- a/VEX/head20041019/memcheck/tests/mempool.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include - -#include "../memcheck.h" - -#define SUPERBLOCK_SIZE 100000 -#define REDZONE_SIZE 8 - -static const int USE_MMAP = 0; - -typedef struct _level_list -{ - struct _level_list *next; - char *where; -} level_list; - -typedef struct _pool { - char *mem; - char *where; - int size, left; - level_list *levels; -} pool; - -pool *make_pool() -{ - pool *p; - - if(USE_MMAP) { - p = (pool *)mmap(0, sizeof(pool), PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - p->where = p->mem = (char *)mmap(NULL, SUPERBLOCK_SIZE, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - } else { - p = (pool *)malloc(sizeof(pool)); - p->where = p->mem = (char *)malloc(SUPERBLOCK_SIZE); - } - - p->size = p->left = SUPERBLOCK_SIZE; - p->levels = NULL; - VALGRIND_MAKE_NOACCESS(p->where, SUPERBLOCK_SIZE); - return p; -} - -void push(pool *p) -{ - level_list *l; - - if(USE_MMAP) - l = (level_list *)mmap(0, sizeof(level_list), - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - else - l = (level_list *)malloc(sizeof(level_list)); - - l->next = p->levels; - l->where = p->where; - VALGRIND_CREATE_MEMPOOL(l->where, REDZONE_SIZE, 0); - p->levels = l; -} - -void pop(pool *p) -{ - level_list *l = p->levels; - p->levels = l->next; - VALGRIND_DESTROY_MEMPOOL(l->where); - VALGRIND_MAKE_NOACCESS(l->where, p->where-l->where); - p->where = l->where; - if(USE_MMAP) - munmap(l, sizeof(level_list)); - else - free(l); -} - -void destroy_pool(pool *p) -{ - level_list *l = p->levels; - - while(l) { - pop(p); - } - if(USE_MMAP) { - munmap(p->mem, SUPERBLOCK_SIZE); - munmap(p, sizeof(pool)); - } else { - free(p->mem); - free(p); - } -} - -char *allocate(pool *p, int size) -{ - char *where; - p->left -= size + (REDZONE_SIZE*2); - where = p->where + REDZONE_SIZE; - p->where += size + (REDZONE_SIZE*2); - VALGRIND_MEMPOOL_ALLOC(p->levels->where, where, size); - return where; -} - -//------------------------------------------------------------------------- -// Rest -//------------------------------------------------------------------------- - -void test(void) -{ - char *x1, *x2, *x3, *x4, *x5; - - pool *p = make_pool(); - - push(p); - - x1 = allocate(p, 10); - x2 = allocate(p, 20); - push(p); - x3 = allocate(p, 10); - x4 = allocate(p, 20); - - *x1 = 'a'; // valid - *x2 = 'b'; // valid - - x1[-1] = 'h'; // invalid - x1[10] = 'i'; // invalid - - pop(p); - - *x3 = 'c'; // invalid - *x4 = 'd'; // invalid - - *x1 = 'e'; // valid - *x2 = 'f'; // valid - - x5 = allocate(p, 10); - - *x5 = 'g'; // valid - - // pop(p); - - // *x5 = 'g'; // invalid - - // destroy_pool(p); -} - -int main(void) -{ - test(); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/mempool.stderr.exp b/VEX/head20041019/memcheck/tests/mempool.stderr.exp deleted file mode 100644 index 26de5ac3f..000000000 --- a/VEX/head20041019/memcheck/tests/mempool.stderr.exp +++ /dev/null @@ -1,38 +0,0 @@ -Invalid write of size 1 - at 0x........: test (mempool.c:124) - by 0x........: main (mempool.c:148) - Address 0x........ is 1 bytes before a block of size 10 client-defined - at 0x........: allocate (mempool.c:99) - by 0x........: test (mempool.c:115) - by 0x........: main (mempool.c:148) - -Invalid write of size 1 - at 0x........: test (mempool.c:125) - by 0x........: main (mempool.c:148) - Address 0x........ is 0 bytes after a block of size 10 client-defined - at 0x........: allocate (mempool.c:99) - by 0x........: test (mempool.c:115) - by 0x........: main (mempool.c:148) - -Invalid write of size 1 - at 0x........: test (mempool.c:129) - by 0x........: main (mempool.c:148) - Address 0x........ is 70 bytes inside a mempool of size 100000 client-defined - at 0x........: make_pool (mempool.c:43) - by 0x........: test (mempool.c:111) - by 0x........: main (mempool.c:148) - -Invalid write of size 1 - at 0x........: test (mempool.c:130) - by 0x........: main (mempool.c:148) - Address 0x........ is 96 bytes inside a mempool of size 100000 client-defined - at 0x........: make_pool (mempool.c:43) - by 0x........: test (mempool.c:111) - by 0x........: main (mempool.c:148) - - -20 bytes in 1 blocks are definitely lost in loss record 2 of 3 - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: make_pool (mempool.c:37) - by 0x........: test (mempool.c:111) - by 0x........: main (mempool.c:148) diff --git a/VEX/head20041019/memcheck/tests/mempool.vgtest b/VEX/head20041019/memcheck/tests/mempool.vgtest deleted file mode 100644 index bcf4ede6f..000000000 --- a/VEX/head20041019/memcheck/tests/mempool.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: mempool -vgopts: -q --leak-check=yes diff --git a/VEX/head20041019/memcheck/tests/metadata.c b/VEX/head20041019/memcheck/tests/metadata.c deleted file mode 100644 index c2ea7f1de..000000000 --- a/VEX/head20041019/memcheck/tests/metadata.c +++ /dev/null @@ -1,46 +0,0 @@ - -#include -#include -#include "../memcheck.h" - -/* Program demonstrating copying of metadata in memcheck. */ - -int main ( void ) -{ - int* a = malloc(10 * sizeof(int)); - int* b = malloc(10 * sizeof(int)); - int* v = malloc(10 * sizeof(int)); - int i, sum, res; - - for (i = 0; i < 10; i++) { - if (i != 5) - a[i] = i; - } - - /* a[0 .. 4] and [6 .. 9] are defined, [5] is undefined. */ - for (i = 0; i < 10; i++) - b[i] = 0; - - /* b[0 .. 9] is defined. */ - - /* Get metadata for a and put it in v. */ - res = VALGRIND_GET_VBITS(a, v, 10*sizeof(int) ); - printf("result of GET is %d (1 for success)\n", res); - /* and copy to b. */ - res = VALGRIND_SET_VBITS(b, v, 10*sizeof(int) ); - printf("result of SET is %d (1 for success)\n", res); - - /* Now we should have that b[5] is undefined since a[5] is - undefined. */ - sum = 100; - for (i = 0; i < 10; i++) - sum += b[i]; - - /* V should yelp at this point, that sum is undefined. */ - if (sum == 0) - printf("sum == 0\n"); - else - printf("sum != 0\n"); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/metadata.stderr.exp b/VEX/head20041019/memcheck/tests/metadata.stderr.exp deleted file mode 100644 index cae2d5f45..000000000 --- a/VEX/head20041019/memcheck/tests/metadata.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (metadata.c:40) diff --git a/VEX/head20041019/memcheck/tests/metadata.stdout.exp b/VEX/head20041019/memcheck/tests/metadata.stdout.exp deleted file mode 100644 index 445a17b23..000000000 --- a/VEX/head20041019/memcheck/tests/metadata.stdout.exp +++ /dev/null @@ -1,3 +0,0 @@ -result of GET is 1 (1 for success) -result of SET is 1 (1 for success) -sum != 0 diff --git a/VEX/head20041019/memcheck/tests/metadata.vgtest b/VEX/head20041019/memcheck/tests/metadata.vgtest deleted file mode 100644 index 6673a75ed..000000000 --- a/VEX/head20041019/memcheck/tests/metadata.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: metadata -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/mismatches.cpp b/VEX/head20041019/memcheck/tests/mismatches.cpp deleted file mode 100644 index 857a07532..000000000 --- a/VEX/head20041019/memcheck/tests/mismatches.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -int main() -{ - int* fpointer = (int*)malloc(10); - delete fpointer; // should give warning - fpointer = (int*)malloc(10); - delete [] fpointer; // should give warning - fpointer = (int*)malloc(10); - free (fpointer); // should work! - - int* nvec = new int[10]; - delete nvec; // should give a warning - nvec = new int[10]; - free (nvec); // should give a warning - nvec = new int[10]; - delete [] nvec; // should work! - - int* n = new int; - delete [] n; // should give a warning - n = new int; - free(n); // should give a warning - n = new int; - delete n; // should work! - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/mismatches.stderr.exp b/VEX/head20041019/memcheck/tests/mismatches.stderr.exp deleted file mode 100644 index 283b65f4b..000000000 --- a/VEX/head20041019/memcheck/tests/mismatches.stderr.exp +++ /dev/null @@ -1,41 +0,0 @@ -Mismatched free() / delete / delete [] - at 0x........: operator delete(void*) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:6) - Address 0x........ is 0 bytes inside a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:5) - -Mismatched free() / delete / delete [] - at 0x........: operator delete[](void*) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:8) - Address 0x........ is 0 bytes inside a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:7) - -Mismatched free() / delete / delete [] - at 0x........: operator delete(void*) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:13) - Address 0x........ is 0 bytes inside a block of size 40 alloc'd - at 0x........: operator new[](unsigned) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:12) - -Mismatched free() / delete / delete [] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:15) - Address 0x........ is 0 bytes inside a block of size 40 alloc'd - at 0x........: operator new[](unsigned) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:14) - -Mismatched free() / delete / delete [] - at 0x........: operator delete[](void*) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:20) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: operator new(unsigned) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:19) - -Mismatched free() / delete / delete [] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:22) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: operator new(unsigned) (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:21) diff --git a/VEX/head20041019/memcheck/tests/mismatches.stderr.exp2 b/VEX/head20041019/memcheck/tests/mismatches.stderr.exp2 deleted file mode 100644 index 448414a1a..000000000 --- a/VEX/head20041019/memcheck/tests/mismatches.stderr.exp2 +++ /dev/null @@ -1,41 +0,0 @@ -Mismatched free() / delete / delete [] - at 0x........: __builtin_delete (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:6) - Address 0x........ is 0 bytes inside a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:5) - -Mismatched free() / delete / delete [] - at 0x........: __builtin_vec_delete (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:8) - Address 0x........ is 0 bytes inside a block of size 10 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:7) - -Mismatched free() / delete / delete [] - at 0x........: __builtin_delete (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:13) - Address 0x........ is 0 bytes inside a block of size 40 alloc'd - at 0x........: __builtin_vec_new (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:12) - -Mismatched free() / delete / delete [] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:15) - Address 0x........ is 0 bytes inside a block of size 40 alloc'd - at 0x........: __builtin_vec_new (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:14) - -Mismatched free() / delete / delete [] - at 0x........: __builtin_vec_delete (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:20) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: __builtin_new (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:19) - -Mismatched free() / delete / delete [] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:22) - Address 0x........ is 0 bytes inside a block of size 4 alloc'd - at 0x........: __builtin_new (vg_replace_malloc.c:...) - by 0x........: main (mismatches.cpp:21) diff --git a/VEX/head20041019/memcheck/tests/mismatches.vgtest b/VEX/head20041019/memcheck/tests/mismatches.vgtest deleted file mode 100644 index 5574afdd4..000000000 --- a/VEX/head20041019/memcheck/tests/mismatches.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: mismatches -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/mmaptest.c b/VEX/head20041019/memcheck/tests/mmaptest.c deleted file mode 100644 index 74a21ed26..000000000 --- a/VEX/head20041019/memcheck/tests/mmaptest.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include -#include -#include - -int main() -{ - int fd; - - mkdir("dir", 0777); - fd = open("dir", O_RDONLY); - mmap(NULL, 4711, PROT_READ, MAP_PRIVATE, fd, 0); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/mmaptest.stderr.exp b/VEX/head20041019/memcheck/tests/mmaptest.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/mmaptest.vgtest b/VEX/head20041019/memcheck/tests/mmaptest.vgtest deleted file mode 100644 index 09d73d39e..000000000 --- a/VEX/head20041019/memcheck/tests/mmaptest.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: mmaptest -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/nanoleak.c b/VEX/head20041019/memcheck/tests/nanoleak.c deleted file mode 100644 index 7f5b0ee80..000000000 --- a/VEX/head20041019/memcheck/tests/nanoleak.c +++ /dev/null @@ -1,9 +0,0 @@ - -#include - -int main ( void ) -{ - volatile int* a = malloc(1000); - a[0] = 0; - return a[0]; -} diff --git a/VEX/head20041019/memcheck/tests/nanoleak.stderr.exp b/VEX/head20041019/memcheck/tests/nanoleak.stderr.exp deleted file mode 100644 index 57fdf3c3b..000000000 --- a/VEX/head20041019/memcheck/tests/nanoleak.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ - -1000 bytes in 1 blocks are definitely lost in loss record 1 of 1 - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: main (nanoleak.c:6) diff --git a/VEX/head20041019/memcheck/tests/nanoleak.supp b/VEX/head20041019/memcheck/tests/nanoleak.supp deleted file mode 100644 index 584c93e20..000000000 --- a/VEX/head20041019/memcheck/tests/nanoleak.supp +++ /dev/null @@ -1,7 +0,0 @@ -{ - this_is_the_nanoleak_suppression_name - Addrcheck,Memcheck:Leak - fun:malloc - fun:main -} - diff --git a/VEX/head20041019/memcheck/tests/nanoleak.vgtest b/VEX/head20041019/memcheck/tests/nanoleak.vgtest deleted file mode 100644 index d633a3626..000000000 --- a/VEX/head20041019/memcheck/tests/nanoleak.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: --leak-check=yes -q -prog: nanoleak -stderr_filter: filter_leak_check_size diff --git a/VEX/head20041019/memcheck/tests/nanoleak_supp.stderr.exp b/VEX/head20041019/memcheck/tests/nanoleak_supp.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/nanoleak_supp.vgtest b/VEX/head20041019/memcheck/tests/nanoleak_supp.vgtest deleted file mode 100644 index 57e894701..000000000 --- a/VEX/head20041019/memcheck/tests/nanoleak_supp.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: --leak-check=yes --suppressions=nanoleak.supp -q -prog: nanoleak -stderr_filter: filter_leak_check_size diff --git a/VEX/head20041019/memcheck/tests/new_nothrow.cpp b/VEX/head20041019/memcheck/tests/new_nothrow.cpp deleted file mode 100644 index 82e5bc514..000000000 --- a/VEX/head20041019/memcheck/tests/new_nothrow.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include - -// At one point, Valgrind wasn't overriding these 'nothrow' versions; since -// they call malloc(), the calls to 'delete' caused bogus mismatch errors. - -int main() -{ - int * a = new (std::nothrow) int; - int * b = new (std::nothrow) int[5]; - delete a; - delete [] b; -} - diff --git a/VEX/head20041019/memcheck/tests/new_nothrow.stderr.exp b/VEX/head20041019/memcheck/tests/new_nothrow.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/new_nothrow.vgtest b/VEX/head20041019/memcheck/tests/new_nothrow.vgtest deleted file mode 100644 index ea8dda3cf..000000000 --- a/VEX/head20041019/memcheck/tests/new_nothrow.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: new_nothrow -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/new_override.cpp b/VEX/head20041019/memcheck/tests/new_override.cpp deleted file mode 100644 index b3feb0c72..000000000 --- a/VEX/head20041019/memcheck/tests/new_override.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -class Test { -public: - int a, b, c, d; -}; - -void *operator new[](size_t size) -{ - void *ret = malloc(size); - printf("Here.\n"); - for (unsigned int i = 0; i < size; i++) ((char *) ret)[i] = 0xFF; - return ret; -} - -int main(int argc, char *argv[]) { - Test *toto; - int i; - int j = 0; - - toto = new Test[2]; - - for (i = 0; i < 2; i++) { - if (toto[i].a) { - j++; - } - //printf("%d : %08x %08x %08x %08x\n", i, toto[i].a, toto[i].b, toto[i].c, toto[i].d); - } -} diff --git a/VEX/head20041019/memcheck/tests/new_override.stderr.exp b/VEX/head20041019/memcheck/tests/new_override.stderr.exp deleted file mode 100644 index 7a5680c58..000000000 --- a/VEX/head20041019/memcheck/tests/new_override.stderr.exp +++ /dev/null @@ -1,7 +0,0 @@ - - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: ... bytes in ... blocks. -malloc/free: ... allocs, ... frees, ... bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/new_override.stdout.exp b/VEX/head20041019/memcheck/tests/new_override.stdout.exp deleted file mode 100644 index fe1846ca2..000000000 --- a/VEX/head20041019/memcheck/tests/new_override.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -Here. diff --git a/VEX/head20041019/memcheck/tests/new_override.vgtest b/VEX/head20041019/memcheck/tests/new_override.vgtest deleted file mode 100644 index 50e624034..000000000 --- a/VEX/head20041019/memcheck/tests/new_override.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: new_override -stderr_filter: filter_allocs diff --git a/VEX/head20041019/memcheck/tests/null_socket.c b/VEX/head20041019/memcheck/tests/null_socket.c deleted file mode 100644 index a2e203e08..000000000 --- a/VEX/head20041019/memcheck/tests/null_socket.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include - - -// It's legit to have NULL buffers; before the bug was fixed Valgrind -// reported spurious errors for the buffers. -int main(void) -{ - if (-1 != accept(99, NULL, 0)) - printf("accept succeeded?\n"); - - if (-1 != recvfrom(0, NULL, 0, 0, NULL, 0)) - printf("recvfrom succeeded?\n"); - - if (-1 != getsockopt(0, 0, 0, NULL, 0)) - printf("getsockopt succeeded?\n"); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/null_socket.stderr.exp b/VEX/head20041019/memcheck/tests/null_socket.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/null_socket.vgtest b/VEX/head20041019/memcheck/tests/null_socket.vgtest deleted file mode 100644 index 7f3a2a492..000000000 --- a/VEX/head20041019/memcheck/tests/null_socket.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: null_socket -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/overlap.c b/VEX/head20041019/memcheck/tests/overlap.c deleted file mode 100644 index d868886f3..000000000 --- a/VEX/head20041019/memcheck/tests/overlap.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include - -char b[50]; - -void reset_b(void) -{ - int i; - - for (i = 0; i < 50; i++) - b[i] = '_'; - b[49] = '\0'; -} - -void reset_b2(void) -{ - reset_b(); - strcpy(b, "ABCDEFG"); -} - -int main(void) -{ - char x[100]; - char a[] = "abcdefghijklmnopqrstuvwxyz"; - int i; - - /* testing memcpy/strcpy overlap */ - - for (i = 0; i < 50; i++) { - x[i] = i+1; // don't put any zeroes in there - } - for (i = 50; i < 100; i++) { - // because of the errors, the strcpy's will overrun, so put some - // zeroes in the second half to stop them eventually - x[i] = 0; - - } - - memcpy(x+20, x, 20); // ok - memcpy(x+20, x, 21); // overlap - memcpy(x, x+20, 20); // ok - memcpy(x, x+20, 21); // overlap - - strncpy(x+20, x, 20); // ok - strncpy(x+20, x, 21); // overlap - strncpy(x, x+20, 20); // ok - strncpy(x, x+20, 21); // overlap - - x[39] = '\0'; - strcpy(x, x+20); // ok - - x[39] = 39; - x[40] = '\0'; - strcpy(x, x+20); // overlap - - x[19] = '\0'; - strcpy(x+20, x); // ok - -/* - x[19] = 19; - x[20] = '\0'; - strcpy(x+20, x); // overlap, but runs forever (or until it seg faults) -*/ - - /* testing strcpy, strncpy() */ - - reset_b(); - printf("`%s'\n", b); - - strcpy(b, a); - printf("`%s'\n", b); - - reset_b(); - strncpy(b, a, 25); - printf("`%s'\n", b); - - reset_b(); - strncpy(b, a, 26); - printf("`%s'\n", b); - - reset_b(); - strncpy(b, a, 27); - printf("`%s'\n", b); - - printf("\n"); - - /* testing strncat() */ - - reset_b2(); - printf("`%s'\n", b); - - reset_b2(); - strcat(b, a); - printf("`%s'\n", b); - - reset_b2(); - strncat(b, a, 25); - printf("`%s'\n", b); - - reset_b2(); - strncat(b, a, 26); - printf("`%s'\n", b); - - reset_b2(); - strncat(b, a, 27); - printf("`%s'\n", b); - - /* Nb: can't actually get strcat warning -- if any overlap occurs, it will - always run forever, I think... */ - - for ( i = 0; i < 2; i++) - strncat(a+20, a, 21); // run twice to check 2nd error isn't shown - strncat(a, a+20, 21); - - /* This is ok, but once gave a warning when strncpy() was wrong, - and used 'n' for the length, even when the src was shorter than 'n' */ - { - char dest[64]; - char src [16]; - strcpy( src, "short" ); - strncpy( dest, src, 20 ); - } - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/overlap.stderr.exp b/VEX/head20041019/memcheck/tests/overlap.stderr.exp deleted file mode 100644 index 6fcbcd1ca..000000000 --- a/VEX/head20041019/memcheck/tests/overlap.stderr.exp +++ /dev/null @@ -1,27 +0,0 @@ -Source and destination overlap in memcpy(0x........, 0x........, 21) - at 0x........: memcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:40) - -Source and destination overlap in memcpy(0x........, 0x........, 21) - at 0x........: memcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:42) - -Source and destination overlap in strncpy(0x........, 0x........, 21) - at 0x........: strncpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:45) - -Source and destination overlap in strncpy(0x........, 0x........, 21) - at 0x........: strncpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:47) - -Source and destination overlap in strcpy(0x........, 0x........) - at 0x........: strcpy (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:54) - -Source and destination overlap in strncat(0x........, 0x........, 21) - at 0x........: strncat (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:112) - -Source and destination overlap in strncat(0x........, 0x........, 21) - at 0x........: strncat (mac_replace_strmem.c:...) - by 0x........: main (overlap.c:113) diff --git a/VEX/head20041019/memcheck/tests/overlap.stdout.exp b/VEX/head20041019/memcheck/tests/overlap.stdout.exp deleted file mode 100644 index 12cb02e54..000000000 --- a/VEX/head20041019/memcheck/tests/overlap.stdout.exp +++ /dev/null @@ -1,11 +0,0 @@ -`_________________________________________________' -`abcdefghijklmnopqrstuvwxyz' -`abcdefghijklmnopqrstuvwxy________________________' -`abcdefghijklmnopqrstuvwxyz_______________________' -`abcdefghijklmnopqrstuvwxyz' - -`ABCDEFG' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' -`ABCDEFGabcdefghijklmnopqrstuvwxy' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' -`ABCDEFGabcdefghijklmnopqrstuvwxyz' diff --git a/VEX/head20041019/memcheck/tests/overlap.vgtest b/VEX/head20041019/memcheck/tests/overlap.vgtest deleted file mode 100644 index 54a0baacf..000000000 --- a/VEX/head20041019/memcheck/tests/overlap.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: overlap -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/pth_once.stderr.exp b/VEX/head20041019/memcheck/tests/pth_once.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/pth_once.stdout.exp b/VEX/head20041019/memcheck/tests/pth_once.stdout.exp deleted file mode 100644 index 97e25d16c..000000000 --- a/VEX/head20041019/memcheck/tests/pth_once.stdout.exp +++ /dev/null @@ -1,22 +0,0 @@ -welcome: Welcome -identify_yourself: Hi, I'm thread # 0 -identify_yourself: Hi, I'm thread # 1 -identify_yourself: Hi, I'm thread # 2 -identify_yourself: Hi, I'm thread # 3 -identify_yourself: Hi, I'm thread # 4 -identify_yourself: Hi, I'm thread # 5 -identify_yourself: Hi, I'm thread # 6 -identify_yourself: Hi, I'm thread # 7 -identify_yourself: Hi, I'm thread # 8 -identify_yourself: Hi, I'm thread # 9 -main: joined to thread 0 -main: joined to thread 1 -main: joined to thread 2 -main: joined to thread 3 -main: joined to thread 4 -main: joined to thread 5 -main: joined to thread 6 -main: joined to thread 7 -main: joined to thread 8 -main: joined to thread 9 -main: Goodbye diff --git a/VEX/head20041019/memcheck/tests/pth_once.vgtest b/VEX/head20041019/memcheck/tests/pth_once.vgtest deleted file mode 100644 index bc571a2a8..000000000 --- a/VEX/head20041019/memcheck/tests/pth_once.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: ../../corecheck/tests/pth_once -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/pushfpopf.stderr.exp b/VEX/head20041019/memcheck/tests/pushfpopf.stderr.exp deleted file mode 100644 index 2d2d623e4..000000000 --- a/VEX/head20041019/memcheck/tests/pushfpopf.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: fooble (...) - by 0x........: main (pushfpopf_c.c:12) diff --git a/VEX/head20041019/memcheck/tests/pushfpopf.stdout.exp b/VEX/head20041019/memcheck/tests/pushfpopf.stdout.exp deleted file mode 100644 index 180f871a1..000000000 --- a/VEX/head20041019/memcheck/tests/pushfpopf.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -fooble: result is 22 diff --git a/VEX/head20041019/memcheck/tests/pushfpopf.vgtest b/VEX/head20041019/memcheck/tests/pushfpopf.vgtest deleted file mode 100644 index 94cdcef78..000000000 --- a/VEX/head20041019/memcheck/tests/pushfpopf.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: pushfpopf -stderr_filter: filter_pushfpopf -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/pushfpopf_c.c b/VEX/head20041019/memcheck/tests/pushfpopf_c.c deleted file mode 100644 index f45271e0f..000000000 --- a/VEX/head20041019/memcheck/tests/pushfpopf_c.c +++ /dev/null @@ -1,14 +0,0 @@ - -#include - -// in pushfpopf.s -extern int fooble ( int, int ); - -int main ( void ) -{ - int arr[2]; - arr[0] = 3; - // arr[1] = 45; - printf("fooble: result is %d\n", fooble(arr[0], arr[1])); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/pushfpopf_s.s b/VEX/head20041019/memcheck/tests/pushfpopf_s.s deleted file mode 100644 index f1409950b..000000000 --- a/VEX/head20041019/memcheck/tests/pushfpopf_s.s +++ /dev/null @@ -1,38 +0,0 @@ - .file "twoparams.c" - .version "01.01" -gcc2_compiled.: -.text - .align 4 -.globl fooble - .type fooble,@function -fooble: - pushl %ebp - movl %esp, %ebp - movl 8(%ebp), %eax - - subl 12(%ebp), %eax - # flags are now undef if either operand is - # save possibly undef flags on stack - pushfl - - movl $0, %eax - addl $0, %eax - # flags are now definitely defined - - popfl - # resulting flag definedness depends on outcome of sub above - # should override that created by 0 + 0 above - - # now use the condition codes to generate a value - # in a way which will cause undefinedness to get reported - jz labelz - movl $22, %eax - jmp theend -labelz: - movl $33, %eax -theend: - popl %ebp - ret -.Lfe1: - .size fooble,.Lfe1-fooble - .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)" diff --git a/VEX/head20041019/memcheck/tests/realloc1.c b/VEX/head20041019/memcheck/tests/realloc1.c deleted file mode 100644 index 91878b332..000000000 --- a/VEX/head20041019/memcheck/tests/realloc1.c +++ /dev/null @@ -1,19 +0,0 @@ - -/* Anyone know what this is supposed to test? I don't - (JRS 2003-07-07) -- which ain't good considering I - probably created it :) -*/ - -#include -#include - -int main ( void ) -{ - int i; - char* p = malloc(1); - for (i = 2; i < 50; i++) { - p = realloc(p, i); - p[i-1] = 'z'; - } - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/realloc1.stderr.exp b/VEX/head20041019/memcheck/tests/realloc1.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/realloc1.vgtest b/VEX/head20041019/memcheck/tests/realloc1.vgtest deleted file mode 100644 index bab181f51..000000000 --- a/VEX/head20041019/memcheck/tests/realloc1.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: realloc1 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/realloc2.c b/VEX/head20041019/memcheck/tests/realloc2.c deleted file mode 100644 index 7b1fbf1e0..000000000 --- a/VEX/head20041019/memcheck/tests/realloc2.c +++ /dev/null @@ -1,21 +0,0 @@ -/* This test demonstrated an obscure bug in malloclists handling caused by - multiple blocks hashing to the same list and one being overwritten at - realloc time due to bad ordering of the things happening. Now runs - without error. */ - -#include -#include - -int main ( void ) -{ - char* p; - int i; - for (i = 0; i < 10000; i++) { - p = malloc(10 + 10 * (i % 100)); - p = realloc(p, 500); - p = realloc(p, 600); - free(p); - } - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/realloc2.stderr.exp b/VEX/head20041019/memcheck/tests/realloc2.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/realloc2.vgtest b/VEX/head20041019/memcheck/tests/realloc2.vgtest deleted file mode 100644 index 8d7803953..000000000 --- a/VEX/head20041019/memcheck/tests/realloc2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: realloc2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/realloc3.c b/VEX/head20041019/memcheck/tests/realloc3.c deleted file mode 100644 index 0c6a5f8a0..000000000 --- a/VEX/head20041019/memcheck/tests/realloc3.c +++ /dev/null @@ -1,28 +0,0 @@ -/* For a long time (from Valgrind 1.0 to 1.9.6, AFAICT) when realloc() was - called and made a block smaller, or didn't change its size, the - ExeContext of the block was not updated; therefore any errors that - referred to it would state that it was allocated not by the realloc(), - but by the previous malloc() or whatever. While this is true in one - sense, it is misleading and not what you'd expect. This test - demonstrates this -- 'x' and 'y' are unchanged and shrunk, and their - ExeContexts should be updated upon their realloc(). I hope that's clear. -*/ -#include - -int main(void) -{ - int* x = malloc(5); - int* y = malloc(10); - int* z = malloc(2); - int a, b, c; - - x = realloc(x, 5); // same size - y = realloc(y, 5); // make smaller - z = realloc(z, 5); // make bigger - - a = (x[5] == 0xdeadbeef ? 1 : 0); - b = (y[5] == 0xdeadbeef ? 1 : 0); - c = (z[5] == 0xdeadbeef ? 1 : 0); - - return a + b + c; -} diff --git a/VEX/head20041019/memcheck/tests/realloc3.stderr.exp b/VEX/head20041019/memcheck/tests/realloc3.stderr.exp deleted file mode 100644 index 51e5da3a1..000000000 --- a/VEX/head20041019/memcheck/tests/realloc3.stderr.exp +++ /dev/null @@ -1,17 +0,0 @@ -Invalid read of size 4 - at 0x........: main (realloc3.c:23) - Address 0x........ is 15 bytes after a block of size 5 alloc'd - at 0x........: realloc (vg_replace_malloc.c:...) - by 0x........: main (realloc3.c:19) - -Invalid read of size 4 - at 0x........: main (realloc3.c:24) - Address 0x........ is 15 bytes after a block of size 5 alloc'd - at 0x........: realloc (vg_replace_malloc.c:...) - by 0x........: main (realloc3.c:20) - -Invalid read of size 4 - at 0x........: main (realloc3.c:25) - Address 0x........ is 15 bytes after a block of size 5 alloc'd - at 0x........: realloc (vg_replace_malloc.c:...) - by 0x........: main (realloc3.c:21) diff --git a/VEX/head20041019/memcheck/tests/realloc3.vgtest b/VEX/head20041019/memcheck/tests/realloc3.vgtest deleted file mode 100644 index ff295abac..000000000 --- a/VEX/head20041019/memcheck/tests/realloc3.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: realloc3 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/sigaltstack.c b/VEX/head20041019/memcheck/tests/sigaltstack.c deleted file mode 100644 index be42442bc..000000000 --- a/VEX/head20041019/memcheck/tests/sigaltstack.c +++ /dev/null @@ -1,41 +0,0 @@ - - -#include -#include -#include -#include - -void sig_handler(int sig){ - int var; - fprintf(stderr, "caught signal, local var is on %p\n", &var); -} - -int main(int argv, char** argc) { - int res, i; - stack_t sigstk; - struct sigaction act; - static const int size = SIGSTKSZ*2; - char *stk = (char *)mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); - sigstk.ss_sp = stk; - - sigstk.ss_size = size; - sigstk.ss_flags = 0; - fprintf(stderr, "calling sigaltstack, stack base is %p\n", sigstk.ss_sp); - if (sigaltstack(&sigstk,0)<0) perror("sigaltstack"); - - fprintf(stderr,"setting sigaction\n"); - act.sa_flags=SA_ONSTACK; - act.sa_handler=&sig_handler; - sigemptyset(&act.sa_mask); - res = sigaction(SIGUSR1,&act,0); - fprintf(stderr, "res = %d\n", res); - fprintf(stderr, "raising the signal\n"); - raise(SIGUSR1); - - /* Loop long enough so valgrind has a forced context switch and - actually delivers the signal before the thread exits. */ - for (i = 0; i < 1000000; i++) ; - - fprintf(stderr, "done\n"); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/sigaltstack.stderr.exp b/VEX/head20041019/memcheck/tests/sigaltstack.stderr.exp deleted file mode 100644 index b95833f61..000000000 --- a/VEX/head20041019/memcheck/tests/sigaltstack.stderr.exp +++ /dev/null @@ -1,6 +0,0 @@ -calling sigaltstack, stack base is 0x........ -setting sigaction -res = 0 -raising the signal -caught signal, local var is on 0x........ -done diff --git a/VEX/head20041019/memcheck/tests/sigaltstack.vgtest b/VEX/head20041019/memcheck/tests/sigaltstack.vgtest deleted file mode 100644 index 532bb26ba..000000000 --- a/VEX/head20041019/memcheck/tests/sigaltstack.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: sigaltstack -stderr_filter: ./filter_stderr_backtrace -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/signal2.c b/VEX/head20041019/memcheck/tests/signal2.c deleted file mode 100644 index a1df7056e..000000000 --- a/VEX/head20041019/memcheck/tests/signal2.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include -#include - -void sig_hdlr ( int signo ) -{ - printf ( "caught sig segv\n" ); - exit(1); -} - -int main ( void ) -{ - printf ( "installing sig handler\n" ); - signal(SIGSEGV, sig_hdlr); - printf ( "doing bad thing\n" ); - * (int*) 65536 = 0; - printf ( "exited normally ?!\n" ); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/signal2.stderr.exp b/VEX/head20041019/memcheck/tests/signal2.stderr.exp deleted file mode 100644 index 32f63f7a4..000000000 --- a/VEX/head20041019/memcheck/tests/signal2.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Invalid write of size 4 - at 0x........: main (signal2.c:17) - Address 0x........ is not stack'd, malloc'd or (recently) free'd diff --git a/VEX/head20041019/memcheck/tests/signal2.stdout.exp b/VEX/head20041019/memcheck/tests/signal2.stdout.exp deleted file mode 100644 index 3e16af082..000000000 --- a/VEX/head20041019/memcheck/tests/signal2.stdout.exp +++ /dev/null @@ -1,3 +0,0 @@ -installing sig handler -doing bad thing -caught sig segv diff --git a/VEX/head20041019/memcheck/tests/signal2.vgtest b/VEX/head20041019/memcheck/tests/signal2.vgtest deleted file mode 100644 index f55551cea..000000000 --- a/VEX/head20041019/memcheck/tests/signal2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: signal2 -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/supp.c b/VEX/head20041019/memcheck/tests/supp.c deleted file mode 100644 index fe1200e3f..000000000 --- a/VEX/head20041019/memcheck/tests/supp.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -int -main () -{ - volatile int x; /* make sure it isn't in a register */ - - if (x == 0) - return 0; - else - return 1; -} diff --git a/VEX/head20041019/memcheck/tests/supp.supp b/VEX/head20041019/memcheck/tests/supp.supp deleted file mode 100644 index c80b76bbe..000000000 --- a/VEX/head20041019/memcheck/tests/supp.supp +++ /dev/null @@ -1,6 +0,0 @@ -{ - name_of_this_suppression - Memcheck:Cond - obj:*supp1 - fun:__libc_start_main -} diff --git a/VEX/head20041019/memcheck/tests/supp1.stderr.exp b/VEX/head20041019/memcheck/tests/supp1.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/supp1.vgtest b/VEX/head20041019/memcheck/tests/supp1.vgtest deleted file mode 100644 index 02e23ba0c..000000000 --- a/VEX/head20041019/memcheck/tests/supp1.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: --suppressions=supp.supp -q -prog: supp1 diff --git a/VEX/head20041019/memcheck/tests/supp2.stderr.exp b/VEX/head20041019/memcheck/tests/supp2.stderr.exp deleted file mode 100644 index 27e684209..000000000 --- a/VEX/head20041019/memcheck/tests/supp2.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: main (supp.c:8) diff --git a/VEX/head20041019/memcheck/tests/supp2.vgtest b/VEX/head20041019/memcheck/tests/supp2.vgtest deleted file mode 100644 index c4f3350e9..000000000 --- a/VEX/head20041019/memcheck/tests/supp2.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -vgopts: --suppressions=supp.supp -q -prog: supp2 diff --git a/VEX/head20041019/memcheck/tests/suppfree.c b/VEX/head20041019/memcheck/tests/suppfree.c deleted file mode 100644 index 8298f021a..000000000 --- a/VEX/head20041019/memcheck/tests/suppfree.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include - -void ddd ( char* x ) -{ - free(x); - free(x); -} - -void ccc (char* x) -{ - ddd(x); -} - -void bbb (char* x) -{ - ccc(x); -} - -void aaa (char* x) -{ - bbb(x); -} - -int main ( void ) -{ - char* x = malloc(10); - aaa(x); - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/suppfree.stderr.exp b/VEX/head20041019/memcheck/tests/suppfree.stderr.exp deleted file mode 100644 index 8beea0719..000000000 --- a/VEX/head20041019/memcheck/tests/suppfree.stderr.exp +++ /dev/null @@ -1,10 +0,0 @@ -Invalid free() / delete / delete[] - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: ddd (suppfree.c:7) - by 0x........: ccc (suppfree.c:12) - by 0x........: bbb (suppfree.c:17) - Address 0x........ is 0 bytes inside a block of size 10 free'd - at 0x........: free (vg_replace_malloc.c:...) - by 0x........: ddd (suppfree.c:6) - by 0x........: ccc (suppfree.c:12) - by 0x........: bbb (suppfree.c:17) diff --git a/VEX/head20041019/memcheck/tests/suppfree.vgtest b/VEX/head20041019/memcheck/tests/suppfree.vgtest deleted file mode 100644 index a7789c3ed..000000000 --- a/VEX/head20041019/memcheck/tests/suppfree.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: suppfree -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/threadederrno.c b/VEX/head20041019/memcheck/tests/threadederrno.c deleted file mode 100644 index 3cad5fbfd..000000000 --- a/VEX/head20041019/memcheck/tests/threadederrno.c +++ /dev/null @@ -1,35 +0,0 @@ - -#include -#include -#include -#include - - -void* thr2 ( void* v ) -{ - FILE* f = fopen("bogus2", "r"); - printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno)); - return NULL; -} - -void* thr3 ( void* v ) -{ - FILE* f = fopen("bogus3", "r"); - printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno)); - return NULL; -} - - -int main ( void ) -{ - FILE* f; - pthread_t tid2, tid3; - pthread_create(&tid2, NULL, &thr2, NULL); - pthread_create(&tid3, NULL, &thr3, NULL); - f = fopen("bogus", "r"); - printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno)); - pthread_join(tid2, NULL); - pthread_join(tid3, NULL); - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/threadederrno.stderr.exp b/VEX/head20041019/memcheck/tests/threadederrno.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/memcheck/tests/threadederrno.stdout.exp b/VEX/head20041019/memcheck/tests/threadederrno.stdout.exp deleted file mode 100644 index 671ad2af5..000000000 --- a/VEX/head20041019/memcheck/tests/threadederrno.stdout.exp +++ /dev/null @@ -1,3 +0,0 @@ -f = (nil), errno = 2 (No such file or directory) -f = (nil), errno = 2 (No such file or directory) -f = (nil), errno = 2 (No such file or directory) diff --git a/VEX/head20041019/memcheck/tests/threadederrno.vgtest b/VEX/head20041019/memcheck/tests/threadederrno.vgtest deleted file mode 100644 index a9fa6bedf..000000000 --- a/VEX/head20041019/memcheck/tests/threadederrno.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: threadederrno -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/toobig-allocs.stderr.exp b/VEX/head20041019/memcheck/tests/toobig-allocs.stderr.exp deleted file mode 100644 index a5ba60a36..000000000 --- a/VEX/head20041019/memcheck/tests/toobig-allocs.stderr.exp +++ /dev/null @@ -1,9 +0,0 @@ - -Attempting too-big malloc()... -Attempting too-big mmap()... - -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 1 allocs, 0 frees, 2145386496 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/toobig-allocs.vgtest b/VEX/head20041019/memcheck/tests/toobig-allocs.vgtest deleted file mode 100644 index 186cf5f90..000000000 --- a/VEX/head20041019/memcheck/tests/toobig-allocs.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: ../../tests/toobig-allocs diff --git a/VEX/head20041019/memcheck/tests/trivialleak.c b/VEX/head20041019/memcheck/tests/trivialleak.c deleted file mode 100644 index f3a896335..000000000 --- a/VEX/head20041019/memcheck/tests/trivialleak.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -static void test() - { - void* leak; - int i; - for (i = 0; i < 1000; i++) - leak = (void*)malloc( 1 ); - } - int main() - { - test(); - return 0; - } diff --git a/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp b/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp deleted file mode 100644 index 1bd6e545f..000000000 --- a/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ - -1000 bytes in 1000 blocks are definitely lost in loss record 1 of 1 - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: test (trivialleak.c:8) - by 0x........: main (trivialleak.c:12) diff --git a/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp2 b/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp2 deleted file mode 100644 index 6b061496a..000000000 --- a/VEX/head20041019/memcheck/tests/trivialleak.stderr.exp2 +++ /dev/null @@ -1,5 +0,0 @@ - -999 bytes in 999 blocks are definitely lost in loss record 2 of 2 - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: test (trivialleak.c:8) - by 0x........: main (trivialleak.c:12) diff --git a/VEX/head20041019/memcheck/tests/trivialleak.vgtest b/VEX/head20041019/memcheck/tests/trivialleak.vgtest deleted file mode 100644 index 7d66a3c0d..000000000 --- a/VEX/head20041019/memcheck/tests/trivialleak.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: --leak-check=yes -q -prog: trivialleak -stderr_filter: filter_leak_check_size diff --git a/VEX/head20041019/memcheck/tests/tronical.S b/VEX/head20041019/memcheck/tests/tronical.S deleted file mode 100644 index 30d336a88..000000000 --- a/VEX/head20041019/memcheck/tests/tronical.S +++ /dev/null @@ -1,102 +0,0 @@ -/* - -Assembly derived from the following program compiled with -O2. -This fools Valgrind, causing it to give a false error. - -#include - -struct Foo -{ - int a1 : 1; - int a2 : 1; - int a3 : 1; - int a4 : 1; - int a5 : 1; - int a6 : 1; - int a7 : 1; - int bleh : 1; -}; - -struct Foo* foo; - -void set() -{ - foo->bleh = 1; -} - -void get() -{ - if ( foo->bleh == 0 ) - printf( "blieb\n" ); -} - -int main() -{ - foo = malloc(sizeof(struct Foo)); - set(); - - get(); - - return 0; -} - -*/ - - .file "tronical.c" - .version "01.01" -gcc2_compiled.: -.text - .align 4 -.globl set - .type set,@function -set: - pushl %ebp - movl foo, %eax - orb $128, (%eax) - movl %esp, %ebp - popl %ebp - ret -.Lfe1: - .size set,.Lfe1-set - .section .rodata -.LC0: - .string "blieb\n" -.text - .align 4 -.globl get - .type get,@function -get: - pushl %ebp - movl %esp, %ebp - subl $8, %esp - movl foo, %eax - cmpb $0, (%eax) - js .L4 - subl $12, %esp - pushl $.LC0 - call printf - addl $16, %esp -.L4: - leave - ret -.Lfe2: - .size get,.Lfe2-get - .align 4 -.globl main - .type main,@function -main: - pushl %ebp - movl %esp, %ebp - subl $20, %esp - pushl $4 - call malloc - movl %eax, foo - call set - call get - xorl %eax, %eax - leave - ret -.Lfe3: - .size main,.Lfe3-main - .comm foo,4,4 - .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)" diff --git a/VEX/head20041019/memcheck/tests/tronical.stderr.exp b/VEX/head20041019/memcheck/tests/tronical.stderr.exp deleted file mode 100644 index c70a82ce2..000000000 --- a/VEX/head20041019/memcheck/tests/tronical.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Conditional jump or move depends on uninitialised value(s) - at 0x........: get (...) - by 0x........: main (...) diff --git a/VEX/head20041019/memcheck/tests/tronical.vgtest b/VEX/head20041019/memcheck/tests/tronical.vgtest deleted file mode 100644 index 1fdf863b6..000000000 --- a/VEX/head20041019/memcheck/tests/tronical.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -prog: tronical -stderr_filter: filter_tronical -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/vgtest_ume.c b/VEX/head20041019/memcheck/tests/vgtest_ume.c deleted file mode 100644 index 84ca3910e..000000000 --- a/VEX/head20041019/memcheck/tests/vgtest_ume.c +++ /dev/null @@ -1,150 +0,0 @@ -#define ELFSZ 32 - -// This file is a unit self-test for ume.c, jmp_with_stack.c - -#include -#include -#include -#include -#include "../../coregrind/ume.h" - -#define STKSZ (64*1024) - -static void* init_sp; - -//------------------------------------------------------------------- -// Test foreach_map() -//------------------------------------------------------------------- - -static int x[8]; - -static int f(char *start, char *end, const char *perm, off_t off, - int maj, int min, int ino, void* dummy) { - // Just do some nonsense action with each of the values so that Memcheck - // checks that they are valid. - x[0] = ( start == 0 ? 0 : 1 ); - x[1] = ( end == 0 ? 0 : 1 ); - x[2] = ( perm == 0 ? 0 : 1 ); - x[3] = ( off == 0 ? 0 : 1 ); - x[4] = ( maj == 0 ? 0 : 1 ); - x[5] = ( min == 0 ? 0 : 1 ); - x[6] = ( ino == 0 ? 0 : 1 ); - x[7] = ( dummy == 0 ? 0 : 1 ); - - return /*True*/1 + x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7]; -} - -static void test__foreach_map(void) -{ - fprintf(stderr, "Calling foreach_map()\n"); - foreach_map(f, /*dummy*/NULL); -} - -//------------------------------------------------------------------- -// Test find_auxv() -//------------------------------------------------------------------- - -static void test__find_auxv(void) -{ - struct ume_auxv *auxv; - - assert(init_sp != NULL); - - fprintf(stderr, "Calling find_auxv()\n"); - auxv = find_auxv((int*)init_sp); - - // Check the auxv value looks sane - assert((void*)auxv > (void*)init_sp); - assert((unsigned int)auxv - (unsigned int)init_sp < 0x10000); - - // Scan the auxv, check it looks sane - for (; auxv->a_type != AT_NULL; auxv++) { - switch(auxv->a_type) { - // Check a_type value looks like a plausible small constant - case 1 ... 64: - break; - - default: - assert(0); - } - } -} - -//------------------------------------------------------------------- -// Test do_exec() -//------------------------------------------------------------------- - -static void push_auxv(unsigned char **espp, int type, void *val) -{ - struct ume_auxv *auxp = (struct ume_auxv *)*espp; - auxp--; - auxp->a_type = type; - auxp->u.a_ptr = val; - *espp = (unsigned char *)auxp; -} - -static void push(unsigned char **espp, void *v) -{ - void **vp = *(void ***)espp; - *--vp = v; - *espp = (unsigned char *)vp; -} - -static void test__do_exec(void) -{ - struct exeinfo info; - int err; - unsigned char* newstack; - unsigned char *esp; - - info.argv = NULL; - info.exe_base = 0x50000000; - info.exe_end = 0x50ffffff; - info.map_base = 0x51000000; - - fprintf(stderr, "Calling do_exec(\"hello\")\n"); - err = do_exec("hello", &info); - assert(0 == err); - -// printf("info.exe_base=%p exe_end=%p\n", -// (void*)info.exe_base, (void*)info.exe_end); - - newstack = malloc(STKSZ); - assert(0 != newstack); - - esp = newstack+STKSZ; - - /* - Set the new executable's stack up like the kernel would after - exec. - - These are being pushed onto the stack, towards decreasing - addresses. - */ - push_auxv(&esp, AT_NULL, 0); // auxv terminator - push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */ - push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so - push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped - push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them - - push(&esp, 0); /* no env */ - push(&esp, 0); /* no argv */ - push(&esp, 0); /* argc=0 */ - -// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp); - - jmp_with_stack(info.init_eip, (addr_t)esp); - - assert(0); // UNREACHABLE -} - -int main(int argc, char** argv) -{ - init_sp = argv - 1; - - test__foreach_map(); - test__find_auxv(); - test__do_exec(); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/vgtest_ume.stderr.exp b/VEX/head20041019/memcheck/tests/vgtest_ume.stderr.exp deleted file mode 100644 index 777f9d110..000000000 --- a/VEX/head20041019/memcheck/tests/vgtest_ume.stderr.exp +++ /dev/null @@ -1,4 +0,0 @@ -Calling foreach_map() -Calling find_auxv() -Calling do_exec("hello") -Hello, world! diff --git a/VEX/head20041019/memcheck/tests/vgtest_ume.vgtest b/VEX/head20041019/memcheck/tests/vgtest_ume.vgtest deleted file mode 100644 index 24da9a3e2..000000000 --- a/VEX/head20041019/memcheck/tests/vgtest_ume.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: vgtest_ume -vgopts: -q diff --git a/VEX/head20041019/memcheck/tests/weirdioctl.c b/VEX/head20041019/memcheck/tests/weirdioctl.c deleted file mode 100644 index a78de65dd..000000000 --- a/VEX/head20041019/memcheck/tests/weirdioctl.c +++ /dev/null @@ -1,44 +0,0 @@ - -/* A program which sets a readable fd to have a timeout, and therefore - needs --weird-hacks=ioctl-VTIME in order to run without - blocking. */ - -#include -#include -#include - -int main ( void ) -{ - int c, i; - int res; - struct termio tty, oldtty; - - /** - ** Save the old tty settings, and get rid of echo - ** for the new tty settings - **/ - ioctl(0, TCGETA, &oldtty); - tty = oldtty; - tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); - tty.c_cc[VMIN] = 0; - tty.c_cc[VTIME] = 5; - res = ioctl(0, TCSETA, &tty); - printf("first ioctl returned %d\n", res); - - /** - ** Now do whatever stuff you want non-echoed - **/ - i = 0; - while (i++ < 50) { - c = getchar(); - printf("got %d\n", c); - } - - /** - ** Now reset the old settings - **/ - res = ioctl(0, TCSETA, &oldtty); - printf("second ioctl returned %d\n", res); - -return 0; -} diff --git a/VEX/head20041019/memcheck/tests/weirdioctl.stderr.exp b/VEX/head20041019/memcheck/tests/weirdioctl.stderr.exp deleted file mode 100644 index 37a24aac1..000000000 --- a/VEX/head20041019/memcheck/tests/weirdioctl.stderr.exp +++ /dev/null @@ -1,5 +0,0 @@ -Syscall param ioctl(TCSET{A,AW,AF}) contains uninitialised or unaddressable byte(s) - at 0x........: ioctl (in /...libc...) - by 0x........: __libc_start_main (...libc...) - by 0x........: ... - Address 0x........ is on thread 1's stack diff --git a/VEX/head20041019/memcheck/tests/weirdioctl.stdout.exp b/VEX/head20041019/memcheck/tests/weirdioctl.stdout.exp deleted file mode 100644 index f9d4a5934..000000000 --- a/VEX/head20041019/memcheck/tests/weirdioctl.stdout.exp +++ /dev/null @@ -1,52 +0,0 @@ -first ioctl returned -1 -got 118 -got 103 -got 111 -got 112 -got 116 -got 115 -got 58 -got 32 -got 45 -got 45 -got 119 -got 101 -got 105 -got 114 -got 100 -got 45 -got 104 -got 97 -got 99 -got 107 -got 115 -got 61 -got 105 -got 111 -got 99 -got 116 -got 108 -got 45 -got 86 -got 84 -got 73 -got 77 -got 69 -got 32 -got 45 -got 113 -got 10 -got 112 -got 114 -got 111 -got 103 -got 58 -got 32 -got 32 -got 32 -got 119 -got 101 -got 105 -got 114 -got 100 -second ioctl returned -1 diff --git a/VEX/head20041019/memcheck/tests/weirdioctl.vgtest b/VEX/head20041019/memcheck/tests/weirdioctl.vgtest deleted file mode 100644 index 8f5d430bd..000000000 --- a/VEX/head20041019/memcheck/tests/weirdioctl.vgtest +++ /dev/null @@ -1,3 +0,0 @@ -vgopts: --weird-hacks=ioctl-VTIME -q -prog: weirdioctl -args: < weirdioctl.vgtest diff --git a/VEX/head20041019/memcheck/tests/writev.c b/VEX/head20041019/memcheck/tests/writev.c deleted file mode 100644 index 7d405409b..000000000 --- a/VEX/head20041019/memcheck/tests/writev.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define K_1 8192 - -#define NBUFS 2 -#define CHUNK K_1 /* single chunk */ -#define MAX_IOVEC 2 -#define DATA_FILE "writev_data_file" - -static char buf1[K_1]; -static char buf2[K_1]; -static char *buf_list[NBUFS], f_name[]="writev_data_file"; -static int fd; - -struct iovec wr_iovec[MAX_IOVEC] = { - {(caddr_t)-1, CHUNK}, - {(caddr_t)NULL, 0} -}; - -int main(void) -{ - int nbytes; - - /* Fill the buf_list[0] and buf_list[1] with 0 zeros */ - buf_list[0] = buf1; - buf_list[1] = buf2; - memset(buf_list[0], 0, K_1); - memset(buf_list[1], 0, K_1); - - if ((fd = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) { - fprintf(stderr, "open(2) failed: fname = %s, errno = %d\n", - f_name, errno); - return 1; - } else if ((nbytes = write(fd, buf_list[1], K_1)) != K_1) { - fprintf(stderr, "write(2) failed: nbytes = %d, errno = %d\n", - nbytes, errno); - return 1; - } - if (close(fd) < 0) { - fprintf(stderr, "close failed: errno = %d\n", errno); - return 1; - } - fprintf(stderr, "Test file created.\n"); - if ((fd = open(f_name, O_RDWR, 0666)) < 0) { - fprintf(stderr, "open failed: fname = %s, errno = %d\n", - f_name, errno); - return 1; - } - - lseek(fd, 0, 0); - if (writev(fd, wr_iovec, 2) < 0) { - if (errno == EFAULT) - fprintf(stderr, "Received EFAULT as expected\n"); - else - fprintf(stderr, "Expected EFAULT, got %d\n", errno); - lseek(fd, K_1, 0); - if ((nbytes = read(fd, buf_list[0], CHUNK)) != 0) - fprintf(stderr, "Expected nbytes = 0, got %d\n", nbytes); - } - else - fprintf(stderr, "Error writev returned a positive value\n"); - // Now check invalid vector count - if (writev(fd, wr_iovec, -1) < 0) { - if (errno == EINVAL) - fprintf(stderr, "Received EINVAL as expected\n"); - else - fprintf(stderr, "expected errno = EINVAL, got %d\n", errno); - } - else - fprintf(stderr, "Error writev returned a positive value\n"); - if (readv(fd, wr_iovec, -1) < 0) { - if (errno == EINVAL) - fprintf(stderr, "Received EINVAL as expected\n"); - else - fprintf(stderr, "expected errno = EINVAL, got %d\n", errno); - } - else - fprintf(stderr, "Error writev returned a positive value\n"); - - unlink(f_name); - - return 0; -} - diff --git a/VEX/head20041019/memcheck/tests/writev.stderr.exp b/VEX/head20041019/memcheck/tests/writev.stderr.exp deleted file mode 100644 index 685d9c638..000000000 --- a/VEX/head20041019/memcheck/tests/writev.stderr.exp +++ /dev/null @@ -1,25 +0,0 @@ - -Test file created. -Syscall param writev(vector[...]) contains uninitialised or unaddressable byte(s) - at 0x........: writev (in /...libc...) - by 0x........: main (writev.c:56) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EFAULT as expected - -Syscall param writev(vector) contains uninitialised or unaddressable byte(s) - at 0x........: writev (in /...libc...) - by 0x........: main (writev.c:68) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EINVAL as expected - -Syscall param readv(vector) contains uninitialised or unaddressable byte(s) - at 0x........: readv (in /...libc...) - by 0x........: main (writev.c:76) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EINVAL as expected - -ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 0 allocs, 0 frees, 0 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/writev.stderr.exp2 b/VEX/head20041019/memcheck/tests/writev.stderr.exp2 deleted file mode 100644 index 001b2b224..000000000 --- a/VEX/head20041019/memcheck/tests/writev.stderr.exp2 +++ /dev/null @@ -1,25 +0,0 @@ - -Test file created. -Syscall param writev(vector[...]) contains uninitialised or unaddressable byte(s) - at 0x........: (within /...libc...) - by 0x........: main (writev.c:56) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EFAULT as expected - -Syscall param writev(vector) contains uninitialised or unaddressable byte(s) - at 0x........: (within /...libc...) - by 0x........: main (writev.c:68) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EINVAL as expected - -Syscall param readv(vector) contains uninitialised or unaddressable byte(s) - at 0x........: readv (in /...libc...) - by 0x........: main (writev.c:76) - Address 0x........ is not stack'd, malloc'd or (recently) free'd -Received EINVAL as expected - -ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) -malloc/free: in use at exit: 0 bytes in 0 blocks. -malloc/free: 0 allocs, 0 frees, 0 bytes allocated. -For a detailed leak analysis, rerun with: --leak-check=yes -For counts of detected errors, rerun with: -v diff --git a/VEX/head20041019/memcheck/tests/writev.vgtest b/VEX/head20041019/memcheck/tests/writev.vgtest deleted file mode 100644 index 0670cc702..000000000 --- a/VEX/head20041019/memcheck/tests/writev.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: writev diff --git a/VEX/head20041019/memcheck/tests/zeropage.c b/VEX/head20041019/memcheck/tests/zeropage.c deleted file mode 100644 index 5a52def7a..000000000 --- a/VEX/head20041019/memcheck/tests/zeropage.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include - -/* The quick sanity check of Memcheck (and other tools with shadow memory) - relies on the first 64KB of memory never being used. So our mmap() - refuses to touch this area. This program tests for that. */ - -int main(void) -{ - /* mmap(0x0, ... FIXED) should fail */ - int* m = mmap(0x0, 1000000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0); - if (m != (int*)-1) - printf("succeeded?!\n"); - - /* mmap(0x1000, ... FIXED) should fail */ - m = mmap((void*)0x1000, 1000000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0); - if (m != (int*)-1) - printf("succeeded?!\n"); - - /* mmap(0xa000, ... FIXED) should fail */ - m = mmap((void*)0xa000, 1000000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0); - if (m != (int*)-1) - printf("succeeded?!\n"); - - /* mmap(0x10000, ... FIXED) should fail */ - m = mmap((void*)0x10000, 1000000, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0); - if (m == (int*)-1) - printf("failed?!\n"); - - return 0; -} diff --git a/VEX/head20041019/memcheck/tests/zeropage.stderr.exp b/VEX/head20041019/memcheck/tests/zeropage.stderr.exp deleted file mode 100644 index d3e3f43bf..000000000 --- a/VEX/head20041019/memcheck/tests/zeropage.stderr.exp +++ /dev/null @@ -1,3 +0,0 @@ -Warning: client syscall mmap2 tried to modify addresses 0x........-0x........ -Warning: client syscall mmap2 tried to modify addresses 0x........-0x........ -Warning: client syscall mmap2 tried to modify addresses 0x........-0x........ diff --git a/VEX/head20041019/memcheck/tests/zeropage.stderr.exp2 b/VEX/head20041019/memcheck/tests/zeropage.stderr.exp2 deleted file mode 100644 index 247d6a93f..000000000 --- a/VEX/head20041019/memcheck/tests/zeropage.stderr.exp2 +++ /dev/null @@ -1,3 +0,0 @@ -Warning: client syscall mmap tried to modify addresses 0x........-0x........ -Warning: client syscall mmap tried to modify addresses 0x........-0x........ -Warning: client syscall mmap tried to modify addresses 0x........-0x........ diff --git a/VEX/head20041019/memcheck/tests/zeropage.vgtest b/VEX/head20041019/memcheck/tests/zeropage.vgtest deleted file mode 100644 index 89038e4d1..000000000 --- a/VEX/head20041019/memcheck/tests/zeropage.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: zeropage -vgopts: -q diff --git a/VEX/head20041019/nightly/CVS/Entries b/VEX/head20041019/nightly/CVS/Entries deleted file mode 100644 index 3bf72ab38..000000000 --- a/VEX/head20041019/nightly/CVS/Entries +++ /dev/null @@ -1,3 +0,0 @@ -/README.txt/1.1/Wed Feb 25 13:14:39 2004// -D/bin//// -D/conf//// diff --git a/VEX/head20041019/nightly/CVS/Repository b/VEX/head20041019/nightly/CVS/Repository deleted file mode 100644 index ce2a83a15..000000000 --- a/VEX/head20041019/nightly/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/nightly diff --git a/VEX/head20041019/nightly/CVS/Root b/VEX/head20041019/nightly/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/nightly/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/nightly/CVS/Template b/VEX/head20041019/nightly/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/nightly/README.txt b/VEX/head20041019/nightly/README.txt deleted file mode 100644 index a00dc11e5..000000000 --- a/VEX/head20041019/nightly/README.txt +++ /dev/null @@ -1,15 +0,0 @@ - -This directory (nightly/) contains a simple, automatic build-and-test -system for Valgrind, intended to be run by cron. - -Note (importantly) it doesn't test the sources in the tree of which -this directory is a part (viz, nightly/..). Instead it checks out -a complete new tree, builds and tests that independently of the -existing tree. - -To use, choose a tag, probably a machine name, and run - - bin/nightly /path/to/valgrind/nightly tag - -and supply conf/tag.conf and conf/tag.sendmail. - diff --git a/VEX/head20041019/nightly/bin/CVS/Entries b/VEX/head20041019/nightly/bin/CVS/Entries deleted file mode 100644 index 93b479544..000000000 --- a/VEX/head20041019/nightly/bin/CVS/Entries +++ /dev/null @@ -1,2 +0,0 @@ -/nightly/1.1/Wed Feb 25 13:14:39 2004// -D diff --git a/VEX/head20041019/nightly/bin/CVS/Repository b/VEX/head20041019/nightly/bin/CVS/Repository deleted file mode 100644 index 072f2cbe4..000000000 --- a/VEX/head20041019/nightly/bin/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/nightly/bin diff --git a/VEX/head20041019/nightly/bin/CVS/Root b/VEX/head20041019/nightly/bin/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/nightly/bin/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/nightly/bin/CVS/Template b/VEX/head20041019/nightly/bin/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/nightly/bin/nightly b/VEX/head20041019/nightly/bin/nightly deleted file mode 100755 index c9d324119..000000000 --- a/VEX/head20041019/nightly/bin/nightly +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -# Automated build and test for Valgrind. -# Use: two args, first is path to top of ValgrindABT tree -# second is name of machine - -ABT_TOP=$1 -ABT_MACHINE=$2 - -ABT_START=`date "+%F %H:%M:%S %Z"` - -cd $ABT_TOP - -source $ABT_TOP/conf/$ABT_MACHINE.conf - -rm -rf log.verbose log.short valgrind - -echo > log.short -echo > log.verbose - -echo "Nightly build on" $ABT_MACHINE "(" $ABT_DETAILS ") started at" $ABT_START >> log.short -echo >> log.short - -echo "Nightly build on" $ABT_MACHINE "(" $ABT_DETAILS ") started at" $ABT_START >> log.verbose -echo >> log.verbose - -echo -n " Checking out source tree ... " >> log.short -cvs co valgrind 2>&1 >> log.verbose -echo "done" >> log.short - -echo -n " Configuring ... " >> log.short -(cd valgrind && ./autogen.sh 2>&1 && ./configure --prefix=`pwd`/Inst 2>&1 ) >> log.verbose -echo "done" >> log.short - -echo -n " Building ... " >> log.short -(cd valgrind && make install 2>&1 ) >> log.verbose -echo "done" >> log.short - -echo -n " Running regression tests ... " >> log.short -(cd valgrind && make regtest 2>&1 ) >> log.verbose -echo "done" >> log.short - -echo >> log.short -echo "Last 20 lines of log.verbose follow" >> log.short -echo >> log.short -tail -20 log.verbose >> log.short - -$ABT_TOP/conf/$ABT_MACHINE.sendmail "$ABT_START nightly build ($ABT_MACHINE, $ABT_DETAILS)" \ - $ABT_TOP/log.short - diff --git a/VEX/head20041019/nightly/conf/CVS/Entries b/VEX/head20041019/nightly/conf/CVS/Entries deleted file mode 100644 index 995497f94..000000000 --- a/VEX/head20041019/nightly/conf/CVS/Entries +++ /dev/null @@ -1,3 +0,0 @@ -/nemesis.conf/1.1/Wed Feb 25 13:14:39 2004// -/nemesis.sendmail/1.1/Wed Feb 25 13:14:39 2004// -D diff --git a/VEX/head20041019/nightly/conf/CVS/Repository b/VEX/head20041019/nightly/conf/CVS/Repository deleted file mode 100644 index f6943744a..000000000 --- a/VEX/head20041019/nightly/conf/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/nightly/conf diff --git a/VEX/head20041019/nightly/conf/CVS/Root b/VEX/head20041019/nightly/conf/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/nightly/conf/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/nightly/conf/CVS/Template b/VEX/head20041019/nightly/conf/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/nightly/conf/nemesis.conf b/VEX/head20041019/nightly/conf/nemesis.conf deleted file mode 100644 index 4aef6c7c7..000000000 --- a/VEX/head20041019/nightly/conf/nemesis.conf +++ /dev/null @@ -1,6 +0,0 @@ - -# Specifics for nemesis (SuSE 9.0, VIA Nehemiah) - -export ABT_DETAILS="SuSE 9.0" -export CVSROOT=":ext:jseward@cvs.kde.org:/home/kde" -export CVS_RSH=ssh diff --git a/VEX/head20041019/nightly/conf/nemesis.sendmail b/VEX/head20041019/nightly/conf/nemesis.sendmail deleted file mode 100755 index ca6af71e3..000000000 --- a/VEX/head20041019/nightly/conf/nemesis.sendmail +++ /dev/null @@ -1,5 +0,0 @@ - -#use: subject file-to-mail - -/usr/bin/mail -s "$1" -R jseward@acm.org -r jseward@acm.org valgrind-developers@lists.sourceforge.net < $2 - \ No newline at end of file diff --git a/VEX/head20041019/none/.cvsignore b/VEX/head20041019/none/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/none/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/none/CVS/Entries b/VEX/head20041019/none/CVS/Entries deleted file mode 100644 index 7acd9a1df..000000000 --- a/VEX/head20041019/none/CVS/Entries +++ /dev/null @@ -1,5 +0,0 @@ -/.cvsignore/1.1/Mon Sep 23 11:36:38 2002// -/Makefile.am/1.46/Wed Sep 1 23:20:49 2004// -/nl_main.c/1.20/Thu Sep 2 08:51:43 2004// -D/docs//// -D/tests//// diff --git a/VEX/head20041019/none/CVS/Repository b/VEX/head20041019/none/CVS/Repository deleted file mode 100644 index 3a215703b..000000000 --- a/VEX/head20041019/none/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/none diff --git a/VEX/head20041019/none/CVS/Root b/VEX/head20041019/none/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/none/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/none/CVS/Template b/VEX/head20041019/none/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/none/Makefile.am b/VEX/head20041019/none/Makefile.am deleted file mode 100644 index a4fc9e6fa..000000000 --- a/VEX/head20041019/none/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/Makefile.tool.am - -val_PROGRAMS = vgskin_none.so - -vgskin_none_so_SOURCES = nl_main.c -vgskin_none_so_LDFLAGS = -shared - diff --git a/VEX/head20041019/none/docs/.cvsignore b/VEX/head20041019/none/docs/.cvsignore deleted file mode 100644 index 3dda72986..000000000 --- a/VEX/head20041019/none/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile diff --git a/VEX/head20041019/none/docs/CVS/Entries b/VEX/head20041019/none/docs/CVS/Entries deleted file mode 100644 index 76fd4d008..000000000 --- a/VEX/head20041019/none/docs/CVS/Entries +++ /dev/null @@ -1,4 +0,0 @@ -/.cvsignore/1.1/Thu Oct 3 09:12:58 2002// -/Makefile.am/1.3/Wed Aug 25 11:40:07 2004// -/nl_main.html/1.4/Sun Jan 4 16:43:23 2004// -D diff --git a/VEX/head20041019/none/docs/CVS/Repository b/VEX/head20041019/none/docs/CVS/Repository deleted file mode 100644 index 2c351a4c7..000000000 --- a/VEX/head20041019/none/docs/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/none/docs diff --git a/VEX/head20041019/none/docs/CVS/Root b/VEX/head20041019/none/docs/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/none/docs/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/none/docs/CVS/Template b/VEX/head20041019/none/docs/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/none/docs/Makefile.am b/VEX/head20041019/none/docs/Makefile.am deleted file mode 100644 index bbd22965f..000000000 --- a/VEX/head20041019/none/docs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -docdir = $(datadir)/doc/valgrind - -dist_doc_DATA = nl_main.html diff --git a/VEX/head20041019/none/docs/nl_main.html b/VEX/head20041019/none/docs/nl_main.html deleted file mode 100644 index a431944cc..000000000 --- a/VEX/head20041019/none/docs/nl_main.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - Cachegrind - - - - - -

    Nulgrind

    -
    This manual was last updated on 2002-10-02
    -

    - -

    -njn25@cam.ac.uk
    -Copyright © 2000-2004 Nicholas Nethercote -

    -Nulgrind is licensed under the GNU General Public License, -version 2
    -Nulgrind is a Valgrind tool that does not very much at all. -

    - -

    - -

    1  Nulgrind

    - -Nulgrind is the minimal tool for Valgrind. It does no initialisation or -finalisation, and adds no instrumentation to the program's code. It is mainly -of use for Valgrind's developers for debugging and regression testing. -

    -Nonetheless you can run programs with Nulgrind. They will run roughly 5-10 -times more slowly than normal, for no useful effect. Note that you need to use -the option --tool=none to run Nulgrind (ie. not ---tool=nulgrind). - -


    - - - diff --git a/VEX/head20041019/none/nl_main.c b/VEX/head20041019/none/nl_main.c deleted file mode 100644 index fd644a77a..000000000 --- a/VEX/head20041019/none/nl_main.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*--------------------------------------------------------------------*/ -/*--- Nulgrind: The null tool. nl_main.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Nulgrind, the simplest possible Valgrind tool, - which does nothing. - - Copyright (C) 2002-2004 Nicholas Nethercote - njn25@cam.ac.uk - - 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. - - The GNU General Public License is contained in the file COPYING. -*/ - -#include "tool.h" -#include "../../../pub/libvex.h" - -void SK_(pre_clo_init)(void) -{ - VG_(details_name) ("Nulgrind"); - VG_(details_version) (NULL); - VG_(details_description) ("a binary JIT-compiler"); - VG_(details_copyright_author)( - "Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote."); - VG_(details_bug_reports_to) (VG_BUGS_TO); - - /* No needs, no core events to track */ -} - -void SK_(post_clo_init)(void) -{ -} - -IRBB* SK_(instrument)(IRBB* bb, VexGuestLayout* layout, IRType hWordTy) -{ - return bb; -} - -void SK_(fini)(Int exitcode) -{ -} - -VG_DETERMINE_INTERFACE_VERSION(SK_(pre_clo_init), 0) - -/*--------------------------------------------------------------------*/ -/*--- end ---*/ -/*--------------------------------------------------------------------*/ diff --git a/VEX/head20041019/none/tests/.cvsignore b/VEX/head20041019/none/tests/.cvsignore deleted file mode 100644 index c1bcb1ae7..000000000 --- a/VEX/head20041019/none/tests/.cvsignore +++ /dev/null @@ -1,77 +0,0 @@ -Makefile.in -Makefile -args -badseg -bitfield1 -bt_everything -bt_literal -closeall -coolo_sigaction -coolo_strlen -cpuid -dastest -discard -exec-sigmask -execve -fcntl_setown -floored -fork -fpu_lazy_eflags -fucomip -gxx304 -insn_basic -insn_basic.c -insn_fpu -insn_fpu.c -insn_cmov -insn_cmov.c -insn_mmx -insn_mmx.c -insn_mmxext -insn_mmxext.c -insn_sse -insn_sse.c -insn_sse2 -insn_sse2.c -int -map_unmap -mq -mremap -munmap_exe -pluto -pth_blockedsig -rcl_assert -rcrl -readline1 -resolv -rlimit_nofile -seg_override -sem -semlimit -sha1_test -shortpush -shorts -smc1 -susphello -syscall-restart1 -syscall-restart2 -system -pth_atfork1 -pth_cancel1 -pth_cancel2 -pth_cvsimple -pth_mutexspeed -pth_once -pth_semaphore1 -pth_simple_mutex -pth_simple_threads -pth_specific -pth_yield -pushpopseg -*.stdout.diff -*.stderr.diff -*.stdout.out -*.stderr.out -tls -vgcore.pid* -yield diff --git a/VEX/head20041019/none/tests/CVS/Entries b/VEX/head20041019/none/tests/CVS/Entries deleted file mode 100644 index 6d4ca95b7..000000000 --- a/VEX/head20041019/none/tests/CVS/Entries +++ /dev/null @@ -1,219 +0,0 @@ -/.cvsignore/1.19/Wed Sep 1 23:34:37 2004// -/Makefile.am/1.43/Sat Aug 14 18:52:27 2004// -/args.c/1.1/Mon Feb 24 22:05:36 2003// -/args.stderr.exp/1.1/Mon Feb 24 22:05:37 2003// -/args.stdout.exp/1.1/Mon Feb 24 22:05:37 2003// -/args.vgtest/1.1/Mon Feb 24 22:05:38 2003// -/badseg.c/1.2/Tue Mar 16 10:51:40 2004// -/badseg.stderr.exp/1.1/Tue Mar 16 09:49:08 2004// -/badseg.stdout.exp/1.1/Tue Mar 16 09:49:08 2004// -/badseg.vgtest/1.1/Tue Mar 16 09:49:08 2004// -/bitfield1.c/1.3/Sat Jan 3 14:24:42 2004// -/bitfield1.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/bitfield1.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/bt_everything.c/1.2/Mon Sep 23 09:36:25 2002// -/bt_everything.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/bt_everything.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/bt_everything.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/bt_literal.c/1.2/Mon Sep 23 09:36:25 2002// -/bt_literal.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/bt_literal.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/bt_literal.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/closeall.c/1.1/Sun Feb 15 16:12:35 2004// -/closeall.stderr.exp/1.1/Sun Feb 15 16:12:35 2004// -/closeall.vgtest/1.1/Sun Feb 15 16:12:35 2004// -/cmdline1.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline1.stdout.exp/1.7/Sat Aug 21 11:10:44 2004// -/cmdline1.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/cmdline2.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline2.stdout.exp/1.7/Sat Aug 21 11:10:44 2004// -/cmdline2.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/cmdline3.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline3.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/cmdline4.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline4.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/cmdline5.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline5.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/cmdline6.stderr.exp/1.1/Tue Jun 15 10:54:39 2004// -/cmdline6.vgtest/1.1/Tue Jun 15 10:54:39 2004// -/coolo_sigaction.cpp/1.2/Mon Sep 23 09:36:25 2002// -/coolo_sigaction.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/coolo_sigaction.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/coolo_sigaction.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/coolo_strlen.c/1.2/Mon Sep 23 09:36:25 2002// -/coolo_strlen.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/coolo_strlen.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/cpuid.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/cpuid.stdout.exp/1.4/Sun Jun 29 10:12:58 2003// -/cpuid.vgtest/1.3/Sun Jun 29 10:12:58 2003// -/cpuid_c.c/1.2/Mon Sep 23 09:36:25 2002// -/cpuid_s.s/1.2/Mon Sep 23 09:36:25 2002// -/dastest.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/dastest.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/dastest.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/dastest_c.c/1.2/Mon Sep 23 09:36:25 2002// -/dastest_s.s/1.2/Mon Sep 23 09:36:25 2002// -/discard.c/1.3/Thu Nov 13 23:02:16 2003// -/discard.stderr.exp/1.2/Sun Dec 15 02:51:21 2002// -/discard.stdout.exp/1.1/Fri Oct 4 14:16:37 2002// -/discard.vgtest/1.1/Fri Oct 4 14:16:37 2002// -/exec-sigmask.c/1.1/Fri Jan 16 05:37:46 2004// -/exec-sigmask.stderr.exp/1.1/Fri Jan 16 02:17:29 2004// -/exec-sigmask.stdout.exp/1.1/Fri Jan 16 02:19:15 2004// -/exec-sigmask.vgtest/1.1/Wed Jan 21 01:20:38 2004// -/execve.c/1.2/Wed Jul 21 16:23:38 2004// -/execve.stderr.exp/1.1/Sat Jun 19 13:02:34 2004// -/execve.stdout.exp/1.1/Sat Jun 19 13:02:34 2004// -/execve.vgtest/1.1/Sat Jun 19 13:02:34 2004// -/fcntl_setown.c/1.1/Thu Jul 29 21:20:11 2004// -/fcntl_setown.stderr.exp/1.1/Thu Jul 29 21:20:11 2004// -/fcntl_setown.stdout.exp/1.1/Thu Jul 29 21:20:11 2004// -/fcntl_setown.vgtest/1.1/Thu Jul 29 21:20:11 2004// -/filter_cpuid/1.1/Sun Jun 29 10:12:58 2003// -/filter_int/1.1/Sat Mar 6 12:53:24 2004// -/filter_none_discards/1.1/Wed Oct 30 15:22:03 2002// -/filter_stderr/1.3/Mon Sep 23 11:21:55 2002// -/floored.c/1.2/Mon Sep 23 09:36:25 2002// -/floored.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/floored.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/floored.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/fork.c/1.4/Tue Jan 6 21:46:02 2004// -/fork.stderr.exp/1.4/Tue Jan 6 21:46:02 2004// -/fork.stdout.exp/1.3/Fri Sep 27 10:38:20 2002// -/fork.vgtest/1.3/Tue Jan 6 21:46:02 2004// -/fpu_lazy_eflags.c/1.1/Tue Apr 8 10:04:31 2003// -/fpu_lazy_eflags.stderr.exp/1.1/Tue Apr 8 10:04:32 2003// -/fpu_lazy_eflags.stdout.exp/1.1/Tue Apr 8 10:04:32 2003// -/fpu_lazy_eflags.vgtest/1.1/Tue Apr 8 10:04:32 2003// -/fucomip.c/1.2/Mon Sep 23 09:36:25 2002// -/fucomip.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/fucomip.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/gen_insn_test.pl/1.8/Sun Jul 25 15:18:21 2004// -/gxx304.cpp/1.2/Mon Sep 23 09:36:25 2002// -/gxx304.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/gxx304.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/insn_basic.def/1.1/Thu Feb 12 08:35:57 2004// -/insn_basic.stderr.exp/1.1/Thu Feb 12 08:35:57 2004// -/insn_basic.stdout.exp/1.1/Thu Feb 12 08:35:57 2004// -/insn_basic.vgtest/1.1/Thu Feb 12 08:35:57 2004// -/insn_cmov.def/1.1/Thu Feb 12 08:35:57 2004// -/insn_cmov.stderr.exp/1.1/Thu Feb 12 08:35:57 2004// -/insn_cmov.stdout.exp/1.1/Thu Feb 12 08:35:57 2004// -/insn_cmov.vgtest/1.1/Thu Feb 12 08:35:57 2004// -/insn_fpu.def/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.stderr.exp/1.1/Sat Mar 27 18:02:37 2004// -/insn_fpu.stdout.exp/1.4/Wed Mar 31 22:47:52 2004// -/insn_fpu.vgtest/1.1/Sat Mar 27 18:02:37 2004// -/insn_mmx.def/1.2/Wed Feb 11 23:33:29 2004// -/insn_mmx.stderr.exp/1.1/Tue Jan 20 09:24:53 2004// -/insn_mmx.stdout.exp/1.1/Tue Jan 20 09:24:53 2004// -/insn_mmx.vgtest/1.1/Tue Jan 20 09:24:53 2004// -/insn_mmxext.def/1.2/Sun Jul 25 15:18:21 2004// -/insn_mmxext.stderr.exp/1.1/Thu Feb 12 08:35:57 2004// -/insn_mmxext.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_mmxext.vgtest/1.1/Thu Feb 12 08:35:57 2004// -/insn_sse.def/1.3/Sun Jul 25 15:18:21 2004// -/insn_sse.stderr.exp/1.1/Tue Jan 20 09:24:53 2004// -/insn_sse.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse.vgtest/1.1/Tue Jan 20 09:24:53 2004// -/insn_sse2.def/1.3/Sun Jul 25 15:18:21 2004// -/insn_sse2.stderr.exp/1.1/Tue Jan 20 09:24:53 2004// -/insn_sse2.stdout.exp/1.2/Sun Jul 25 15:18:21 2004// -/insn_sse2.vgtest/1.1/Tue Jan 20 09:24:53 2004// -/int.c/1.1/Sat Mar 6 12:53:24 2004// -/int.stderr.exp/1.2/Tue Mar 16 11:03:09 2004// -/int.stdout.exp/1.1/Sat Mar 6 12:53:24 2004// -/int.vgtest/1.1/Sat Mar 6 12:53:24 2004// -/map_unmap.c/1.4/Mon Jan 19 21:47:52 2004// -/map_unmap.stderr.exp/1.1/Fri Dec 19 21:56:04 2003// -/map_unmap.stdout.exp/1.1/Fri Dec 19 21:56:04 2003// -/map_unmap.vgtest/1.1/Fri Dec 19 21:56:04 2003// -/mq.c/1.1/Sat Aug 14 18:52:27 2004// -/mq.stderr.exp/1.1/Sat Aug 14 18:52:27 2004// -/mq.vgtest/1.1/Sat Aug 14 18:52:27 2004// -/mremap.c/1.1/Mon Dec 22 08:48:50 2003// -/mremap.stderr.exp/1.1/Mon Dec 22 08:48:50 2003// -/mremap.stdout.exp/1.1/Mon Dec 22 08:48:50 2003// -/mremap.vgtest/1.1/Mon Dec 22 08:48:50 2003// -/munmap_exe.c/1.3/Sat Jan 3 14:24:42 2004// -/munmap_exe.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/munmap_exe.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_blockedsig.c/1.2/Mon Sep 23 09:36:25 2002// -/pth_blockedsig.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/pth_blockedsig.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/pth_blockedsig.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/pth_specific.c/1.2/Mon Sep 23 09:36:25 2002// -/pushpopseg.c/1.2/Mon Mar 15 12:58:55 2004// -/pushpopseg.stderr.exp/1.1/Thu Mar 4 23:36:58 2004// -/pushpopseg.stdout.exp/1.1/Thu Mar 4 23:36:58 2004// -/pushpopseg.vgtest/1.1/Thu Mar 4 23:36:58 2004// -/rcl_assert.S/1.2/Mon Sep 23 09:36:25 2002// -/rcl_assert.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/rcl_assert.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/rcrl.c/1.2/Mon Sep 23 09:36:25 2002// -/rcrl.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/rcrl.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/rcrl.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/readline1.c/1.2/Mon Sep 23 09:36:25 2002// -/readline1.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/readline1.stdout.exp/1.2/Mon Sep 23 09:36:25 2002// -/readline1.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/resolv.c/1.3/Sat Jan 3 14:24:42 2004// -/resolv.stderr.exp/1.1/Tue Oct 1 11:45:34 2002// -/resolv.stdout.exp/1.2/Thu Apr 3 00:50:21 2003// -/resolv.vgtest/1.1/Tue Oct 1 11:45:34 2002// -/rlimit_nofile.c/1.1/Sat Jun 26 11:27:52 2004// -/rlimit_nofile.stderr.exp/1.1/Sat Jun 26 11:27:52 2004// -/rlimit_nofile.stdout.exp/1.1/Sat Jun 26 11:27:52 2004// -/rlimit_nofile.vgtest/1.1/Sat Jun 26 11:27:52 2004// -/seg_override.c/1.2/Wed Jan 21 01:27:27 2004// -/seg_override.stderr.exp/1.1/Wed Oct 2 10:36:46 2002// -/seg_override.stdout.exp/1.1/Wed Oct 2 10:36:46 2002// -/seg_override.vgtest/1.1/Wed Oct 2 10:36:46 2002// -/sem.c/1.4/Mon Jun 14 17:27:41 2004// -/sem.stderr.exp/1.1/Sun Jun 13 14:23:00 2004// -/sem.stdout.exp/1.1/Sun Jun 13 14:23:00 2004// -/sem.vgtest/1.1/Sun Jun 13 14:23:00 2004// -/semlimit.c/1.1/Tue Mar 23 19:48:54 2004// -/semlimit.stderr.exp/1.1/Tue Mar 23 19:48:54 2004// -/semlimit.stdout.exp/1.1/Tue Mar 23 19:48:54 2004// -/semlimit.vgtest/1.1/Tue Mar 23 19:48:54 2004// -/sha1_test.c/1.4/Sat Jan 3 14:24:42 2004// -/sha1_test.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/sha1_test.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/shortpush.c/1.2/Mon Sep 23 09:36:25 2002// -/shortpush.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/shortpush.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/shorts.c/1.2/Mon Sep 23 09:36:25 2002// -/shorts.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/shorts.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/smc1.c/1.3/Tue Dec 16 02:05:15 2003// -/smc1.stderr.exp/1.2/Mon Sep 23 09:36:25 2002// -/smc1.stdout.exp/1.3/Tue Dec 16 02:05:15 2003// -/smc1.vgtest/1.2/Mon Sep 23 09:36:25 2002// -/susphello.c/1.1/Wed Mar 17 18:20:46 2004// -/susphello.stderr.exp/1.1/Wed Mar 17 18:20:46 2004// -/susphello.stdout.exp/1.1/Wed Mar 17 18:20:46 2004// -/susphello.vgtest/1.1/Wed Mar 17 18:20:46 2004// -/syscall-restart1.c/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart1.stderr.exp/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart1.stdout.exp/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart1.vgtest/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart2.c/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart2.stderr.exp/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart2.stdout.exp/1.1/Fri Jan 16 02:15:23 2004// -/syscall-restart2.vgtest/1.1/Fri Jan 16 02:15:23 2004// -/system.c/1.1/Sun Feb 15 16:15:05 2004// -/system.stderr.exp/1.1/Sun Feb 15 16:15:05 2004// -/system.vgtest/1.1/Sun Feb 15 16:15:05 2004// -/tls.c/1.1/Wed Jan 21 01:27:27 2004// -/tls.stderr.exp/1.1/Wed Jan 21 01:27:27 2004// -/tls.stdout.exp/1.1/Wed Jan 21 01:27:27 2004// -/tls2.c/1.1/Wed Jan 21 01:27:27 2004// -/tls2_so.c/1.1/Wed Jan 21 01:27:27 2004// -/tls_so.c/1.1/Wed Jan 21 01:27:27 2004// -/yield.c/1.1/Thu Dec 18 09:08:51 2003// -/yield.stderr.exp/1.1/Thu Dec 18 09:08:51 2003// -/yield.stdout.exp/1.1/Thu Dec 18 09:08:51 2003// -/yield.vgtest/1.1/Thu Dec 18 09:08:51 2003// -D diff --git a/VEX/head20041019/none/tests/CVS/Repository b/VEX/head20041019/none/tests/CVS/Repository deleted file mode 100644 index 4c318ac4b..000000000 --- a/VEX/head20041019/none/tests/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -valgrind/none/tests diff --git a/VEX/head20041019/none/tests/CVS/Root b/VEX/head20041019/none/tests/CVS/Root deleted file mode 100644 index 0cb7c52e1..000000000 --- a/VEX/head20041019/none/tests/CVS/Root +++ /dev/null @@ -1 +0,0 @@ -:ext:jseward@cvs.kde.org:/home/kde diff --git a/VEX/head20041019/none/tests/CVS/Template b/VEX/head20041019/none/tests/CVS/Template deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/none/tests/Makefile.am b/VEX/head20041019/none/tests/Makefile.am deleted file mode 100644 index 6ddfca3c8..000000000 --- a/VEX/head20041019/none/tests/Makefile.am +++ /dev/null @@ -1,167 +0,0 @@ -noinst_SCRIPTS = filter_cpuid filter_none_discards filter_stderr filter_int gen_insn_test.pl - -CLEANFILES = $(addsuffix .c,$(INSN_TESTS)) -INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2 - -EXTRA_DIST = $(noinst_SCRIPTS) \ - args.stderr.exp args.stdout.exp args.vgtest \ - badseg.stderr.exp badseg.stdout.exp badseg.vgtest \ - bitfield1.stderr.exp bitfield1.vgtest \ - bt_everything.stderr.exp \ - bt_everything.stdout.exp bt_everything.vgtest \ - bt_literal.stderr.exp bt_literal.stdout.exp \ - bt_literal.vgtest \ - closeall.stderr.exp closeall.vgtest \ - cmdline1.stderr.exp cmdline1.stdout.exp cmdline1.vgtest \ - cmdline2.stderr.exp cmdline2.stdout.exp cmdline2.vgtest \ - cmdline3.stderr.exp cmdline3.vgtest \ - cmdline4.stderr.exp cmdline4.vgtest \ - cmdline5.stderr.exp cmdline5.vgtest \ - cmdline6.stderr.exp cmdline6.vgtest \ - coolo_sigaction.stderr.exp \ - coolo_sigaction.stdout.exp coolo_sigaction.vgtest \ - coolo_strlen.stderr.exp coolo_strlen.vgtest \ - cpuid.stderr.exp cpuid.stdout.exp cpuid.vgtest \ - dastest.stderr.exp dastest.stdout.exp \ - dastest.vgtest \ - discard.stderr.exp discard.stdout.exp \ - discard.vgtest \ - exec-sigmask.vgtest exec-sigmask.stdout.exp exec-sigmask.stderr.exp \ - execve.vgtest execve.stdout.exp execve.stderr.exp \ - fcntl_setown.vgtest fcntl_setown.stdout.exp fcntl_setown.stderr.exp \ - floored.stderr.exp floored.stdout.exp \ - floored.vgtest \ - fork.stderr.exp fork.stdout.exp fork.vgtest \ - fpu_lazy_eflags.stderr.exp fpu_lazy_eflags.stdout.exp \ - fpu_lazy_eflags.vgtest \ - fucomip.stderr.exp fucomip.vgtest \ - gxx304.stderr.exp gxx304.vgtest \ - $(addsuffix .stderr.exp,$(INSN_TESTS)) \ - $(addsuffix .stdout.exp,$(INSN_TESTS)) \ - $(addsuffix .vgtest,$(INSN_TESTS)) \ - int.stderr.exp int.stdout.exp int.vgtest \ - map_unmap.stderr.exp map_unmap.stdout.exp map_unmap.vgtest \ - mq.stderr.exp mq.vgtest \ - mremap.stderr.exp mremap.stdout.exp mremap.vgtest \ - munmap_exe.stderr.exp munmap_exe.vgtest \ - pth_blockedsig.stderr.exp \ - pth_blockedsig.stdout.exp pth_blockedsig.vgtest \ - pushpopseg.stderr.exp pushpopseg.stdout.exp pushpopseg.vgtest \ - rcl_assert.stderr.exp rcl_assert.vgtest \ - rcrl.stderr.exp rcrl.stdout.exp rcrl.vgtest \ - readline1.stderr.exp readline1.stdout.exp \ - readline1.vgtest \ - resolv.stderr.exp resolv.stdout.exp resolv.vgtest \ - rlimit_nofile.stderr.exp rlimit_nofile.stdout.exp rlimit_nofile.vgtest \ - seg_override.stderr.exp \ - seg_override.stdout.exp seg_override.vgtest \ - sem.stderr.exp sem.stdout.exp sem.vgtest \ - semlimit.stderr.exp semlimit.stdout.exp semlimit.vgtest \ - susphello.stdout.exp susphello.stderr.exp susphello.vgtest \ - sha1_test.stderr.exp sha1_test.vgtest \ - shortpush.stderr.exp shortpush.vgtest \ - shorts.stderr.exp shorts.vgtest \ - tls.stderr.exp tls.stdout.exp \ - smc1.stderr.exp smc1.stdout.exp smc1.vgtest \ - syscall-restart1.vgtest syscall-restart1.stdout.exp syscall-restart1.stderr.exp \ - syscall-restart2.vgtest syscall-restart2.stdout.exp syscall-restart2.stderr.exp \ - system.stderr.exp system.vgtest \ - yield.stderr.exp yield.stdout.exp yield.vgtest - -check_PROGRAMS = \ - args badseg bitfield1 bt_everything bt_literal closeall coolo_strlen \ - cpuid dastest discard exec-sigmask execve fcntl_setown floored fork \ - fpu_lazy_eflags fucomip $(INSN_TESTS) \ - int munmap_exe map_unmap mq mremap rcl_assert rcrl readline1 \ - resolv rlimit_nofile seg_override sem semlimit sha1_test \ - shortpush shorts smc1 susphello pth_blockedsig pushpopseg \ - syscall-restart1 syscall-restart2 system \ - coolo_sigaction gxx304 yield - -AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -I$(top_srcdir)/include -AM_CXXFLAGS = $(AM_CFLAGS) - -# generic C ones -args_SOURCES = args.c -badseg_SOURCES = badseg.c -bitfield1_SOURCES = bitfield1.c -bt_everything_SOURCES = bt_everything.c -bt_literal_SOURCES = bt_literal.c -closeall_SOURCES = closeall.c -cpuid_SOURCES = cpuid_c.c cpuid_s.s -coolo_strlen_SOURCES = coolo_strlen.c -dastest_SOURCES = dastest_c.c dastest_s.s -discard_SOURCES = discard.c -exec_sigmask_SOURCES = exec-sigmask.c -execve_SOURCES = execve.c -fcntl_setown_SOURCES = fcntl_setown.c -fork_SOURCES = fork.c -floored_SOURCES = floored.c -floored_LDADD = -lm -fpu_lazy_eflags_SOURCES = fpu_lazy_eflags.c -fucomip_SOURCES = fucomip.c -insn_basic_SOURCES = insn_basic.def -insn_basic_LDADD = -lm -insn_fpu_SOURCES = insn_fpu.def -insn_fpu_LDADD = -lm -insn_cmov_SOURCES = insn_cmov.def -insn_cmov_LDADD = -lm -insn_mmx_SOURCES = insn_mmx.def -insn_mmx_LDADD = -lm -insn_mmxext_SOURCES = insn_mmxext.def -insn_mmxext_LDADD = -lm -insn_sse_SOURCES = insn_sse.def -insn_sse_LDADD = -lm -insn_sse2_SOURCES = insn_sse2.def -insn_sse2_LDADD = -lm -int_SOURCES = int.c -map_unmap_SOURCES = map_unmap.c -mq_SOURCES = mq.c -mq_LDADD = -lrt -mremap_SOURCES = mremap.c -munmap_exe_SOURCES = munmap_exe.c -pushpopseg_SOURCES = pushpopseg.c -rcl_assert_SOURCES = rcl_assert.S -rcrl_SOURCES = rcrl.c -readline1_SOURCES = readline1.c -resolv_SOURCES = resolv.c -rlimit_nofile_SOURCES = rlimit_nofile.c -seg_override_SOURCES = seg_override.c -sem_SOURCES = sem.c -semlimit_SOURCES = semlimit.c -semlimit_LDADD = -lpthread -smc1_SOURCES = smc1.c -sha1_test_SOURCES = sha1_test.c -shortpush_SOURCES = shortpush.c -shorts_SOURCES = shorts.c -susphello_SOURCES = susphello.c -susphello_LDADD = -lpthread -syscall_restart1_SOURCES = syscall-restart1.c -syscall_restart2_SOURCES = syscall-restart2.c -system_SOURCES = system.c -#tls_SOURCES = tls.c tls2.c -#tls_DEPENDENCIES = tls.so -#tls_LDFLAGS = -Wl,-rpath,$(srcdir) -#tls_LDADD = tls.so -lpthread -#tls_so_SOURCES = tls_so.c -#tls_so_LDADD = tls2.so -#tls_so_DEPENDENCIES = tls2.so -#tls_so_LDFLAGS = -Wl,-rpath,$(srcdir) -shared -#tls2_so_SOURCES = tls2_so.c -#tls2_so_LDFLAGS = -shared -yield_SOURCES = yield.c -yield_LDADD = -lpthread - -# pthread C ones -pth_blockedsig_SOURCES = pth_blockedsig.c -pth_blockedsig_LDADD = -lpthread - -# generic C++ ones -coolo_sigaction_SOURCES = coolo_sigaction.cpp -gxx304_SOURCES = gxx304.cpp - -# must be built with these flags -- bug only occurred with them -fpu_lazy_eflags.o: CFLAGS += -O2 -mcpu=pentiumpro -march=pentiumpro - -.def.c: $(srcdir)/gen_insn_test.pl - $(PERL) $(srcdir)/gen_insn_test.pl < $< > $@ diff --git a/VEX/head20041019/none/tests/args.c b/VEX/head20041019/none/tests/args.c deleted file mode 100644 index e7307a09d..000000000 --- a/VEX/head20041019/none/tests/args.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -int main(int argc, char* argv[]) -{ - int i; - - for (i = 0; i < argc; i++) { - printf("arg %d: `%s'\n", i, argv[i]); - } - return 0; -} diff --git a/VEX/head20041019/none/tests/args.stderr.exp b/VEX/head20041019/none/tests/args.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/args.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/args.stdout.exp b/VEX/head20041019/none/tests/args.stdout.exp deleted file mode 100644 index 0d9db35c0..000000000 --- a/VEX/head20041019/none/tests/args.stdout.exp +++ /dev/null @@ -1,4 +0,0 @@ -arg 0: `./args' -arg 1: `a' -arg 2: `b' -arg 3: `1 2 3' diff --git a/VEX/head20041019/none/tests/args.vgtest b/VEX/head20041019/none/tests/args.vgtest deleted file mode 100644 index 4b3529d67..000000000 --- a/VEX/head20041019/none/tests/args.vgtest +++ /dev/null @@ -1,2 +0,0 @@ -prog: args -args: a b "1 2 3" diff --git a/VEX/head20041019/none/tests/badseg.c b/VEX/head20041019/none/tests/badseg.c deleted file mode 100644 index 0c27d4fd5..000000000 --- a/VEX/head20041019/none/tests/badseg.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -static void handler(int sig, siginfo_t *info, void *v) -{ - printf("info: sig=%d code=%d addr=%p\n", - info->si_signo, info->si_code, info->si_addr); - exit(0); -} - -int main() -{ - struct sigaction sa; - int val; - - sa.sa_sigaction = handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - - sigaction(SIGSEGV, &sa, NULL); - - asm volatile("mov %1, %%fs; mov %%fs:0, %0" : "=r" (val) : "r"(4)); - - printf("val=%d\n", val); - - return 0; -} diff --git a/VEX/head20041019/none/tests/badseg.stderr.exp b/VEX/head20041019/none/tests/badseg.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/badseg.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/badseg.stdout.exp b/VEX/head20041019/none/tests/badseg.stdout.exp deleted file mode 100644 index 40a293750..000000000 --- a/VEX/head20041019/none/tests/badseg.stdout.exp +++ /dev/null @@ -1 +0,0 @@ -info: sig=11 code=128 addr=(nil) diff --git a/VEX/head20041019/none/tests/badseg.vgtest b/VEX/head20041019/none/tests/badseg.vgtest deleted file mode 100644 index e5622a3a6..000000000 --- a/VEX/head20041019/none/tests/badseg.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: badseg diff --git a/VEX/head20041019/none/tests/bitfield1.c b/VEX/head20041019/none/tests/bitfield1.c deleted file mode 100644 index 1dcf4c949..000000000 --- a/VEX/head20041019/none/tests/bitfield1.c +++ /dev/null @@ -1,19 +0,0 @@ - -#include - -typedef - struct { - int x; - unsigned int y:1; - int z; - } - Fooble; - -int main ( void ) -{ - Fooble* f = malloc(sizeof(Fooble)); - f->x = 1; - f->z = 1; - f->y = (f == (Fooble*)17 ? 1 : 0); - return 0; -} diff --git a/VEX/head20041019/none/tests/bitfield1.stderr.exp b/VEX/head20041019/none/tests/bitfield1.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/bitfield1.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/bitfield1.vgtest b/VEX/head20041019/none/tests/bitfield1.vgtest deleted file mode 100644 index 88260d87f..000000000 --- a/VEX/head20041019/none/tests/bitfield1.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: bitfield1 diff --git a/VEX/head20041019/none/tests/bt_everything.c b/VEX/head20041019/none/tests/bt_everything.c deleted file mode 100644 index 123d417a6..000000000 --- a/VEX/head20041019/none/tests/bt_everything.c +++ /dev/null @@ -1,217 +0,0 @@ - -#include -#include -#include - - -unsigned int btsl_mem ( char* base, int bitno ) -{ - unsigned char res; - __asm__ - __volatile__("btsl\t%2, %0\n\t" - "setc\t%1" - : "=m" (*base), "=q" (res) - : "r" (bitno)); - /* Pretty meaningless to dereference base here, but that's what you - have to do to get a btsl insn which refers to memory starting at - base. */ - return res; -} - -unsigned int btrl_mem ( char* base, int bitno ) -{ - unsigned char res; - __asm__ - __volatile__("btrl\t%2, %0\n\t" - "setc\t%1" - : "=m" (*base), "=q" (res) - : "r" (bitno)); - return res; -} - -unsigned int btcl_mem ( char* base, int bitno ) -{ - unsigned char res; - __asm__ - __volatile__("btcl\t%2, %0\n\t" - "setc\t%1" - : "=m" (*base), "=q" (res) - : "r" (bitno)); - return res; -} - -unsigned int btl_mem ( char* base, int bitno ) -{ - unsigned char res; - __asm__ - __volatile__("btl\t%2, %0\n\t" - "setc\t%1" - : "=m" (*base), "=q" (res) - : "r" (bitno) - : "cc", "memory"); - return res; -} - - - - -unsigned int btsl_reg ( unsigned int reg_in, int bitno, - unsigned int* reg_out_p ) -{ - unsigned char res; - unsigned int reg_out; - __asm__ - __volatile__("movl\t%3, %%eax\n\t" - "btsl\t%2, %%eax\n\t" - "movl\t%%eax, %1\n\t" - "setc\t%0" - : "=q" (res), "=r" (reg_out) - : "r" (bitno), "r" (reg_in) - : "cc", "eax"); - *reg_out_p = reg_out; - return res; -} - - -unsigned int btrl_reg ( unsigned int reg_in, int bitno, - unsigned int* reg_out_p ) -{ - unsigned char res; - unsigned int reg_out; - __asm__ - __volatile__("movl\t%3, %%eax\n\t" - "btrl\t%2, %%eax\n\t" - "movl\t%%eax, %1\n\t" - "setc\t%0" - : "=q" (res), "=r" (reg_out) - : "r" (bitno), "r" (reg_in) - : "cc", "eax"); - *reg_out_p = reg_out; - return res; -} - - -unsigned int btcl_reg ( unsigned int reg_in, int bitno, - unsigned int* reg_out_p ) -{ - unsigned char res; - unsigned int reg_out; - __asm__ - __volatile__("movl\t%3, %%eax\n\t" - "btcl\t%2, %%eax\n\t" - "movl\t%%eax, %1\n\t" - "setc\t%0" - : "=q" (res), "=r" (reg_out) - : "r" (bitno), "r" (reg_in) - : "cc", "eax"); - *reg_out_p = reg_out; - return res; -} - - -unsigned int btl_reg ( unsigned int reg_in, int bitno, - unsigned int* reg_out_p ) -{ - unsigned char res; - unsigned int reg_out; - __asm__ - __volatile__("movl\t%3, %%eax\n\t" - "btl\t%2, %%eax\n\t" - "movl\t%%eax, %1\n\t" - "setc\t%0" - : "=q" (res), "=r" (reg_out) - : "r" (bitno), "r" (reg_in) - : "cc", "eax"); - *reg_out_p = reg_out; - return res; -} - - - - - - - -typedef unsigned int UInt; -typedef unsigned char UChar; - -UInt rol1 ( UInt x ) -{ - return (x << 1) | (x >> 31); -} - -int main ( void ) -{ - UInt n, bitoff, op; - UInt carrydep, c, res; - UChar* block; - UInt reg; - - /*------------------------ MEM-L -----------------------*/ - - carrydep = 0; - block = calloc(200,1); - block += 100; - /* Valid bit offsets are -800 .. 799 inclusive. */ - - for (n = 0; n < 10000; n++) { - bitoff = (random() % 1600) - 800; - op = random() % 4; - c = 2; - switch (op) { - case 0: c = btsl_mem(block, bitoff); break; - case 1: c = btrl_mem(block, bitoff); break; - case 2: c = btcl_mem(block, bitoff); break; - case 3: c = btl_mem(block, bitoff); break; - } - assert(c == 0 || c == 1); - carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep; - } - - /* Compute final result */ - block -= 100; - res = 0; - for (n = 0; n < 200; n++) { - UChar ch = block[n]; - /* printf("%d ", (int)block[n]); */ - res = rol1(res) ^ (UInt)ch; - } - - printf("MEM-L: final res 0x%x, carrydep 0x%x\n", res, carrydep); - - /*------------------------ REG-L -----------------------*/ - - carrydep = 0; - reg = 0; - - for (n = 0; n < 1000; n++) { - bitoff = (random() % 100) - 50; - op = random() % 4; - c = 2; - switch (op) { - case 0: c = btsl_reg(reg, bitoff, ®); break; - case 1: c = btrl_reg(reg, bitoff, ®); break; - case 2: c = btcl_reg(reg, bitoff, ®); break; - case 3: c = btl_reg(reg, bitoff, ®); break; - } - assert(c == 0 || c == 1); - carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep; - } - - printf("REG-L: final res 0x%x, carrydep 0x%x\n", reg, carrydep); - - block += 100; - - /* Just try one of these at once; more than one can cause a - confusing merging of error messages. */ - //btsl_mem(block, -800); /* should not complain */ - //btsl_mem(block, -801); /* should complain */ - //btsl_mem(block, 799); /* should not complain */ - //btsl_mem(block, 800); /* should complain */ - - block -= 100; - free(block); - - return 0; -} - diff --git a/VEX/head20041019/none/tests/bt_everything.stderr.exp b/VEX/head20041019/none/tests/bt_everything.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/bt_everything.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/bt_everything.stdout.exp b/VEX/head20041019/none/tests/bt_everything.stdout.exp deleted file mode 100644 index fd6722196..000000000 --- a/VEX/head20041019/none/tests/bt_everything.stdout.exp +++ /dev/null @@ -1,2 +0,0 @@ -MEM-L: final res 0xd2bfea53, carrydep 0x5b80deee -REG-L: final res 0x605d78ff, carrydep 0x7c0dc86a diff --git a/VEX/head20041019/none/tests/bt_everything.vgtest b/VEX/head20041019/none/tests/bt_everything.vgtest deleted file mode 100644 index 711210d7e..000000000 --- a/VEX/head20041019/none/tests/bt_everything.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: bt_everything diff --git a/VEX/head20041019/none/tests/bt_literal.c b/VEX/head20041019/none/tests/bt_literal.c deleted file mode 100644 index 3f7e764f1..000000000 --- a/VEX/head20041019/none/tests/bt_literal.c +++ /dev/null @@ -1,150 +0,0 @@ - -#include -#include -#include - -typedef unsigned int UInt; - -/* Given a word, do bt/bts/btr/btc on bits 0, 1, 2 and 3 of it, and - also reconstruct the original bits 0, 1, 2, 3 by looking at the - carry flag. Returned result has mashed bits 0-3 at the bottom and - the reconstructed original bits 0-3 as 4-7. */ -UInt mash_reg_L ( UInt orig ) -{ - UInt reconstructed, mashed; - __asm__ __volatile__ ( - "movl %2, %%edx\n\t" - "" - "movl $0, %%eax\n\t" - "\n\t" - "btl $0, %%edx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btsl $1, %%edx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $1, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btrl $2, %%edx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $2, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btcl $3, %%edx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $3, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "movl %%eax, %0\n\t" - "movl %%edx, %1" - - : "=r" (reconstructed), "=r" (mashed) - : "r" (orig) - : "eax", "ecx", "edx", "cc"); - return (mashed & 0xF) | ((reconstructed & 0xF) << 4); -} - - - - -UInt mash_mem_L ( UInt* origp ) -{ - UInt reconstructed, mashed; - __asm__ __volatile__ ( - "movl %2, %%edx\n\t" - "" - "movl $0, %%eax\n\t" - "\n\t" - "btl $0, (%%edx)\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btsl $1, (%%edx)\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $1, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btrl $2, (%%edx)\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $2, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btcl $3, (%%edx)\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $3, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "movl %%eax, %0\n\t" - "movl (%%edx), %1" - - : "=r" (reconstructed), "=r" (mashed) - : "r" (origp) - : "eax", "ecx", "edx", "cc"); - return (mashed & 0xF) | ((reconstructed & 0xF) << 4); -} - - - -UInt mash_reg_W ( UInt orig ) -{ - UInt reconstructed, mashed; - __asm__ __volatile__ ( - "movl %2, %%edx\n\t" - "" - "movl $0, %%eax\n\t" - "\n\t" - "btw $0, %%dx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btsw $1, %%dx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $1, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btrw $2, %%dx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $2, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "btcw $3, %%dx\n\t" - "setb %%cl\n\t" - "movzbl %%cl, %%ecx\n\t" - "shll $3, %%ecx\n\t" - "orl %%ecx, %%eax\n\t" - "\n\t" - "movl %%eax, %0\n\t" - "movl %%edx, %1" - - : "=r" (reconstructed), "=r" (mashed) - : "r" (orig) - : "eax", "ecx", "edx", "cc"); - return (mashed & 0xF) | ((reconstructed & 0xF) << 4); -} - - - - -int main ( void ) -{ - int i, ii; - for (i = 0; i < 0x10; i++) { - ii = i; - printf("0x%x -> 0x%2x 0x%2x 0x%2x\n", i, - mash_reg_L(i), mash_mem_L(&ii), mash_reg_W(i)); - } - return 1; -} - diff --git a/VEX/head20041019/none/tests/bt_literal.stderr.exp b/VEX/head20041019/none/tests/bt_literal.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/bt_literal.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/bt_literal.stdout.exp b/VEX/head20041019/none/tests/bt_literal.stdout.exp deleted file mode 100644 index c9bb28d52..000000000 --- a/VEX/head20041019/none/tests/bt_literal.stdout.exp +++ /dev/null @@ -1,16 +0,0 @@ -0x0 -> 0x a 0x a 0x a -0x1 -> 0x1b 0x1b 0x1b -0x2 -> 0x2a 0x2a 0x2a -0x3 -> 0x3b 0x3b 0x3b -0x4 -> 0x4a 0x4a 0x4a -0x5 -> 0x5b 0x5b 0x5b -0x6 -> 0x6a 0x6a 0x6a -0x7 -> 0x7b 0x7b 0x7b -0x8 -> 0x82 0x82 0x82 -0x9 -> 0x93 0x93 0x93 -0xa -> 0xa2 0xa2 0xa2 -0xb -> 0xb3 0xb3 0xb3 -0xc -> 0xc2 0xc2 0xc2 -0xd -> 0xd3 0xd3 0xd3 -0xe -> 0xe2 0xe2 0xe2 -0xf -> 0xf3 0xf3 0xf3 diff --git a/VEX/head20041019/none/tests/bt_literal.vgtest b/VEX/head20041019/none/tests/bt_literal.vgtest deleted file mode 100644 index 9c06c648e..000000000 --- a/VEX/head20041019/none/tests/bt_literal.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: bt_literal diff --git a/VEX/head20041019/none/tests/closeall.c b/VEX/head20041019/none/tests/closeall.c deleted file mode 100644 index facf6a580..000000000 --- a/VEX/head20041019/none/tests/closeall.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - struct rlimit lim; - int fd; - - getrlimit(RLIMIT_NOFILE, &lim); - - for ( fd = 3; fd < lim.rlim_cur; fd++ ) - close( fd ); - - exit( 0 ); -} diff --git a/VEX/head20041019/none/tests/closeall.stderr.exp b/VEX/head20041019/none/tests/closeall.stderr.exp deleted file mode 100644 index 139597f9c..000000000 --- a/VEX/head20041019/none/tests/closeall.stderr.exp +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/VEX/head20041019/none/tests/closeall.vgtest b/VEX/head20041019/none/tests/closeall.vgtest deleted file mode 100644 index 23738b157..000000000 --- a/VEX/head20041019/none/tests/closeall.vgtest +++ /dev/null @@ -1 +0,0 @@ -prog: closeall diff --git a/VEX/head20041019/none/tests/cmdline1.stderr.exp b/VEX/head20041019/none/tests/cmdline1.stderr.exp deleted file mode 100644 index e69de29bb..000000000 diff --git a/VEX/head20041019/none/tests/cmdline1.stdout.exp b/VEX/head20041019/none/tests/cmdline1.stdout.exp deleted file mode 100644 index ac28bbb02..000000000 --- a/VEX/head20041019/none/tests/cmdline1.stdout.exp +++ /dev/null @@ -1,47 +0,0 @@ -usage: valgrind --tool= [options] prog-and-args - - common user options for all Valgrind tools, with defaults in [ ]: - --tool= use the Valgrind tool named - -h --help show this message - --help-debug show this message, plus debugging options - --version show version - -q --quiet run silently; only print error msgs - -v --verbose be more verbose, incl counts of errors - --trace-children=no|yes Valgrind-ise child processes? [no] - --track-fds=no|yes track open file descriptors? [no] - --time-stamp=no|yes add timestamps to log messages? [no] - - uncommon user options for all Valgrind tools: - --run-libc-freeres=no|yes free up glibc memory at exit? [yes] - --weird-hacks=hack1,hack2,... recognised hacks: lax-ioctls [none] - --signal-polltime=