OSDN Git Service

Initial import from mingw-utils-0.3 mingw_utils_v0_3 start v0_43
authorCharles Wilson <cwilso11@users.sourceforge.net>
Tue, 15 Sep 2009 03:32:56 +0000 (03:32 +0000)
committerCharles Wilson <cwilso11@users.sourceforge.net>
Tue, 15 Sep 2009 03:32:56 +0000 (03:32 +0000)
13 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
README [new file with mode: 0644]
hlex.l [new file with mode: 0644]
hparse.h [new file with mode: 0644]
hparse.y [new file with mode: 0644]
pe.h [new file with mode: 0644]
pexports.c [new file with mode: 0644]
pexports.h [new file with mode: 0644]
str_tree.c [new file with mode: 0644]
str_tree.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..7878c75
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Anders Norlander <anorland@hem2.passagen.se>
+Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..eeb586b
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   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.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..648a8e7
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,56 @@
+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.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..e85f8b0
--- /dev/null
@@ -0,0 +1,7 @@
+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
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..02ae61f
--- /dev/null
+++ b/README
@@ -0,0 +1,38 @@
+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.
diff --git a/hlex.l b/hlex.l
new file mode 100644 (file)
index 0000000..c9ad56f
--- /dev/null
+++ b/hlex.l
@@ -0,0 +1,54 @@
+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);
+}
diff --git a/hparse.h b/hparse.h
new file mode 100644 (file)
index 0000000..15dc352
--- /dev/null
+++ b/hparse.h
@@ -0,0 +1,7 @@
+typedef union {
+       char *s;
+} YYSTYPE;
+#define        ID      258
+
+
+extern YYSTYPE yylval;
diff --git a/hparse.y b/hparse.y
new file mode 100644 (file)
index 0000000..d7ed286
--- /dev/null
+++ b/hparse.y
@@ -0,0 +1,100 @@
+%{
+
+#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;
+}
diff --git a/pe.h b/pe.h
new file mode 100644 (file)
index 0000000..7e676a5
--- /dev/null
+++ b/pe.h
@@ -0,0 +1,169 @@
+/* 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
+
+
+
diff --git a/pexports.c b/pexports.c
new file mode 100644 (file)
index 0000000..1f7ebfc
--- /dev/null
@@ -0,0 +1,519 @@
+#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);
+}
diff --git a/pexports.h b/pexports.h
new file mode 100644 (file)
index 0000000..fabd15e
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ 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 */
diff --git a/str_tree.c b/str_tree.c
new file mode 100644 (file)
index 0000000..7eb6357
--- /dev/null
@@ -0,0 +1,64 @@
+#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;
+}
diff --git a/str_tree.h b/str_tree.h
new file mode 100644 (file)
index 0000000..09d7fd6
--- /dev/null
@@ -0,0 +1,15 @@
+#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 */