]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Ipf/PeCoffLoaderEx.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Pei / PeiLib / Ipf / PeCoffLoaderEx.c
1 /*++
2
3 Copyright (c) 2004 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeCoffLoaderEx.c
15
16 Abstract:
17
18 Fixes Intel Itanium(TM) specific relocation types
19
20
21 Revision History
22
23 --*/
24
25 #include "TianoCommon.h"
26 #include "EfiImage.h"
27
28 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
29 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
30
31 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
32 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
33 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
34
35 #define IMM64_IMM7B_INST_WORD_X 3
36 #define IMM64_IMM7B_SIZE_X 7
37 #define IMM64_IMM7B_INST_WORD_POS_X 4
38 #define IMM64_IMM7B_VAL_POS_X 0
39
40 #define IMM64_IMM9D_INST_WORD_X 3
41 #define IMM64_IMM9D_SIZE_X 9
42 #define IMM64_IMM9D_INST_WORD_POS_X 18
43 #define IMM64_IMM9D_VAL_POS_X 7
44
45 #define IMM64_IMM5C_INST_WORD_X 3
46 #define IMM64_IMM5C_SIZE_X 5
47 #define IMM64_IMM5C_INST_WORD_POS_X 13
48 #define IMM64_IMM5C_VAL_POS_X 16
49
50 #define IMM64_IC_INST_WORD_X 3
51 #define IMM64_IC_SIZE_X 1
52 #define IMM64_IC_INST_WORD_POS_X 12
53 #define IMM64_IC_VAL_POS_X 21
54
55 #define IMM64_IMM41a_INST_WORD_X 1
56 #define IMM64_IMM41a_SIZE_X 10
57 #define IMM64_IMM41a_INST_WORD_POS_X 14
58 #define IMM64_IMM41a_VAL_POS_X 22
59
60 #define IMM64_IMM41b_INST_WORD_X 1
61 #define IMM64_IMM41b_SIZE_X 8
62 #define IMM64_IMM41b_INST_WORD_POS_X 24
63 #define IMM64_IMM41b_VAL_POS_X 32
64
65 #define IMM64_IMM41c_INST_WORD_X 2
66 #define IMM64_IMM41c_SIZE_X 23
67 #define IMM64_IMM41c_INST_WORD_POS_X 0
68 #define IMM64_IMM41c_VAL_POS_X 40
69
70 #define IMM64_SIGN_INST_WORD_X 3
71 #define IMM64_SIGN_SIZE_X 1
72 #define IMM64_SIGN_INST_WORD_POS_X 27
73 #define IMM64_SIGN_VAL_POS_X 63
74
75 EFI_STATUS
76 PeCoffLoaderRelocateImageEx (
77 IN UINT16 *Reloc,
78 IN OUT CHAR8 *Fixup,
79 IN OUT CHAR8 **FixupData,
80 IN UINT64 Adjust
81 )
82 /*++
83
84 Routine Description:
85
86 Performs an Itanium-based specific relocation fixup
87
88 Arguments:
89
90 Reloc - Pointer to the relocation record
91
92 Fixup - Pointer to the address to fix up
93
94 FixupData - Pointer to a buffer to log the fixups
95
96 Adjust - The offset to adjust the fixup
97
98 Returns:
99
100 Status code
101
102 --*/
103 {
104 UINT64 *F64;
105 UINT64 FixupVal;
106
107 switch ((*Reloc) >> 12) {
108
109 case EFI_IMAGE_REL_BASED_IA64_IMM64:
110
111 //
112 // Align it to bundle address before fixing up the
113 // 64-bit immediate value of the movl instruction.
114 //
115
116 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
117 FixupVal = (UINT64)0;
118
119 //
120 // Extract the lower 32 bits of IMM64 from bundle
121 //
122 EXT_IMM64(FixupVal,
123 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
124 IMM64_IMM7B_SIZE_X,
125 IMM64_IMM7B_INST_WORD_POS_X,
126 IMM64_IMM7B_VAL_POS_X
127 );
128
129 EXT_IMM64(FixupVal,
130 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
131 IMM64_IMM9D_SIZE_X,
132 IMM64_IMM9D_INST_WORD_POS_X,
133 IMM64_IMM9D_VAL_POS_X
134 );
135
136 EXT_IMM64(FixupVal,
137 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
138 IMM64_IMM5C_SIZE_X,
139 IMM64_IMM5C_INST_WORD_POS_X,
140 IMM64_IMM5C_VAL_POS_X
141 );
142
143 EXT_IMM64(FixupVal,
144 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
145 IMM64_IC_SIZE_X,
146 IMM64_IC_INST_WORD_POS_X,
147 IMM64_IC_VAL_POS_X
148 );
149
150 EXT_IMM64(FixupVal,
151 (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
152 IMM64_IMM41a_SIZE_X,
153 IMM64_IMM41a_INST_WORD_POS_X,
154 IMM64_IMM41a_VAL_POS_X
155 );
156
157 //
158 // Update 64-bit address
159 //
160 FixupVal += Adjust;
161
162 //
163 // Insert IMM64 into bundle
164 //
165 INS_IMM64(FixupVal,
166 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
167 IMM64_IMM7B_SIZE_X,
168 IMM64_IMM7B_INST_WORD_POS_X,
169 IMM64_IMM7B_VAL_POS_X
170 );
171
172 INS_IMM64(FixupVal,
173 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
174 IMM64_IMM9D_SIZE_X,
175 IMM64_IMM9D_INST_WORD_POS_X,
176 IMM64_IMM9D_VAL_POS_X
177 );
178
179 INS_IMM64(FixupVal,
180 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
181 IMM64_IMM5C_SIZE_X,
182 IMM64_IMM5C_INST_WORD_POS_X,
183 IMM64_IMM5C_VAL_POS_X
184 );
185
186 INS_IMM64(FixupVal,
187 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
188 IMM64_IC_SIZE_X,
189 IMM64_IC_INST_WORD_POS_X,
190 IMM64_IC_VAL_POS_X
191 );
192
193 INS_IMM64(FixupVal,
194 ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
195 IMM64_IMM41a_SIZE_X,
196 IMM64_IMM41a_INST_WORD_POS_X,
197 IMM64_IMM41a_VAL_POS_X
198 );
199
200 INS_IMM64(FixupVal,
201 ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
202 IMM64_IMM41b_SIZE_X,
203 IMM64_IMM41b_INST_WORD_POS_X,
204 IMM64_IMM41b_VAL_POS_X
205 );
206
207 INS_IMM64(FixupVal,
208 ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
209 IMM64_IMM41c_SIZE_X,
210 IMM64_IMM41c_INST_WORD_POS_X,
211 IMM64_IMM41c_VAL_POS_X
212 );
213
214 INS_IMM64(FixupVal,
215 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
216 IMM64_SIGN_SIZE_X,
217 IMM64_SIGN_INST_WORD_POS_X,
218 IMM64_SIGN_VAL_POS_X
219 );
220
221 F64 = (UINT64 *) Fixup;
222 if (*FixupData != NULL) {
223 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
224 *(UINT64 *)(*FixupData) = *F64;
225 *FixupData = *FixupData + sizeof(UINT64);
226 }
227 break;
228
229 default:
230 return EFI_UNSUPPORTED;
231 }
232
233 return EFI_SUCCESS;
234 }
235
236 BOOLEAN
237 PeCoffLoaderImageFormatSupported (
238 IN UINT16 Machine
239 )
240 /*++
241 Routine Description:
242
243 Returns TRUE if the machine type of PE/COFF image is supported. Supported
244 does not mean the image can be executed it means the PE/COFF loader supports
245 loading and relocating of the image type. It's up to the caller to support
246 the entry point.
247
248 This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
249 images. Calling the entry point in a correct mannor is up to the
250 consumer of this library.
251
252 Arguments:
253
254 Machine - Machine type from the PE Header.
255
256 Returns:
257
258 TRUE - if this PE/COFF loader can load the image
259 FALSE - if this PE/COFF loader cannot load the image
260
261 --*/
262 {
263 if ((Machine == EFI_IMAGE_MACHINE_IA64) || (Machine == EFI_IMAGE_MACHINE_EBC)) {
264 return TRUE;
265 }
266
267 return FALSE;
268 }