preload.cpp revision c58f1213e628a545081c70e26c6b67a841cff880
/* $Id$ */
/** @file
* bin2c - Binary 2 C Structure Converter.
*/
/*
* Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#ifdef RT_OS_WINDOWS
# include <Windows.h>
#else
# include <sys/mman.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <errno.h>
#endif
#include <stdio.h>
#include <string.h>
static int load(const char *pszImage)
{
#ifdef RT_OS_WINDOWS
HANDLE hFile = CreateFile(pszImage,
GENERIC_READ,
FILE_SHARE_READ,
NULL /*pSecurityAttributes*/,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL /*hTemplateFile*/);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("error: CreateFile('%s',): %d\n", pszImage, GetLastError());
return 1;
}
DWORD cbHigh = 0;
DWORD cbLow = GetFileSize(hFile, &cbHigh);
size_t cbFile = cbLow != INVALID_FILE_SIZE
? cbHigh == 0
? cbLow
: ~(DWORD)0 / 4
: 64;
HANDLE hMap = CreateFileMapping(hFile,
NULL /*pAttributes*/,
PAGE_READONLY | SEC_COMMIT,
0 /*dwMaximumSizeHigh -> file size*/,
0 /*dwMaximumSizeLow -> file size*/,
NULL /*pName*/);
if (hMap == INVALID_HANDLE_VALUE)
printf("error: CreateFile('%s',): %d\n", pszImage, GetLastError());
CloseHandle(hFile);
if (hMap == INVALID_HANDLE_VALUE)
return 1;
void *pvWhere = MapViewOfFile(hMap,
FILE_MAP_READ,
0 /*dwFileOffsetHigh*/,
0 /*dwFileOffsetLow*/,
0 /*dwNumberOfBytesToMap - file size */);
if (!pvWhere)
{
printf("error: MapViewOfView('%s',): %d\n", pszImage, GetLastError());
CloseHandle(hMap);
return 1;
}
#else
int fd = open(pszImage, O_RDONLY, 0);
if (fd < 0)
{
printf("error: open('%s',): %d\n", pszImage, errno);
return 1;
}
struct stat st;
memset(&st, 0, sizeof(st));
if (fstat(fd, &st))
st.st_size = 64;
size_t cbFile = st.st_size < ~(size_t)0
? (size_t)st.st_size
: ~(size_t)0 / 4;
void *pvWhere = mmap(NULL /*addr*/, cbFile, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0 /*offset*/);
if (pvWhere == MAP_FAILED)
printf("error: mmap(,%lu,)/'%s': %d\n", (unsigned long)cbFile, pszImage, errno);
close(fd);
if (pvWhere == MAP_FAILED)
return 1;
#endif
/* Touch the whole image... do a dummy crc to keep the optimizer from begin
smart with us. */
unsigned char *puchFile = (unsigned char *)pvWhere;
size_t off = 0;
unsigned int uCrc = 0;
while (off < cbFile)
uCrc += puchFile[off++];
printf("info: %p/%#lx/%#x - %s\n", pvWhere, (unsigned long)cbFile, (unsigned char)uCrc, pszImage);
return 0;
}
static int usage(const char *argv0)
{
printf("Generic executable image preloader.\n"
"Usage: %s [dll|exe|file []]\n", argv0);
return 1;
}
int main(int argc, char **argv)
{
/*
* Check for options.
*/
for (int i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
if ( argv[i][1] == '-'
&& argv[i][2] == '\0')
break;
if ( !strcmp(argv[i], "--help")
|| !strcmp(argv[i], "-help")
|| !strcmp(argv[i], "-h")
|| !strcmp(argv[i], "-?"))
{
usage(argv[0]);
return 1;
}
if ( !strcmp(argv[i], "--version")
|| !strcmp(argv[i], "-V"))
{
printf("$Revision$\n");
return 0;
}
fprintf(stderr, "syntax error: unknown option '%s'\n", argv[i]);
return 1;
}
}
if (argc <= 1)
return usage(argv[0]);
/*
* Do the loading.
*/
for (int i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "--"))
continue;
if (argv[i][0] == '@')
{
FILE *pFile = fopen(&argv[i][1], "r");
if (pFile)
{
char szLine[4096];
while (fgets(szLine, sizeof(szLine), pFile))
{
char *psz = szLine;
while (*psz == ' ' || *psz == '\t')
psz++;
size_t off = strlen(psz);
while ( off > 0
&& ( psz[off - 1] == ' '
|| psz[off - 1] == '\t'
|| psz[off - 1] == '\n'
|| psz[off - 1] == '\r')
)
psz[--off] = '\0';
if (*psz && *psz != '#')
load(psz);
}
fclose(pFile);
}
else
fprintf(stderr, "error: fopen('%s','r'): %d\n", argv[i][1], errno);
}
else
load(argv[i]);
}
/*
* Sleep for ever.
*/
for (;;)
{
#ifdef RT_OS_WINDOWS
Sleep(3600*1000);
#else
sleep(3600);
#endif
}
return 0;
}