Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Relocate.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-jump-tables -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/Core/Init -resource-dir /opt/xgcc/lib/clang/17 -include PcdData.h -D COREBOOT32 -D RELEASE -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EDKII/BaseTools/Source/C/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include/x64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Runtime -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/../Runtime -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Runtime/../Init -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Runtime/. -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -Os -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/Core/Init -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-max-loop 10 -analyzer-output=plist-html -faddrsig -o /cb-build/coreboot_scanbuild.0/PURISM_LIBREM15_V4_STM-scanbuildtmp/2024-05-02-081243-2232343-1/report-rNrFW0.plist -x c /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Init/Relocate.c
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
22extern UINT64 GetMsegInfoFromTxt (
23 OUT UINT64 *MsegBase,
24 OUT UINT64 *MsegLength
25 );
26
27extern 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**/
43VOIDvoid
44PeCoffRelocateImageOnTheSpot (
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//
214extern UINT64 _ElfRelocTablesEnd, _ElfRelocTablesStart;
215
216static 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**/
280VOIDvoid
281RelocateStmImage (
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}