[lld][llvm-objcopy] Enable Xbox subsystem for PE images. (#191779)

This patch enables selecting the Xbox subsystem (IMAGE_SUBSYSTEM_XBOX)
for PE images. Certain existing tools used in the Xbox homebrew scene
expect images to use the Xbox subsystem, so it's nice to be able to set
this within the LLVM toolchain instead of invoking yet another tool or
manually patching the binaries.
This commit is contained in:
Ashlyn
2026-04-14 16:29:14 -06:00
committed by GitHub
parent 392f76ac68
commit 18519f3465
4 changed files with 29 additions and 11 deletions

View File

@@ -122,17 +122,19 @@ void LinkerDriver::parseSubsystem(StringRef arg, WindowsSubsystem *sys,
auto [sysStr, ver] = arg.split(',');
std::string sysStrLower = sysStr.lower();
*sys = StringSwitch<WindowsSubsystem>(sysStrLower)
.Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
.Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
.Case("default", IMAGE_SUBSYSTEM_UNKNOWN)
.Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
.Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
.Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
.Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
.Case("native", IMAGE_SUBSYSTEM_NATIVE)
.Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
.Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
.Default(IMAGE_SUBSYSTEM_UNKNOWN);
.Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
.Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
.Case("default", IMAGE_SUBSYSTEM_UNKNOWN)
.Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
.Case("efi_boot_service_driver",
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
.Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
.Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
.Case("native", IMAGE_SUBSYSTEM_NATIVE)
.Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
.Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
.Case("xbox", IMAGE_SUBSYSTEM_XBOX)
.Default(IMAGE_SUBSYSTEM_UNKNOWN);
if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default")
Fatal(ctx) << "unknown subsystem: " << sysStr;
if (!ver.empty())

View File

@@ -48,3 +48,13 @@ CHECK5: MajorOperatingSystemVersion: 1
CHECK5: MinorOperatingSystemVersion: 2
CHECK5: MajorSubsystemVersion: 3
CHECK5: MinorSubsystemVersion: 4
# RUN: lld-link /entry:main /out:%t.exe /subsystem:xbox,8.9 \
# RUN: %p/Inputs/ret42.obj
# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK6 %s
CHECK6: MajorOperatingSystemVersion: 8
CHECK6: MinorOperatingSystemVersion: 9
CHECK6: MajorSubsystemVersion: 8
CHECK6: MinorSubsystemVersion: 9
CHECK6: Subsystem: IMAGE_SUBSYSTEM_XBOX

View File

@@ -51,6 +51,11 @@
# EFI-RUNTIME-DRIVER: Subsystem: IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
# RUN: llvm-objcopy --subsystem=xbox %t.in.exe %t.out.exe
# RUN: llvm-readobj --file-headers %t.out.exe | FileCheck %s --check-prefix=XBOX
# XBOX: Subsystem: IMAGE_SUBSYSTEM_XBOX
--- !COFF
OptionalHeader:
AddressOfEntryPoint: 4096

View File

@@ -821,6 +821,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
.Case("native", COFF::IMAGE_SUBSYSTEM_NATIVE)
.Case("posix", COFF::IMAGE_SUBSYSTEM_POSIX_CUI)
.Case("windows", COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI)
.Case("xbox", COFF::IMAGE_SUBSYSTEM_XBOX)
.Default(COFF::IMAGE_SUBSYSTEM_UNKNOWN);
if (*COFFConfig.Subsystem == COFF::IMAGE_SUBSYSTEM_UNKNOWN)
return createStringError(errc::invalid_argument,