mirror of
https://github.com/systemd/systemd
synced 2024-10-01 13:55:20 +00:00
elf2efi: Add --copy-sections option
This makes the special PE sections available again in our output EFI images. Since the compiler provides no way to mark a section as not allocated, we use GNU assembler syntax to emit the sections instead. This ensures the section data isn't emitted twice as load segments will only contain allocating input sections.
This commit is contained in:
parent
7d6fd7f099
commit
898e9edc46
|
@ -4,12 +4,11 @@
|
|||
#include "version.h"
|
||||
|
||||
/* Magic string for recognizing our own binaries */
|
||||
_used_ _section_(".sdmagic") static const char magic[] =
|
||||
"#### LoaderInfo: systemd-addon " GIT_VERSION " ####";
|
||||
DECLARE_NOALLOC_SECTION(".sdmagic", "#### LoaderInfo: systemd-addon " GIT_VERSION " ####");
|
||||
|
||||
/* This is intended to carry data, not to be executed */
|
||||
|
||||
EFIAPI EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table);
|
||||
EFIAPI EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,15 @@
|
|||
#include "vmm.h"
|
||||
|
||||
/* Magic string for recognizing our own binaries */
|
||||
_used_ _section_(".sdmagic") static const char magic[] =
|
||||
"#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
|
||||
#define SD_MAGIC "#### LoaderInfo: systemd-boot " GIT_VERSION " ####"
|
||||
DECLARE_NOALLOC_SECTION(".sdmagic", SD_MAGIC);
|
||||
|
||||
/* Makes systemd-boot available from \EFI\Linux\ for testing purposes. */
|
||||
_used_ _section_(".osrel") static const char osrel[] =
|
||||
"ID=systemd-boot\n"
|
||||
"VERSION=\"" GIT_VERSION "\"\n"
|
||||
"NAME=\"systemd-boot " GIT_VERSION "\"\n";
|
||||
DECLARE_NOALLOC_SECTION(
|
||||
".osrel",
|
||||
"ID=systemd-boot\n"
|
||||
"VERSION=\"" GIT_VERSION "\"\n"
|
||||
"NAME=\"systemd-boot " GIT_VERSION "\"\n");
|
||||
|
||||
DECLARE_SBAT(SBAT_BOOT_SECTION_TEXT);
|
||||
|
||||
|
@ -1890,14 +1891,14 @@ static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) {
|
|||
assert(loader_path);
|
||||
|
||||
err = pe_file_locate_sections(root_dir, loader_path, sections, &offset, &size);
|
||||
if (err != EFI_SUCCESS || size != sizeof(magic))
|
||||
if (err != EFI_SUCCESS || size != sizeof(SD_MAGIC))
|
||||
return false;
|
||||
|
||||
err = file_read(root_dir, loader_path, offset, size, &content, &read);
|
||||
if (err != EFI_SUCCESS || size != read)
|
||||
return false;
|
||||
|
||||
return memcmp(content, magic, sizeof(magic)) == 0;
|
||||
return memcmp(content, SD_MAGIC, sizeof(SD_MAGIC)) == 0;
|
||||
}
|
||||
|
||||
static ConfigEntry *config_entry_add_loader_auto(
|
||||
|
|
|
@ -361,6 +361,7 @@ foreach efi_elf_binary : efi_elf_binaries
|
|||
'--efi-minor=1',
|
||||
'--subsystem=10',
|
||||
'--minimum-sections=' + minimum_sections,
|
||||
'--copy-sections=.sbat,.sdmagic,.osrel',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@',
|
||||
])
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "vmm.h"
|
||||
|
||||
/* magic string to find in the binary image */
|
||||
_used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
|
||||
DECLARE_NOALLOC_SECTION(".sdmagic", "#### LoaderInfo: systemd-stub " GIT_VERSION " ####");
|
||||
|
||||
DECLARE_SBAT(SBAT_STUB_SECTION_TEXT);
|
||||
|
||||
|
|
|
@ -396,9 +396,15 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
|
|||
type name[]; \
|
||||
}
|
||||
|
||||
/* Declares an ELF read-only string section that does not occupy memory at runtime. */
|
||||
#define DECLARE_NOALLOC_SECTION(name, text) \
|
||||
asm(".pushsection " name ",\"S\"\n\t" \
|
||||
".ascii " STRINGIFY(text) "\n\t" \
|
||||
".zero 1\n\t" \
|
||||
".popsection\n")
|
||||
|
||||
#ifdef SBAT_DISTRO
|
||||
#define DECLARE_SBAT(text) \
|
||||
static const char sbat[] _used_ _section_(".sbat") = (text)
|
||||
#define DECLARE_SBAT(text) DECLARE_NOALLOC_SECTION(".sbat", text)
|
||||
#else
|
||||
#define DECLARE_SBAT(text)
|
||||
#endif
|
||||
|
|
|
@ -333,6 +333,32 @@ def convert_sections(elf: ELFFile, opt: PeOptionalHeader) -> typing.List[PeSecti
|
|||
return sections
|
||||
|
||||
|
||||
def copy_sections(
|
||||
elf: ELFFile,
|
||||
opt: PeOptionalHeader,
|
||||
input_names: str,
|
||||
sections: typing.List[PeSection],
|
||||
):
|
||||
for name in input_names.split(","):
|
||||
elf_s = elf.get_section_by_name(name)
|
||||
if not elf_s:
|
||||
continue
|
||||
if elf_s.data_alignment > 1 and SECTION_ALIGNMENT % elf_s.data_alignment != 0:
|
||||
raise RuntimeError(f"ELF section {name} is not aligned.")
|
||||
if elf_s["sh_flags"] & (SH_FLAGS.SHF_EXECINSTR | SH_FLAGS.SHF_WRITE) != 0:
|
||||
raise RuntimeError(f"ELF section {name} is not read-only data.")
|
||||
|
||||
pe_s = PeSection()
|
||||
pe_s.Name = name.encode()
|
||||
pe_s.data = elf_s.data()
|
||||
pe_s.VirtualAddress = next_section_address(sections)
|
||||
pe_s.VirtualSize = len(elf_s.data())
|
||||
pe_s.SizeOfRawData = align_to(len(elf_s.data()), FILE_ALIGNMENT)
|
||||
pe_s.Characteristics = PE_CHARACTERISTICS_R
|
||||
opt.SizeOfInitializedData += pe_s.VirtualSize
|
||||
sections.append(pe_s)
|
||||
|
||||
|
||||
def apply_elf_relative_relocation(
|
||||
reloc: ElfRelocation,
|
||||
image_base: int,
|
||||
|
@ -561,6 +587,7 @@ def elf2efi(args: argparse.Namespace):
|
|||
opt.ImageBase = (0x100000000 + opt.ImageBase) & 0x1FFFF0000
|
||||
|
||||
sections = convert_sections(elf, opt)
|
||||
copy_sections(elf, opt, args.copy_sections, sections)
|
||||
pe_reloc_s = convert_elf_relocations(elf, opt, sections, args.minimum_sections)
|
||||
|
||||
coff.Machine = pe_arch
|
||||
|
@ -647,6 +674,12 @@ def main():
|
|||
default=0,
|
||||
help="Minimum number of sections to leave space for",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--copy-sections",
|
||||
type=str,
|
||||
default="",
|
||||
help="Copy these sections if found",
|
||||
)
|
||||
|
||||
elf2efi(parser.parse_args())
|
||||
|
||||
|
|
Loading…
Reference in a new issue