Table of Contents Previous topic Next topic
LINKER->Linker Command Line Options->Generate Relocatable Binary Output (/RBIN)
This option causes the program code to be generated in as a binary image of target memory (as for the /BIN option) and appends a relocation table to the front of the file. A smart loader can use this relocation table to update the program so that it will run correctly at the address into which it has been loaded.
The format for the file is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long GetLong(FILE* fp);
void main(int argc, char *argv[])
{
long nRelocationOffset;
char* pszFilename;
FILE* fpInput;
FILE* fpOutput;
char szOutfile[_MAX_PATH];
long nProgramOffset;
char nByte;
if (argc < 3)
{
printf("Usage: rbin2bin <input filename> <relocation offset (decimal)>\n");
exit(1);
}
nRelocationOffset = atol(argv[2]);
pszFilename = argv[1];
fpInput = fopen(pszFilename, "rb");
if (fpInput == NULL)
{
printf("Cannot open file %s for input\n", pszFilename);
exit(1);
}
strcpy(szOutfile, pszFilename);
strcat(szOutfile, ".BIN");
fpOutput = fopen(szOutfile, "w+b"); // open for reading and writing
if (fpOutput == NULL)
{
printf("Cannot open file %s for output\n", szOutfile);
exit(1);
}
else
{
printf("Creating output file %s\n", szOutfile);
}
// read the first 4 bytes to get to the position of the start of the program bytes
nProgramOffset = GetLong(fpInput);
fseek(fpInput, nProgramOffset, SEEK_SET); // move to the start of the program
// copy the complete program to the output file
while (1)
{
nByte = fgetc(fpInput);
if (nByte == EOF)
{
if (feof(fpInput) != 0)
break; // it's a genuine end of file
}
putc((int)nByte, fpOutput);
};
if (nRelocationOffset != 0)
{
// now read the relocation table and modify the output file
fseek(fpInput, 4, SEEK_SET); // move to the start of the relocation table
while (ftell(fpInput) < nProgramOffset)
{
long nAddress;
long temp = ftell(fpInput);
// keep going until we get to the program bytes
long nOffset = GetLong(fpInput);
fseek(fpOutput, nOffset, SEEK_SET); // move to the position in the output file
nAddress = GetLong(fpOutput); // read the bytes to be modify
nAddress += nRelocationOffset;
fseek(fpOutput, nOffset, SEEK_SET); // move back to the position in the output file
// write the modified data back to the output file
putc((int)(char)(nAddress >> 24), fpOutput);
putc((int)(char)(nAddress >> 16), fpOutput);
putc((int)(char)(nAddress >> 8), fpOutput);
putc((int)(char)nAddress, fpOutput);
}
}
fclose(fpInput);
fclose(fpOutput);
}
long GetLong(FILE* fp)
{
unsigned char nByte1 = fgetc(fp);
unsigned char nByte2 = fgetc(fp);
unsigned char nByte3 = fgetc(fp);
unsigned char nByte4 = fgetc(fp);
// construct the long value
long nValue = (long)nByte1 << 24 | (long)nByte2 << 16 | (long)nByte3 << 8 | (long)nByte4;
return nValue;
}