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