Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/uefi/include/uefi/system_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ typedef struct {

typedef struct EfiSystemTable {
EfiTableHeader header;
const char16_t* firmware_vendor;
const EfiChar16* firmware_vendor;
uint32_t firmware_revision;
EfiHandle console_in_handle;
void* con_in;
Expand Down
2 changes: 1 addition & 1 deletion lib/uefi/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct IMAGE_DOS_HEADER { // DOS .EXE header
u16 e_res2[10]; // Reserved words
u32 e_lfanew; // File address of new exe header

// ASCII "PE\x0\x0"
// DOS "MZ" signature
constexpr bool CheckMagic() const { return LE32(e_magic) == 0x5A4D; }
IMAGE_NT_HEADERS64 *GetPEHeader() {
auto address = reinterpret_cast<char *>(this);
Expand Down
21 changes: 10 additions & 11 deletions lib/uefi/relocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,23 @@ int relocate_image(char *image) {
case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA: {
// The next four instructions are used to load a 64 bit address,
// relocate all of them
if (reinterpret_cast<char *>(Fixup32) + 4 * sizeof(uint32_t) > image + optional_header->SizeOfImage) {
printf("Relocation out of bounds\n");
return -1;
}

uint64_t Value =
(*Fixup32 & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5
(*(Fixup32 + 0) & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5
(*(Fixup32 + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10
uint64_t Tmp1 = *(Fixup32 + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5
uint64_t Tmp2 = *(Fixup32 + 3) & 0x3ffc00; // lu52i.d 12bits from bit10
Value = Value | (Tmp1 << 27) | (Tmp2 << 42);
Value += Adjust;

*Fixup32 = (*Fixup32 & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);

Fixup += sizeof(uint32_t);
*Fixup32 = (*Fixup32 & ~0x3ffc00) | ((Value & 0xfff) << 10);

Fixup += sizeof(uint32_t);
*Fixup32 = (*Fixup32 & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);

Fixup += sizeof(uint32_t);
*Fixup32 = (*Fixup32 & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
*(Fixup32 + 0) = (*(Fixup32 + 0) & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);
*(Fixup32 + 1) = (*(Fixup32 + 1) & ~0x3ffc00) | ((Value & 0xfff) << 10);
*(Fixup32 + 2) = (*(Fixup32 + 2) & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);
*(Fixup32 + 3) = (*(Fixup32 + 3) & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
break;
}
default:
Expand Down
17 changes: 11 additions & 6 deletions lib/uefi/uefi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "runtime_service_provider.h"
#include "switch_stack.h"
#include "text_protocol.h"
#include "uefi/types.h"
#include "uefi_platform.h"
#include "variable_mem.h"

Expand Down Expand Up @@ -130,7 +131,7 @@ int load_sections_and_execute(ImageReader *reader,
}
for (size_t i = 0; i < sections; i++) {
if (section_header[i].NumberOfRelocations != 0) {
printf("Section %s requires relocation, which is not supported.\n",
printf("Section %.8s requires relocation, which is not supported.\n",
section_header[i].Name);
return ERR_NOT_SUPPORTED;
}
Expand All @@ -153,8 +154,8 @@ int load_sections_and_execute(ImageReader *reader,
DEFER { free_pages(image_base, virtual_size / PAGE_SIZE); };
ssize_t bytes_read =
reader->read(image_base, 0, section_header[0].PointerToRawData);
if (bytes_read != section_header[0].SizeOfRawData) {
printf("Failed to read section %s\n", section_header[0].Name);
if (bytes_read != static_cast<ssize_t>(section_header[0].PointerToRawData)) {
printf("Failed to read PE headers before first section\n");
return ERR_IO;
}

Expand All @@ -163,7 +164,7 @@ int load_sections_and_execute(ImageReader *reader,
bytes_read = reader->read(image_base + section.VirtualAddress,
section.PointerToRawData, section.SizeOfRawData);
if (bytes_read != section.SizeOfRawData) {
printf("Failed to read section %s %zu\n", section.Name, bytes_read);
printf("Failed to read section %.8s %zd\n", section.Name, bytes_read);
return ERR_IO;
}
}
Expand All @@ -183,7 +184,7 @@ int load_sections_and_execute(ImageReader *reader,
fill(&boot_service, 0);
setup_runtime_service_table(&runtime_service);
setup_boot_service_table(&boot_service);
table.firmware_vendor = reinterpret_cast<const char16_t *>(firmwareVendor);
table.firmware_vendor = reinterpret_cast<const EfiChar16*>(firmwareVendor);
table.runtime_services = &runtime_service;
table.boot_services = &boot_service;
table.header.signature = EFI_SYSTEM_TABLE_SIGNATURE;
Expand All @@ -208,6 +209,7 @@ int load_sections_and_execute(ImageReader *reader,
}
char path[FS_MAX_PATH_LEN];
reader->get_name(path, sizeof(path));
path[sizeof(path) - 1] = '\0';
setup_debug_support(table, image_base, virtual_size, path);

constexpr size_t kStackSize = 1 * 1024ul * 1024;
Expand Down Expand Up @@ -276,10 +278,12 @@ int load_pe_file(ImageReader *reader) {
}
DEFER { free(address); };
ssize_t err = reader->read(reinterpret_cast<char *>(address), 0, kBlocKSize);
t = current_time() - t;
// Prevent divide by 0 errors
t = MAX(current_time() - t, 1);
if (err < 0) {
char name[128];
reader->get_name(name, sizeof(name));
name[sizeof(name) - 1] = '\0';
printf("error reading PE header from %s: %zd\n", name, err);
return ERR_IO;
}
Expand All @@ -306,6 +310,7 @@ int load_pe_file(ImageReader *reader) {
if (file_header->Machine != ArchitectureType::ARM64) {
printf("Unsupported PE header machine type: %x\n",
static_cast<int>(file_header->Machine));
return ERR_NOT_SUPPORTED;
}
if (file_header->SizeOfOptionalHeader > sizeof(IMAGE_OPTIONAL_HEADER64) ||
file_header->SizeOfOptionalHeader <
Expand Down