#include <Common/UefiBaseTypes.h>\r
#include <IndustryStandard/PeImage.h>\r
#include "PeCoffLib.h"\r
+#include "CommonLib.h"\r
+\r
\r
#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
*Instruction = (*Instruction & ~0x70ff) | Patch;\r
}\r
\r
+/**\r
+ Pass in a pointer to an ARM MOVW/MOVT instruciton pair and \r
+ return the immediate data encoded in the two` instruction\r
+\r
+ @param Instructions Pointer to ARM MOVW/MOVT insturction pair\r
+\r
+ @return Immediate address encoded in the instructions\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+ThumbMovwMovtImmediateAddress (\r
+ IN UINT16 *Instructions\r
+ )\r
+{\r
+ UINT16 *Word;\r
+ UINT16 *Top;\r
+ \r
+ Word = Instructions; // MOVW\r
+ Top = Word + 2; // MOVT\r
+ \r
+ return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);\r
+}\r
+\r
+\r
+/**\r
+ Update an ARM MOVW/MOVT immediate instruction instruction pair.\r
+\r
+ @param Instructions Pointer to ARM MOVW/MOVT instruction pair\r
+ @param Address New addres to patch into the instructions\r
+**/\r
+VOID\r
+EFIAPI\r
+ThumbMovwMovtImmediatePatch (\r
+ IN OUT UINT16 *Instructions,\r
+ IN UINT32 Address\r
+ )\r
+{\r
+ UINT16 *Word;\r
+ UINT16 *Top;\r
+ \r
+ Word = (UINT16 *)Instructions; // MOVW\r
+ Top = Word + 2; // MOVT\r
+\r
+ ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));\r
+ ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));\r
+}\r
+\r
+\r
/**\r
Performs an ARM-based specific relocation fixup and is a no-op on other\r
instruction sets.\r
)\r
{\r
UINT16 *Fixup16;\r
- UINT16 FixupVal;\r
- UINT16 *Addend;\r
+ UINT32 FixupVal;\r
\r
- Fixup16 = (UINT16 *) Fixup;\r
+ Fixup16 = (UINT16 *) Fixup;\r
\r
switch ((**Reloc) >> 12) {\r
- case EFI_IMAGE_REL_BASED_ARM_THUMB_MOVW:\r
- FixupVal = ThumbMovtImmediateAddress (Fixup16) + (UINT16)Adjust;\r
- ThumbMovtImmediatePatch (Fixup16, FixupVal);\r
-\r
- if (*FixupData != NULL) {\r
- *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT16));\r
- *(UINT16 *)*FixupData = *Fixup16;\r
- *FixupData = *FixupData + sizeof (UINT16);\r
- }\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_ARM_THUMB_MOVT:\r
- // For MOVT you need to know the lower 16-bits do do the math\r
- // So this relocation entry is really two entries.\r
- *Reloc = *Reloc + 1;\r
- Addend = *Reloc; \r
- FixupVal = (UINT16)(((ThumbMovtImmediateAddress (Fixup16) << 16) + Adjust + *Addend) >> 16);\r
- ThumbMovtImmediatePatch (Fixup16, FixupVal);\r
-\r
+ \r
+ case EFI_IMAGE_REL_BASED_ARM_MOV32T:\r
+ FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;\r
+ ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);\r
+ \r
+ \r
if (*FixupData != NULL) {\r
- *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT16));\r
- *(UINT16 *)*FixupData = *Fixup16;\r
- *FixupData = *FixupData + sizeof (UINT16);\r
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
+ *(UINT64 *)(*FixupData) = *Fixup16;\r
+ CopyMem (*FixupData, Fixup16, sizeof (UINT64));\r
}\r
break;\r
\r
+ case EFI_IMAGE_REL_BASED_ARM_MOV32A:\r
+ // break omitted - ARM instruction encoding not implemented\r
default:\r
return RETURN_UNSUPPORTED;\r
}\r