exeflat: add support for response file to exeflat utility

the command line can overflow DOS max length that it fixes this issue
This commit is contained in:
Jiri Malak 2024-07-14 17:59:18 +02:00 committed by Kenneth J Davis
parent 2fb0956513
commit a5b516dd7b
3 changed files with 222 additions and 147 deletions

View File

@ -74,6 +74,7 @@ git clean -x -d -f -e test -e _output -e _downloads -e _watcom
echo set XCPU=386
echo set XFAT=32
echo set XNASM='C:\\devel\\nasm\\nasm'
echo set XUPX=upx --8086 --best
echo set OLDPATH=%PATH%
echo set PATH='%WATCOM%\\binw;C:\\bin;%OLDPATH%'
} | unix2dos > config.bat

View File

@ -36,8 +36,8 @@ production: ../bin/$(TARGET).sys
# -S to avoid showing expected relocations
# 0x10 & 0x78 or 0x79 depending on compilation options
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) -S0x10 -S0x78 -S0x79 -E..$(DIRSEP)utils$(DIRSEP)upxentry.bin -D..$(DIRSEP)utils$(DIRSEP)upxdevic.bin $(UPXOPT) $(XUPX)
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin exeflat.rsp
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) @exeflat.rsp
kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS)
$(LINK) @$(TARGET).lnk;
@ -46,11 +46,21 @@ clobber: clean
-$(RM) kernel.exe kernel.sys status.me
clean:
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk *.rsp
# XXX: This is a very ugly way of linking the kernel, forced upon us by the
# inability of Turbo `make' 2.0 to perform command line redirection. -- ror4
exeflat.rsp: makefile
-$(RM) exeflat.rsp
$(ECHOTO) exeflat.rsp -S0x10
$(ECHOTO) exeflat.rsp -S0x78
$(ECHOTO) exeflat.rsp -S0x79
$(ECHOTO) exeflat.rsp -E..$(DIRSEP)utils$(DIRSEP)upxentry.bin
$(ECHOTO) exeflat.rsp -D..$(DIRSEP)utils$(DIRSEP)upxdevic.bin
$(ECHOTO) exeflat.rsp $(UPXOPT)
$(ECHOTO) exeflat.rsp $(XUPX)
$(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER).mak
-$(RM) *.lnk
$(ECHOTO) $(TARGET).lnk $(OBJS1)+

View File

