Skip to content

Commit c59da84

Browse files
committed
[lib][uefi] Remove THUMB mode relocation, added aarch64 specific
relocation
1 parent 3e73cb0 commit c59da84

2 files changed

Lines changed: 23 additions & 105 deletions

File tree

lib/uefi/pe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ static constexpr size_t EFI_IMAGE_REL_BASED_HIGHADJ = 4;
285285
static constexpr size_t EFI_IMAGE_REL_BASED_MIPS_JMPADDR = 5;
286286
static constexpr size_t EFI_IMAGE_REL_BASED_ARM_MOV32A = 5;
287287
static constexpr size_t EFI_IMAGE_REL_BASED_ARM_MOV32T = 7;
288+
static constexpr size_t EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA = 8;
288289
static constexpr size_t EFI_IMAGE_REL_BASED_IA64_IMM64 = 9;
289290
static constexpr size_t EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 = 9;
290291
static constexpr size_t EFI_IMAGE_REL_BASED_DIR64 = 10;

lib/uefi/relocation.cpp

Lines changed: 22 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -7,102 +7,6 @@
77

88
#include "pe.h"
99

10-
namespace {
11-
12-
constexpr size_t BIT26 = 1 << 26;
13-
constexpr size_t BIT11 = 1 << 11;
14-
constexpr size_t BIT10 = 1 << 10;
15-
16-
/**
17-
Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and
18-
return the immediate data encoded in the instruction.
19-
20-
@param Instruction Pointer to ARM MOVT or MOVW immediate instruction
21-
22-
@return Immediate address encoded in the instruction
23-
24-
**/
25-
uint16_t ThumbMovtImmediateAddress(const uint16_t *Instruction) {
26-
uint32_t Movt{};
27-
uint16_t Address{};
28-
29-
// Thumb2 is two 16-bit instructions working together. Not a single 32-bit
30-
// instruction Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
31-
Movt = (*Instruction << 16) | (*(Instruction + 1));
32-
33-
// imm16 = imm4:i:imm3:imm8
34-
// imm4 -> Bit19:Bit16
35-
// i -> Bit26
36-
// imm3 -> Bit14:Bit12
37-
// imm8 -> Bit7:Bit0
38-
Address = static_cast<uint16_t>(Movt & 0x000000ff); // imm8
39-
Address |= static_cast<uint16_t>((Movt >> 4) & 0x0000f700); // imm4 imm3
40-
Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i
41-
return Address;
42-
}
43-
44-
/**
45-
Pass in a pointer to an ARM MOVW/MOVT instruciton pair and
46-
return the immediate data encoded in the two` instruction.
47-
48-
@param Instructions Pointer to ARM MOVW/MOVT insturction pair
49-
50-
@return Immediate address encoded in the instructions
51-
52-
**/
53-
uint32_t ThumbMovwMovtImmediateAddress(uint16_t *Instructions) {
54-
uint16_t *Word{};
55-
uint16_t *Top{};
56-
57-
Word = Instructions; // MOVW
58-
Top = Word + 2; // MOVT
59-
60-
return (ThumbMovtImmediateAddress(Top) << 16) +
61-
ThumbMovtImmediateAddress(Word);
62-
}
63-
64-
/**
65-
Update an ARM MOVT or MOVW immediate instruction immediate data.
66-
67-
@param Instruction Pointer to ARM MOVT or MOVW immediate instruction
68-
@param Address New addres to patch into the instruction
69-
**/
70-
void ThumbMovtImmediatePatch(uint16_t *Instruction, uint16_t Address) {
71-
uint16_t Patch{};
72-
73-
// First 16-bit chunk of instruciton
74-
Patch = ((Address >> 12) & 0x000f); // imm4
75-
Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i
76-
// Mask out instruction bits and or in address
77-
*(Instruction) = (*Instruction & ~0x040f) | Patch;
78-
79-
// Second 16-bit chunk of instruction
80-
Patch = Address & 0x000000ff; // imm8
81-
Patch |= ((Address << 4) & 0x00007000); // imm3
82-
// Mask out instruction bits and or in address
83-
Instruction++;
84-
*Instruction = (*Instruction & ~0x70ff) | Patch;
85-
}
86-
87-
/**
88-
Update an ARM MOVW/MOVT immediate instruction instruction pair.
89-
90-
@param Instructions Pointer to ARM MOVW/MOVT instruction pair
91-
@param Address New addres to patch into the instructions
92-
**/
93-
void ThumbMovwMovtImmediatePatch(uint16_t *Instructions, uint32_t Address) {
94-
uint16_t *Word{};
95-
uint16_t *Top{};
96-
97-
Word = Instructions; // MOVW
98-
Top = Word + 2; // MOVT
99-
100-
ThumbMovtImmediatePatch(Word, static_cast<uint16_t>(Address & 0xffff));
101-
ThumbMovtImmediatePatch(Top, static_cast<uint16_t>(Address >> 16));
102-
}
103-
104-
} // namespace
105-
10610
int relocate_image(char *image) {
10711
const auto dos_header = reinterpret_cast<IMAGE_DOS_HEADER *>(image);
10812
const auto pe_header = dos_header->GetPEHeader();
@@ -141,7 +45,6 @@ int relocate_image(char *image) {
14145
auto Fixup16 = reinterpret_cast<uint16_t *>(Fixup);
14246
auto Fixup32 = reinterpret_cast<uint32_t *>(Fixup);
14347
auto Fixup64 = reinterpret_cast<uint64_t *>(Fixup);
144-
uint32_t FixupVal = 0;
14548
switch ((*Reloc) >> 12) {
14649
case EFI_IMAGE_REL_BASED_ABSOLUTE:
14750
break;
@@ -167,18 +70,32 @@ int relocate_image(char *image) {
16770
*Fixup64 = *Fixup64 + static_cast<uint64_t>(Adjust);
16871
break;
16972

170-
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
171-
FixupVal = ThumbMovwMovtImmediateAddress(Fixup16) +
172-
static_cast<uint32_t>(Adjust);
173-
ThumbMovwMovtImmediatePatch(Fixup16, FixupVal);
174-
175-
break;
176-
17773
case EFI_IMAGE_REL_BASED_ARM_MOV32A:
17874
printf("Unsupported relocation type: EFI_IMAGE_REL_BASED_ARM_MOV32A\n");
17975
// break omitted - ARM instruction encoding not implemented
18076
break;
181-
77+
case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA: {
78+
// The next four instructions are used to load a 64 bit address,
79+
// relocate all of them
80+
uint64_t Value =
81+
(*Fixup32 & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5
82+
(*(Fixup32 + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10
83+
uint64_t Tmp1 = *(Fixup32 + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5
84+
uint64_t Tmp2 = *(Fixup32 + 3) & 0x3ffc00; // lu52i.d 12bits from bit10
85+
Value = Value | (Tmp1 << 27) | (Tmp2 << 42);
86+
Value += Adjust;
87+
88+
*Fixup32 = (*Fixup32 & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);
89+
90+
Fixup += sizeof(uint32_t);
91+
*Fixup32 = (*Fixup32 & ~0x3ffc00) | ((Value & 0xfff) << 10);
92+
93+
Fixup += sizeof(uint32_t);
94+
*Fixup32 = (*Fixup32 & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);
95+
96+
Fixup += sizeof(uint32_t);
97+
*Fixup32 = (*Fixup32 & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
98+
}
18299
default:
183100
printf("Unsupported relocation type: %d\n", (*Reloc) >> 12);
184101
return -1;

0 commit comments

Comments
 (0)