OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
EfiLdrImage.c
Go to the documentation of this file.
1
21#include <stdio.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25#include <stdarg.h>
26
27#define MAX_PE_IMAGES 63
28#define FILE_TYPE_FIXED_LOADER 0
29#define FILE_TYPE_RELOCATABLE_PE_IMAGE 1
30
31typedef struct {
35 uint8_t FileName[52];
37
38typedef struct {
44
45//
46// Utility Name
47//
48#define UTILITY_NAME "EfiLdrImage"
49
50//
51// Utility version information
52//
53#define UTILITY_MAJOR_VERSION 1
54#define UTILITY_MINOR_VERSION 0
55
56void
58 char *FileName,
59 uint32_t LineNumber,
60 uint32_t ErrorCode,
61 char *OffendingText,
62 char *MsgFmt,
63 ...
64 )
65{
66 va_list List;
67 va_start (List, MsgFmt);
68 vprintf (MsgFmt, List);
69 va_end (List);
70 puts("");
71}
72
73void
75 void
76 )
77/*++
78
79Routine Description:
80
81 Displays the standard utility information to SDTOUT
82
83Arguments:
84
85 None
86
87Returns:
88
89 None
90
91--*/
92{
93 printf ("%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
94}
95
96void
98 void
99 )
100{
101 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
102 printf ("%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
103 printf ("Copyright (c) 1999-2017 Intel Corporation. All rights reserved.\n");
104 printf ("\n The EfiLdrImage tool is used to combine PE files into EFILDR image with Efi loader header.\n");
105}
106
107int
109 const char* VerboseLevelString,
110 const uint64_t Length,
111 uint64_t *ReturnValue
112)
113{
114 uint64_t i = 0;
115 for (;i < Length; ++i) {
116 if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {
117 return -1;
118 }
119 ++(*ReturnValue);
120 }
121
122 return 0;
123}
124
127 FILE *in,
128 FILE *out
129 )
130/*++
131Routine Description:
132 Write all the content of input file to output file.
133
134Arguments:
135 in - input file pointer
136 out - output file pointer
137
138Return:
139 uint64_t : file size of input file
140--*/
141{
142 uint32_t filesize, offset, length;
143 char Buffer[8*1024];
144
145 fseek (in, 0, SEEK_END);
146 filesize = ftell(in);
147
148 fseek (in, 0, SEEK_SET);
149
150 offset = 0;
151 while (offset < filesize) {
152 length = sizeof(Buffer);
153 if (filesize-offset < length) {
154 length = filesize-offset;
155 }
156
157 int r = fread (Buffer, length, 1, in);
158 if (r < 0) {
159 abort();
160 }
161 fwrite (Buffer, length, 1, out);
162 offset += length;
163 }
164
165 return filesize;
166}
167
168
169int
171 int argc,
172 char *argv[]
173 )
174/*++
175
176Routine Description:
177
178
179Arguments:
180
181
182Returns:
183
184
185--*/
186{
187 uint64_t i;
188 uint64_t filesize;
189 FILE *fpIn, *fpOut;
190 EFILDR_HEADER EfiLdrHeader;
191 EFILDR_IMAGE EfiLdrImage[MAX_PE_IMAGES];
192 char* OutputFileName = NULL;
193 char* InputFileNames[MAX_PE_IMAGES + 1];
194 char* InputName;
195 uint8_t InputFileCount = 0;
196 uint64_t DebugLevel = 0;
197 uint64_t VerboseLevel = 0;
198 int Status = 0;
199
200 if (argc == 1) {
201 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
202 return EXIT_FAILURE;
203 }
204
205 argc --;
206 argv ++;
207
208 if ((strcmp (argv[0], "-h") == 0) || (strcmp (argv[0], "--help") == 0)) {
209 Usage();
210 return EXIT_SUCCESS;
211 }
212
213 if (strcmp (argv[0], "--version") == 0) {
214 Version();
215 return EXIT_SUCCESS;
216 }
217
218 while (argc > 0) {
219
220 if ((strcmp (argv[0], "-o") == 0) || (strcmp (argv[0], "--output") == 0)) {
221 OutputFileName = argv[1];
222 if (OutputFileName == NULL) {
223 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
224 return EXIT_FAILURE;
225 }
226 argc -= 2;
227 argv += 2;
228 continue;
229 }
230
231 if ((strcmp (argv[0], "-q") == 0) || (strcmp (argv[0], "--quiet") == 0)) {
232 argc --;
233 argv ++;
234 continue;
235 }
236
237 if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (strcmp (argv[0], "--verbose") == 0)) {
238 VerboseLevel = 1;
239 if (strlen(argv[0]) > 2) {
240 Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);
241 if (Status != 0) {
242 Error (NULL, 0, 1003, "Invalid option value", "%s", argv[0]);
243 return EXIT_FAILURE;
244 }
245 }
246
247 argc --;
248 argv ++;
249 continue;
250 }
251
252 if ((strcmp (argv[0], "-d") == 0) || (strcmp (argv[0], "--debug") == 0)) {
253 DebugLevel = strtoull (argv[1], NULL, 0);
254 argc -= 2;
255 argv += 2;
256 continue;
257 }
258 //
259 // Don't recognize the parameter, should be regarded as the input file name.
260 //
261 InputFileNames[InputFileCount] = argv[0];
262 InputFileCount++;
263 argc--;
264 argv++;
265 }
266
267 if (InputFileCount == 0) {
268 Error (NULL, 0, 1001, "Missing option", "No input file");
269 return EXIT_FAILURE;
270 }
271 //
272 // Open output file for write
273 //
274 if (OutputFileName == NULL) {
275 Error (NULL, 0, 1001, "Missing option", "No output file");
276 return EXIT_FAILURE;
277 }
278
279 fpOut = fopen (OutputFileName, "w+b");
280 if (!fpOut) {
281 Error (NULL, 0, 0001, "Could not open output file", OutputFileName);
282 return EXIT_FAILURE;
283 }
284
285 memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader));
286 memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (InputFileCount));
287
288 memcpy (&EfiLdrHeader.Signature, "EFIL", 4);
289 EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(InputFileCount);
290
291 //
292 // Skip the file header first
293 //
294 fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET);
295
296 //
297 // copy all the input files to the output file
298 //
299 for(i=0;i<InputFileCount;i++) {
300 //
301 // Copy the content of PeImage file to output file
302 //
303 fpIn = fopen (InputFileNames[i], "rb");
304 if (!fpIn) {
305 Error (NULL, 0, 0001, "Could not open input file", InputFileNames[i]);
306 fclose (fpOut);
307 return EXIT_FAILURE;
308 }
309 filesize = FCopyFile (fpIn, fpOut);
310 fclose(fpIn);
311
312 //
313 // And in the same time update the EfiLdrHeader and EfiLdrImage array
314 //
315 EfiLdrImage[i].Offset = EfiLdrHeader.FileLength;
316 EfiLdrImage[i].Length = (uint32_t) filesize;
317 InputName = strrchr(InputFileNames[i], '/');
318 if (InputName == NULL) {
319 InputName = strrchr(InputFileNames[i], '\\');
320 if (InputName == NULL) {
321 InputName = InputFileNames[i];
322 } else {
323 ++InputName;
324 }
325 } else {
326 ++InputName;
327 }
328 strncpy ((char*) EfiLdrImage[i].FileName, InputName, sizeof (EfiLdrImage[i].FileName) - 1);
329 EfiLdrHeader.FileLength += (uint32_t) filesize;
330 EfiLdrHeader.NumberOfImages++;
331 }
332
333 //
334 // Write the image header to the output file finally
335 //
336 fseek (fpOut, 0, SEEK_SET);
337 fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER) , 1, fpOut);
338 fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(InputFileCount), 1, fpOut);
339
340 fclose (fpOut);
341 printf ("Created %s\n", OutputFileName);
342 return 0;
343}
344
UINT64 Length
#define UTILITY_MAJOR_VERSION
Definition EfiLdrImage.c:53
#define UTILITY_NAME
Definition EfiLdrImage.c:48
void Usage(void)
Definition EfiLdrImage.c:97
int CountVerboseLevel(const char *VerboseLevelString, const uint64_t Length, uint64_t *ReturnValue)
void Error(char *FileName, uint32_t LineNumber, uint32_t ErrorCode, char *OffendingText, char *MsgFmt,...)
Definition EfiLdrImage.c:57
uint64_t FCopyFile(FILE *in, FILE *out)
#define MAX_PE_IMAGES
Definition EfiLdrImage.c:27
void Version(void)
Definition EfiLdrImage.c:74
#define UTILITY_MINOR_VERSION
Definition EfiLdrImage.c:54
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
#define va_end
Definition Ubsan.h:99
#define va_list
Definition Ubsan.h:97
#define vprintf(f, v)
Definition Ubsan.h:206
#define va_start
Definition Ubsan.h:98
#define uint32_t
Definition Ubsan.h:59
int main()
Definition acdtinfo.c:181
#define memset(ptr, c, len)
UINT8 uint8_t
UINT32 uint32_t
UINT64 uint64_t
#define memcpy(Dst, Src, Size)
Definition lzvn.h:57
UINT32 NumberOfImages
uint32_t NumberOfImages
Definition EfiLdrImage.c:42
uint32_t HeaderCheckSum
Definition EfiLdrImage.c:40
uint32_t Signature
Definition EfiLdrImage.c:39
uint32_t FileLength
Definition EfiLdrImage.c:41
uint32_t CheckSum
Definition EfiLdrImage.c:32
uint32_t Length
Definition EfiLdrImage.c:34
uint32_t Offset
Definition EfiLdrImage.c:33