[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnet/ilstrip .cvsignore,NONE,1.1 Makefile.am
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnet/ilstrip .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 ilstrip.1,NONE,1.1 ilstrip.c,NONE,1.1 |
Date: |
Sat, 05 Jul 2003 06:29:30 -0400 |
Update of /cvsroot/dotgnu-pnet/pnet/ilstrip
In directory subversions:/tmp/cvs-serv4389/ilstrip
Added Files:
.cvsignore Makefile.am ilstrip.1 ilstrip.c
Log Message:
Add the "ilstrip" program.
--- NEW FILE ---
Makefile
Makefile.in
.deps
ilstrip
--- NEW FILE ---
bin_PROGRAMS = ilstrip
man_MANS = ilstrip.1
EXTRA_DIST = $(man_MANS)
ilstrip_SOURCES = ilstrip.c
ilstrip_LDADD = ../support/libILSupport.a
AM_CFLAGS = -I$(top_srcdir)/include
--- NEW FILE ---
.\" Copyright (c) 2003 Southern Storm Software, Pty Ltd.
.\"
.\" 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
.TH ilstrip 1 "5 July 2003" "Southern Storm Software" "Portable.NET Development
Tools"
.SH NAME
ilstrip \- strip debug symbols from Intermediate Language (IL) programs
.SH SYNOPSIS
.ll +8
.B ilstrip
[ options ]
.I input
\&...
.SH DESCRIPTION
.B Ilstrip
strips the debug symbol information from an IL executable (.exe)
or an IL dynamic link library (.dll).
.SH OPTIONS
.TP
.B \-o \fIfile\fR, \-\-output \fIfile\fR
Specify the output filename. By default the stripped version of a
file overwrites the original name.
.TP
.B \-p, \-\-preserve\-dates
Preserve the original access and modification times on the input files.
.TP
.B \-v, \-\-verbose
List all files as they are modified.
.TP
.B \-\-help
Print a usage message for the \fBilstrip\fR program.
.TP
.B \-V, \-\-version
Print the version of the \fBilstrip\fR program.
.TP
.B \-\-
Marks the end of the command-line options, and the beginning of
the input filenames. You may need to use this if your filename
begins with '-'. e.g. "ilstrip -- -input.exe". This is not needed
if the input is stdin: "ilstrip -" is perfectly valid.
.SH "AUTHOR"
Written by Southern Storm Software, Pty Ltd.
http://www.southern-storm.com.au/
.SH "SEE ALSO"
ilsize(1), ilfind(1), ilasm(1), strip(1)
.SH "DIAGNOSTICS"
Exit status is 1 if an error occurred while processing the input.
Otherwise the exit status is 0. See the manual page for
\fBilsize\fR(1) for a complete list of errors that may occur
when loading an IL image file.
--- NEW FILE ---
/*
* ilstrip.c - Strip debug symbol information from IL binaries.
*
* Copyright (C) 2003 Southern Storm Software, Pty Ltd.
*
* 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
*/
#include <stdio.h>
#include "il_system.h"
#include "il_utils.h"
#include "il_sysio.h"
#ifndef IL_WIN32_PLATFORM
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Table of command-line options.
*/
static ILCmdLineOption const options[] = {
{"-o", 'o', 1, 0, 0},
{"--output", 'o', 1,
"--output FILE or -o FILE",
"Specify the output filename, if not the same as the input."},
{"-p", 'p', 0, 0, 0},
{"--preserve-dates", 'p', 0,
"--preserve-dates or -p",
"Preserve access and modification times."},
{"-v", 'v', 0, 0, 0},
{"--verbose", 'v', 0,
"--verbose or -v",
"List all files that are modified."},
{"-V", 'V', 0, 0, 0},
{"--version", 'V', 0,
"--version or -V",
"Print the version of the program."},
{"--help", 'h', 0,
"--help",
"Print this help message."},
/* GNU strip compatibility options that we don't use */
{"-F", '*', 1, 0, 0},
{"--target", '*', 1, 0, 0},
{"-I", '*', 1, 0, 0},
{"--input-target", '*', 1, 0, 0},
{"-O", '*', 1, 0, 0},
{"--output-target", '*', 1, 0, 0},
{"-R", '*', 1, 0, 0},
{"--remove-section", '*', 1, 0, 0},
{"-N", '*', 1, 0, 0},
{"--strip-symbol", '*', 1, 0, 0},
{"-K", '*', 1, 0, 0},
{"--keep-symbol", '*', 1, 0, 0},
{"-s", '*', 0, 0, 0},
{"--strip-all", '*', 0, 0, 0},
{"-g", '*', 0, 0, 0},
{"-S", '*', 0, 0, 0},
{"--strip-debug", '*', 0, 0, 0},
{"--strip-unneeded", '*', 0, 0, 0},
{"-x", '*', 0, 0, 0},
{"--discard-all", '*', 0, 0, 0},
{"-X", '*', 0, 0, 0},
{"--discard-locals", '*', 0, 0, 0},
{0, 0, 0, 0, 0}
};
static void usage(const char *progname);
static void version(void);
static int stripFile(const char *progname, const char *input,
const char *output, int preserveDates,
int verbose);
int main(int argc, char *argv[])
{
char *progname = argv[0];
const char *output = 0;
int preserveDates = 0;
int verbose = 0;
int errors;
int state, opt;
char *param;
/* Parse the command-line arguments */
state = 0;
while((opt = ILCmdLineNextOption(&argc, &argv, &state,
options, ¶m)) != 0)
{
switch(opt)
{
case 'o':
{
output = param;
}
break;
case 'p':
{
preserveDates = 1;
}
break;
case 'v':
{
verbose = 1;
}
break;
case 'V':
{
version();
return 0;
}
/* Not reached */
case '*': break; /* Ignore compatibility options
*/
default:
{
usage(progname);
return 1;
}
/* Not reached */
}
}
/* We need at least one input file argument */
if(argc <= 1)
{
usage(progname);
return 1;
}
/* Can only have one argument if an output file is specified */
if(output && argc != 2)
{
usage(progname);
return 1;
}
/* Strip the specified files */
errors = 0;
while(argc > 1)
{
if(output && !strcmp(output, argv[1]))
{
output = 0;
}
errors |= stripFile(progname, argv[1], output, preserveDates,
verbose);
++argv;
--argc;
}
/* Done */
return errors;
}
static void usage(const char *progname)
{
fprintf(stdout, "ILSTRIP " VERSION " - IL Binary Strip Utility\n");
fprintf(stdout, "Copyright (c) 2003 Southern Storm Software, Pty
Ltd.\n");
fprintf(stdout, "\n");
fprintf(stdout, "Usage: %s [options] input ...\n", progname);
fprintf(stdout, "\n");
ILCmdLineHelp(options);
}
static void version(void)
{
fprintf(stdout, "ILSTRIP " VERSION " - IL Binary Strip Utility\n");
fprintf(stdout, "Copyright (c) 2003 Southern Storm Software, Pty
Ltd.\n");
printf("\n");
printf("ILSTRIP comes with ABSOLUTELY NO WARRANTY. This is free
software,\n");
printf("and you are welcome to redistribute it under the terms of
the\n");
printf("GNU General Public License. See the file COPYING for further
details.\n");
printf("\n");
printf("Use the `--help' option to get help on the command-line
options.\n");
}
/*
* Report that a file has the wrong format.
*/
static void wrongFormat(const char *progname, const char *input, FILE *file)
{
fclose(file);
fputs(progname, stderr);
fputs(": ", stderr);
fputs(input, stderr);
fputs(": File format not recognized\n", stderr);
}
/*
* Open a file, trying both binary and text versions.
*/
static FILE *openFile(const char *progname, const char *filename,
const char *openBinary, const char
*openText)
{
FILE *file;
if((file = fopen(filename, openBinary)) == 0)
{
/* Try again, in case the "b" flag is not understood by libc */
if((file = fopen(filename, openText)) == 0)
{
fputs(progname, stderr);
fputs(": ", stderr);
perror(filename);
return 0;
}
}
return file;
}
/*
* Strip an IL binary.
*/
static int stripFile(const char *progname, const char *input,
const char *output, int preserveDates,
int verbose)
{
FILE *infile;
FILE *outfile;
char buffer[4096];
ILUInt32 len;
ILUInt32 offset;
ILUInt32 optHeader;
ILUInt32 numSectionsOffset;
ILUInt32 numSections;
ILUInt32 headerSize;
ILUInt32 debugRVA;
ILUInt32 debugStart;
const char *tempFile;
char *nameBuf;
/* Attempt to open the specified file */
if((infile = openFile(progname, input, "rb", "r")) == 0)
{
return 1;
}
/* Read the first 4k of the file so that we can parse the headers */
len = (ILUInt32)fread(buffer, 1, sizeof(buffer), infile);
/* Do we have an MS-DOS stub and PE signature? Note: other "strip"
programs support object files and ".a" archives, but we don't yet */
if(len < 64)
{
wrongFormat(progname, input, infile);
return 1;
}
if(buffer[0] != 'M' || buffer[1] != 'Z')
{
wrongFormat(progname, input, infile);
return 1;
}
offset = IL_READ_UINT32(buffer + 60);
if((offset + 4) >= len)
{
wrongFormat(progname, input, infile);
return 1;
}
if(buffer[offset] != 'P' || buffer[offset + 1] != 'E' ||
buffer[offset + 2] != '\0' || buffer[offset + 3] != '\0')
{
wrongFormat(progname, input, infile);
return 1;
}
offset += 4;
/* Process the PE/COFF header and skip to the start of the section
table */
if((offset + 20) > len)
{
wrongFormat(progname, input, infile);
return 1;
}
numSectionsOffset = offset + 2;
numSections = IL_READ_UINT16(buffer + offset + 2);
headerSize = IL_READ_UINT16(buffer + offset + 16);
if(headerSize < 216 || headerSize > 1024)
{
wrongFormat(progname, input, infile);
return 1;
}
optHeader = offset + 20;
offset += 20 + headerSize;
if(offset >= len)
{
wrongFormat(progname, input, infile);
return 1;
}
/* Determine if the last section is ".ildebug". If it isn't,
then the binary has already been stripped of debug symbols */
if((offset + 40 * numSections) > len)
{
wrongFormat(progname, input, infile);
return 1;
}
if(numSections == 0 ||
ILMemCmp(buffer + offset + (numSections - 1) * 40, ".ildebug", 8) !=
0)
{
/* We exit successfully if the file is already stripped */
if(output)
{
/* Copy the entire contents to the output */
if((outfile = openFile(progname, output, "wb", "w")) ==
0)
{
fclose(infile);
return 1;
}
while(len > 0)
{
fwrite(buffer, 1, (int)len, outfile);
if(len < sizeof(buffer))
{
len = 0;
}
else
{
len = (ILUInt32)fread(buffer, 1,
sizeof(buffer), infile);
}
}
fclose(outfile);
}
fclose(infile);
return 0;
}
/* Patch the header to remove the ".ildebug" section, and determine
how many bytes will remain in the file once the section is gone */
debugRVA = IL_READ_UINT32(buffer + offset + (numSections - 1) * 40 +
12);
debugStart = IL_READ_UINT32(buffer + offset + (numSections - 1) * 40 +
20);
ILMemZero(buffer + offset + (numSections - 1) * 40, 40);
IL_WRITE_UINT32(buffer + optHeader + 56, debugRVA); /* New image
size */
IL_WRITE_UINT16(buffer + numSectionsOffset, numSections - 1);
if(debugStart < len)
{
len = debugStart;
}
/* Create the temporary output filename */
if(output)
{
tempFile = output;
nameBuf = 0;
}
else
{
if((nameBuf = (char *)ILMalloc(strlen(input) + 5)) == 0)
{
fputs("virtual memory exhausted\n", stderr);
fclose(infile);
return 1;
}
strcpy(nameBuf, input);
strcat(nameBuf, ".tmp");
tempFile = nameBuf;
}
/* Print what we are doing if the verbose flag is set */
if(verbose)
{
printf("copy from %s(pecoff-cli) to %s(pecoff-cli)\n",
input, tempFile);
}
/* Open the temporary file */
if((outfile = openFile(progname, tempFile, "wb", "w")) == 0)
{
fclose(infile);
if(nameBuf)
{
ILFree(nameBuf);
}
return 1;
}
/* Copy the contents across, with the ".ildebug" section removed */
offset = 0;
while(offset < debugStart && len > 0)
{
fwrite(buffer, 1, (int)len, outfile);
offset += len;
if(offset < debugStart && len >= sizeof(buffer))
{
len = (debugStart - offset);
if(len > sizeof(buffer))
{
len = sizeof(buffer);
}
len = fread(buffer, 1, (int)len, infile);
}
else
{
len = 0;
}
}
/* Close the streams */
fclose(infile);
fclose(outfile);
#if !defined(IL_WIN32_PLATFORM) && defined(HAVE_STAT) && defined(HAVE_UTIME)
/* Copy the date information across if necessary */
if(preserveDates)
{
struct stat st;
struct utimbuf ut;
if(stat(input, &st) >= 0)
{
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
utime(tempFile, &ut);
}
}
#endif
/* Rename the temporary file, to replace the original input */
if(!output)
{
ILRenameDir(tempFile, input);
}
if(nameBuf)
{
ILFree(nameBuf);
}
/* Finished */
return 0;
}
#ifdef __cplusplus
};
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/ilstrip .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 ilstrip.1,NONE,1.1 ilstrip.c,NONE,1.1,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] CVS: pnet/ilstrip - New directory
- Next by Date:
[Dotgnu-pnet-commits] CVS: pnet ChangeLog,1.2512,1.2513 Makefile.am,1.23,1.24 configure.in,1.133,1.134
- Previous by thread:
[Dotgnu-pnet-commits] CVS: pnet/ilstrip - New directory
- Next by thread:
[Dotgnu-pnet-commits] CVS: pnet ChangeLog,1.2512,1.2513 Makefile.am,1.23,1.24 configure.in,1.133,1.134
- Index(es):