]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c
1. Removed the unnecessary #include statements and include files
[mirror_edk2.git] / Tools / Source / TianoTools / PeCoffLoader / Ipf / PeCoffLoaderEx.c
1 /*++
2
3 Copyright (c) 2004, 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 <Common/UefiBaseTypes.h>
26 #include <Common/EfiImage.h>
27 #include <Library/PeCoffLib.h>
28
29
30
31
32
33 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
34 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
35
36 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
37 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
38 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
39
40 #define IMM64_IMM7B_INST_WORD_X 3
41 #define IMM64_IMM7B_SIZE_X 7
42 #define IMM64_IMM7B_INST_WORD_POS_X 4
43 #define IMM64_IMM7B_VAL_POS_X 0
44
45 #define IMM64_IMM9D_INST_WORD_X 3
46 #define IMM64_IMM9D_SIZE_X 9
47 #define IMM64_IMM9D_INST_WORD_POS_X 18
48 #define IMM64_IMM9D_VAL_POS_X 7
49
50 #define IMM64_IMM5C_INST_WORD_X 3
51 #define IMM64_IMM5C_SIZE_X 5
52 #define IMM64_IMM5C_INST_WORD_POS_X 13
53 #define IMM64_IMM5C_VAL_POS_X 16
54
55 #define IMM64_IC_INST_WORD_X 3
56 #define IMM64_IC_SIZE_X 1
57 #define IMM64_IC_INST_WORD_POS_X 12
58 #define IMM64_IC_VAL_POS_X 21
59
60 #define IMM64_IMM41a_INST_WORD_X 1
61 #define IMM64_IMM41a_SIZE_X 10
62 #define IMM64_IMM41a_INST_WORD_POS_X 14
63 #define IMM64_IMM41a_VAL_POS_X 22
64
65 #define IMM64_IMM41b_INST_WORD_X 1
66 #define IMM64_IMM41b_SIZE_X 8
67 #define IMM64_IMM41b_INST_WORD_POS_X 24
68 #define IMM64_IMM41b_VAL_POS_X 32
69
70 #define IMM64_IMM41c_INST_WORD_X 2
71 #define IMM64_IMM41c_SIZE_X 23
72 #define IMM64_IMM41c_INST_WORD_POS_X 0
73 #define IMM64_IMM41c_VAL_POS_X 40
74
75 #define IMM64_SIGN_INST_WORD_X 3
76 #define IMM64_SIGN_SIZE_X 1
77 #define IMM64_SIGN_INST_WORD_POS_X 27
78 #define IMM64_SIGN_VAL_POS_X 63
79
80 RETURN_STATUS
81 PeCoffLoaderRelocateImageEx (
82 IN UINT16 *Reloc,
83 IN OUT CHAR8 *Fixup,
84 IN OUT CHAR8 **FixupData,
85 IN UINT64 Adjust
86 )
87 /*++
88
89 Routine Description:
90
91 Performs an Itanium-based specific relocation fixup
92
93 Arguments:
94
95 Reloc - Pointer to the relocation record
96
97 Fixup - Pointer to the address to fix up
98
99 FixupData - Pointer to a buffer to log the fixups
100
101 Adjust - The offset to adjust the fixup
102
103 Returns:
104
105 Status code
106
107 --*/
108 {
109 UINT64 *F64;
110 UINT64 FixupVal;
111
112 switch ((*Reloc) >> 12) {
113
114 case EFI_IMAGE_REL_BASED_DIR64:
115 F64 = (UINT64 *) Fixup;
116 *F64 = *F64 + (UINT64) Adjust;
117 if (*FixupData != NULL) {
118 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
119 *(UINT64 *)(*FixupData) = *F64;
120 *FixupData = *FixupData + sizeof(UINT64);
121 }
122 break;
123
124 case EFI_IMAGE_REL_BASED_IA64_IMM64:
125
126 //
127 // Align it to bundle address before fixing up the
128 // 64-bit immediate value of the movl instruction.
129 //
130
131 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
132 FixupVal = (UINT64)0;
133
134 //
135 // Extract the lower 32 bits of IMM64 from bundle
136 //
137 EXT_IMM64(FixupVal,
138 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
139 IMM64_IMM7B_SIZE_X,
140 IMM64_IMM7B_INST_WORD_POS_X,
141 IMM64_IMM7B_VAL_POS_X
142 );
143
144 EXT_IMM64(FixupVal,
145 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
146 IMM64_IMM9D_SIZE_X,
147 IMM64_IMM9D_INST_WORD_POS_X,
148 IMM64_IMM9D_VAL_POS_X
149 );
150
151 EXT_IMM64(FixupVal,
152 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
153 IMM64_IMM5C_SIZE_X,
154 IMM64_IMM5C_INST_WORD_POS_X,
155 IMM64_IMM5C_VAL_POS_X
156 );
157
158 EXT_IMM64(FixupVal,
159 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
160 IMM64_IC_SIZE_X,
161 IMM64_IC_INST_WORD_POS_X,
162 IMM64_IC_VAL_POS_X
163 );
164
165 EXT_IMM64(FixupVal,
166 (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
167 IMM64_IMM41a_SIZE_X,
168 IMM64_IMM41a_INST_WORD_POS_X,
169 IMM64_IMM41a_VAL_POS_X
170 );
171
172 //
173 // Update 64-bit address
174 //
175 FixupVal += Adjust;
176
177 //
178 // Insert IMM64 into bundle
179 //
180 INS_IMM64(FixupVal,
181 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
182 IMM64_IMM7B_SIZE_X,
183 IMM64_IMM7B_INST_WORD_POS_X,
184 IMM64_IMM7B_VAL_POS_X
185 );
186
187 INS_IMM64(FixupVal,
188 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
189 IMM64_IMM9D_SIZE_X,
190 IMM64_IMM9D_INST_WORD_POS_X,
191 IMM64_IMM9D_VAL_POS_X
192 );
193
194 INS_IMM64(FixupVal,
195 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
196 IMM64_IMM5C_SIZE_X,
197 IMM64_IMM5C_INST_WORD_POS_X,
198 IMM64_IMM5C_VAL_POS_X
199 );
200
201 INS_IMM64(FixupVal,
202 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
203 IMM64_IC_SIZE_X,
204 IMM64_IC_INST_WORD_POS_X,
205 IMM64_IC_VAL_POS_X
206 );
207
208 INS_IMM64(FixupVal,
209 ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
210 IMM64_IMM41a_SIZE_X,
211 IMM64_IMM41a_INST_WORD_POS_X,
212 IMM64_IMM41a_VAL_POS_X
213 );
214
215 INS_IMM64(FixupVal,
216 ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
217 IMM64_IMM41b_SIZE_X,
218 IMM64_IMM41b_INST_WORD_POS_X,
219 IMM64_IMM41b_VAL_POS_X
220 );
221
222 INS_IMM64(FixupVal,
223 ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
224 IMM64_IMM41c_SIZE_X,
225 IMM64_IMM41c_INST_WORD_POS_X,
226 IMM64_IMM41c_VAL_POS_X
227 );
228
229 INS_IMM64(FixupVal,
230 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
231 IMM64_SIGN_SIZE_X,
232 IMM64_SIGN_INST_WORD_POS_X,
233 IMM64_SIGN_VAL_POS_X
234 );
235
236 F64 = (UINT64 *) Fixup;
237 if (*FixupData != NULL) {
238 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
239 *(UINT64 *)(*FixupData) = *F64;
240 *FixupData = *FixupData + sizeof(UINT64);
241 }
242 break;
243
244 default:
245 return RETURN_UNSUPPORTED;
246 }
247
248 return RETURN_SUCCESS;
249 }