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