[edk2,3/6] MdePkg/BasePeCoffLib: account for carry in high/low relocation pairs

Message ID 1435916407-29683-4-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel July 3, 2015, 9:40 a.m.
Relocations of types EFI_IMAGE_REL_BASED_HIGH and EFI_IMAGE_REL_BASED_LOW
occur in pairs, where each of the pair relocates a 16-bit word half of a
32-bit dword.

Since the target of the relocation arithmetic is a 32-bit quantity,
we should handle a carry that may occur in the low word relocation,
by taking the carry into account when relocating the high word.

Since we know the relocation pair refers to a single value, we can
simply perform the addition for the entire value when handling the high
relocation, and truncate the result to 16-bits.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index 33cad23a014e..28c84062d125 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -1103,7 +1103,8 @@  PeCoffLoaderRelocateImage (
 
         case EFI_IMAGE_REL_BASED_HIGH:
           Fixup16   = (UINT16 *) Fixup;
-          *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
+          Fixup32   = (UINT32 *) (Fixup16 - 1);
+          *Fixup16  = (UINT16) ((*Fixup32 + (UINT32) Adjust) >> 16);
           if (FixupData != NULL) {
             *(UINT16 *) FixupData = *Fixup16;
             FixupData             = FixupData + sizeof (UINT16);
@@ -1828,8 +1829,9 @@  PeCoffLoaderRelocateImageForRuntime (
 
       case EFI_IMAGE_REL_BASED_HIGH:
         Fixup16 = (UINT16 *) Fixup;
+        Fixup32 = (UINT32 *) (Fixup16 - 1);
         if (*(UINT16 *) FixupData == *Fixup16) {
-          *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
+          *Fixup16 = (UINT16) ((*Fixup32 + (UINT32) Adjust) >> 16);
         }
 
         FixupData = FixupData + sizeof (UINT16);