Skip to main content

igvmfilegen/
platform_mask.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Helpers for resolving `IgvmPlatformType` <-> compatibility-mask
5//! mappings declared in an IGVM file's platform headers, and for
6//! deriving human-readable / file-name-safe short names for each
7//! supported platform.
8
9use igvm::IgvmPlatformHeader;
10use igvm_defs::IgvmPlatformType;
11
12/// Short lowercase name for a measurable platform, suitable for file
13/// names and CLI suffixes (e.g. `"snp"`, `"tdx"`, `"vbs"`).
14///
15/// Returns `None` for platform variants that don't have a canonical
16/// short name in this tool (e.g. `Native`).
17pub fn isolation_short_name(platform: IgvmPlatformType) -> Option<&'static str> {
18    match platform {
19        IgvmPlatformType::SEV_SNP => Some("snp"),
20        IgvmPlatformType::TDX => Some("tdx"),
21        IgvmPlatformType::VSM_ISOLATION => Some("vbs"),
22        _ => None,
23    }
24}
25
26/// Always-safe label for a platform, used to generate sibling file
27/// names and human-readable platform tags. Falls back to
28/// `platform_<Debug>` for variants without a canonical short name,
29/// ensuring two distinct platforms never collide on the same label.
30pub fn isolation_label(platform: IgvmPlatformType) -> String {
31    match isolation_short_name(platform) {
32        Some(name) => name.to_string(),
33        None => format!("platform_{platform:?}"),
34    }
35}
36
37/// Look up the compatibility mask for a given platform type by reading the
38/// platform headers from the IGVM file.
39///
40/// Each IGVM file declares its own platform-to-mask mapping via
41/// `IGVM_VHS_SUPPORTED_PLATFORM` headers.
42///
43/// Returns an error if the requested platform type is not present in the
44/// file's platform headers.
45pub fn lookup_compatibility_mask(
46    platforms: &[IgvmPlatformHeader],
47    platform: IgvmPlatformType,
48) -> anyhow::Result<u32> {
49    for header in platforms {
50        match header {
51            IgvmPlatformHeader::SupportedPlatform(info) => {
52                if info.platform_type == platform {
53                    return Ok(info.compatibility_mask);
54                }
55            }
56        }
57    }
58
59    anyhow::bail!(
60        "Platform type {platform:?} not found in IGVM file platform headers. \
61         Available platforms: {}",
62        platforms
63            .iter()
64            .map(|h| match h {
65                IgvmPlatformHeader::SupportedPlatform(info) => {
66                    format!(
67                        "{:?} (mask=0x{:X})",
68                        info.platform_type, info.compatibility_mask
69                    )
70                }
71            })
72            .collect::<Vec<_>>()
73            .join(", ")
74    )
75}
76
77/// Format a compatibility mask as a human-readable platform list using
78/// the platform headers from the IGVM file.
79pub fn format_platform_mask(platforms: &[IgvmPlatformHeader], mask: u32) -> String {
80    let mut names = Vec::new();
81    for header in platforms {
82        match header {
83            IgvmPlatformHeader::SupportedPlatform(info) => {
84                if mask & info.compatibility_mask != 0 {
85                    names.push(format!("{:?}", info.platform_type));
86                }
87            }
88        }
89    }
90    if names.is_empty() {
91        "Unknown".to_string()
92    } else {
93        names.join(", ")
94    }
95}
96
97/// Map a compatibility mask to a lowercase platform name suitable for use in
98/// file names. Returns the platform's canonical short name (`"vbs"`, `"snp"`,
99/// `"tdx"`) when the mask matches a known platform header; otherwise
100/// `platform_<Debug>` for a matching header whose platform type has no
101/// canonical short name, or `mask_0x<hex>` if the mask matches no platform
102/// header at all.
103pub fn platform_name_for_mask(platforms: &[IgvmPlatformHeader], mask: u32) -> String {
104    for header in platforms {
105        match header {
106            IgvmPlatformHeader::SupportedPlatform(info) => {
107                if info.compatibility_mask == mask {
108                    return isolation_label(info.platform_type);
109                }
110            }
111        }
112    }
113    format!("mask_0x{mask:x}")
114}