#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;
}
#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);
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(
'--efi-minor=1',
'--subsystem=10',
'--minimum-sections=' + minimum_sections,
+ '--copy-sections=.sbat,.sdmagic,.osrel',
'@INPUT@',
'@OUTPUT@',
])
#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);
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
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,
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
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())