summaryrefslogtreecommitdiff
path: root/gbl/libefi/BUILD
blob: 0c75174694c95db1129a6a131f8f21b638b85424 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Copyright (C) 2023 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@gbl_llvm_prebuilts//:info.bzl", "LLVM_PREBUILTS_C_INCLUDE")
load("@rules_rust//bindgen:defs.bzl", "rust_bindgen")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

package(
    default_visibility = ["//visibility:public"],
)

# Newer version of `rust_bindgen` requires a `cc_library` target that actually produces a static
# library and instead of only headers. Thus we generate a placeholder source file to meet the
# requirement.
genrule(
    name = "bindgen_noop_cc",
    outs = ["bindgen_noop_cc.cc"],
    cmd = "touch $(OUTS)",
)

cc_library(
    name = "efi_c_headers",
    srcs = [":bindgen_noop_cc"],
    hdrs = [
        "defs/boot_service.h",
        "defs/efi.h",
        "defs/protocols/block_io_protocol.h",
        "defs/protocols/device_path_protocol.h",
        "defs/protocols/loaded_image_protocol.h",
        "defs/protocols/riscv_efi_boot_protocol.h",
        "defs/protocols/simple_network_protocol.h",
        "defs/protocols/simple_text_output_protocol.h",
        "defs/system_table.h",
        "defs/types.h",
    ],
    includes = ["defs"],
)

# Side note: function pointers for UEFI interfaces need to specify the "efiapi" ABI. i.e.
# "unsafe extern "efiapi" fn(...)". bindgen uses "extern "C"" by default. We are currently fine
# because for x86_64/x86_32/aarch64, we use dedicated rust UEFI compiler which uses EFIAPI ABI by
# default. For riscv64 which we use ELF compiler, the efiapi calling convention is the same as C
# calling convention according to the UEFI spec at the time of writing. If we do eventually run
# into problems, we need to use a newer version of bindgen 0.65.0 or above, which offers
# "--override-abi" with "efiapi" option.
rust_bindgen(
    name = "efi_defs_bindgen",
    bindgen_flags = [
        "--ctypes-prefix",
        "core::ffi",
        "--use-core",
        "--with-derive-partialeq",
        "--with-derive-default",
        "--with-derive-custom-struct=EfiMemoryDescriptor=AsBytes,FromBytes,FromZeroes",
        "--allowlist-type",
        "(Efi.*)",
        "--raw-line",
        """
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use zerocopy::{AsBytes, FromBytes, FromZeroes};""",
    ],
    cc_lib = ":efi_c_headers",
    # For x86_32, we need to explicitly specify 32bit architecture.
    clang_flags = select({
        "@gbl//toolchain:gbl_rust_uefi_x86_32": ["-m32"],
        "//conditions:default": ["-m64"],
    }) + [
        "-I{}".format(LLVM_PREBUILTS_C_INCLUDE),
        "-nostdinc",
    ],
    header = "defs/efi.h",
)

# Copy the generated source to "src/defs.rs" in the output assembly, so that libefi can include it
# as a source.
genrule(
    name = "efi_defs_genrule",
    srcs = [":efi_defs_bindgen"],
    outs = ["src/defs.rs"],
    cmd = "cat $(location :efi_defs_bindgen) > $@",
)

rust_library(
    name = "libefi",
    srcs = [
        "src/allocation.rs",
        "src/defs.rs",  # Generated by :efi_defs_genrule
        "src/lib.rs",
        "src/protocol.rs",
    ],
    crate_name = "efi",
    data = [":efi_defs_genrule"],
    deps = ["@zerocopy"],
)

rust_test(
    name = "libefi_test",
    crate = ":libefi",
)