xref: /aosp_15_r20/external/intel-media-driver/Tools/MediaDriverTools/GenKrnBin/linkfile.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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