blob: 7c1d61236b579571078b5e733f9a3f86ee8cb25a [file] [log] [blame]
// Disable deprecated
#pragma warning(disable : 4995)
#include <assert.h>
#include <list>
#include <string>
#include <fstream>
#include <vector>
#include <stdlib.h>
#include "linkfile.h"
#ifdef LINUX_
#include <strings.h>
#include <cstring>
#endif
#ifdef LINUX_
#define StrCmp strcasecmp
#else
#define StrCmp stricmp
#endif
using namespace std;
// scratch global variables for writing files
char *skipspace(char *ch)
{
if (!ch) return NULL;
// skip space chars
while (isspace(*ch))
{
(*ch++) = 0;
}
// end of string
if (*ch == 0)
{
ch = NULL;
}
return ch;
}
char *nextword(char *ch)
{
if (!ch) return NULL;
// skip current word (non-space chars)
while ((*ch) && !isspace(*ch))
{
ch++;
}
// skip space chars after word, point to next word
return skipspace(ch);
}
void CreateLinkFile(char *pDirectoryName, list <string> &kernels)
{
list <string> labels;
list <string>::iterator i;
char LinkFileTxt[MAX_STRING_SIZE];
char LinkFileBin[MAX_STRING_SIZE];
char *pText = NULL;
LinkData *pLink = NULL;
LinkFileHeader LinkHeader;
FILE *hText = NULL;
FILE *hBin = NULL;
unsigned int dwFileSize, dwBytesRead, dwBytesWrite;
unsigned int dwKernelID, dwLabelID, dwOffset;
bool bExport;
bool bInline;
int lines;
int links = 0;
int exports = 0;
int imports = 0;
char *ch;
string name_krn;
string name_hex;
// Create full LinkFile binary name
#ifdef LINUX_
sprintf(LinkFileTxt, "%s/%s", pDirectoryName, "LinkFile.txt");
#else
sprintf(LinkFileTxt, "%s\\%s", pDirectoryName, "LinkFile.txt");
#endif
hText = fopen(LinkFileTxt, "r");
if (hText == NULL) goto done;
// Create full LinkFile binary name - remove pre-existing file
#ifdef LINUX_
sprintf(LinkFileBin, "%s/%s", pDirectoryName, "LinkFile.krn");
#else
sprintf(LinkFileBin, "%s\\%s", pDirectoryName, "LinkFile.krn");
#endif
remove(LinkFileBin);
// Allocate text buffer for reading
fseek(hText, 0, SEEK_END);
dwFileSize = ftell(hText);
fseek(hText, 0, SEEK_SET);
pText = (char *)malloc(dwFileSize + 1);
if (!pText) goto done;
memset(pText,0,dwFileSize + 1);
// Read text file
dwBytesRead = fread(pText, 1, dwFileSize, hText);
pText[dwFileSize] = 0;
// Count lines, split into strings
for (lines = 0, ch = pText; (ch != NULL); lines++)
{
ch = strchr(ch, '\n');
if (ch) *(ch++) = 0;
}
// Allocate binary file (from number of lines : 1 link entry per line)
pLink = (LinkData *)malloc(lines * sizeof(LinkData));
if (!pLink) goto done;
memset(pLink, 0, lines * sizeof(LinkData));
// Start parsing the file
labels.empty();
char *module;
char *label;
char *export_str;
char *offset;
for (ch = pText; lines > 0; lines--)
{
// Split the words
module = ch;
ch = ch + strlen(ch) + 1;
module = skipspace(module);
label = nextword (module);
export_str = nextword (label);
offset = nextword (export_str);
// Check for structure
if (!(module && label && export_str && offset))
{
continue;
}
// Module search
name_krn = module;
name_hex = module;
name_krn.append(".krn");
name_hex.append(".hex");
for (dwKernelID = 0, i = kernels.begin(); i != kernels.end(); dwKernelID++, i++)
{
if (StrCmp(i->c_str(), name_krn.c_str()) == 0) break;
if (StrCmp(i->c_str(), name_hex.c_str()) == 0) break;
}
if (i == kernels.end())
{
fprintf(stderr, "Unresolved reference to %s\n", module);
exit (-1);
}
// Label ID
for (dwLabelID = 0, i = labels.begin(); i != labels.end(); dwLabelID++, i++)
{
if (strcmp(i->c_str(), label) == 0) break;
}
if (i == labels.end())
{
labels.push_back(label);
}
// Export/import
if (strcmp(export_str, "export") == 0)
{
bExport = true;
bInline = false;
}
else if (strcmp(export_str, "import") == 0)
{
bExport = false;
bInline = false;
}
else if (strcmp(export_str, "include") == 0)
{
bExport = false;
bInline = true;
}
else if (strcmp(export_str, "inline") == 0)
{
bExport = true;
bInline = true;
}
else
{
fprintf(stderr, "Invalid Export/Import syntax\n");
exit(-1);
}
// Offset in instructions
dwOffset = atoi(offset);
pLink[links].dwKernelID = dwKernelID;
pLink[links].dwLabelID = dwLabelID;
pLink[links].bExport = bExport;
pLink[links].bInline = bInline;
pLink[links].dwOffset = dwOffset << 2;
links++;
exports += bExport;
imports += !bExport;
}
hBin = fopen(LinkFileBin, "wb");
if (hBin == NULL) goto done;
// Generate link header
LinkHeader.dwVersion = LINKFILE_VERSION;
LinkHeader.dwExports = exports;
LinkHeader.dwImports = imports;
LinkHeader.dwSize = links * sizeof(LinkData);
// Write header and link data
fwrite(&LinkHeader, 1, sizeof(LinkHeader), hBin);
fwrite(pLink, 1, links * sizeof(LinkData), hBin);
done:
if (hText) fclose(hText);
if (hBin) fclose(hBin);
if (pText) free(pText);
if (pLink) free(pLink);
}
void DeleteLinkFile(char *pDirectoryName)
{
char LinkFileBin[MAX_STRING_SIZE];
// Create full LinkFile binary name - delete file
sprintf(LinkFileBin, "%s\\%s", pDirectoryName, "LinkFile.krn");
remove(LinkFileBin);
}