]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
1. UINTN & INTN issue for EBC architecture:
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / Ipf / PeCoffLoaderEx.c
CommitLineData
878ddf1f 1/** @file\r
2 Fixes Intel Itanium(TM) specific relocation types.\r
3\r
4 Copyright (c) 2006, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 Module Name: PeCoffLoaderEx.c\r
14\r
15**/\r
16\r
17\r
18\r
19\r
20\r
21#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
22 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
23\r
24#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \\r
25 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \\r
26 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)\r
27\r
28#define IMM64_IMM7B_INST_WORD_X 3 \r
29#define IMM64_IMM7B_SIZE_X 7 \r
30#define IMM64_IMM7B_INST_WORD_POS_X 4 \r
31#define IMM64_IMM7B_VAL_POS_X 0 \r
32\r
33#define IMM64_IMM9D_INST_WORD_X 3 \r
34#define IMM64_IMM9D_SIZE_X 9 \r
35#define IMM64_IMM9D_INST_WORD_POS_X 18 \r
36#define IMM64_IMM9D_VAL_POS_X 7 \r
37\r
38#define IMM64_IMM5C_INST_WORD_X 3 \r
39#define IMM64_IMM5C_SIZE_X 5 \r
40#define IMM64_IMM5C_INST_WORD_POS_X 13 \r
41#define IMM64_IMM5C_VAL_POS_X 16 \r
42\r
43#define IMM64_IC_INST_WORD_X 3 \r
44#define IMM64_IC_SIZE_X 1 \r
45#define IMM64_IC_INST_WORD_POS_X 12 \r
46#define IMM64_IC_VAL_POS_X 21 \r
47\r
48#define IMM64_IMM41a_INST_WORD_X 1 \r
49#define IMM64_IMM41a_SIZE_X 10 \r
50#define IMM64_IMM41a_INST_WORD_POS_X 14 \r
51#define IMM64_IMM41a_VAL_POS_X 22 \r
52\r
53#define IMM64_IMM41b_INST_WORD_X 1 \r
54#define IMM64_IMM41b_SIZE_X 8 \r
55#define IMM64_IMM41b_INST_WORD_POS_X 24 \r
56#define IMM64_IMM41b_VAL_POS_X 32 \r
57\r
58#define IMM64_IMM41c_INST_WORD_X 2 \r
59#define IMM64_IMM41c_SIZE_X 23 \r
60#define IMM64_IMM41c_INST_WORD_POS_X 0 \r
61#define IMM64_IMM41c_VAL_POS_X 40 \r
62\r
63#define IMM64_SIGN_INST_WORD_X 3 \r
64#define IMM64_SIGN_SIZE_X 1 \r
65#define IMM64_SIGN_INST_WORD_POS_X 27 \r
66#define IMM64_SIGN_VAL_POS_X 63 \r
67\r
68/**\r
69 Performs an Itanium-based specific relocation fixup.\r
70\r
4ba61e5e 71 @param Reloc Pointer to the relocation record.\r
72 @param Fixup Pointer to the address to fix up.\r
73 @param FixupData Pointer to a buffer to log the fixups.\r
74 @param Adjust The offset to adjust the fixup.\r
878ddf1f 75\r
76 @return Status code.\r
77\r
78**/\r
79RETURN_STATUS\r
80PeCoffLoaderRelocateImageEx (\r
81 IN UINT16 *Reloc,\r
82 IN OUT CHAR8 *Fixup, \r
83 IN OUT CHAR8 **FixupData,\r
84 IN UINT64 Adjust\r
85 )\r
86{\r
87 UINT64 *F64;\r
88 UINT64 FixupVal;\r
89\r
90 switch ((*Reloc) >> 12) {\r
91\r
92 case EFI_IMAGE_REL_BASED_DIR64:\r
93 F64 = (UINT64 *) Fixup;\r
94 *F64 = *F64 + (UINT64) Adjust;\r
95 if (*FixupData != NULL) {\r
96 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
97 *(UINT64 *)(*FixupData) = *F64;\r
98 *FixupData = *FixupData + sizeof(UINT64);\r
99 }\r
100 break;\r
101\r
102 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
103\r
104 //\r
105 // Align it to bundle address before fixing up the\r
106 // 64-bit immediate value of the movl instruction.\r
107 //\r
108\r
109 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));\r
110 FixupVal = (UINT64)0;\r
111 \r
112 // \r
113 // Extract the lower 32 bits of IMM64 from bundle\r
114 //\r
115 EXT_IMM64(FixupVal,\r
116 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,\r
117 IMM64_IMM7B_SIZE_X,\r
118 IMM64_IMM7B_INST_WORD_POS_X,\r
119 IMM64_IMM7B_VAL_POS_X\r
120 );\r
121\r
122 EXT_IMM64(FixupVal,\r
123 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,\r
124 IMM64_IMM9D_SIZE_X,\r
125 IMM64_IMM9D_INST_WORD_POS_X,\r
126 IMM64_IMM9D_VAL_POS_X\r
127 );\r
128\r
129 EXT_IMM64(FixupVal,\r
130 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,\r
131 IMM64_IMM5C_SIZE_X,\r
132 IMM64_IMM5C_INST_WORD_POS_X,\r
133 IMM64_IMM5C_VAL_POS_X\r
134 );\r
135\r
136 EXT_IMM64(FixupVal,\r
137 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,\r
138 IMM64_IC_SIZE_X,\r
139 IMM64_IC_INST_WORD_POS_X,\r
140 IMM64_IC_VAL_POS_X\r
141 );\r
142\r
143 EXT_IMM64(FixupVal,\r
144 (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,\r
145 IMM64_IMM41a_SIZE_X,\r
146 IMM64_IMM41a_INST_WORD_POS_X,\r
147 IMM64_IMM41a_VAL_POS_X\r
148 );\r
149 \r
150 // \r
151 // Update 64-bit address\r
152 //\r
153 FixupVal += Adjust;\r
154\r
155 // \r
156 // Insert IMM64 into bundle\r
157 //\r
158 INS_IMM64(FixupVal,\r
159 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),\r
160 IMM64_IMM7B_SIZE_X,\r
161 IMM64_IMM7B_INST_WORD_POS_X,\r
162 IMM64_IMM7B_VAL_POS_X\r
163 );\r
164\r
165 INS_IMM64(FixupVal,\r
166 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),\r
167 IMM64_IMM9D_SIZE_X,\r
168 IMM64_IMM9D_INST_WORD_POS_X,\r
169 IMM64_IMM9D_VAL_POS_X\r
170 );\r
171\r
172 INS_IMM64(FixupVal,\r
173 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),\r
174 IMM64_IMM5C_SIZE_X,\r
175 IMM64_IMM5C_INST_WORD_POS_X,\r
176 IMM64_IMM5C_VAL_POS_X\r
177 );\r
178\r
179 INS_IMM64(FixupVal,\r
180 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),\r
181 IMM64_IC_SIZE_X,\r
182 IMM64_IC_INST_WORD_POS_X,\r
183 IMM64_IC_VAL_POS_X\r
184 );\r
185\r
186 INS_IMM64(FixupVal,\r
187 ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),\r
188 IMM64_IMM41a_SIZE_X,\r
189 IMM64_IMM41a_INST_WORD_POS_X,\r
190 IMM64_IMM41a_VAL_POS_X\r
191 );\r
192\r
193 INS_IMM64(FixupVal,\r
194 ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),\r
195 IMM64_IMM41b_SIZE_X,\r
196 IMM64_IMM41b_INST_WORD_POS_X,\r
197 IMM64_IMM41b_VAL_POS_X\r
198 );\r
199\r
200 INS_IMM64(FixupVal,\r
201 ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),\r
202 IMM64_IMM41c_SIZE_X,\r
203 IMM64_IMM41c_INST_WORD_POS_X,\r
204 IMM64_IMM41c_VAL_POS_X\r
205 );\r
206\r
207 INS_IMM64(FixupVal,\r
208 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),\r
209 IMM64_SIGN_SIZE_X,\r
210 IMM64_SIGN_INST_WORD_POS_X,\r
211 IMM64_SIGN_VAL_POS_X\r
212 );\r
213\r
214 F64 = (UINT64 *) Fixup;\r
215 if (*FixupData != NULL) {\r
216 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
217 *(UINT64 *)(*FixupData) = *F64;\r
218 *FixupData = *FixupData + sizeof(UINT64);\r
219 }\r
220 break;\r
221\r
222 default:\r
223 return RETURN_UNSUPPORTED;\r
224 }\r
225\r
226 return RETURN_SUCCESS;\r
227}\r