1 // Disable deprecated
2 #pragma warning(disable : 4995)
3
4 #include <assert.h>
5 #include <list>
6 #include <string>
7 #include <fstream>
8 #include <vector>
9 #include <stdlib.h>
10 #include "linkfile.h"
11
12 #ifdef LINUX_
13 #include <strings.h>
14 #include <cstring>
15 #endif
16
17 #ifdef LINUX_
18 #define StrCmp strcasecmp
19 #else
20 #define StrCmp stricmp
21 #endif
22
23 using namespace std;
24
25 // scratch global variables for writing files
skipspace(char * ch)26 char *skipspace(char *ch)
27 {
28 if (!ch) return NULL;
29
30 // skip space chars
31 while (isspace(*ch))
32 {
33 (*ch++) = 0;
34 }
35
36 // end of string
37 if (*ch == 0)
38 {
39 ch = NULL;
40 }
41
42 return ch;
43 }
44
nextword(char * ch)45 char *nextword(char *ch)
46 {
47 if (!ch) return NULL;
48
49 // skip current word (non-space chars)
50 while ((*ch) && !isspace(*ch))
51 {
52 ch++;
53 }
54
55 // skip space chars after word, point to next word
56 return skipspace(ch);
57 }
58
CreateLinkFile(char * pDirectoryName,list<string> & kernels)59 void CreateLinkFile(char *pDirectoryName, list <string> &kernels)
60 {
61 list <string> labels;
62 list <string>::iterator i;
63
64 char LinkFileTxt[MAX_STRING_SIZE];
65 char LinkFileBin[MAX_STRING_SIZE];
66 char *pText = NULL;
67 LinkData *pLink = NULL;
68 LinkFileHeader LinkHeader;
69 FILE *hText = NULL;
70 FILE *hBin = NULL;
71 unsigned int dwFileSize, dwBytesRead, dwBytesWrite;
72 unsigned int dwKernelID, dwLabelID, dwOffset;
73 bool bExport;
74 bool bInline;
75 int lines;
76 int links = 0;
77 int exports = 0;
78 int imports = 0;
79 char *ch;
80 string name_krn;
81 string name_hex;
82
83 // Create full LinkFile binary name
84 #ifdef LINUX_
85 sprintf(LinkFileTxt, "%s/%s", pDirectoryName, "LinkFile.txt");
86 #else
87 sprintf(LinkFileTxt, "%s\\%s", pDirectoryName, "LinkFile.txt");
88 #endif
89 hText = fopen(LinkFileTxt, "r");
90 if (hText == NULL) goto done;
91
92 // Create full LinkFile binary name - remove pre-existing file
93 #ifdef LINUX_
94 sprintf(LinkFileBin, "%s/%s", pDirectoryName, "LinkFile.krn");
95 #else
96 sprintf(LinkFileBin, "%s\\%s", pDirectoryName, "LinkFile.krn");
97 #endif
98 remove(LinkFileBin);
99
100 // Allocate text buffer for reading
101 fseek(hText, 0, SEEK_END);
102 dwFileSize = ftell(hText);
103 fseek(hText, 0, SEEK_SET);
104 pText = (char *)malloc(dwFileSize + 1);
105 if (!pText) goto done;
106
107 memset(pText,0,dwFileSize + 1);
108
109 // Read text file
110 dwBytesRead = fread(pText, 1, dwFileSize, hText);
111 pText[dwFileSize] = 0;
112
113 // Count lines, split into strings
114 for (lines = 0, ch = pText; (ch != NULL); lines++)
115 {
116 ch = strchr(ch, '\n');
117 if (ch) *(ch++) = 0;
118 }
119
120 // Allocate binary file (from number of lines : 1 link entry per line)
121 pLink = (LinkData *)malloc(lines * sizeof(LinkData));
122 if (!pLink) goto done;
123 memset(pLink, 0, lines * sizeof(LinkData));
124
125 // Start parsing the file
126 labels.empty();
127
128 char *module;
129 char *label;
130 char *export_str;
131 char *offset;
132 for (ch = pText; lines > 0; lines--)
133 {
134 // Split the words
135 module = ch;
136 ch = ch + strlen(ch) + 1;
137 module = skipspace(module);
138 label = nextword (module);
139 export_str = nextword (label);
140 offset = nextword (export_str);
141
142 // Check for structure
143 if (!(module && label && export_str && offset))
144 {
145 continue;
146 }
147
148 // Module search
149 name_krn = module;
150 name_hex = module;
151 name_krn.append(".krn");
152 name_hex.append(".hex");
153 for (dwKernelID = 0, i = kernels.begin(); i != kernels.end(); dwKernelID++, i++)
154 {
155 if (StrCmp(i->c_str(), name_krn.c_str()) == 0) break;
156 if (StrCmp(i->c_str(), name_hex.c_str()) == 0) break;
157 }
158 if (i == kernels.end())
159 {
160 fprintf(stderr, "Unresolved reference to %s\n", module);
161 exit (-1);
162 }
163
164 // Label ID
165 for (dwLabelID = 0, i = labels.begin(); i != labels.end(); dwLabelID++, i++)
166 {
167 if (strcmp(i->c_str(), label) == 0) break;
168 }
169 if (i == labels.end())
170 {
171 labels.push_back(label);
172 }
173
174 // Export/import
175 if (strcmp(export_str, "export") == 0)
176 {
177 bExport = true;
178 bInline = false;
179 }
180 else if (strcmp(export_str, "import") == 0)
181 {
182 bExport = false;
183 bInline = false;
184 }
185 else if (strcmp(export_str, "include") == 0)
186 {
187 bExport = false;
188 bInline = true;
189 }
190 else if (strcmp(export_str, "inline") == 0)
191 {
192 bExport = true;
193 bInline = true;
194 }
195 else
196 {
197 fprintf(stderr, "Invalid Export/Import syntax\n");
198 exit(-1);
199 }
200
201 // Offset in instructions
202 dwOffset = atoi(offset);
203
204 pLink[links].dwKernelID = dwKernelID;
205 pLink[links].dwLabelID = dwLabelID;
206 pLink[links].bExport = bExport;
207 pLink[links].bInline = bInline;
208 pLink[links].dwOffset = dwOffset << 2;
209 links++;
210 exports += bExport;
211 imports += !bExport;
212 }
213
214 hBin = fopen(LinkFileBin, "wb");
215 if (hBin == NULL) goto done;
216
217 // Generate link header
218 LinkHeader.dwVersion = LINKFILE_VERSION;
219 LinkHeader.dwExports = exports;
220 LinkHeader.dwImports = imports;
221 LinkHeader.dwSize = links * sizeof(LinkData);
222
223 // Write header and link data
224 fwrite(&LinkHeader, 1, sizeof(LinkHeader), hBin);
225 fwrite(pLink, 1, links * sizeof(LinkData), hBin);
226
227 done:
228 if (hText) fclose(hText);
229 if (hBin) fclose(hBin);
230 if (pText) free(pText);
231 if (pLink) free(pLink);
232 }
233
DeleteLinkFile(char * pDirectoryName)234 void DeleteLinkFile(char *pDirectoryName)
235 {
236 char LinkFileBin[MAX_STRING_SIZE];
237
238 // Create full LinkFile binary name - delete file
239 sprintf(LinkFileBin, "%s\\%s", pDirectoryName, "LinkFile.krn");
240 remove(LinkFileBin);
241 }
242