Skip to content

Commit 153ccbe

Browse files
[NFCI][SYCL] Refactor getBinaryImageFormat (#12586)
A future PR will add support for magic numbers other than four bytes. Refactor the code to make those future changes easier to review.
1 parent d3d6e78 commit 153ccbe

File tree

1 file changed

+32
-38
lines changed

1 file changed

+32
-38
lines changed

sycl/source/detail/pi.cpp

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -685,45 +685,39 @@ static uint16_t getELFHeaderType(const unsigned char *ImgData, size_t ImgSize) {
685685
sycl::detail::pi::PiDeviceBinaryType
686686
getBinaryImageFormat(const unsigned char *ImgData, size_t ImgSize) {
687687
// Top-level magic numbers for the recognized binary image formats.
688-
struct {
689-
sycl::detail::pi::PiDeviceBinaryType Fmt;
690-
const uint32_t Magic;
691-
} Fmts[] = {{PI_DEVICE_BINARY_TYPE_SPIRV, 0x07230203},
692-
{PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE, 0xDEC04342},
693-
// 'I', 'N', 'T', 'C' ; Intel native
694-
{PI_DEVICE_BINARY_TYPE_NATIVE, 0x43544E49}};
695-
696-
if (ImgSize >= sizeof(Fmts[0].Magic)) {
697-
std::remove_const_t<decltype(Fmts[0].Magic)> Hdr = 0;
698-
std::copy(ImgData, ImgData + sizeof(Hdr), reinterpret_cast<char *>(&Hdr));
699-
700-
// Check headers for direct formats.
701-
for (const auto &Fmt : Fmts) {
702-
if (Hdr == Fmt.Magic)
703-
return Fmt.Fmt;
704-
}
705-
706-
// ELF e_type for recognized binary image formats.
707-
struct {
708-
sycl::detail::pi::PiDeviceBinaryType Fmt;
709-
const uint16_t Magic;
710-
} ELFFmts[] = {{PI_DEVICE_BINARY_TYPE_NATIVE, 0xFF04}, // OpenCL executable
711-
{PI_DEVICE_BINARY_TYPE_NATIVE, 0xFF12}}; // ZEBIN executable
712-
713-
// ELF files need to be parsed separately. The header type ends after 18
714-
// bytes.
715-
if (Hdr == 0x464c457F && ImgSize >= 18) {
716-
uint16_t HdrType = getELFHeaderType(ImgData, ImgSize);
717-
for (const auto &ELFFmt : ELFFmts) {
718-
if (HdrType == ELFFmt.Magic)
719-
return ELFFmt.Fmt;
720-
}
721-
// Newer ZEBIN format does not have a special header type, but can instead
722-
// be identified by having a required .ze_info section.
723-
if (checkELFSectionPresent(".ze_info", ImgData, ImgSize))
724-
return PI_DEVICE_BINARY_TYPE_NATIVE;
725-
}
688+
auto MatchMagicNumber = [&](auto Number) {
689+
return ImgSize >= sizeof(Number) &&
690+
std::memcmp(ImgData, &Number, sizeof(Number)) == 0;
691+
};
692+
693+
if (MatchMagicNumber(uint32_t{0x07230203}))
694+
return PI_DEVICE_BINARY_TYPE_SPIRV;
695+
696+
if (MatchMagicNumber(uint32_t{0xDEC04342}))
697+
return PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE;
698+
699+
if (MatchMagicNumber(uint32_t{0x43544E49}))
700+
// 'I', 'N', 'T', 'C' ; Intel native
701+
return PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE;
702+
703+
// Check for ELF format, size requirements include data we'll read in case of
704+
// succesful match.
705+
if (ImgSize >= 18 && MatchMagicNumber(uint32_t{0x464c457F})) {
706+
uint16_t ELFHdrType = getELFHeaderType(ImgData, ImgSize);
707+
if (ELFHdrType == 0xFF04)
708+
// OpenCL executable.
709+
return PI_DEVICE_BINARY_TYPE_NATIVE;
710+
711+
if (ELFHdrType == 0xFF12)
712+
// ZEBIN executable.
713+
return PI_DEVICE_BINARY_TYPE_NATIVE;
714+
715+
// Newer ZEBIN format does not have a special header type, but can instead
716+
// be identified by having a required .ze_info section.
717+
if (checkELFSectionPresent(".ze_info", ImgData, ImgSize))
718+
return PI_DEVICE_BINARY_TYPE_NATIVE;
726719
}
720+
727721
return PI_DEVICE_BINARY_TYPE_NONE;
728722
}
729723

0 commit comments

Comments
 (0)