File: | home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Relocate.c |
Warning: | line 229, column 16 Value stored to 'reloc_table' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /** @file |
2 | STM relocation |
3 | |
4 | Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> |
5 | This program and the accompanying materials |
6 | are licensed and made available under the terms and conditions of the BSD License |
7 | which accompanies this distribution. The full text of the license may be found at |
8 | http://opensource.org/licenses/bsd-license.php. |
9 | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. |
12 | |
13 | **/ |
14 | |
15 | #include "StmInit.h" |
16 | #include <IndustryStandard/PeImage.h> |
17 | |
18 | #include <elf.h> |
19 | |
20 | //#define PRINTRELOC |
21 | |
22 | extern UINT64 GetMsegInfoFromTxt ( |
23 | OUT UINT64 *MsegBase, |
24 | OUT UINT64 *MsegLength |
25 | ); |
26 | |
27 | extern UINT64 GetMsegInfoFromMsr ( |
28 | OUT UINT64 *MsegBase, |
29 | OUT UINT64 *MsegLength |
30 | ); |
31 | |
32 | /** |
33 | |
34 | This function relocate image at ImageBase. |
35 | |
36 | @param ImageBase Image base |
37 | @param PeImageBase Image base field in PE/COFF header |
38 | @param IsTeardown If the relocation is for teardown. |
39 | FALSE means relocation for setup. |
40 | TRUE means relocation for teardown. |
41 | |
42 | **/ |
43 | VOIDvoid |
44 | PeCoffRelocateImageOnTheSpot ( |
45 | IN UINTN ImageBase, |
46 | IN UINTN PeImageBase, |
47 | IN BOOLEAN IsTeardown |
48 | ) |
49 | { |
50 | EFI_IMAGE_DOS_HEADER *DosHdr; |
51 | EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; |
52 | UINT32 NumberOfRvaAndSizes; |
53 | EFI_IMAGE_DATA_DIRECTORY *DataDirectory; |
54 | EFI_IMAGE_DATA_DIRECTORY *RelocDir; |
55 | EFI_IMAGE_BASE_RELOCATION *RelocBase; |
56 | EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; |
57 | UINT16 *Reloc; |
58 | UINT16 *RelocEnd; |
59 | CHAR8 *Fixup; |
60 | CHAR8 *FixupBase; |
61 | UINT16 *Fixup16; |
62 | UINT32 *Fixup32; |
63 | UINT64 *Fixup64; |
64 | UINTN Adjust; |
65 | UINT16 Magic; |
66 | |
67 | if (!IsTeardown) { |
68 | Adjust = ImageBase - PeImageBase; |
69 | } else { |
70 | Adjust = PeImageBase - ImageBase; |
71 | } |
72 | |
73 | // |
74 | // Find the image's relocate dir info |
75 | // |
76 | DosHdr = (EFI_IMAGE_DOS_HEADER *)ImageBase; |
77 | if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE(('M') | ('Z' << 8))) { |
78 | // |
79 | // Valid DOS header so get address of PE header |
80 | // |
81 | Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(((CHAR8 *)DosHdr) + DosHdr->e_lfanew); |
82 | } else { |
83 | // |
84 | // No Dos header so assume image starts with PE header. |
85 | // |
86 | Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)ImageBase; |
87 | } |
88 | |
89 | if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE((('P') | ('E' << 8)) | ((('\0') | ('\0' << 8)) << 16))) { |
90 | // |
91 | // Not a valid PE image so Exit |
92 | // |
93 | return ; |
94 | } |
95 | |
96 | Magic = Hdr.Pe32->OptionalHeader.Magic; |
97 | |
98 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC0x10b) { |
99 | // |
100 | // Use PE32 offset |
101 | // |
102 | NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; |
103 | DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[0]); |
104 | } else { |
105 | // |
106 | // Use PE32+ offset |
107 | // |
108 | NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; |
109 | DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[0]); |
110 | } |
111 | |
112 | // |
113 | // Find the relocation block |
114 | // |
115 | // Per the PE/COFF spec, you can't assume that a given data directory |
116 | // is present in the image. You have to check the NumberOfRvaAndSizes in |
117 | // the optional header to verify a desired directory entry is there. |
118 | // |
119 | if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC5) { |
120 | RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC5; |
121 | RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress); |
122 | RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress + RelocDir->Size); |
123 | } else { |
124 | // |
125 | // Cannot find relocations, good just return. |
126 | // |
127 | return ; |
128 | } |
129 | |
130 | // |
131 | // ASSERT for the invalid image when RelocBase and RelocBaseEnd are both NULL. |
132 | // |
133 | ASSERT (RelocBase != NULL && RelocBaseEnd != NULL)do { if (DebugAssertEnabled ()) { if (!(RelocBase != ((void * ) 0) && RelocBaseEnd != ((void *) 0))) { DebugAssert ( "/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Relocate.c" , 133, "RelocBase != ((void *) 0) && RelocBaseEnd != ((void *) 0)" ); } } } while (((BOOLEAN)(0==1))); |
134 | |
135 | // |
136 | // Run the whole relocation block. And re-fixup data that has not been |
137 | // modified. The FixupData is used to see if the image has been modified |
138 | // since it was relocated. This is so data sections that have been updated |
139 | // by code will not be fixed up, since that would set them back to |
140 | // defaults. |
141 | // |
142 | while (RelocBase < RelocBaseEnd) { |
143 | |
144 | Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); |
145 | RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock); |
146 | FixupBase = (CHAR8 *) ((UINTN)ImageBase) + RelocBase->VirtualAddress; |
147 | |
148 | // |
149 | // Run this relocation record |
150 | // |
151 | while (Reloc < RelocEnd) { |
152 | |
153 | Fixup = FixupBase + (*Reloc & 0xFFF); |
154 | switch ((*Reloc) >> 12) { |
155 | |
156 | case EFI_IMAGE_REL_BASED_ABSOLUTE0: |
157 | break; |
158 | |
159 | case EFI_IMAGE_REL_BASED_HIGH1: |
160 | Fixup16 = (UINT16 *) Fixup; |
161 | *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16))); |
162 | break; |
163 | |
164 | case EFI_IMAGE_REL_BASED_LOW2: |
165 | Fixup16 = (UINT16 *) Fixup; |
166 | *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) Adjust & 0xffff)); |
167 | break; |
168 | |
169 | case EFI_IMAGE_REL_BASED_HIGHLOW3: |
170 | Fixup32 = (UINT32 *) Fixup; |
171 | *Fixup32 = *Fixup32 + (UINT32) Adjust; |
172 | break; |
173 | |
174 | case EFI_IMAGE_REL_BASED_DIR6410: |
175 | Fixup64 = (UINT64 *) Fixup; |
176 | *Fixup64 = *Fixup64 + (UINT64)Adjust; |
177 | break; |
178 | |
179 | case EFI_IMAGE_REL_BASED_HIGHADJ4: |
180 | // |
181 | // Not valid Relocation type for UEFI image, ASSERT |
182 | // |
183 | ASSERT (FALSE)do { if (DebugAssertEnabled ()) { if (!(((BOOLEAN)(0==1)))) { DebugAssert ("/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Relocate.c" , 183, "((BOOLEAN)(0==1))"); } } } while (((BOOLEAN)(0==1))); |
184 | break; |
185 | |
186 | default: |
187 | // |
188 | // Only Itanium requires ConvertPeImage_Ex |
189 | // |
190 | ASSERT (FALSE)do { if (DebugAssertEnabled ()) { if (!(((BOOLEAN)(0==1)))) { DebugAssert ("/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Relocate.c" , 190, "((BOOLEAN)(0==1))"); } } } while (((BOOLEAN)(0==1))); |
191 | break; |
192 | } |
193 | // |
194 | // Next relocation record |
195 | // |
196 | Reloc += 1; |
197 | } |
198 | // |
199 | // next reloc block |
200 | // |
201 | RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; |
202 | } |
203 | } |
204 | |
205 | // elf_process_reloc_table - a very simple relocation processor |
206 | // |
207 | // it does only X64 relative relocations -- others are flagged |
208 | // |
209 | // Parameters: |
210 | // UINT64 BaseLocation - location of module im memory, in this case start of MSEG |
211 | // UINT64 RelativeLocation - for setup - location of module in memory |
212 | // for teardown - 0 - to reset values to make sinit happy |
213 | // |
214 | extern UINT64 _ElfRelocTablesEnd, _ElfRelocTablesStart; |
215 | |
216 | static int elf_process_reloc_table(UINT64 BaseLocation, UINT64 RelativeLocation ) { |
217 | int size; |
218 | int idx; |
219 | Elf64_Rela * reloc_table = (Elf64_Rela *) ((UINT64)&_ElfRelocTablesStart); |
220 | |
221 | // The following conditional is necessary because of differences in compler behaviors |
222 | // in handling the "&" |
223 | // Depending on the compiler and in some instances the version the "&" can be |
224 | // interpeted either as a LEA or as a relative address (where a base address has |
225 | // to be added) |
226 | |
227 | if((((UINT64) reloc_table) & BaseLocation) == 0) |
228 | { |
229 | Elf64_Rela * reloc_table = (Elf64_Rela *) ((UINT64)&_ElfRelocTablesStart + (UINT64)BaseLocation); |
Value stored to 'reloc_table' during its initialization is never read | |
230 | } |
231 | |
232 | DEBUG((EFI_D_INFO, "ELF Relocation in progress Base %x Reloc tables %x\n", BaseLocation, &_ElfRelocTablesStart))do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "ELF Relocation in progress Base %x Reloc tables %x\n" , BaseLocation, &_ElfRelocTablesStart); } } while (((BOOLEAN )(0==1))); |
233 | |
234 | size = (UINT64)((UINT64)&_ElfRelocTablesEnd - (UINT64)&_ElfRelocTablesStart)/ sizeof(Elf64_Rela); |
235 | DEBUG((EFI_D_INFO, "%d locations to be relocated\n", size))do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "%d locations to be relocated\n" , size); } } while (((BOOLEAN)(0==1))); |
236 | |
237 | for(idx = 0; idx < size; idx++) |
238 | { |
239 | |
240 | if(ELF64_R_TYPE(reloc_table[idx].r_info)((reloc_table[idx].r_info) & 0xffffffff) != R_X86_64_RELATIVE8) |
241 | { |
242 | DEBUG((EFI_D_INFO, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
243 | idx,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
244 | &reloc_table[idx],do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
245 | reloc_table[idx].r_offset,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
246 | reloc_table[idx].r_addend,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
247 | ELF64_R_TYPE(reloc_table[idx].r_info)do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))) |
248 | ))do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) WARNING only X86_64 relative relocations done - Loc %x r_offset %x r_addend %x Type %d\n" , idx, &reloc_table[idx], reloc_table[idx].r_offset, reloc_table [idx].r_addend, ((reloc_table[idx].r_info) & 0xffffffff) ) ; } } while (((BOOLEAN)(0==1))); |
249 | } |
250 | else |
251 | { |
252 | UINT64 * OFFSET = (UINT64*) (reloc_table[idx].r_offset + BaseLocation); |
253 | *OFFSET = reloc_table[idx].r_addend + RelativeLocation; |
254 | |
255 | #ifdef PRINTRELOC |
256 | DEBUG((EFI_D_INFO, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n",do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))) |
257 | idx,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))) |
258 | reloc_table[idx].r_offset,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))) |
259 | reloc_table[idx].r_addend,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))) |
260 | OFFSET,do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))) |
261 | *OFFSET))do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "(%d) Relocation r_offset %x r_addend %x OFFSET %x *OFFSET %x Type %d\n" , idx, reloc_table[idx].r_offset, reloc_table[idx].r_addend, OFFSET , *OFFSET); } } while (((BOOLEAN)(0==1))); |
262 | #endif |
263 | } |
264 | |
265 | } |
266 | DEBUG((EFI_D_INFO, "ELF Relocation done\n"))do { if (DebugPrintEnabled ()) { DebugPrint (0x00000040, "ELF Relocation done\n" ); } } while (((BOOLEAN)(0==1))); |
267 | |
268 | return 0; |
269 | } |
270 | |
271 | /** |
272 | |
273 | This function relocate this STM image. |
274 | |
275 | @param IsTeardown If the relocation is for teardown. |
276 | FALSE means relocation for setup. |
277 | TRUE means relocation for teardown. |
278 | |
279 | **/ |
280 | VOIDvoid |
281 | RelocateStmImage ( |
282 | IN BOOLEAN IsTeardown |
283 | ) |
284 | { |
285 | UINT64 StmImage; |
286 | UINT64 MsegLength; |
287 | UINT64 ImageBase; |
288 | UINT64 PeImageBase; |
289 | EFI_IMAGE_DOS_HEADER *DosHdr; |
290 | EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; |
291 | UINT16 Magic; |
292 | |
293 | //StmImage = (UINT64)((UINT32)AsmReadMsr64(IA32_SMM_MONITOR_CTL_MSR_INDEX) & 0xFFFFF000); |
294 | |
295 | if (IsSentryEnabled()) { |
296 | GetMsegInfoFromTxt (&StmImage, &MsegLength); |
297 | } else { |
298 | GetMsegInfoFromMsr (&StmImage, &MsegLength); |
299 | } |
300 | |
301 | ImageBase = StmImage + STM_CODE_OFFSET0x1000 + 0x1000; |
302 | |
303 | // |
304 | // Find the image's relocate dir info |
305 | // |
306 | DosHdr = (EFI_IMAGE_DOS_HEADER *)ImageBase; |
307 | if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE(('M') | ('Z' << 8))) { |
308 | // |
309 | // Valid DOS header so get address of PE header |
310 | // |
311 | Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(((CHAR8 *)DosHdr) + DosHdr->e_lfanew); |
312 | } else { |
313 | // |
314 | // No Dos header so assume image starts with PE header. |
315 | // |
316 | Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)ImageBase; |
317 | } |
318 | |
319 | if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE((('P') | ('E' << 8)) | ((('\0') | ('\0' << 8)) << 16))) { |
320 | // |
321 | // Not a valid PE image so Exit |
322 | // |
323 | elf_process_reloc_table(StmImage, StmImage ); |
324 | return ; |
325 | } |
326 | |
327 | Magic = Hdr.Pe32->OptionalHeader.Magic; |
328 | |
329 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC0x10b) { |
330 | // |
331 | // Use PE32 offset |
332 | // |
333 | PeImageBase = (UINTN)Hdr.Pe32->OptionalHeader.ImageBase; |
334 | } else { |
335 | // |
336 | // Use PE32+ offset |
337 | // |
338 | PeImageBase = (UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase; |
339 | } |
340 | |
341 | // |
342 | // Basic Check |
343 | // |
344 | if (!IsTeardown) { |
345 | if (PeImageBase == ImageBase) { |
346 | // |
347 | // Relocated |
348 | // |
349 | CpuDeadLoop (); |
350 | return ; |
351 | } |
352 | if (PeImageBase != 0) { |
353 | // |
354 | // Build tool need gurantee it is 0-base address. |
355 | // |
356 | CpuDeadLoop (); |
357 | } |
358 | } else { |
359 | if (PeImageBase == 0) { |
360 | // |
361 | // Already Relocated back |
362 | // |
363 | CpuDeadLoop (); |
364 | return ; |
365 | } |
366 | // |
367 | // relocated back |
368 | // |
369 | PeImageBase = 0; |
370 | } |
371 | |
372 | // |
373 | // This is self-contain PE-COFF loader. |
374 | // |
375 | PeCoffRelocateImageOnTheSpot (ImageBase, PeImageBase, IsTeardown); |
376 | |
377 | AsmWbinvd (); |
378 | |
379 | // |
380 | // Set value indicate we have already relocated |
381 | // |
382 | if (!IsTeardown) { |
383 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC0x10b) { |
384 | // |
385 | // Use PE32 offset |
386 | // |
387 | Hdr.Pe32->OptionalHeader.ImageBase = (UINT32)ImageBase; |
388 | } else { |
389 | // |
390 | // Use PE32+ offset |
391 | // |
392 | Hdr.Pe32Plus->OptionalHeader.ImageBase = (UINT64)ImageBase; |
393 | } |
394 | } else { |
395 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC0x10b) { |
396 | // |
397 | // Use PE32 offset |
398 | // |
399 | Hdr.Pe32->OptionalHeader.ImageBase = (UINT32)0; |
400 | } else { |
401 | // |
402 | // Use PE32+ offset |
403 | // |
404 | Hdr.Pe32Plus->OptionalHeader.ImageBase = (UINT64)0; |
405 | } |
406 | } |
407 | |
408 | return ; |
409 | } |