--- /dev/null
+Anders Norlander <anorland@hem2.passagen.se>
+Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
--- /dev/null
+ 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.
+\f
+ 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.)
+\f
+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.
+\f
+ 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.
+\f
+ 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
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+2002-11-08 Luke Dunstan <infidel@users.sourceforge.net>
+
+ * pexports.c (dump_exports): fix exports incorrectly
+ determined to be forwarders.
+
+1999-04-02 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
+
+ * pexports.c: now distinguishes data/non-data symbols,
+ depending on type of section symbol in
+ * pexports.c: in verbose mode prints section name for symbol
+ * pexports.c: file offsets are now in hex
+
+1998-11-07 Anders Norlander <kv98anr@cs.umu.se>
+
+ * hparse.y: types and parameters are now recognized as
+ a series of tokens, which means that keywords like const
+ struct and so on are not recognized as such, allowing any
+ kind of parameter, including function pointers.
+
+1998-11-05 Anders Norlander <kv98anr@cs.umu.se>
+
+ * hlex.l: removed all tokens except ID, CONST and VOLATILE
+ * hparse.y: Added INC_ARGS macro to increment arg_size only if
+ new flag inc_flag is set
+ * hparse.y: Added function_pointer and function_pointer_name rules
+ * hparse.y: Function attributes are now handled as list of ID's
+ * pexports.h: Incremented VER_MINOR
+ * pexports.c: Print name of file if a header is not found
+ * pexports.c: Separated printing to function dump_symbol
+ * pexports.c: Fixed handling of forwarded exports
+
+1998-10-26 Anders Norlander <anorland@hem2.passagen.se>
+
+ * New files: str_tree.c str_tree.h: implements
+ a symbol tree.
+ * pexports.c: changed symbol handling to use str_tree,
+ add_function_prot removed.
+ * pexports.h: removed add_function_prot prototype
+ * hlex.l: removed unnecessary code (count, CONSTANT, STRING)
+ * hlex.l: added ATTRIBUTE token.
+ * hparse.y: completely rewritten. *Much* improved parser.
+ * pexports.h: changed VER_MINOR to 3
+
+1998-10-21 Anders Norlander <anorland@hem2.passagen.se>
+
+ * pexports.c: removed include_path structure and replaced
+ it with a generic string list str_list.
+ * pexports.c: preprocessor now defaults to "gcc -E -xc-header"
+ instead of "cpp".
+ * pexports.h: incremented minor version VER_MINOR to 2
+ * pexports.c: headers are now parsed after all paramaters
+ command line options have been parsed.
+ * hparse.y: fixed problem with unnamed parameters that
+ are pointers.
+ * pexports.c: in dump_exports: don't print extra white
+ space if ordinals are not supposed to be printed.
--- /dev/null
+bin_PROGRAMS = pexports
+
+pexports_SOURCES = hlex.l hparse.h hparse.y pe.h pexports.c pexports.h str_tree.c str_tree.h
+
+docdir = $(prefix)/doc/pexports
+
+doc_DATA = AUTHORS COPYING README
--- /dev/null
+PEXPORTS 0.43 README
+============================================
+
+PEXPORTS is a program to extract exported symbols from a PE image
+(executable). It can perform a simple check on the size of the
+arguments of the exported functions, provided there is a header with
+prototypes for the functions. This is useful when you want the
+decorated function names for functions using the stdcall calling
+convention. GCC is used to do the preprocessing so it must be in your
+path.
+
+Note that the mingw32 version uses ';' as path separator,
+while the cygwin version uses ':'.
+
+Command line options:
+=====================
+ -h <header> parse header
+ -o print function ordinals
+ -p <preprocessor> set preprocessor
+ -v verbose mode
+
+Header files are searched for in the following directories:
+1. Current directory
+2. Directories in C_INCLUDE_PATH
+3. Directories in CPLUS_INCLUDE_PATH
+4. Directories in PATH
+
+NOTE: The header parser is *very* primitive, it only tries to find
+function prototypes and check the number of arguments a function
+expects. It is NOT a complete C parser, there are probably many
+conditions when it will fail (especially complex parameter types),
+although I it works fine for me. Please report bugs or send me a
+patch.
+
+Pexports, Copyright (C) 1998 Anders Norlander
+This program has ABSOLUTELY NO WARRANTY; This is free software, and you are
+welcome to redistribute it under certain conditions; see COPYING
+for details.
--- /dev/null
+D [0-9]
+L [a-zA-Z_]
+OS [ ]*
+
+%{
+#include <stdio.h>
+#include <string.h>
+#include "hparse.h"
+
+
+%}
+
+%%
+"#".* { }
+"//".* { }
+"/*" {
+ char c, c1;
+
+loop:
+ while ((c = input()) != '*' && c != 0)
+ putchar(c);
+
+ if ((c1 = input()) != '/' && c != 0)
+ {
+ unput(c1);
+ goto loop;
+ }
+
+ if (c != 0)
+ putchar(c1);
+}
+
+"__"{L}+ { return(ID); }
+"__"{L}+{OS}*"("+{L}({L}|{D})*")"+ { return(ID); }
+{L}({L}|{D})* {
+ yylval.s = strdup(yytext);
+ return ID;
+ }
+
+"," { return(','); }
+"*" { return('*'); }
+"(" { return('('); }
+")" { return(')'); }
+";" { return(';'); }
+
+[ \t\v\n\f] { }
+. { }
+
+%%
+
+yywrap()
+{
+ return(1);
+}
--- /dev/null
+typedef union {
+ char *s;
+} YYSTYPE;
+#define ID 258
+
+
+extern YYSTYPE yylval;
--- /dev/null
+%{
+
+#include "pexports.h"
+
+
+static int inc_flag = 1;
+static int arg_size = 0;
+
+#define INC_ARGS(n) arg_size += (inc_flag ? n : 0)
+%}
+
+%union {
+ char *s;
+};
+
+%token <s> ID
+
+%type <s> type_name
+%%
+
+start
+ : function_declaration
+ | start function_declaration
+ ;
+
+function_declaration
+ : type_name '(' parameter_list ')' ';'
+ {
+ ADD_FUNCTION($1, arg_size);
+ arg_size = 0;
+ }
+ | type_name '(' ')' ';'
+ {
+ ADD_FUNCTION($1, 0);
+ arg_size = 0;
+ }
+ | error { arg_size = 0; yyclearin; }
+ ;
+
+type_name
+ : ID
+ | ID pointer
+ { $$ = ""; }
+ | type_name ID
+ { $$ = $2; }
+ | type_name ID pointer
+ { $$ = ""; }
+ | type_name function_pointer
+ { $$ = ""; }
+ ;
+
+function_pointer
+ : '(' function_pointer_name ')' '(' ')'
+ {}
+ | '(' function_pointer_name ')' '('
+ { inc_flag = 0; }
+ parameter_list ')'
+ { inc_flag = 1; }
+ ;
+
+function_pointer_name
+ : pointer
+ | pointer ID
+ ;
+
+pointer
+ : '*'
+ | '*' pointer
+ ;
+
+parameter_declaration
+ : type_name
+ {
+ if (strcmp($1, "POINT") == 0)
+ INC_ARGS(8);
+ else if (strcmp($1, "RECT") == 0)
+ INC_ARGS(16);
+ else if (strcasecmp($1, "float") == 0)
+ INC_ARGS(sizeof(float));
+ else if (strcmp($1, "double") == 0)
+ INC_ARGS(sizeof(double));
+ else if (strcasecmp($1, "void") != 0)
+ INC_ARGS(4);
+ }
+ ;
+
+parameter_list
+ : parameter_declaration
+ | parameter_list ',' parameter_declaration
+ ;
+
+%%
+#include <stdio.h>
+
+yyerror(s)
+char *s;
+{
+ /* ignore error */
+ arg_size = 0;
+}
--- /dev/null
+/* PE COFF header information */
+
+#ifndef _PE_H
+#define _PE_H
+
+/* NT specific file attributes */
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/* additional flags to be set for section headers to allow the NT loader to
+ read and write to the section data (to replace the addresses of data in
+ dlls for one thing); also to execute the section in .text's case */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+/*
+ * Section characteristics added for ppc-nt
+ */
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
+
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
+
+/* COMDAT selection codes. */
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
+#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
+#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
+
+/* Magic values that are true for all dos/nt implementations */
+#define DOSMAGIC 0x5a4d
+#define NT_SIGNATURE 0x00004550
+
+ /* NT allows long filenames, we want to accommodate this. This may break
+ some of the bfd functions */
+#undef FILNMLEN
+#define FILNMLEN 18 /* # characters in a file name */
+
+
+#ifdef COFF_IMAGE_WITH_PE
+/* The filehdr is only weired in images */
+
+#undef FILHDR
+struct external_PE_filehdr
+{
+ /* DOS header fields */
+ char e_magic[2]; /* Magic number, 0x5a4d */
+ char e_cblp[2]; /* Bytes on last page of file, 0x90 */
+ char e_cp[2]; /* Pages in file, 0x3 */
+ char e_crlc[2]; /* Relocations, 0x0 */
+ char e_cparhdr[2]; /* Size of header in paragraphs, 0x4 */
+ char e_minalloc[2]; /* Minimum extra paragraphs needed, 0x0 */
+ char e_maxalloc[2]; /* Maximum extra paragraphs needed, 0xFFFF */
+ char e_ss[2]; /* Initial (relative) SS value, 0x0 */
+ char e_sp[2]; /* Initial SP value, 0xb8 */
+ char e_csum[2]; /* Checksum, 0x0 */
+ char e_ip[2]; /* Initial IP value, 0x0 */
+ char e_cs[2]; /* Initial (relative) CS value, 0x0 */
+ char e_lfarlc[2]; /* File address of relocation table, 0x40 */
+ char e_ovno[2]; /* Overlay number, 0x0 */
+ char e_res[4][2]; /* Reserved words, all 0x0 */
+ char e_oemid[2]; /* OEM identifier (for e_oeminfo), 0x0 */
+ char e_oeminfo[2]; /* OEM information; e_oemid specific, 0x0 */
+ char e_res2[10][2]; /* Reserved words, all 0x0 */
+ char e_lfanew[4]; /* File address of new exe header, 0x80 */
+ char dos_message[16][4]; /* other stuff, always follow DOS header */
+ char nt_signature[4]; /* required NT signature, 0x4550 */
+
+ /* From standard header */
+
+
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+
+};
+
+
+#define FILHDR struct external_PE_filehdr
+#undef FILHSZ
+#define FILHSZ 152
+
+#endif
+
+typedef struct
+{
+ AOUTHDR standard;
+
+ /* NT extra fields; see internal.h for descriptions */
+ char ImageBase[4];
+ char SectionAlignment[4];
+ char FileAlignment[4];
+ char MajorOperatingSystemVersion[2];
+ char MinorOperatingSystemVersion[2];
+ char MajorImageVersion[2];
+ char MinorImageVersion[2];
+ char MajorSubsystemVersion[2];
+ char MinorSubsystemVersion[2];
+ char Reserved1[4];
+ char SizeOfImage[4];
+ char SizeOfHeaders[4];
+ char CheckSum[4];
+ char Subsystem[2];
+ char DllCharacteristics[2];
+ char SizeOfStackReserve[4];
+ char SizeOfStackCommit[4];
+ char SizeOfHeapReserve[4];
+ char SizeOfHeapCommit[4];
+ char LoaderFlags[4];
+ char NumberOfRvaAndSizes[4];
+ /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
+ char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
+
+} PEAOUTHDR;
+
+
+#undef AOUTSZ
+#define AOUTSZ (AOUTHDRSZ + 196)
+
+#undef E_FILNMLEN
+#define E_FILNMLEN 18 /* # characters in a file name */
+#endif
+
+
+
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "str_tree.h"
+#include "pexports.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 260
+#endif
+
+#ifdef __MINGW32__
+/* mingw32 uses ';' instead if ':' */
+#define PATH_SEPARATOR ';'
+#else
+#define PATH_SEPARATOR ':'
+#endif
+
+/* get pointer to section header n */
+#define IMAGE_SECTION_HDR(n) ((PIMAGE_SECTION_HEADER) ((DWORD) nt_hdr + \
+ 4 + sizeof(IMAGE_FILE_HEADER) + \
+ nt_hdr->FileHeader.SizeOfOptionalHeader + \
+ n * sizeof(IMAGE_SECTION_HEADER)))
+
+/* convert relative virtual address to a useable pointer */
+#define RVA_TO_PTR(rva,type) ((type) rva_to_ptr((DWORD) rva))
+
+typedef struct str_list {
+ char *s;
+ struct str_list *next;
+} str_list;
+
+static void *xmalloc(size_t count);
+static void cleanup(void);
+static void add_path_list(char *path);
+static const char *find_file(const char *name);
+static void str_list_add(str_list **head, const char *s);
+static void str_list_free(str_list **head);
+static void parse_headers();
+static void dump_symbol(char *name, int ord, DWORD rva);
+
+const char mz_sign[2] = {'M','Z'};
+const char pe_sign[4] = {'P','E','\0','\0'};
+const char exp_sign[6] = {'.','e','d','a','t','a'};
+
+PIMAGE_DOS_HEADER dos_hdr;
+PIMAGE_NT_HEADERS nt_hdr;
+
+char *filename = NULL;
+char *program_name;
+char *cpp = "gcc -E -xc-header";
+
+str_tree *symbols = NULL;
+str_list *inc_path = NULL;
+str_list *header_files = NULL;
+
+int verbose = 0;
+int ordinal_flag = 0;
+
+extern FILE *yyin;
+
+int
+main(int argc, char *argv[])
+{
+ PIMAGE_SECTION_HEADER section;
+ DWORD exp_rva;
+ int i;
+
+ program_name = argv[0];
+
+ atexit(cleanup);
+
+ /* add standard include paths */
+ add_path_list(getenv("C_INCLUDE_PATH"));
+ add_path_list(getenv("CPLUS_INCLUDE_PATH"));
+ add_path_list(getenv("PATH"));
+
+ /* parse command line */
+ for ( i = 1; i < argc; i++ )
+ {
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'o':
+ ordinal_flag = 1;
+ break;
+ case 'h':
+ if (!argv[++i])
+ {
+ fprintf(stderr, "-h requires an argument\n");
+ return 1;
+ }
+ str_list_add(&header_files, argv[i]);
+ break;
+ case 'p':
+ if (!argv[++i])
+ {
+ fprintf(stderr, "-p requires an argument\n");
+ return 1;
+ }
+ cpp = argv[i];
+ break;
+ default:
+ fprintf(stderr, "%s: Unknown option: %s\n",
+ program_name, argv[i]);
+ return 1;
+ }
+ }
+ else
+ filename = argv[i];
+ }
+
+ if (filename == NULL)
+ {
+ printf("PExports %d.%d Copyright 1998, Anders Norlander\n"
+ "Changed 1999, Paul Sokolovsky\n"
+ "This program is free software; you may redistribute it under the terms of\n"
+ "the GNU General Public License. This program has absolutely no warranty.\n"
+
+ "\nUsage: %s [-v] [-n] [-h header] [-p preprocessor] dll\n"
+ " -h\tparse header\n"
+ " -o\tprint ordinals\n"
+ " -p\tset preprocessor program\n"
+ " -v\tverbose mode\n"
+ "\nReport bugs to anorland@hem2.passagen.se or Paul.Sokolovsky@technologist.com\n",
+ VER_MAJOR, VER_MINOR,
+ program_name);
+ return 1;
+ }
+
+ /* parse headers and build symbol tree */
+ parse_headers();
+
+ /* load file */
+ dos_hdr = load_pe_image(filename);
+ if (dos_hdr == NULL)
+ {
+ fprintf(stderr, "%s: %s: could not load PE image\n",
+ program_name, filename);
+ return 1;
+ }
+
+ nt_hdr = (PIMAGE_NT_HEADERS) ((DWORD) dos_hdr + dos_hdr->e_lfanew);
+
+ exp_rva = nt_hdr->OptionalHeader.DataDirectory[0].VirtualAddress;
+
+ section = IMAGE_SECTION_HDR(0);
+
+ /* Look for export section */
+ for (i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, section++)
+ {
+ if (verbose)
+ {
+ printf("; %8s: RVA: %08x, File offset: %08x\n",
+ section->Name,
+ section->VirtualAddress,
+ section->PointerToRawData);
+ }
+ if (memcmp(section->Name, exp_sign, sizeof(exp_sign)) == 0)
+ dump_exports(section->VirtualAddress);
+ else if ((exp_rva >= section->VirtualAddress) &&
+ (exp_rva < (section->VirtualAddress + section->SizeOfRawData)))
+ dump_exports(exp_rva);
+ }
+
+ free(dos_hdr);
+ return 0;
+}
+
+/* dump exported symbols on stdout */
+void
+dump_exports(DWORD exports_rva)
+{
+ PIMAGE_SECTION_HEADER section;
+ PIMAGE_EXPORT_DIRECTORY exports;
+ char *export_name;
+ PWORD ordinal_table;
+ char **name_table;
+ DWORD *function_table;
+ int i;
+ static int first = 1;
+ DWORD exports_end;
+
+ section = find_section(exports_rva);
+
+ if (nt_hdr->OptionalHeader.DataDirectory[0].Size == 0)
+ exports_end = section->VirtualAddress + section->SizeOfRawData;
+ else
+ exports_end = exports_rva + nt_hdr->OptionalHeader.DataDirectory[0].Size;
+
+ if (verbose)
+ printf("; Reading exports from section: %s\n",
+ section->Name);
+
+ exports = RVA_TO_PTR(exports_rva, PIMAGE_EXPORT_DIRECTORY);
+
+ /* set up various pointers */
+ export_name = RVA_TO_PTR(exports->Name,char*);
+ ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals,PWORD);
+ name_table = RVA_TO_PTR(exports->AddressOfNames,char**);
+ function_table = RVA_TO_PTR(exports->AddressOfFunctions,void*);
+
+ if (verbose)
+ {
+ printf("; Export table: %s\n", export_name);
+ printf("; Ordinal base: %d\n", exports->Base);
+ printf("; Ordinal table RVA: %08x\n",
+ exports->AddressOfNameOrdinals);
+ printf("; Name table RVA: %08x\n", exports->AddressOfNames);
+ printf("; Export address table RVA: %08x\n",
+ exports->AddressOfFunctions);
+ }
+
+ if (first)
+ {
+ printf("LIBRARY %s\n", export_name);
+ printf("EXPORTS\n");
+ first = 0;
+ }
+ else
+ printf("; LIBRARY %s\n", export_name);
+
+ for (i = 0; i < exports->NumberOfNames; i++)
+ {
+ dump_symbol(RVA_TO_PTR(name_table[i],char*),
+ ordinal_table[i] + exports->Base,
+ function_table[ordinal_table[i]]);
+ printf("\n");
+ }
+
+ for (i = 0; i < exports->NumberOfFunctions; i++)
+ {
+ if ( (function_table[i] >= exports_rva) &&
+ (function_table[i] < exports_end))
+ {
+ dump_symbol(strchr(RVA_TO_PTR(function_table[i],char*), '.')+1,
+ i + exports->Base,
+ function_table[i]);
+ if (verbose)
+ printf(" ; Forwarder\n");
+ else
+ printf("\n");
+ }
+ }
+}
+
+static void dump_symbol(char *name, int ord, DWORD rva)
+{
+ char s[256];
+ str_tree *symbol = str_tree_find(symbols, name);
+ /* if a symbol was found, emit size of stack */
+ if (symbol)
+ sprintf(s, "%s@%d", name, (int) symbol->extra);
+ else
+ sprintf(s, "%s", name);
+
+ /* output ordinal */
+ if (ordinal_flag)
+ printf("%-24s\t@%d", s, ord);
+ else
+ printf("%s", s);
+
+ {
+ PIMAGE_SECTION_HEADER s=find_section(rva);
+
+/* Stupid msvc doesn't have .bss section, it spews uninitilized data
+ to no section */
+ if (!s) { printf(" DATA"); if (verbose) printf (" ; no section"); }
+ else
+ {
+ if (!(s->Characteristics&IMAGE_SCN_CNT_CODE)) printf(" DATA");
+ if (verbose) printf (" ; %.8s",s->Name);
+ }
+ }
+
+ if (verbose)
+ printf(" ; RVA %08x", rva);
+}
+
+/* get section to which rva points */
+PIMAGE_SECTION_HEADER
+find_section(DWORD rva)
+{
+ int i;
+ PIMAGE_SECTION_HEADER section = IMAGE_SECTION_HDR(0);
+ for (i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, section++)
+ if ((rva >= section->VirtualAddress) &&
+ (rva <= (section->VirtualAddress + section->SizeOfRawData)))
+ return section;
+ return NULL;
+}
+
+/* convert rva to pointer into loaded file */
+DWORD
+rva_to_ptr(DWORD rva)
+{
+ PIMAGE_SECTION_HEADER section = find_section(rva);
+ if (section->PointerToRawData == 0)
+ return 0;
+ else
+ return ((DWORD) dos_hdr + (DWORD) rva - (section->VirtualAddress - section->PointerToRawData));
+}
+
+/* Load a portable executable into memory */
+PIMAGE_DOS_HEADER
+load_pe_image(const char *filename)
+{
+ struct stat st;
+ PIMAGE_DOS_HEADER phdr;
+ FILE *f;
+
+ if (stat(filename, &st) == -1)
+ return NULL;
+
+ phdr = (PIMAGE_DOS_HEADER) xmalloc(st.st_size);
+
+ f = fopen(filename, "rb");
+ if (f == NULL)
+ {
+ free(phdr);
+ return NULL;
+ }
+
+ if (fread(phdr, st.st_size, 1, f) != 1)
+ {
+ free(phdr);
+ phdr = NULL;
+ }
+ else if (memcmp(mz_sign, phdr, sizeof(mz_sign)) != 0)
+ {
+ free(phdr);
+ phdr = NULL;
+ }
+ else if (memcmp((char *) phdr + phdr->e_lfanew, pe_sign, sizeof(pe_sign)) != 0)
+ {
+ free(phdr);
+ phdr = NULL;
+ }
+
+ fclose(f);
+ return phdr;
+}
+
+/* parse headers to build symbol tree */
+void
+parse_headers()
+{
+ str_list *header;
+ char *cpp_cmd;
+ int len;
+ FILE *f;
+
+ header = header_files;
+ if (!header)
+ return;
+
+ /* construct command line */
+ cpp_cmd = strdup(cpp);
+ if (cpp_cmd == NULL)
+ {
+ fprintf(stderr, "%s: out of memory\n", program_name);
+ exit(1);
+ }
+ len = strlen(cpp_cmd);
+
+ while (header)
+ {
+ const char *fullname = find_file(header->s);
+ int tmp;
+ if (fullname == NULL)
+ {
+ perror(header->s);
+ exit(1);
+ }
+ tmp = strlen(fullname) + 10;
+ cpp_cmd = realloc(cpp_cmd, len + tmp);
+ if (cpp_cmd == NULL)
+ {
+ fprintf(stderr, "%s: out of memory\n", program_name);
+ exit(1);
+ }
+ if (!header->next)
+ sprintf(cpp_cmd + len, " %s", fullname);
+ else
+ sprintf(cpp_cmd + len, " -include %s", fullname);
+ len += tmp;
+ header = header->next;
+ }
+ cpp_cmd[len] = '\0';
+
+ if (verbose)
+ printf("; %s\n", cpp_cmd);
+
+ /* Run preprocessor.
+ Note: CRTDLL messes up stdout when popen is called so
+ if you try to pipe output through another program
+ with | it will hang. Redirect it to a file instead
+ and pass that file to the program (more,less or whatever).
+ This does not apply to cygwin.
+ */
+ f = popen(cpp_cmd, "r");
+ free(cpp_cmd);
+ if (f == NULL)
+ {
+ fprintf(stderr, "%s: %s: could not execute\n", program_name, cpp_cmd);
+ exit(1);
+ }
+ yyin = f;
+ yyparse();
+ pclose(f);
+}
+
+/* allocate memory; abort on failure */
+static void *xmalloc(size_t count)
+{
+ void *p = malloc(count);
+ if (p == NULL)
+ {
+ fprintf(stderr, "%s: out of memory\n", program_name);
+ exit(1);
+ }
+ return p;
+}
+
+/* clean up */
+static void cleanup(void)
+{
+ str_tree_free(&symbols);
+ str_list_free(&inc_path);
+ str_list_free(&header_files);
+}
+
+/* add string to end of list */
+static void str_list_add(str_list **head, const char *s)
+{
+ str_list *node = xmalloc(sizeof(str_list));
+ node->s = strdup(s);
+ node->next = NULL;
+ if (!*head)
+ {
+ *head = node;
+ }
+ else
+ {
+ str_list *p = *head;
+ while (p->next)
+ p = p->next;
+ p->next = node;
+ }
+}
+
+/* free memory used by string list */
+static void str_list_free(str_list **head)
+{
+ str_list *node = *head;
+ while (node)
+ {
+ str_list *tmp = node->next;
+ free(node->s);
+ free(node);
+ node = tmp;
+ }
+ *head = NULL;
+}
+
+/* find a file in include path */
+static const char *find_file(const char *name)
+{
+ static char fullname[PATH_MAX];
+ FILE *f = fopen(name, "r");
+ str_list *path = inc_path;
+ if (f != NULL)
+ {
+ fclose(f);
+ return name;
+ }
+ while (path)
+ {
+ strcpy(fullname, path->s);
+ strcat(fullname, "/");
+ strcat(fullname, name);
+ f = fopen(fullname, "r");
+ if (f != NULL)
+ {
+ fclose(f);
+ return fullname;
+ }
+ path = path->next;
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+/* add a environment-style path list to list of include paths */
+static void add_path_list(char *path)
+{
+ char *p = path;
+ if (!p)
+ return;
+ while (*p)
+ {
+ if (*p == PATH_SEPARATOR)
+ {
+ *p = '\0';
+ str_list_add(&inc_path, path);
+ path = p + 1;
+ *p = PATH_SEPARATOR;
+ }
+ p++;
+ }
+ if (p[-1] != PATH_SEPARATOR)
+ str_list_add(&inc_path, path);
+}
--- /dev/null
+/*
+ pexports - a program to extract exported symbols from a Portable
+ Executable (PE) file.
+
+ Copyright (C) 1998 Anders Norlander
+
+ pexports is distributed under the GNU General Public License and
+ has absolutely NO WARRANTY.
+
+ pexports will work only on intel machines.
+*/
+
+#ifndef _pexports_h
+#define _pexports_h
+
+#include <stdio.h>
+
+#include "str_tree.h"
+
+#define VER_MAJOR 0
+#define VER_MINOR 43
+
+/* These are needed */
+typedef unsigned short WORD;
+typedef unsigned int DWORD;
+typedef unsigned char BYTE;
+typedef long LONG;
+typedef WORD *PWORD;
+typedef DWORD *PDWORD;
+
+/* PE structures */
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Reserved1;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[16];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+
+typedef struct _IMAGE_NT_HEADERS {
+ char Signature[4];
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[8];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ PDWORD *AddressOfFunctions;
+ PDWORD *AddressOfNames;
+ PWORD *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+typedef struct _IMAGE_DOS_HEADER {
+ WORD e_magic;
+ WORD e_cblp;
+ WORD e_cp;
+ WORD e_crlc;
+ WORD e_cparhdr;
+ WORD e_minalloc;
+ WORD e_maxalloc;
+ WORD e_ss;
+ WORD e_sp;
+ WORD e_csum;
+ WORD e_ip;
+ WORD e_cs;
+ WORD e_lfarlc;
+ WORD e_ovno;
+ WORD e_res[4];
+ WORD e_oemid;
+ WORD e_oeminfo;
+ WORD e_res2[10];
+ LONG e_lfanew;
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+PIMAGE_SECTION_HEADER
+find_section(DWORD rva);
+
+PIMAGE_DOS_HEADER
+load_pe_image(const char *filename);
+
+DWORD
+rva_to_ptr(DWORD rva);
+
+void
+dump_exports(DWORD exports_rva);
+
+#define ADD_FUNCTION(nm,n) str_tree_add(&symbols, nm, (void*)n)
+extern str_tree *symbols;
+
+/* pe.h from bfd */
+
+/* dirty! */
+#define AOUTHDR int
+
+#include "pe.h"
+
+#endif /* _pexports_h */
--- /dev/null
+#include <string.h>
+
+#include "str_tree.h"
+
+static str_tree *new_leaf(const char *s, void *extra)
+{
+ str_tree *leaf;
+ leaf = (str_tree *) malloc(sizeof(str_tree));
+ if (!leaf)
+ return NULL;
+ leaf->s = strdup(s);
+ if (!leaf->s)
+ {
+ free(leaf);
+ return NULL;
+ }
+ leaf->extra = extra;
+ leaf->left = leaf->right = NULL;
+ return leaf;
+}
+str_tree *str_tree_add(str_tree **root, const char *s, void *extra)
+{
+ if (!*root)
+ return (*root = new_leaf(s, extra));
+ else if (strcmp(s, (*root)->s) < 0)
+ return str_tree_add(&(*root)->left, s, extra);
+ else
+ return str_tree_add(&(*root)->right, s, extra);
+}
+
+str_tree *str_tree_find(str_tree *node, const char *s)
+{
+ if (node == NULL)
+ return NULL;
+ if (strcmp(s, node->s) == 0)
+ return node;
+ else if (strcmp(s, node->s) < 0)
+ return str_tree_find(node->left, s);
+ else
+ return str_tree_find(node->right, s);
+}
+
+void str_tree_free(str_tree **root)
+{
+ if (*root)
+ {
+ str_tree *node = *root;
+ free(node->s);
+ str_tree_free(&node->left);
+ str_tree_free(&node->right);
+ free(node);
+ *root = NULL;
+ }
+}
+
+int str_tree_traverse(str_tree *root,int(*f)(str_tree *node))
+{
+ if (root == NULL) return 1;
+
+ if (!str_tree_traverse(root->left,f) ||
+ !f(root) ||
+ !str_tree_traverse(root->right,f)) return 0;
+ return 1;
+}
--- /dev/null
+#ifndef _str_tree
+#define _str_tree
+
+typedef struct str_tree {
+ char *s;
+ void *extra;
+ struct str_tree *left, *right;
+} str_tree;
+
+str_tree *str_tree_add(str_tree **root, const char *s, void *extra);
+str_tree *str_tree_find(str_tree *node, const char *s);
+void str_tree_free(str_tree **root);
+int str_tree_traverse(str_tree *root,int(*f)(str_tree *node));
+
+#endif /* _str_tree */