mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2024-11-27 10:00:17 -06:00
Fix the virtual memory addresses and sizes in the EFI image headers.
When the reloc and sbat sections were added by PR #34, three bugs were introduced: 1. The virtual address and size fields in the PE headers were set to the same values as the raw address and size fields. This is incorrect, because the sections in the image file are aligned on 512 byte boundaries, but when loaded into memory they need to be aligned on 4096 byte boundaries. 2. The value programmed into the SizeOfImage field was too large, as it double-counted the region before the start of the .text section. 3. The value programmed into the SizeOfImage field no longer included the bss size. That potentially allowed the EFI loader to load the image immediately before a reserved region of memory without leaving enough space for the bss section. This commit fixes those bugs by calculating both file and virtual memory offsets & sizes in the ld script. Note that we can't add a bss section to the EFI image because many EFI loaders fail to load images that have uninitialised data sections. Instead the text region size in virtual memory is increased to include the bss size. This fixes issue #243. It also eliminates the gaps between sections observed in issue #202.
This commit is contained in:
parent
485bfa46a3
commit
a4c9adc445
@ -7,7 +7,7 @@
|
|||||||
// end of the boot sector), with the remainder of the header being provided by
|
// end of the boot sector), with the remainder of the header being provided by
|
||||||
// setup.S.
|
// setup.S.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2020 Martin Whitaker.
|
// Copyright (C) 2020-2023 Martin Whitaker.
|
||||||
//
|
//
|
||||||
// Derived from Linux 5.6 arch/x86/boot/header.S:
|
// Derived from Linux 5.6 arch/x86/boot/header.S:
|
||||||
//
|
//
|
||||||
@ -28,7 +28,6 @@
|
|||||||
# address well away from HIGH_LOAD_ADDR, to avoid overlap when relocating the code.
|
# address well away from HIGH_LOAD_ADDR, to avoid overlap when relocating the code.
|
||||||
|
|
||||||
#define IMAGE_BASE 0x200000
|
#define IMAGE_BASE 0x200000
|
||||||
#define BASE_OF_CODE 0x1000
|
|
||||||
|
|
||||||
.section ".header", "ax", @progbits
|
.section ".header", "ax", @progbits
|
||||||
.code16
|
.code16
|
||||||
@ -117,15 +116,15 @@ optional_header:
|
|||||||
.byte 0x02 # MajorLinkerVersion
|
.byte 0x02 # MajorLinkerVersion
|
||||||
.byte 0x14 # MinorLinkerVersion
|
.byte 0x14 # MinorLinkerVersion
|
||||||
|
|
||||||
.long _text_size # SizeOfCode
|
.long _virt_text_size # SizeOfCode
|
||||||
.long _sbat_size # SizeOfInitializedData
|
.long _virt_sbat_size # SizeOfInitializedData
|
||||||
.long 0 # SizeOfUninitializedData
|
.long 0 # SizeOfUninitializedData
|
||||||
|
|
||||||
.long BASE_OF_CODE + 0x1e0 # AddressOfEntryPoint
|
.long _virt_text_start + 0x1e0 # AddressOfEntryPoint
|
||||||
|
|
||||||
.long BASE_OF_CODE # BaseOfCode
|
.long _virt_text_start # BaseOfCode
|
||||||
#ifndef __x86_64__
|
#ifndef __x86_64__
|
||||||
.long _sbat_start # BaseOfData
|
.long _virt_sbat_start # BaseOfData
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extra_header_fields:
|
extra_header_fields:
|
||||||
@ -144,7 +143,7 @@ extra_header_fields:
|
|||||||
.word 0 # MinorSubsystemVersion
|
.word 0 # MinorSubsystemVersion
|
||||||
.long 0 # Win32VersionValue
|
.long 0 # Win32VersionValue
|
||||||
|
|
||||||
.long BASE_OF_CODE + _img_end # SizeOfImage
|
.long _virt_img_size # SizeOfImage
|
||||||
.long end_of_headers # SizeOfHeaders
|
.long end_of_headers # SizeOfHeaders
|
||||||
.long 0 # CheckSum
|
.long 0 # CheckSum
|
||||||
.word 10 # Subsystem (EFI application)
|
.word 10 # Subsystem (EFI application)
|
||||||
@ -173,8 +172,8 @@ extra_header_fields:
|
|||||||
.long 0 # DataDirectory.Exception.Size
|
.long 0 # DataDirectory.Exception.Size
|
||||||
.long 0 # DataDirectory.Certs.VirtualAddress
|
.long 0 # DataDirectory.Certs.VirtualAddress
|
||||||
.long 0 # DataDirectory.Certs.Size
|
.long 0 # DataDirectory.Certs.Size
|
||||||
.long _reloc_start # DataDirectory.BaseReloc.VirtualAddress
|
.long _virt_reloc_start # DataDirectory.BaseReloc.VirtualAddress
|
||||||
.long _reloc_size # DataDirectory.BaseReloc.Size
|
.long _real_reloc_size # DataDirectory.BaseReloc.Size
|
||||||
|
|
||||||
# Section table
|
# Section table
|
||||||
section_table:
|
section_table:
|
||||||
@ -182,10 +181,10 @@ section_table:
|
|||||||
.byte 0
|
.byte 0
|
||||||
.byte 0
|
.byte 0
|
||||||
.byte 0
|
.byte 0
|
||||||
.long _text_size # VirtualSize
|
.long _virt_text_size # VirtualSize
|
||||||
.long BASE_OF_CODE # VirtualAddress
|
.long _virt_text_start # VirtualAddress
|
||||||
.long _text_size # SizeOfRawData
|
.long _file_text_size # SizeOfRawData
|
||||||
.long _text_start # PointerToRawData
|
.long _file_text_start # PointerToRawData
|
||||||
.long 0 # PointerToRelocations
|
.long 0 # PointerToRelocations
|
||||||
.long 0 # PointerToLineNumbers
|
.long 0 # PointerToLineNumbers
|
||||||
.word 0 # NumberOfRelocations
|
.word 0 # NumberOfRelocations
|
||||||
@ -198,10 +197,10 @@ section_table:
|
|||||||
.ascii ".reloc"
|
.ascii ".reloc"
|
||||||
.byte 0
|
.byte 0
|
||||||
.byte 0
|
.byte 0
|
||||||
.long _reloc_size # VirtualSize
|
.long _virt_reloc_size # VirtualSize
|
||||||
.long _reloc_start # VirtualAddress
|
.long _virt_reloc_start # VirtualAddress
|
||||||
.long _reloc_size # SizeOfRawData
|
.long _file_reloc_size # SizeOfRawData
|
||||||
.long _reloc_start # PointerToRawData
|
.long _file_reloc_start # PointerToRawData
|
||||||
.long 0 # PointerToRelocations
|
.long 0 # PointerToRelocations
|
||||||
.long 0 # PointerToLineNumbers
|
.long 0 # PointerToLineNumbers
|
||||||
.word 0 # NumberOfRelocations
|
.word 0 # NumberOfRelocations
|
||||||
@ -214,10 +213,10 @@ section_table:
|
|||||||
.byte 0
|
.byte 0
|
||||||
.byte 0
|
.byte 0
|
||||||
.byte 0
|
.byte 0
|
||||||
.long _sbat_size # VirtualSize
|
.long _virt_sbat_size # VirtualSize
|
||||||
.long _sbat_start # VirtualAddress
|
.long _virt_sbat_start # VirtualAddress
|
||||||
.long _sbat_size # SizeOfRawData
|
.long _file_sbat_size # SizeOfRawData
|
||||||
.long _sbat_start # PointerToRawData
|
.long _file_sbat_start # PointerToRawData
|
||||||
.long 0 # PointerToRelocations
|
.long 0 # PointerToRelocations
|
||||||
.long 0 # PointerToLineNumbers
|
.long 0 # PointerToLineNumbers
|
||||||
.word 0 # NumberOfRelocations
|
.word 0 # NumberOfRelocations
|
||||||
|
@ -12,32 +12,47 @@ SECTIONS {
|
|||||||
}
|
}
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
.text : {
|
.text : {
|
||||||
_text_start = . ;
|
_file_text_start = . ;
|
||||||
*(.data)
|
*(.data)
|
||||||
|
_real_text_end = . ;
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
_text_end = . ;
|
_file_text_end = . ;
|
||||||
}
|
}
|
||||||
. = ALIGN(512);
|
|
||||||
.reloc : {
|
.reloc : {
|
||||||
_reloc_start = . ;
|
_file_reloc_start = . ;
|
||||||
*(.reloc)
|
*(.reloc)
|
||||||
_reloc_end = . ;
|
_real_reloc_end = . ;
|
||||||
}
|
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
|
_file_reloc_end = . ;
|
||||||
|
}
|
||||||
.sbat : {
|
.sbat : {
|
||||||
_sbat_start = . ;
|
_file_sbat_start = . ;
|
||||||
*(.sbat)
|
*(.sbat)
|
||||||
|
_real_sbat_end = . ;
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
_sbat_end = . ;
|
_file_sbat_end = . ;
|
||||||
}
|
}
|
||||||
. = ALIGN(4096);
|
|
||||||
_img_end = . ;
|
|
||||||
/DISCARD/ : { *(*) }
|
/DISCARD/ : { *(*) }
|
||||||
|
|
||||||
_text_size = (_text_end - _text_start);
|
_real_text_size = _real_text_end - _file_text_start;
|
||||||
|
_real_reloc_size = _real_reloc_end - _file_reloc_start;
|
||||||
|
_real_sbat_size = _real_sbat_end - _file_sbat_start;
|
||||||
|
|
||||||
_reloc_size = (_reloc_end - _reloc_start);
|
_file_text_size = _file_text_end - _file_text_start;
|
||||||
_sbat_size = (_sbat_end - _sbat_start);
|
_file_reloc_size = _file_reloc_end - _file_reloc_start;
|
||||||
_sys_size = _text_size >> 4;
|
_file_sbat_size = _file_sbat_end - _file_sbat_start;
|
||||||
_init_size = _text_size + _bss_size;
|
|
||||||
|
_sys_size = (_real_text_size + 15) >> 4;
|
||||||
|
_init_size = _real_text_size + _bss_size;
|
||||||
|
|
||||||
|
_virt_head_size = ((_file_text_start + 4095) >> 12) << 12;
|
||||||
|
_virt_text_size = ((_init_size + 4095) >> 12) << 12;
|
||||||
|
_virt_reloc_size = ((_file_reloc_size + 4095) >> 12) << 12;
|
||||||
|
_virt_sbat_size = ((_file_sbat_size + 4095) >> 12) << 12;
|
||||||
|
|
||||||
|
_virt_text_start = _virt_head_size;
|
||||||
|
_virt_reloc_start = _virt_text_start + _virt_text_size;
|
||||||
|
_virt_sbat_start = _virt_reloc_start + _virt_reloc_size;
|
||||||
|
|
||||||
|
_virt_img_size = _virt_sbat_start + _virt_sbat_size;
|
||||||
}
|
}
|
||||||
|
@ -12,32 +12,47 @@ SECTIONS {
|
|||||||
}
|
}
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
.text : {
|
.text : {
|
||||||
_text_start = . ;
|
_file_text_start = . ;
|
||||||
*(.data)
|
*(.data)
|
||||||
|
_real_text_end = . ;
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
_text_end = . ;
|
_file_text_end = . ;
|
||||||
}
|
}
|
||||||
. = ALIGN(512);
|
|
||||||
.reloc : {
|
.reloc : {
|
||||||
_reloc_start = . ;
|
_file_reloc_start = . ;
|
||||||
*(.reloc)
|
*(.reloc)
|
||||||
_reloc_end = . ;
|
_real_reloc_end = . ;
|
||||||
}
|
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
|
_file_reloc_end = . ;
|
||||||
|
}
|
||||||
.sbat : {
|
.sbat : {
|
||||||
_sbat_start = . ;
|
_file_sbat_start = . ;
|
||||||
*(.sbat)
|
*(.sbat)
|
||||||
|
_real_sbat_end = . ;
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
_sbat_end = . ;
|
_file_sbat_end = . ;
|
||||||
}
|
}
|
||||||
. = ALIGN(4096);
|
|
||||||
_img_end = . ;
|
|
||||||
/DISCARD/ : { *(*) }
|
/DISCARD/ : { *(*) }
|
||||||
|
|
||||||
_text_size = (_text_end - _text_start);
|
_real_text_size = _real_text_end - _file_text_start;
|
||||||
|
_real_reloc_size = _real_reloc_end - _file_reloc_start;
|
||||||
|
_real_sbat_size = _real_sbat_end - _file_sbat_start;
|
||||||
|
|
||||||
_reloc_size = (_reloc_end - _reloc_start);
|
_file_text_size = _file_text_end - _file_text_start;
|
||||||
_sbat_size = (_sbat_end - _sbat_start);
|
_file_reloc_size = _file_reloc_end - _file_reloc_start;
|
||||||
_sys_size = _text_size >> 4;
|
_file_sbat_size = _file_sbat_end - _file_sbat_start;
|
||||||
_init_size = _text_size + _bss_size;
|
|
||||||
|
_sys_size = (_real_text_size + 15) >> 4;
|
||||||
|
_init_size = _real_text_size + _bss_size;
|
||||||
|
|
||||||
|
_virt_head_size = ((_file_text_start + 4095) >> 12) << 12;
|
||||||
|
_virt_text_size = ((_init_size + 4095) >> 12) << 12;
|
||||||
|
_virt_reloc_size = ((_file_reloc_size + 4095) >> 12) << 12;
|
||||||
|
_virt_sbat_size = ((_file_sbat_size + 4095) >> 12) << 12;
|
||||||
|
|
||||||
|
_virt_text_start = _virt_head_size;
|
||||||
|
_virt_reloc_start = _virt_text_start + _virt_text_size;
|
||||||
|
_virt_sbat_start = _virt_reloc_start + _virt_reloc_size;
|
||||||
|
|
||||||
|
_virt_img_size = _virt_sbat_start + _virt_sbat_size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user