@ -90,7 +90,7 @@ static void usage(void)
static int exeflat(const char *srcfile, const char *dstfile,
const char *start, short *silentSegments, short silentcount,
int UPX, UWORD stubexesize, UWORD stubdevsize,
int use_upx, UWORD stubexesize, UWORD stubdevsize,
UWORD entryparagraphs, exe_header *header)
{
int i, j;
@ -207,7 +207,7 @@ static int exeflat(const char *srcfile, const char *dstfile,
printf("\nProcessed %d relocations, %d not shown\n",
header->exRelocItems, silentdone);
if (UPX)
if (use_upx)
{
struct x {
char y[(KERNEL_CONFIG_LENGTH + 2) <= BUFSIZE ? 1 : -1];
@ -224,7 +224,7 @@ static int exeflat(const char *srcfile, const char *dstfile,
/* The biggest .sys file that UPX accepts seems to be 65419 bytes long.
Actually, UPX 3.96 appears to accept DOS/SYS files up to 65426 bytes.
To avoid problems we use a slightly lower limit. */
if (UPX) {
if (use_upx) {
if (stubdevsize && stubexesize)
compress_sys_file = (size - stubdevsize) <= /* 65426 */ 65400;
/* would need to subtract 0x10 for the device header here
@ -407,13 +407,59 @@ static void write_header(FILE *dest, unsigned char * code, UWORD stubsize,
}
}
int my_isspace( int c )
{
switch( c ) {
case ' ':
case '\n':
case '\r':
case '\f':
case '\t':
case '\v':
return( 1 );
default:
return( 0 );
}
}
char *getarg( FILE *fp )
{
static char buff[256];
char *str;
size_t len;
while( (str = fgets( buff, sizeof(buff) - 1, fp )) != NULL ) {
buff[sizeof(buff) - 1] = '\0';
len = strlen(buff);
while( len > 0 ) {
len--;
if( my_isspace( buff[len] ) ) {
buff[len] = '\0';
continue;
}
len++;
break;
}
while( len-- > 0 ) {
if( !my_isspace(*str) ) {
break;
}
}
if( *str != '\0' ) {
break;
}
}
return( str );
}
int main(int argc, char **argv)
{
short silentSegments[20], silentcount = 0;
static exe_header header; /* must be initialized to zero */
int UPX = FALSE;
int use_upx = 0;
char *upx_cmd;
int i;
size_t sz, len, len2, n;
size_t len;
int compress_sys_file;
char *buffer, *tmpexe, *cmdbuf, *entryexefilename = "", *entrydevfilename = "";
FILE *dest, *source;
@ -423,30 +469,60 @@ int main(int argc, char **argv)
FILE * entryf = NULL;
UWORD end;
UWORD stubexesize = 0, stubdevsize = 0;
FILE *indir = NULL;
/* if no arguments provided, show usage and exit */
if (argc < 4) usage();
upx_cmd = malloc(1);
*upx_cmd = '\0';
i = 4;
/* do optional argument processing here */
for (i = 4; i < argc && !UPX; i++)
while ( i < argc || indir != NULL )
{
char *argptr = argv[i];
char *argptr = NULL;
if (argptr[0] != '-' && argptr[0] != '/')
usage();
argptr++;
switch (toupper(argptr[0]))
if( indir != NULL ) {
argptr = getarg( indir );
if(argptr == NULL) {
fclose( indir );
indir = NULL;
continue;
}
}
if( argptr == NULL ) {
argptr = argv[i++];
}
if( use_upx ) {
len = strlen( upx_cmd );
if( len > 0 ) len++;
upx_cmd = realloc( upx_cmd, len + strlen( argptr ) + 1 );
if( len > 0 ) upx_cmd[len - 1] = ' ';
strcpy( upx_cmd + len, argptr );
} else {
switch (*(unsigned char *)argptr++)
{
case '@':
indir = fopen( argptr, "r" );
if( indir == NULL ) {
printf("can't open indirect file '%s'\n", argptr);
exit(1);
}
break;
case '-':
case '/':
switch (toupper(*(unsigned char *)argptr++))
{
case 'U':
UPX = i;
use_upx = 1;
break;
case 'E':
entryexefilename = &argptr[1];
entryexefilename = malloc(strlen(argptr) + 1);
strcpy(entryexefilename, argptr);
break;
case 'D':
entrydevfilename = &argptr[1];
entrydevfilename = malloc(strlen(argptr) + 1);
strcpy(entrydevfilename, argptr);
break;
case 'S':
if (silentcount >= LENGTH(silentSegments))
@ -455,16 +531,19 @@ int main(int argc, char **argv)
(int)LENGTH(silentSegments));
exit(1);
}
silentSegments[silentcount++] = (short)strtol(argptr + 1, NULL, 0);
silentSegments[silentcount++] = (short)strtol(argptr, NULL, 0);
break;
default:
usage();
}
break;
default:
usage();
}
}
}
if (UPX) {
if (use_upx) {
if (*entryexefilename) {
entryf = fopen(entryexefilename, "rb");
if (!entryf) {
@ -510,10 +589,9 @@ int main(int argc, char **argv)
compress_sys_file = exeflat(argv[1], argv[2], argv[3],
silentSegments, silentcount,
UPX, stubexesize, stubdevsize, 0, &header);
if (!UPX)
exit(0);
use_upx, stubexesize, stubdevsize, 0, &header);
if (use_upx)
{
/* move kernel.sys tmp.exe */
if (!compress_sys_file)
{
@ -527,27 +605,12 @@ int main(int argc, char **argv)
exit(1);
}
len2 = strlen(tmpexe) + 1;
sz = len2;
if (sz < 256) sz = 256;
cmdbuf = malloc(sz);
len = 0;
for (i = UPX+1; i < argc; i++)
{
n = strlen(argv[i]);
if (len + len2 + n + 2 >= sz) {
sz *= 2;
cmdbuf = realloc(cmdbuf, sz);
}
if (i > UPX+1)
cmdbuf[len++] = ' ';
memcpy(cmdbuf + len, argv[i], n + 1);
len += n;
}
cmdbuf[len++] = ' ';
len = strlen(upx_cmd);
cmdbuf = malloc(len + 1 + strlen(tmpexe) + 1);
strcpy(cmdbuf, upx_cmd);
cmdbuf[len] = ' ';
/* if tmpexe is tmpfile set above no quotes needed, if user needs quotes should add on cmd line */
memcpy(cmdbuf + len, tmpexe, len2);
cmdbuf[len + len2] = '\0';
strcpy(cmdbuf + len + 1, tmpexe);
printf("%s\n", cmdbuf);
fflush(stdout);
if (system(cmdbuf))
@ -620,5 +683,6 @@ int main(int argc, char **argv)
fclose(source);
remove("tmp.bin");
remove(tmpexe);
}
return 0;
}